diff options
234 files changed, 17615 insertions, 7315 deletions
@@ -1,8 +1,8 @@ /GIT-BUILD-OPTIONS /GIT-CFLAGS /GIT-LDFLAGS -/GIT-GUI-VARS /GIT-PREFIX +/GIT-PYTHON-VARS /GIT-SCRIPT-DEFINES /GIT-USER-AGENT /GIT-VERSION-FILE @@ -124,7 +124,8 @@ /git-remote-ftps /git-remote-fd /git-remote-ext -/git-remote-testgit +/git-remote-testpy +/git-remote-testsvn /git-repack /git-replace /git-repo-config @@ -170,7 +171,6 @@ /git-whatchanged /git-write-tree /git-core-*/?* -/gitk-git/gitk-wish /gitweb/GITWEB-BUILD-OPTIONS /gitweb/gitweb.cgi /gitweb/static/gitweb.js diff --git a/Documentation/Makefile b/Documentation/Makefile index fe9a91d..e53d333 100644 --- a/Documentation/Makefile +++ b/Documentation/Makefile @@ -21,6 +21,7 @@ ARTICLES += git-tools ARTICLES += git-bisect-lk2009 # with their own formatting rules. SP_ARTICLES = user-manual +SP_ARTICLES += howto/new-command SP_ARTICLES += howto/revert-branch-rebase SP_ARTICLES += howto/using-merge-subtree SP_ARTICLES += howto/using-signed-tag-in-pull-request @@ -31,7 +32,6 @@ SP_ARTICLES += howto/separating-topic-branches SP_ARTICLES += howto/revert-a-faulty-merge SP_ARTICLES += howto/recover-corrupted-blob-object SP_ARTICLES += howto/rebuild-from-update-hook -SP_ARTICLES += howto/rebuild-from-update-hook SP_ARTICLES += howto/rebase-from-internal-branch SP_ARTICLES += howto/maintain-git API_DOCS = $(patsubst %.txt,%,$(filter-out technical/api-index-skel.txt technical/api-index.txt, $(wildcard technical/api-*.txt))) diff --git a/Documentation/RelNotes/1.8.1.txt b/Documentation/RelNotes/1.8.1.txt new file mode 100644 index 0000000..d6f9555 --- /dev/null +++ b/Documentation/RelNotes/1.8.1.txt @@ -0,0 +1,241 @@ +Git v1.8.1 Release Notes +======================== + +Backward compatibility notes +---------------------------- + +In the next major release (not *this* one), we will change the +behavior of the "git push" command. + +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). We will use the "simple" semantics that pushes the +current branch to the branch with the same name, only when the current +branch is set to integrate with that remote branch. There is a user +preference configuration variable "push.default" to change this, and +"git push" will warn about the upcoming change until you set this +variable in this release. + +"git branch --set-upstream" is deprecated and may be removed in a +relatively distant future. "git branch [-u|--set-upstream-to]" has +been introduced with a saner order of arguments to replace it. + + +Updates since v1.8.0 +-------------------- + +UI, Workflows & Features + + * Command-line completion scripts for tcsh and zsh have been added. + + * "git-prompt" scriptlet (in contrib/completion) can be told to paint + pieces of the hints in the prompt string in colors. + + * Some documentation pages that used to ship only in the plain text + format are now formatted in HTML as well. + + * We used to have a workaround for a bug in ancient "less" that + causes it to exit without any output when the terminal is resized. + The bug has been fixed in "less" version 406 (June 2007), and the + workaround has been removed in this release. + + * When "git checkout" checks out a branch, it tells the user how far + behind (or ahead) the new branch is relative to the remote tracking + branch it builds upon. The message now also advises how to sync + them up by pushing or pulling. This can be disabled with the + advice.statusHints configuration variable. + + * "git config --get" used to diagnose presence of multiple + definitions of the same variable in the same configuration file as + an error, but it now applies the "last one wins" rule used by the + internal configuration logic. Strictly speaking, this may be an + API regression but it is expected that nobody will notice it in + practice. + + * A new configuration variable "diff.context" can be used to + give the default number of context lines in the patch output, to + override the hardcoded default of 3 lines. + + * "git format-patch" learned the "--notes=<ref>" option to give + notes for the commit after the three-dash lines in its output. + + * "git log -p -S<string>" now looks for the <string> after applying + the textconv filter (if defined); earlier it inspected the contents + of the blobs without filtering. + + * "git log --grep=<pcre>" learned to honor the "grep.patterntype" + configuration set to "perl". + + * "git replace -d <object>" now interprets <object> as an extended + SHA-1 (e.g. HEAD~4 is allowed), instead of only accepting full hex + object name. + + * "git rm $submodule" used to punt on removing a submodule working + tree to avoid losing the repository embedded in it. Because + recent git uses a mechanism to separate the submodule repository + from the submodule working tree, "git rm" learned to detect this + case and removes the submodule working tree when it is safe to do so. + + * "git send-email" used to prompt for the sender address, even when + the committer identity is well specified (e.g. via user.name and + user.email configuration variables). The command no longer gives + this prompt when not necessary. + + * "git send-email" did not allow non-address garbage strings to + appear after addresses on Cc: lines in the patch files (and when + told to pick them up to find more recipients), e.g. + + Cc: Stable Kernel <stable@k.org> # for v3.2 and up + + The command now strips " # for v3.2 and up" part before adding the + remainder of this line to the list of recipients. + + * "git submodule add" learned to add a new submodule at the same + path as the path where an unrelated submodule was bound to in an + existing revision via the "--name" option. + + * "git submodule sync" learned the "--recursive" option. + + * "diff.submodule" configuration variable can be used to give custom + default value to the "git diff --submodule" option. + + * "git symbolic-ref" learned the "-d $symref" option to delete the + named symbolic ref, which is more intuitive way to spell it than + "update-ref -d --no-deref $symref". + + +Foreign Interface + + * "git cvsimport" can be told to record timezones (other than GMT) + per-author via its author info file. + + * The remote helper interface to interact with subversion + repositories (one of the GSoC 2012 projects) has been merged. + + * A new remote-helper interface for Mercurial has been added to + contrib/remote-helpers. + + * The documentation for git(1) was pointing at a page at an external + site for the list of authors that no longer existed. The link has + been updated to point at an alternative site. + + +Performance, Internal Implementation, etc. + + * Compilation on Cygwin with newer header files are supported now. + + * A couple of low-level implementation updates on MinGW. + + * The logic to generate the initial advertisement from "upload-pack" + (i.e. what is invoked by "git fetch" on the other side of the + connection) to list what refs are available in the repository has + been optimized. + + * The logic to find set of attributes that match a given path has + been optimized. + + * Use preloadindex in "git diff-index" and "git update-index", which + has a nice speedup on systems with slow stat calls (and even on + Linux). + + +Also contains minor documentation updates and code clean-ups. + + +Fixes since v1.8.0 +------------------ + +Unless otherwise noted, all the fixes since v1.8.0 in the maintenance +track are contained in this release (see release notes to them for +details). + + * The configuration parser had an unnecessary hardcoded limit on + variable names that was not checked consistently. + + * The "say" function in the test scaffolding incorrectly allowed + "echo" to interpret "\a" as if it were a C-string asking for a + BEL output. + + * "git mergetool" feeds /dev/null as a common ancestor when dealing + with an add/add conflict, but p4merge backend cannot handle + it. Work it around by passing a temporary empty file. + + * "git log -F -E --grep='<ere>'" failed to use the given <ere> + pattern as extended regular expression, and instead looked for the + string literally. + + * "git grep -e pattern <tree>" asked the attribute system to read + "<tree>:.gitattributes" file in the working tree, which was + nonsense. + + * A symbolic ref refs/heads/SYM was not correctly removed with "git + branch -d SYM"; the command removed the ref pointed by SYM + instead. + + * Update "remote tracking branch" in the documentation to + "remote-tracking branch". + + * "git pull --rebase" run while the HEAD is detached tried to find + the upstream branch of the detached HEAD (which by definition + does not exist) and emitted unnecessary error messages. + + * The refs/replace hierarchy was not mentioned in the + repository-layout docs. + + * Various rfc2047 quoting issues around a non-ASCII name on the + From: line in the output from format-patch have been corrected. + + * Sometimes curl_multi_timeout() function suggested a wrong timeout + value when there is no file descriptor to wait on and the http + transport ended up sleeping for minutes in select(2) system call. + A workaround has been added for this. + + * For a fetch refspec (or the result of applying wildcard on one), + we always want the RHS to map to something inside "refs/" + hierarchy, but the logic to check it was not exactly right. + (merge 5c08c1f jc/maint-fetch-tighten-refname-check later to maint). + + * "git diff -G<pattern>" did not honor textconv filter when looking + for changes. + + * Some HTTP servers ask for auth only during the actual packing phase + (not in ls-remote phase); this is not really a recommended + configuration, but the clients used to fail to authenticate with + such servers. + (merge 2e736fd jk/maint-http-half-auth-fetch later to maint). + + * "git p4" used to try expanding malformed "$keyword$" that spans + across multiple lines. + + * Syntax highlighting in "gitweb" was not quite working. + + * RSS feed from "gitweb" had a xss hole in its title output. + + * "git config --path $key" segfaulted on "[section] key" (a boolean + "true" spelled without "=", not "[section] key = true"). + + * "git checkout -b foo" while on an unborn branch did not say + "Switched to a new branch 'foo'" like other cases. + + * Various codepaths have workaround for a common misconfiguration to + spell "UTF-8" as "utf8", but it was not used uniformly. Most + notably, mailinfo (which is used by "git am") lacked this support. + + * We failed to mention a file without any content change but whose + permission bit was modified, or (worse yet) a new file without any + content in the "git diff --stat" output. + + * When "--stat-count" hides a diffstat for binary contents, the total + number of added and removed lines at the bottom was computed + incorrectly. + + * When "--stat-count" hides a diffstat for unmerged paths, the total + number of affected files at the bottom of the "diff --stat" output + was computed incorrectly. + + * "diff --shortstat" miscounted the total number of affected files + when there were unmerged paths. + + * "update-ref -d --deref SYM" to delete a ref through a symbolic ref + that points to it did not remove it correctly. diff --git a/Documentation/RelNotes/1.8.2.txt b/Documentation/RelNotes/1.8.2.txt new file mode 100644 index 0000000..92de751 --- /dev/null +++ b/Documentation/RelNotes/1.8.2.txt @@ -0,0 +1,147 @@ +Git v1.8.2 Release Notes +======================== + +Backward compatibility notes +---------------------------- + +In the upcoming major release (tentatively called 1.8.2), we will +change the behavior of the "git push" command. + +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). We will use the "simple" semantics that pushes the +current branch to the branch with the same name, only when the current +branch is set to integrate with that remote branch. There is a user +preference configuration variable "push.default" to change this. + + +Updates since v1.8.1 +-------------------- + +UI, Workflows & Features + + * Initial ports to QNX and z/OS UNIX System Services have started. + + * Output from the tests is coloured using "green is okay, yellow is + questionable, red is bad and blue is informative" scheme. + + * In bare repositories, "git shortlog" and other commands now read + mailmap files from the tip of the history, to help running these + tools in server settings. + + * Color specifiers, e.g. "%C(blue)Hello%C(reset)", used in the + "--format=" option of "git log" and friends can be disabled when + the output is not sent to a terminal by prefixing them with + "auto,", e.g. "%C(auto,blue)Hello%C(auto,reset)". + + * Scripts can ask Git that wildcard patterns in pathspecs they give do + not have any significance, i.e. take them as literal strings. + + * "git fetch --mirror" and fetch that uses other forms of refspec + with wildcard used to attempt to update a symbolic ref that match + the wildcard on the receiving end, which made little sense (the + real ref that is pointed at by the symbolic ref would be updated + anyway). Symbolic refs no longer are affected by such a fetch. + + * "git push" now requires "-f" to update a tag, even if it is a + fast-forward, as tags are meant to be fixed points. + + * "git submodule" started learning a new mode to integrate with the + tip of the remote branch (as opposed to integrating with the commit + recorded in the superproject's gitlink). + + +Foreign Interface + + * "git fast-export" has been updated for its use in the context of + the remote helper interface. + + +Performance, Internal Implementation, etc. + + * "git fsck" has been taught to be pickier about entries in tree + objects that should not be there, e.g. ".", ".git", and "..". + + * Matching paths with common forms of pathspecs that contain wildcard + characters has been optimized further. + + * The implementation of "imap-send" has been updated to reuse xml + quoting code from http-push codepath. + + +Also contains minor documentation updates and code clean-ups. + + +Fixes since v1.8.1 +------------------ + +Unless otherwise noted, all the fixes since v1.8.1 in the maintenance +track are contained in this release (see release notes to them for +details). + + * An element on GIT_CEILING_DIRECTORIES list that does not name the + real path to a directory (i.e. a symbolic link) could have caused + the GIT_DIR discovery logic to escape the ceiling. + (merge 059b379 mh/ceiling later to maint). + + * t4014, t9502 and t0200 tests had various portability issues that + broke on OpenBSD. + (merge 27f6342 jc/maint-test-portability later to maint). + + * t9020 and t3600 tests had various portability issues. + (merge 5a02966 jc/test-portability later to maint). + + * t9200 runs "cvs init" on a directory that already exists, but a + platform can configure this fail for the current user (e.g. you + need to be in the cvsadmin group on NetBSD 6.0). + (merge 8666df0 jc/test-cvs-no-init-in-existing-dir later to maint). + + * The behaviour visible to the end users was confusing, when they + attempt to kill a process spawned in the editor that was in turn + launched by Git with SIGINT (or SIGQUIT), as Git would catch that + signal and die. We ignore these signals now. + (merge 1250857 pf/editor-ignore-sigint later to maint). + + * After failing to create a temporary file using mkstemp(), failing + pathname was not reported correctly on some platforms. + (merge f7be59b jc/mkstemp-more-careful-error-reporting later to maint). + + * The attribute mechanism didn't allow limiting attributes to be + applied to only a single directory itself with "path/" like the + exclude mechanism does. + (merge 94bc671 ja/directory-attrs later to maint). + + * The way "git svn" asked for password using SSH_ASKPASS and + GIT_ASKPASS was not in line with the rest of the system. + (merge e9263e4 ss/svn-prompt later to maint). + + * The --graph code fell into infinite loop when asked to do what the + code did not expect. + (merge 656197a mk/maint-graph-infinity-loop later to maint). + + * http transport was wrong to ask for the username when the + authentication is done by certificate identity. + (merge 75e9a40 rb/http-cert-cred-no-username-prompt later to maint). + + * "git pack-refs" that ran in parallel to another process that + created new refs had a nasty race. + (merge b3f1280 jk/repack-ref-racefix later to maint). + + * After "git add -N" and then writing a tree object out of the + index, the cache-tree data structure got corrupted. + (merge eec3e7e nd/invalidate-i-t-a-cache-tree later to maint). + + * "gitweb", when sorting by age to show repositories with new + activities first, used to sort repositories with absolutely + nothing in it early, which was not very useful. + (merge 28dae18 md/gitweb-sort-by-age later to maint). + + * When a line to be wrapped has a solid run of non space characters + whose length exactly is the wrap width, "git shortlog -w" failed + to add a newline after such a line. + (merge e0db176 sp/shortlog-missing-lf later to maint). + + * Some shells do not behave correctly when IFS is unset; work it + around by explicitly setting it to the default value. + (merge 393050c jc/maint-fbsd-sh-ifs-workaround later to maint). diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches index c34c9d1..75935d5 100644 --- a/Documentation/SubmittingPatches +++ b/Documentation/SubmittingPatches @@ -174,7 +174,8 @@ message starts, you can put a "From: " line to name that person. You often want to add additional explanation about the patch, other than the commit message itself. Place such "cover letter" -material between the three dash lines and the diffstat. +material between the three dash lines and the diffstat. Git-notes +can also be inserted using the `--notes` option. Do not attach the patch as a MIME attachment, compressed or not. Do not let your e-mail client send quoted-printable. Do not let diff --git a/Documentation/config.txt b/Documentation/config.txt index d1de857..53c4ca1 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -140,10 +140,11 @@ advice.*:: can tell Git that you do not need help by setting these to 'false': + -- - pushNonFastForward:: + pushUpdateRejected:: Set this variable to 'false' if you want to disable - 'pushNonFFCurrent', 'pushNonFFDefault', and - 'pushNonFFMatching' simultaneously. + 'pushNonFFCurrent', 'pushNonFFDefault', + 'pushNonFFMatching', and 'pushAlreadyExists' + simultaneously. pushNonFFCurrent:: Advice shown when linkgit:git-push[1] fails due to a non-fast-forward update to the current branch. @@ -158,11 +159,15 @@ advice.*:: 'matching refs' explicitly (i.e. you used ':', or specified a refspec that isn't your current branch) and it resulted in a non-fast-forward error. + pushAlreadyExists:: + Shown when linkgit:git-push[1] rejects an update that + does not qualify for fast-forwarding (e.g., a tag.) statusHints:: Show directions on how to proceed from the current - state in the output of linkgit:git-status[1] and in + state in the output of linkgit:git-status[1], in the template shown when writing commit messages in - linkgit:git-commit[1]. + linkgit:git-commit[1], and in the help message shown + by linkgit:git-checkout[1] when switching branch. commitBeforeMerge:: Advice shown when linkgit:git-merge[1] refuses to merge to avoid overwriting local changes. @@ -538,14 +543,14 @@ core.pager:: `LESS` variable to some other value. Alternately, these settings can be overridden on a project or global basis by setting the `core.pager` option. - Setting `core.pager` has no affect on the `LESS` + Setting `core.pager` has no effect on the `LESS` environment variable behaviour above, so if you want to override git's default settings this way, you need to be explicit. For example, to disable the S option in a backward compatible manner, set `core.pager` - to `less -+$LESS -FRX`. This will be passed to the - shell by git, which will translate the final command to - `LESS=FRSX less -+FRSX -FRX`. + to `less -+S`. This will be passed to the shell by + git, which will translate the final command to + `LESS=FRSX less -+S`. core.whitespace:: A comma separated list of common whitespace problems to @@ -1516,6 +1521,14 @@ mailmap.file:: subdirectory, or somewhere outside of the repository itself. See linkgit:git-shortlog[1] and linkgit:git-blame[1]. +mailmap.blob:: + Like `mailmap.file`, but consider the value as a reference to a + blob in the repository. If both `mailmap.file` and + `mailmap.blob` are given, both are parsed, with entries from + `mailmap.file` taking precedence. In a bare repository, this + defaults to `HEAD:.mailmap`. In a non-bare repository, it + defaults to empty. + man.viewer:: Specify the programs that may be used to display help in the 'man' format. See linkgit:git-help[1]. @@ -1994,6 +2007,12 @@ submodule.<name>.update:: URL and other values found in the `.gitmodules` file. See linkgit:git-submodule[1] and linkgit:gitmodules[5] for details. +submodule.<name>.branch:: + The remote branch name for a submodule, used by `git submodule + update --remote`. Set this option to override the value found in + the `.gitmodules` file. See linkgit:git-submodule[1] and + linkgit:gitmodules[5] for details. + submodule.<name>.fetchRecurseSubmodules:: This option can be used to control recursive fetching of this submodule. It can be overridden by using the --[no-]recurse-submodules diff --git a/Documentation/diff-config.txt b/Documentation/diff-config.txt index c2b94f9..4314ad0 100644 --- a/Documentation/diff-config.txt +++ b/Documentation/diff-config.txt @@ -56,6 +56,10 @@ diff.statGraphWidth:: Limit the width of the graph part in --stat output. If set, applies to all commands generating --stat output except format-patch. +diff.context:: + Generate diffs with <n> lines of context instead of the default + of 3. This value is overridden by the -U option. + diff.external:: If this config variable is set, diff generation is not performed using the internal diff machinery, but using the @@ -103,6 +107,13 @@ diff.suppressBlankEmpty:: A boolean to inhibit the standard behavior of printing a space before each empty output line. Defaults to false. +diff.submodule:: + Specify the format in which differences in submodules are + shown. The "log" format lists the commits in the range like + linkgit:git-submodule[1] `summary` does. The "short" format + format just shows the names of the commits at the beginning + and end of the range. Defaults to short. + diff.wordRegex:: A POSIX Extended Regular Expression used to determine what is a "word" when performing word-by-word difference calculations. Character diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt index 1fb6f2d..39f2c50 100644 --- a/Documentation/diff-options.txt +++ b/Documentation/diff-options.txt @@ -170,7 +170,8 @@ any of those replacements occurred. the commits in the range like linkgit:git-submodule[1] `summary` does. Omitting the `--submodule` option or specifying `--submodule=short`, uses the 'short' format. This format just shows the names of the commits - at the beginning and end of the range. + at the beginning and end of the range. Can be tweaked via the + `diff.submodule` configuration variable. --color[=<when>]:: Show colored diff. diff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt index 19cbb90..7bdb039 100644 --- a/Documentation/git-commit.txt +++ b/Documentation/git-commit.txt @@ -109,6 +109,10 @@ OPTIONS format. See linkgit:git-status[1] for details. Implies `--dry-run`. +--long:: + When doing a dry-run, give the output in a the long-format. + Implies `--dry-run`. + -z:: --null:: When showing `short` or `porcelain` status output, terminate diff --git a/Documentation/git-config.txt b/Documentation/git-config.txt index eaea079..9ae2508 100644 --- a/Documentation/git-config.txt +++ b/Documentation/git-config.txt @@ -240,6 +240,10 @@ GIT_CONFIG:: Using the "--global" option forces this to ~/.gitconfig. Using the "--system" option forces this to $(prefix)/etc/gitconfig. +GIT_CONFIG_NOSYSTEM:: + Whether to skip reading settings from the system-wide + $(prefix)/etc/gitconfig file. See linkgit:git[1] for details. + See also <<FILES>>. diff --git a/Documentation/git-cvsimport.txt b/Documentation/git-cvsimport.txt index 6695ab3..98d9881 100644 --- a/Documentation/git-cvsimport.txt +++ b/Documentation/git-cvsimport.txt @@ -137,17 +137,19 @@ This option can be used several times to provide several detection regexes. -A <author-conv-file>:: CVS by default uses the Unix username when writing its commit logs. Using this option and an author-conv-file - in this format + maps the name recorded in CVS to author name, e-mail and + optional timezone: + --------- exon=Andreas Ericsson <ae@op5.se> - spawn=Simon Pawn <spawn@frog-pond.org> + spawn=Simon Pawn <spawn@frog-pond.org> America/Chicago --------- + 'git cvsimport' will make it appear as those authors had their GIT_AUTHOR_NAME and GIT_AUTHOR_EMAIL set properly -all along. +all along. If a timezone is specified, GIT_AUTHOR_DATE will +have the corresponding offset applied. + For convenience, this data is saved to `$GIT_DIR/cvs-authors` each time the '-A' option is provided and read from that same diff --git a/Documentation/git-fast-import.txt b/Documentation/git-fast-import.txt index 68bca1a..3da5cc2 100644 --- a/Documentation/git-fast-import.txt +++ b/Documentation/git-fast-import.txt @@ -39,10 +39,6 @@ OPTIONS See ``Date Formats'' below for details about which formats are supported, and their syntax. --- done:: - Terminate with error if there is no 'done' command at the - end of the stream. - --force:: Force updating modified existing branches, even if doing so would cause commits to be lost (as the new commit does @@ -108,7 +104,8 @@ OPTIONS output. --done:: - Require a `done` command at the end of the stream. + Terminate with error if there is no `done` command at the + end of the stream. This option might be useful for detecting errors that cause the frontend to terminate before it has started to write a stream. diff --git a/Documentation/git-format-patch.txt b/Documentation/git-format-patch.txt index 6d43f56..259dce4 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] [--to=<email>] [--cc=<email>] - [--cover-letter] [--quiet] + [--cover-letter] [--quiet] [--notes[=<ref>]] [<common diff options>] [ <since> | <revision range> ] @@ -191,6 +191,18 @@ will want to ensure that threading is disabled for `git send-email`. containing the shortlog and the overall diffstat. You can fill in a description in the file before sending it out. +--notes[=<ref>]:: + Append the notes (see linkgit:git-notes[1]) for the commit + after the three-dash line. ++ +The expected use case of this is to write supporting explanation for +the commit that does not belong to the commit log message proper, +and include it with the patch submission. While one can simply write +these explanations after `format-patch` has run but before sending, +keeping them as git notes allows them to be maintained between versions +of the patch series (but see the discussion of the `notes.rewrite` +configuration options in linkgit:git-notes[1] to use this workflow). + --[no]-signature=<signature>:: Add a signature to each message produced. Per RFC 3676 the signature is separated from the body by a line with '-- ' on it. If the diff --git a/Documentation/git-log.txt b/Documentation/git-log.txt index 585dac4..08a185d 100644 --- a/Documentation/git-log.txt +++ b/Documentation/git-log.txt @@ -167,7 +167,7 @@ log.showroot:: `git log -p` output would be shown without a diff attached. The default is `true`. -mailmap.file:: +mailmap.*:: See linkgit:git-shortlog[1]. notes.displayRef:: diff --git a/Documentation/git-notes.txt b/Documentation/git-notes.txt index b95aafa..46ef046 100644 --- a/Documentation/git-notes.txt +++ b/Documentation/git-notes.txt @@ -39,6 +39,10 @@ message stored in the commit object, the notes are indented like the message, after an unindented line saying "Notes (<refname>):" (or "Notes:" for `refs/notes/commits`). +Notes can also be added to patches prepared with `git format-patch` by +using the `--notes` option. Such notes are added as a patch commentary +after a three dash separator line. + To change which notes are shown by 'git log', see the "notes.displayRef" configuration in linkgit:git-log[1]. diff --git a/Documentation/git-push.txt b/Documentation/git-push.txt index 8b637d3..c964b79 100644 --- a/Documentation/git-push.txt +++ b/Documentation/git-push.txt @@ -51,10 +51,11 @@ be named. If `:`<dst> is omitted, the same ref as <src> will be updated. + The object referenced by <src> is used to update the <dst> reference -on the remote side, but by default this is only allowed if the -update can fast-forward <dst>. By having the optional leading `+`, -you can tell git to update the <dst> ref even when the update is not a -fast-forward. This does *not* attempt to merge <src> into <dst>. See +on the remote side. By default this is only allowed if <dst> is not +a tag (annotated or lightweight), and then only if it can fast-forward +<dst>. By having the optional leading `+`, you can tell git to update +the <dst> ref even if it is not allowed by default (e.g., it is not a +fast-forward.) This does *not* attempt to merge <src> into <dst>. See EXAMPLES below for details. + `tag <tag>` means the same as `refs/tags/<tag>:refs/tags/<tag>`. diff --git a/Documentation/git-remote-helpers.txt b/Documentation/git-remote-helpers.txt index 4f81a5b..6d696e0 100644 --- a/Documentation/git-remote-helpers.txt +++ b/Documentation/git-remote-helpers.txt @@ -88,53 +88,17 @@ Each remote helper is expected to support only a subset of commands. The operations a helper supports are declared to git in the response to the `capabilities` command (see COMMANDS, below). -'option':: - For specifying settings like `verbosity` (how much output to - write to stderr) and `depth` (how much history is wanted in the - case of a shallow clone) that affect how other commands are - carried out. - -'connect':: - For fetching and pushing using git's native packfile protocol - that requires a bidirectional, full-duplex connection. - -'push':: - For listing remote refs and pushing specified objects from the - local object store to remote refs. - -'fetch':: - For listing remote refs and fetching the associated history to - the local object store. - -'import':: - For listing remote refs and fetching the associated history as - a fast-import stream. - -'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. - It is recommended that all importers providing the 'import' - capability use this. -+ -A helper advertising the capability -`refspec refs/heads/*:refs/svn/origin/branches/*` -is saying that, when it is asked to `import refs/heads/topic`, the -stream it outputs will update the `refs/svn/origin/branches/topic` -ref. -+ -This capability can be advertised multiple times. The first -applicable refspec takes precedence. The left-hand of refspecs -advertised with this capability must cover all refs reported by -the list command. If no 'refspec' capability is advertised, -there is an implied `refspec *:*`. +In the following, we list all defined capabilities and for +each we list which commands a helper with that capability +must provide. Capabilities for Pushing -~~~~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^^^^ 'connect':: Can attempt to connect to 'git receive-pack' (for pushing), - 'git upload-pack', etc for communication using the - packfile protocol. + 'git upload-pack', etc for communication using + git's native packfile protocol. This + requires a bidirectional, full-duplex connection. + Supported commands: 'connect'. @@ -144,16 +108,26 @@ Supported commands: 'connect'. + Supported commands: 'list for-push', 'push'. -If a helper advertises both 'connect' and 'push', git will use -'connect' if possible and fall back to 'push' if the helper requests -so when connecting (see the 'connect' command under COMMANDS). +'export':: + Can discover remote refs and push specified objects from a + fast-import stream to remote refs. ++ +Supported commands: 'list for-push', 'export'. + +If a helper advertises 'connect', git will use it if possible and +fall back to another capability if the helper requests so when +connecting (see the 'connect' command under COMMANDS). +When choosing between 'push' and 'export', git prefers 'push'. +Other frontends may have some other order of preference. + Capabilities for Fetching -~~~~~~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^^^^^^ 'connect':: Can try to connect to 'git upload-pack' (for fetching), 'git receive-pack', etc for communication using the - packfile protocol. + git's native packfile protocol. This + requires a bidirectional, full-duplex connection. + Supported commands: 'connect'. @@ -175,14 +149,27 @@ connecting (see the 'connect' command under COMMANDS). When choosing between 'fetch' and 'import', git prefers 'fetch'. Other frontends may have some other order of preference. +Miscellaneous capabilities +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +'option':: + For specifying settings like `verbosity` (how much output to + write to stderr) and `depth` (how much history is wanted in the + case of a shallow clone) that affect how other commands are + carried out. + 'refspec' <refspec>:: - This modifies the 'import' capability. + 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. + It is recommended that all importers providing the 'import' + capability use this. + -A helper advertising +A helper advertising the capability `refspec refs/heads/*:refs/svn/origin/branches/*` -in its capabilities is saying that, when it handles -`import refs/heads/topic`, the stream it outputs will update the -`refs/svn/origin/branches/topic` ref. +is saying that, when it is asked to `import refs/heads/topic`, the +stream it outputs will update the `refs/svn/origin/branches/topic` +ref. + This capability can be advertised multiple times. The first applicable refspec takes precedence. The left-hand of refspecs @@ -190,6 +177,34 @@ advertised with this capability must cover all refs reported by the list command. If no 'refspec' capability is advertised, there is an implied `refspec *:*`. +'bidi-import':: + This modifies the 'import' capability. + The fast-import commands 'cat-blob' and 'ls' can be used by remote-helpers + to retrieve information about blobs and trees that already exist in + fast-import's memory. This requires a channel from fast-import to the + remote-helper. + If it is advertised in addition to "import", git establishes a pipe from + fast-import to the remote-helper's stdin. + It follows that git and fast-import are both connected to the + remote-helper's stdin. Because git can send multiple commands to + the remote-helper it is required that helpers that use 'bidi-import' + buffer all 'import' commands of a batch before sending data to fast-import. + This is to prevent mixing commands and fast-import responses on the + helper's stdin. + +'export-marks' <file>:: + This modifies the 'export' capability, instructing git to dump the + internal marks table to <file> when complete. For details, + read up on '--export-marks=<file>' in linkgit:git-fast-export[1]. + +'import-marks' <file>:: + This modifies the 'export' capability, instructing git to load the + marks specified in <file> before processing any input. For details, + read up on '--import-marks=<file>' in linkgit:git-fast-export[1]. + + + + COMMANDS -------- @@ -198,9 +213,11 @@ Commands are given by the caller on the helper's standard input, one per line. 'capabilities':: Lists the capabilities of the helper, one per line, ending with a blank line. Each capability may be preceded with '*', - which marks them mandatory for git version using the remote - helper to understand (unknown mandatory capability is fatal - error). + which marks them mandatory for git versions using the remote + helper to understand. Any unknown mandatory capability is a + fatal error. ++ +Support for this command is mandatory. 'list':: Lists the refs, one per line, in the format "<value> <name> @@ -210,9 +227,20 @@ Commands are given by the caller on the helper's standard input, one per line. the name; unrecognized attributes are ignored. The list ends with a blank line. + -If 'push' is supported this may be called as 'list for-push' -to obtain the current refs prior to sending one or more 'push' -commands to the helper. +See REF LIST ATTRIBUTES for a list of currently defined attributes. ++ +Supported if the helper has the "fetch" or "import" capability. + +'list for-push':: + Similar to 'list', except that it is used if and only if + the caller wants to the resulting ref list to prepare + push commands. + A helper supporting both push and fetch can use this + to distinguish for which operation the output of 'list' + is going to be used, possibly reducing the amount + of work that needs to be performed. ++ +Supported if the helper has the "push" or "export" capability. 'option' <name> <value>:: Sets the transport helper option <name> to <value>. Outputs a @@ -222,6 +250,8 @@ commands to the helper. for it). Options should be set before other commands, and may influence the behavior of those commands. + +See OPTIONS for a list of currently defined options. ++ Supported if the helper has the "option" capability. 'fetch' <sha1> <name>:: @@ -230,7 +260,7 @@ Supported if the helper has the "option" capability. per line, terminated with a blank line. Outputs a single blank line when all fetch commands in the same batch are complete. Only objects which were reported - in the ref list with a sha1 may be fetched this way. + in the output of 'list' with a sha1 may be fetched this way. + Optionally may output a 'lock <file>' line indicating a file under GIT_DIR/objects/pack which is keeping a pack until refs can be @@ -286,8 +316,29 @@ terminated with a blank line. For each batch of 'import', the remote helper should produce a fast-import stream terminated by a 'done' command. + +Note that if the 'bidi-import' capability is used the complete batch +sequence has to be buffered before starting to send data to fast-import +to prevent mixing of commands and fast-import responses on the helper's +stdin. ++ Supported if the helper has the "import" capability. +'export':: + Instructs the remote helper that any subsequent input is + part of a fast-import stream (generated by 'git fast-export') + containing objects which should be pushed to the remote. ++ +Especially useful for interoperability with a foreign versioning +system. ++ +The 'export-marks' and 'import-marks' capabilities, if specified, +affect this command in so far as they are passed on to 'git +fast-export', which then will load/store a table of marks for +local objects. This can be used to implement for incremental +operations. ++ +Supported if the helper has the "export" capability. + 'connect' <service>:: Connects to given service. Standard input and standard output of helper are connected to specified service (git prefix is @@ -313,10 +364,9 @@ capabilities reported by the helper. REF LIST ATTRIBUTES ------------------- -'for-push':: - The caller wants to use the ref list to prepare push - commands. A helper might chose to acquire the ref list by - opening a different type of connection to the destination. +The 'list' command produces a list of refs in which each ref +may be followed by a list of attributes. The following ref list +attributes are defined. 'unchanged':: This ref is unchanged since the last import or fetch, although @@ -324,6 +374,10 @@ REF LIST ATTRIBUTES OPTIONS ------- + +The following options are defined and (under suitable circumstances) +set by git if the remote helper has the 'option' capability. + 'option verbosity' <n>:: Changes the verbosity of messages displayed by the helper. A value of 0 for <n> means that processes operate diff --git a/Documentation/git-remote-testgit.txt b/Documentation/git-remote-testgit.txt index 2a67d45..612a625 100644 --- a/Documentation/git-remote-testgit.txt +++ b/Documentation/git-remote-testgit.txt @@ -19,7 +19,7 @@ testcase for the remote-helper functionality, and as an example to show remote-helper authors one possible implementation. The best way to learn more is to read the comments and source code in -'git-remote-testgit.py'. +'git-remote-testgit'. SEE ALSO -------- diff --git a/Documentation/git-rm.txt b/Documentation/git-rm.txt index 5d31860..262436b 100644 --- a/Documentation/git-rm.txt +++ b/Documentation/git-rm.txt @@ -134,6 +134,21 @@ use the following command: git diff --name-only --diff-filter=D -z | xargs -0 git rm --cached ---------------- +Submodules +~~~~~~~~~~ +Only submodules using a gitfile (which means they were cloned +with a git version 1.7.8 or newer) will be removed from the work +tree, as their repository lives inside the .git directory of the +superproject. If a submodule (or one of those nested inside it) +still uses a .git directory, `git rm` will fail - no matter if forced +or not - to protect the submodule's history. + +A submodule is considered up-to-date when the HEAD is the same as +recorded in the index, no tracked files are modified and no untracked +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. + EXAMPLES -------- `git rm Documentation/\*.txt`:: diff --git a/Documentation/git-send-email.txt b/Documentation/git-send-email.txt index 3241170..eeb561c 100644 --- a/Documentation/git-send-email.txt +++ b/Documentation/git-send-email.txt @@ -126,6 +126,10 @@ The --to option must be repeated for each user you want on the to list. + Note that no attempts whatsoever are made to validate the encoding. +--compose-encoding=<encoding>:: + Specify encoding of compose message. Default is the value of the + 'sendemail.composeencoding'; if that is unspecified, UTF-8 is assumed. + Sending ~~~~~~~ diff --git a/Documentation/git-status.txt b/Documentation/git-status.txt index 67e5f53..9f1ef9a 100644 --- a/Documentation/git-status.txt +++ b/Documentation/git-status.txt @@ -38,6 +38,9 @@ OPTIONS across git versions and regardless of user configuration. See below for details. +--long:: + Give the output in the long-format. This is the default. + -u[<mode>]:: --untracked-files[=<mode>]:: Show untracked files. diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt index a65f38e..b1996f1 100644 --- a/Documentation/git-submodule.txt +++ b/Documentation/git-submodule.txt @@ -9,11 +9,11 @@ git-submodule - Initialize, update or inspect submodules SYNOPSIS -------- [verse] -'git submodule' [--quiet] add [-b <branch>] [-f|--force] +'git submodule' [--quiet] add [-b <branch>] [-f|--force] [--name <name>] [--reference <repository>] [--] <repository> [<path>] 'git submodule' [--quiet] status [--cached] [--recursive] [--] [<path>...] 'git submodule' [--quiet] init [--] [<path>...] -'git submodule' [--quiet] update [--init] [-N|--no-fetch] [--rebase] +'git submodule' [--quiet] update [--init] [--remote] [-N|--no-fetch] [--rebase] [--reference <repository>] [--merge] [--recursive] [--] [<path>...] 'git submodule' [--quiet] summary [--cached|--files] [(-n|--summary-limit) <n>] [commit] [--] [<path>...] @@ -208,6 +208,8 @@ OPTIONS -b:: --branch:: Branch of repository to add as submodule. + The name of the branch is recorded as `submodule.<path>.branch` in + `.gitmodules` for `update --remote`. -f:: --force:: @@ -236,6 +238,27 @@ OPTIONS (the default). This limit only applies to modified submodules. The size is always limited to 1 for added/deleted/typechanged submodules. +--remote:: + This option is only valid for the update command. Instead of using + the superproject's recorded SHA-1 to update the submodule, use the + status of the submodule's remote tracking branch. The remote used + is branch's remote (`branch.<name>.remote`), defaulting to `origin`. + The remote branch used defaults to `master`, but the branch name may + be overridden by setting the `submodule.<name>.branch` option in + either `.gitmodules` or `.git/config` (with `.git/config` taking + precedence). ++ +This works for any of the supported update procedures (`--checkout`, +`--rebase`, etc.). The only change is the source of the target SHA-1. +For example, `submodule update --remote --merge` will merge upstream +submodule changes into the submodules, while `submodule update +--merge` will merge superproject gitlink changes into the submodules. ++ +In order to ensure a current tracking branch state, `update --remote` +fetches the submodule's remote repository before calculating the +SHA-1. If you don't want to fetch, you should use `submodule update +--remote --no-fetch`. + -N:: --no-fetch:: This option is only valid for the update command. @@ -265,6 +288,11 @@ OPTIONS Initialize all submodules for which "git submodule init" has not been called so far before updating. +--name:: + This option is only valid for the add command. It sets the submodule's + name to the given string instead of defaulting to its path. The name + must be valid as a directory name and may not end with a '/'. + --reference <repository>:: This option is only valid for add and update commands. These commands sometimes need to clone a remote repository. In this case, diff --git a/Documentation/git-symbolic-ref.txt b/Documentation/git-symbolic-ref.txt index 981d3a8..ef68ad2 100644 --- a/Documentation/git-symbolic-ref.txt +++ b/Documentation/git-symbolic-ref.txt @@ -3,13 +3,14 @@ git-symbolic-ref(1) NAME ---- -git-symbolic-ref - Read and modify symbolic refs +git-symbolic-ref - Read, modify and delete symbolic refs SYNOPSIS -------- [verse] 'git symbolic-ref' [-m <reason>] <name> <ref> 'git symbolic-ref' [-q] [--short] <name> +'git symbolic-ref' --delete [-q] <name> DESCRIPTION ----------- @@ -21,6 +22,9 @@ argument to see which branch your working tree is on. Given two arguments, creates or updates a symbolic ref <name> to point at the given branch <ref>. +Given `--delete` and an additional argument, deletes the given +symbolic ref. + A symbolic ref is a regular file that stores a string that begins with `ref: refs/`. For example, your `.git/HEAD` is a regular file whose contents is `ref: refs/heads/master`. @@ -28,6 +32,10 @@ a regular file whose contents is `ref: refs/heads/master`. OPTIONS ------- +-d:: +--delete:: + Delete the symbolic ref <name>. + -q:: --quiet:: Do not issue an error message if the <name> is not a diff --git a/Documentation/git.txt b/Documentation/git.txt index b0e8f02..c03b7ad 100644 --- a/Documentation/git.txt +++ b/Documentation/git.txt @@ -43,6 +43,11 @@ 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.1/git.html[documentation for release 1.8.1] + +* release notes for + link:RelNotes/1.8.1.txt[1.8.1]. + * link:v1.8.0.3/git.html[documentation for release 1.8.0.3] * release notes for @@ -423,6 +428,11 @@ help ...`. Do not use replacement refs to replace git objects. See linkgit:git-replace[1] for more information. +--literal-pathspecs:: + Treat pathspecs literally, rather than as glob patterns. This is + equivalent to setting the `GIT_LITERAL_PATHSPECS` environment + variable to `1`. + GIT COMMANDS ------------ @@ -767,6 +777,14 @@ for further details. and read the password from its STDOUT. See also the 'core.askpass' option in linkgit:git-config[1]. +'GIT_CONFIG_NOSYSTEM':: + Whether to skip reading settings from the system-wide + `$(prefix)/etc/gitconfig` file. This environment variable can + be used along with `$HOME` and `$XDG_CONFIG_HOME` to create a + predictable environment for a picky script, or you can set it + temporarily to avoid using a buggy `/etc/gitconfig` file while + waiting for someone with sufficient permissions to fix it. + 'GIT_FLUSH':: If this environment variable is set to "1", then commands such as 'git blame' (in incremental mode), 'git rev-list', 'git log', @@ -791,6 +809,16 @@ for further details. as a file path and will try to write the trace messages into it. +GIT_LITERAL_PATHSPECS:: + Setting this variable to `1` will cause git to treat all + pathspecs literally, rather than as glob patterns. For example, + running `GIT_LITERAL_PATHSPECS=1 git log -- '*.c'` will search + for commits that touch the path `*.c`, not any paths that the + glob `*.c` matches. You might want this if you are feeding + literal paths to git (e.g., paths previously given to you by + `git ls-tree`, `--raw` diff output, etc). + + Discussion[[Discussion]] ------------------------ diff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt index ba02d4d..2698f63 100644 --- a/Documentation/gitattributes.txt +++ b/Documentation/gitattributes.txt @@ -56,6 +56,7 @@ When more than one pattern matches the path, a later line overrides an earlier line. This overriding is done per attribute. The rules how the pattern matches paths are the same as in `.gitignore` files; see linkgit:gitignore[5]. +Unlike `.gitignore`, negative patterns are forbidden. When deciding what attributes are assigned to a path, git consults `$GIT_DIR/info/attributes` file (which has the highest diff --git a/Documentation/gitmodules.txt b/Documentation/gitmodules.txt index 4effd78..52d7ae4 100644 --- a/Documentation/gitmodules.txt +++ b/Documentation/gitmodules.txt @@ -18,7 +18,9 @@ working tree, is a text file with a syntax matching the requirements of linkgit:git-config[1]. The file contains one subsection per submodule, and the subsection value -is the name of the submodule. Each submodule section also contains the +is the name of the submodule. The name is set to the path where the +submodule has been added unless it was customized with the '--name' +option of 'git submodule add'. Each submodule section also contains the following required keys: submodule.<name>.path:: @@ -47,6 +49,11 @@ submodule.<name>.update:: This config option is overridden if 'git submodule update' is given the '--merge', '--rebase' or '--checkout' options. +submodule.<name>.branch:: + A remote branch name for tracking updates in the upstream submodule. + If the option is not specified, it defaults to 'master'. See the + `--remote` documentation in linkgit:git-submodule[1] for details. + submodule.<name>.fetchRecurseSubmodules:: This option can be used to control recursive fetching of this submodule. If this option is also present in the submodules entry in diff --git a/Documentation/howto/new-command.txt b/Documentation/howto/new-command.txt new file mode 100644 index 0000000..36502f6 --- /dev/null +++ b/Documentation/howto/new-command.txt @@ -0,0 +1,104 @@ +From: Eric S. Raymond <esr@thyrsus.com> +Abstract: This is how-to documentation for people who want to add extension + commands to git. It should be read alongside api-builtin.txt. +Content-type: text/asciidoc + +How to integrate new subcommands +================================ + +This is how-to documentation for people who want to add extension +commands to git. It should be read alongside api-builtin.txt. + +Runtime environment +------------------- + +git subcommands are standalone executables that live in the git exec +path, normally /usr/lib/git-core. The git executable itself is a +thin wrapper that knows where the subcommands live, and runs them by +passing command-line arguments to them. + +(If "git foo" is not found in the git exec path, the wrapper +will look in the rest of your $PATH for it. Thus, it's possible +to write local git extensions that don't live in system space.) + +Implementation languages +------------------------ + +Most subcommands are written in C or shell. A few are written in +Perl. + +While we strongly encourage coding in portable C for portability, +these specific scripting languages are also acceptable. We won't +accept more without a very strong technical case, as we don't want +to broaden the git suite's required dependencies. Import utilities, +surgical tools, remote helpers and other code at the edges of the +git suite are more lenient and we allow Python (and even Tcl/tk), +but they should not be used for core functions. + +This may change in the future. Especially Python is not allowed in +core because we need better Python integration in the git Windows +installer before we can be confident people in that environment +won't experience an unacceptably large loss of capability. + +C commands are normally written as single modules, named after the +command, that link a collection of functions called libgit. Thus, +your command 'git-foo' would normally be implemented as a single +"git-foo.c" (or "builtin/foo.c" if it is to be linked to the main +binary); this organization makes it easy for people reading the code +to find things. + +See the CodingGuidelines document for other guidance on what we consider +good practice in C and shell, and api-builtin.txt for the support +functions available to built-in commands written in C. + +What every extension command needs +---------------------------------- + +You must have a man page, written in asciidoc (this is what git help +followed by your subcommand name will display). Be aware that there is +a local asciidoc configuration and macros which you should use. It's +often helpful to start by cloning an existing page and replacing the +text content. + +You must have a test, written to report in TAP (Test Anything Protocol). +Tests are executables (usually shell scripts) that live in the 't' +subdirectory of the tree. Each test name begins with 't' and a sequence +number that controls where in the test sequence it will be executed; +conventionally the rest of the name stem is that of the command +being tested. + +Read the file t/README to learn more about the conventions to be used +in writing tests, and the test support library. + +Integrating a command +--------------------- + +Here are the things you need to do when you want to merge a new +subcommand into the git tree. + +1. Don't forget to sign off your patch! + +2. Append your command name to one of the variables BUILTIN_OBJS, +EXTRA_PROGRAMS, SCRIPT_SH, SCRIPT_PERL or SCRIPT_PYTHON. + +3. Drop its test in the t directory. + +4. If your command is implemented in an interpreted language with a +p-code intermediate form, make sure .gitignore in the main directory +includes a pattern entry that ignores such files. Python .pyc and +.pyo files will already be covered. + +5. If your command has any dependency on a particular version of +your language, document it in the INSTALL file. + +6. There is a file command-list.txt in the distribution main directory +that categorizes commands by type, so they can be listed in appropriate +subsections in the documentation's summary command list. Add an entry +for yours. To understand the categories, look at git-cmmands.txt +in the main directory. + +7. Give the maintainer one paragraph to include in the RelNotes file +to describe the new feature; a good place to do so is in the cover +letter [PATCH 0/n]. + +That's all there is to it. diff --git a/Documentation/mailmap.txt b/Documentation/mailmap.txt index dd89fca..4a8c276 100644 --- a/Documentation/mailmap.txt +++ b/Documentation/mailmap.txt @@ -1,5 +1,6 @@ If the file `.mailmap` exists at the toplevel of the repository, or at -the location pointed to by the mailmap.file configuration option, it +the location pointed to by the mailmap.file or mailmap.blob +configuration options, it is used to map author and committer names and email addresses to canonical real names and email addresses. diff --git a/Documentation/pretty-formats.txt b/Documentation/pretty-formats.txt index d9edded..105f18a 100644 --- a/Documentation/pretty-formats.txt +++ b/Documentation/pretty-formats.txt @@ -144,7 +144,11 @@ The placeholders are: - '%Cgreen': switch color to green - '%Cblue': switch color to blue - '%Creset': reset color -- '%C(...)': color specification, as described in color.branch.* config option +- '%C(...)': color specification, as described in color.branch.* config option; + 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) - '%m': left, right or boundary mark - '%n': newline - '%%': a raw '%' diff --git a/Documentation/pt_BR/gittutorial.txt b/Documentation/pt_BR/gittutorial.txt deleted file mode 100644 index beba065..0000000 --- a/Documentation/pt_BR/gittutorial.txt +++ /dev/null @@ -1,675 +0,0 @@ -gittutorial(7) -============== - -NOME ----- -gittutorial - Um tutorial de introdução ao git (para versão 1.5.1 ou mais nova) - -SINOPSE --------- -git * - -DESCRIÇÃO ------------ - -Este tutorial explica como importar um novo projeto para o git, -adicionar mudanças a ele, e compartilhar mudanças com outros -desenvolvedores. - -Se, ao invés disso, você está interessado primariamente em usar git para -obter um projeto, por exemplo, para testar a última versão, você pode -preferir começar com os primeiros dois capÃtulos de -link:user-manual.html[O Manual do Usuário Git]. - -Primeiro, note que você pode obter documentação para um comando como -`git log --graph` com: - ------------------------------------------------- -$ man git-log ------------------------------------------------- - -ou: - ------------------------------------------------- -$ git help log ------------------------------------------------- - -Com a última forma, você pode usar o visualizador de manual de sua -escolha; veja linkgit:git-help[1] para maior informação. - -É uma boa idéia informar ao git seu nome e endereço público de email -antes de fazer qualquer operação. A maneira mais fácil de fazê-lo é: - ------------------------------------------------- -$ git config --global user.name "Seu Nome Vem Aqui" -$ git config --global user.email voce@seudominio.exemplo.com ------------------------------------------------- - - -Importando um novo projeto ------------------------ - -Assuma que você tem um tarball project.tar.gz com seu trabalho inicial. -Você pode colocá-lo sob controle de revisão git da seguinte forma: - ------------------------------------------------- -$ tar xzf project.tar.gz -$ cd project -$ git init ------------------------------------------------- - -Git irá responder - ------------------------------------------------- -Initialized empty Git repository in .git/ ------------------------------------------------- - -Agora que você iniciou seu diretório de trabalho, você deve ter notado que um -novo diretório foi criado com o nome de ".git". - -A seguir, diga ao git para gravar um instantâneo do conteúdo de todos os -arquivos sob o diretório atual (note o '.'), com 'git-add': - ------------------------------------------------- -$ git add . ------------------------------------------------- - -Este instantâneo está agora armazenado em uma área temporária que o git -chama de "index" ou Ãndice. Você pode armazenar permanentemente o -conteúdo do Ãndice no repositório com 'git-commit': - ------------------------------------------------- -$ git commit ------------------------------------------------- - -Isto vai te pedir por uma mensagem de commit. Você agora gravou sua -primeira versão de seu projeto no git. - -Fazendo mudanças --------------- - -Modifique alguns arquivos, e, então, adicione seu conteúdo atualizado ao -Ãndice: - ------------------------------------------------- -$ git add file1 file2 file3 ------------------------------------------------- - -Você está agora pronto para fazer o commit. Você pode ver o que está -para ser gravado usando 'git-diff' com a opção --cached: - ------------------------------------------------- -$ git diff --cached ------------------------------------------------- - -(Sem --cached, o comando 'git-diff' irá te mostrar quaisquer mudanças -que você tenha feito mas ainda não adicionou ao Ãndice.) Você também -pode obter um breve sumário da situação com 'git-status': - ------------------------------------------------- -$ git status -# On branch master -# Changes to be committed: -# (use "git reset HEAD <file>..." to unstage) -# -# modified: file1 -# modified: file2 -# modified: file3 -# ------------------------------------------------- - -Se você precisar fazer qualquer outro ajuste, faça-o agora, e, então, -adicione qualquer conteúdo modificado ao Ãndice. Finalmente, grave suas -mudanças com: - ------------------------------------------------- -$ git commit ------------------------------------------------- - -Ao executar esse comando, ele irá te pedir uma mensagem descrevendo a mudança, -e, então, irá gravar a nova versão do projeto. - -Alternativamente, ao invés de executar 'git-add' antes, você pode usar - ------------------------------------------------- -$ git commit -a ------------------------------------------------- - -o que irá automaticamente notar quaisquer arquivos modificados (mas não -novos), adicioná-los ao Ãndices, e gravar, tudo em um único passo. - -Uma nota em mensagens de commit: Apesar de não ser exigido, é uma boa -idéia começar a mensagem com uma simples e curta (menos de 50 -caracteres) linha sumarizando a mudança, seguida de uma linha em branco -e, então, uma descrição mais detalhada. Ferramentas que transformam -commits em email, por exemplo, usam a primeira linha no campo de -cabeçalho "Subject:" e o resto no corpo. - -Git rastreia conteúdo, não arquivos ----------------------------- - -Muitos sistemas de controle de revisão provêem um comando `add` que diz -ao sistema para começar a rastrear mudanças em um novo arquivo. O -comando `add` do git faz algo mais simples e mais poderoso: 'git-add' é -usado tanto para arquivos novos e arquivos recentemente modificados, e -em ambos os casos, ele tira o instantâneo dos arquivos dados e armazena -o conteúdo no Ãndice, pronto para inclusão do próximo commit. - -Visualizando a história do projeto ------------------------ - -Em qualquer ponto você pode visualizar a história das suas mudanças -usando - ------------------------------------------------- -$ git log ------------------------------------------------- - -Se você também quiser ver a diferença completa a cada passo, use - ------------------------------------------------- -$ git log -p ------------------------------------------------- - -Geralmente, uma visão geral da mudança é útil para ter a sensação de -cada passo - ------------------------------------------------- -$ git log --stat --summary ------------------------------------------------- - -Gerenciando "branches"/ramos ------------------ - -Um simples repositório git pode manter múltiplos ramos de -desenvolvimento. Para criar um novo ramo chamado "experimental", use - ------------------------------------------------- -$ git branch experimental ------------------------------------------------- - -Se você executar agora - ------------------------------------------------- -$ git branch ------------------------------------------------- - -você vai obter uma lista de todos os ramos existentes: - ------------------------------------------------- - experimental -* master ------------------------------------------------- - -O ramo "experimental" é o que você acaba de criar, e o ramo "master" é o -ramo padrão que foi criado pra você automaticamente. O asterisco marca -o ramo em que você está atualmente; digite - ------------------------------------------------- -$ git checkout experimental ------------------------------------------------- - -para mudar para o ramo experimental. Agora edite um arquivo, grave a -mudança, e mude de volta para o ramo master: - ------------------------------------------------- -(edita arquivo) -$ git commit -a -$ git checkout master ------------------------------------------------- - -Verifique que a mudança que você fez não está mais visÃvel, já que ela -foi feita no ramo experimental e você está de volta ao ramo master. - -Você pode fazer uma mudança diferente no ramo master: - ------------------------------------------------- -(edit file) -$ git commit -a ------------------------------------------------- - -neste ponto, os dois ramos divergiram, com diferentes mudanças feitas em -cada um. Para unificar as mudanças feitas no experimental para o -master, execute - ------------------------------------------------- -$ git merge experimental ------------------------------------------------- - -Se as mudanças não conflitarem, estará pronto. Se existirem conflitos, -marcadores serão deixados nos arquivos problemáticos exibindo o -conflito; - ------------------------------------------------- -$ git diff ------------------------------------------------- - -vai exibir isto. Após você editar os arquivos para resolver os -conflitos, - ------------------------------------------------- -$ git commit -a ------------------------------------------------- - -irá gravar o resultado da unificação. Finalmente, - ------------------------------------------------- -$ gitk ------------------------------------------------- - -vai mostrar uma bela representação gráfica da história resultante. - -Neste ponto você pode remover seu ramo experimental com - ------------------------------------------------- -$ git branch -d experimental ------------------------------------------------- - -Este comando garante que as mudanças no ramo experimental já estão no -ramo atual. - -Se você desenvolve em um ramo ideia-louca, e se arrepende, você pode -sempre remover o ramo com - -------------------------------------- -$ git branch -D ideia-louca -------------------------------------- - -Ramos são baratos e fáceis, então isto é uma boa maneira de experimentar -alguma coisa. - -Usando git para colaboração ---------------------------- - -Suponha que Alice começou um novo projeto com um repositório git em -/home/alice/project, e que Bob, que tem um diretório home na mesma -máquina, quer contribuir. - -Bob começa com: - ------------------------------------------------- -bob$ git clone /home/alice/project myrepo ------------------------------------------------- - -Isso cria um novo diretório "myrepo" contendo um clone do repositório de -Alice. O clone está no mesmo pé que o projeto original, possuindo sua -própria cópia da história do projeto original. - -Bob então faz algumas mudanças e as grava: - ------------------------------------------------- -(editar arquivos) -bob$ git commit -a -(repetir conforme necessário) ------------------------------------------------- - -Quanto está pronto, ele diz a Alice para puxar as mudanças do -repositório em /home/bob/myrepo. Ela o faz com: - ------------------------------------------------- -alice$ cd /home/alice/project -alice$ git pull /home/bob/myrepo master ------------------------------------------------- - -Isto unifica as mudanças do ramo "master" do Bob ao ramo atual de Alice. -Se Alice fez suas próprias mudanças no intervalo, ela, então, pode -precisar corrigir manualmente quaisquer conflitos. (Note que o argumento -"master" no comando acima é, de fato, desnecessário, já que é o padrão.) - -O comando "pull" executa, então, duas operações: ele obtém mudanças de -um ramo remoto, e, então, as unifica no ramo atual. - -Note que, em geral, Alice gostaria que suas mudanças locais fossem -gravadas antes de iniciar este "pull". Se o trabalho de Bob conflita -com o que Alice fez desde que suas histórias se ramificaram, Alice irá -usar seu diretório de trabalho e o Ãndice para resolver conflitos, e -mudanças locais existentes irão interferir com o processo de resolução -de conflitos (git ainda irá realizar a obtenção mas irá se recusar a -unificar --- Alice terá que se livrar de suas mudanças locais de alguma -forma e puxar de novo quando isso acontecer). - -Alice pode espiar o que Bob fez sem unificar primeiro, usando o comando -"fetch"; isto permite Alice inspecionar o que Bob fez, usando um sÃmbolo -especial "FETCH_HEAD", com o fim de determinar se ele tem alguma coisa -que vale puxar, assim: - ------------------------------------------------- -alice$ git fetch /home/bob/myrepo master -alice$ git log -p HEAD..FETCH_HEAD ------------------------------------------------- - -Esta operação é segura mesmo se Alice tem mudanças locais não gravadas. -A notação de intervalo "HEAD..FETCH_HEAD" significa mostrar tudo que é -alcançável de FETCH_HEAD mas exclua tudo o que é alcançável de HEAD. -Alice já sabe tudo que leva a seu estado atual (HEAD), e revisa o que Bob -tem em seu estado (FETCH_HEAD) que ela ainda não viu com esse comando. - -Se Alice quer visualizar o que Bob fez desde que suas histórias se -ramificaram, ela pode disparar o seguinte comando: - ------------------------------------------------- -$ gitk HEAD..FETCH_HEAD ------------------------------------------------- - -Isto usa a mesma notação de intervalo que vimos antes com 'git log'. - -Alice pode querer ver o que ambos fizeram desde que ramificaram. Ela -pode usar a forma com três pontos ao invés da forma com dois pontos: - ------------------------------------------------- -$ gitk HEAD...FETCH_HEAD ------------------------------------------------- - -Isto significa "mostre tudo que é alcançável de qualquer um deles, mas -exclua tudo que é alcançável a partir de ambos". - -Por favor, note que essas notações de intervalo podem ser usadas tanto -com gitk quanto com "git log". - -Após inspecionar o que Bob fez, se não há nada urgente, Alice pode -decidir continuar trabalhando sem puxar de Bob. Se a história de Bob -tem alguma coisa que Alice precisa imediatamente, Alice pode optar por -separar seu trabalho em progresso primeiro, fazer um "pull", e, então, -finalmente, retomar seu trabalho em progresso em cima da história -resultante. - -Quando você está trabalhando em um pequeno grupo unido, não é incomum -interagir com o mesmo repositório várias e várias vezes. Definindo um -repositório remoto antes de tudo, você pode fazê-lo mais facilmente: - ------------------------------------------------- -alice$ git remote add bob /home/bob/myrepo ------------------------------------------------- - -Com isso, Alice pode executar a primeira parte da operação "pull" usando -o comando 'git-fetch' sem unificar suas mudanças com seu próprio ramo, -usando: - -------------------------------------- -alice$ git fetch bob -------------------------------------- - -Diferente da forma longa, quando Alice obteve de Bob usando um -repositório remoto antes definido com 'git-remote', o que foi obtido é -armazenado em um ramo remoto, neste caso `bob/master`. Então, após isso: - -------------------------------------- -alice$ git log -p master..bob/master -------------------------------------- - -mostra uma lista de todas as mudanças que Bob fez desde que ramificou do -ramo master de Alice. - -Após examinar essas mudanças, Alice pode unificá-las em seu ramo master: - -------------------------------------- -alice$ git merge bob/master -------------------------------------- - -Esse `merge` pode também ser feito puxando de seu próprio ramo remoto, -assim: - -------------------------------------- -alice$ git pull . remotes/bob/master -------------------------------------- - -Note que 'git pull' sempre unifica ao ramo atual, independente do que -mais foi passado na linha de comando. - -Depois, Bob pode atualizar seu repositório com as últimas mudanças de -Alice, usando - -------------------------------------- -bob$ git pull -------------------------------------- - -Note que ele não precisa dar o caminho do repositório de Alice; quando -Bob clonou seu repositório, o git armazenou a localização de seu -repositório na configuração do mesmo, e essa localização é usada -para puxar: - -------------------------------------- -bob$ git config --get remote.origin.url -/home/alice/project -------------------------------------- - -(A configuração completa criada por 'git-clone' é visÃvel usando `git -config -l`, e a página de manual linkgit:git-config[1] explica o -significado de cada opção.) - -Git também mantém uma cópia limpa do ramo master de Alice sob o nome -"origin/master": - -------------------------------------- -bob$ git branch -r - origin/master -------------------------------------- - -Se Bob decidir depois em trabalhar em um host diferente, ele ainda pode -executar clones e puxar usando o protocolo ssh: - -------------------------------------- -bob$ git clone alice.org:/home/alice/project myrepo -------------------------------------- - -Alternativamente, o git tem um protocolo nativo, ou pode usar rsync ou -http; veja linkgit:git-pull[1] para detalhes. - -Git pode também ser usado em um modo parecido com CVS, com um -repositório central para o qual vários usuários empurram modificações; -veja linkgit:git-push[1] e linkgit:gitcvs-migration[7]. - -Explorando história ------------------ - -A história no git é representada como uma série de commits -interrelacionados. Nós já vimos que o comando 'git-log' pode listar -esses commits. Note que a primeira linha de cada entrada no log também -dá o nome para o commit: - -------------------------------------- -$ git log -commit c82a22c39cbc32576f64f5c6b3f24b99ea8149c7 -Author: Junio C Hamano <junkio@cox.net> -Date: Tue May 16 17:18:22 2006 -0700 - - merge-base: Clarify the comments on post processing. -------------------------------------- - -Nós podemos dar este nome ao 'git-show' para ver os detalhes sobre este -commit. - -------------------------------------- -$ git show c82a22c39cbc32576f64f5c6b3f24b99ea8149c7 -------------------------------------- - -Mas há outras formas de se referir aos commits. Você pode usar qualquer -parte inicial do nome que seja longo o bastante para identificar -unicamente o commit: - -------------------------------------- -$ git show c82a22c39c # os primeiros caracteres do nome são o bastante - # usualmente -$ git show HEAD # a ponta do ramo atual -$ git show experimental # a ponta do ramo "experimental" -------------------------------------- - -Todo commit normalmente tem um commit "pai" que aponta para o estado -anterior do projeto: - -------------------------------------- -$ git show HEAD^ # para ver o pai de HEAD -$ git show HEAD^^ # para ver o avô de HEAD -$ git show HEAD~4 # para ver o trisavô de HEAD -------------------------------------- - -Note que commits de unificação podem ter mais de um pai: - -------------------------------------- -$ git show HEAD^1 # mostra o primeiro pai de HEAD (o mesmo que HEAD^) -$ git show HEAD^2 # mostra o segundo pai de HEAD -------------------------------------- - -Você também pode dar aos commits nomes à sua escolha; após executar - -------------------------------------- -$ git tag v2.5 1b2e1d63ff -------------------------------------- - -você pode se referir a 1b2e1d63ff pelo nome "v2.5". Se você pretende -compartilhar esse nome com outras pessoas (por exemplo, para identificar -uma versão de lançamento), você deveria criar um objeto "tag", e talvez -assiná-lo; veja linkgit:git-tag[1] para detalhes. - -Qualquer comando git que precise conhecer um commit pode receber -quaisquer desses nomes. Por exemplo: - -------------------------------------- -$ git diff v2.5 HEAD # compara o HEAD atual com v2.5 -$ git branch stable v2.5 # inicia um novo ramo chamado "stable" baseado - # em v2.5 -$ git reset --hard HEAD^ # reseta seu ramo atual e seu diretório de - # trabalho a seu estado em HEAD^ -------------------------------------- - -Seja cuidadoso com o último comando: além de perder quaisquer mudanças -em seu diretório de trabalho, ele também remove todos os commits -posteriores desse ramo. Se esse ramo é o único ramo contendo esses -commits, eles serão perdidos. Também, não use 'git-reset' num ramo -publicamente visÃvel de onde outros desenvolvedores puxam, já que vai -forçar unificações desnecessárias para que outros desenvolvedores limpem -a história. Se você precisa desfazer mudanças que você empurrou, use -'git-revert' no lugar. - -O comando 'git-grep' pode buscar strings em qualquer versão de seu -projeto, então - -------------------------------------- -$ git grep "hello" v2.5 -------------------------------------- - -procura por todas as ocorrências de "hello" em v2.5. - -Se você deixar de fora o nome do commit, 'git-grep' irá procurar -quaisquer dos arquivos que ele gerencia no diretório corrente. Então - -------------------------------------- -$ git grep "hello" -------------------------------------- - -é uma forma rápida de buscar somente os arquivos que são rastreados pelo -git. - -Muitos comandos git também recebem um conjunto de commits, o que pode -ser especificado de várias formas. Aqui estão alguns exemplos com 'git-log': - -------------------------------------- -$ git log v2.5..v2.6 # commits entre v2.5 e v2.6 -$ git log v2.5.. # commits desde v2.5 -$ git log --since="2 weeks ago" # commits das últimas 2 semanas -$ git log v2.5.. Makefile # commits desde v2.5 que modificam - # Makefile -------------------------------------- - -Você também pode dar ao 'git-log' um "intervalo" de commits onde o -primeiro não é necessariamente um ancestral do segundo; por exemplo, se -as pontas dos ramos "stable" e "master" divergiram de um commit -comum algum tempo atrás, então - -------------------------------------- -$ git log stable..master -------------------------------------- - -irá listar os commits feitos no ramo "master" mas não no ramo -"stable", enquanto - -------------------------------------- -$ git log master..stable -------------------------------------- - -irá listar a lista de commits feitos no ramo "stable" mas não no ramo -"master". - -O comando 'git-log' tem uma fraqueza: ele precisa mostrar os commits em -uma lista. Quando a história tem linhas de desenvolvimento que -divergiram e então foram unificadas novamente, a ordem em que 'git-log' -apresenta essas mudanças é irrelevante. - -A maioria dos projetos com múltiplos contribuidores (como o kernel -Linux, ou o próprio git) tem unificações frequentes, e 'gitk' faz um -trabalho melhor de visualizar sua história. Por exemplo, - -------------------------------------- -$ gitk --since="2 weeks ago" drivers/ -------------------------------------- - -permite a você navegar em quaisquer commits desde as últimas duas semanas -de commits que modificaram arquivos sob o diretório "drivers". (Nota: -você pode ajustar as fontes do gitk segurando a tecla control enquanto -pressiona "-" ou "+".) - -Finalmente, a maioria dos comandos que recebem nomes de arquivo permitirão -também, opcionalmente, preceder qualquer nome de arquivo por um -commit, para especificar uma versão particular do arquivo: - -------------------------------------- -$ git diff v2.5:Makefile HEAD:Makefile.in -------------------------------------- - -Você pode usar 'git-show' para ver tal arquivo: - -------------------------------------- -$ git show v2.5:Makefile -------------------------------------- - -Próximos passos ----------- - -Este tutorial deve ser o bastante para operar controle de revisão -distribuÃdo básico para seus projetos. No entanto, para entender -plenamente a profundidade e o poder do git você precisa entender duas -idéias simples nas quais ele se baseia: - - * A base de objetos é um sistema bem elegante usado para armazenar a - história de seu projeto--arquivos, diretórios, e commits. - - * O arquivo de Ãndice é um cache do estado de uma árvore de diretório, - usado para criar commits, restaurar diretórios de trabalho, e - armazenar as várias árvores envolvidas em uma unificação. - -A parte dois deste tutorial explica a base de objetos, o arquivo de -Ãndice, e algumas outras coisinhas que você vai precisar pra usar o -máximo do git. Você pode encontrá-la em linkgit:gittutorial-2[7]. - -Se você não quiser continuar com o tutorial agora nesse momento, algumas -outras digressões que podem ser interessantes neste ponto são: - - * linkgit:git-format-patch[1], linkgit:git-am[1]: Estes convertem - séries de commits em patches para email, e vice-versa, úteis para - projetos como o kernel Linux que dependem fortemente de patches - enviados por email. - - * linkgit:git-bisect[1]: Quando há uma regressão em seu projeto, uma - forma de rastrear um bug é procurando pela história para encontrar o - commit culpado. Git bisect pode ajudar a executar uma busca binária - por esse commit. Ele é inteligente o bastante para executar uma - busca próxima da ótima mesmo no caso de uma história complexa - não-linear com muitos ramos unificados. - - * link:everyday.html[GIT diariamente com 20 e tantos comandos] - - * linkgit:gitcvs-migration[7]: Git para usuários de CVS. - -VEJA TAMBÉM --------- -linkgit:gittutorial-2[7], -linkgit:gitcvs-migration[7], -linkgit:gitcore-tutorial[7], -linkgit:gitglossary[7], -linkgit:git-help[1], -link:everyday.html[git diariamente], -link:user-manual.html[O Manual do Usuário git] - -GIT ---- -Parte da suite linkgit:git[1]. diff --git a/Documentation/rev-list-options.txt b/Documentation/rev-list-options.txt index ee49743..1ec14a0 100644 --- a/Documentation/rev-list-options.txt +++ b/Documentation/rev-list-options.txt @@ -79,6 +79,11 @@ if it is part of the log message. Match the regexp limiting patterns without regard to letters case. +--basic-regexp:: + + Consider the limiting patterns to be basic regular expressions; + this is the default. + -E:: --extended-regexp:: @@ -91,6 +96,11 @@ if it is part of the log message. Consider the limiting patterns to be fixed strings (don't interpret pattern as a regular expression). +--perl-regexp:: + + Consider the limiting patterns to be Perl-compatible regexp. + Requires libpcre to be compiled in. + --remove-empty:: Stop when a given path disappears from the tree. diff --git a/Documentation/technical/api-argv-array.txt b/Documentation/technical/api-argv-array.txt index 1a79781..a959517 100644 --- a/Documentation/technical/api-argv-array.txt +++ b/Documentation/technical/api-argv-array.txt @@ -53,3 +53,11 @@ Functions `argv_array_clear`:: Free all memory associated with the array and return it to the initial, empty state. + +`argv_array_detach`:: + Detach the argv array from the `struct argv_array`, transfering + ownership of the allocated array and strings. + +`argv_array_free_detached`:: + Free the memory allocated by a `struct argv_array` that was later + detached and is now no longer needed. diff --git a/Documentation/technical/api-history-graph.txt b/Documentation/technical/api-history-graph.txt index d6fc90a..18142b6 100644 --- a/Documentation/technical/api-history-graph.txt +++ b/Documentation/technical/api-history-graph.txt @@ -33,11 +33,11 @@ The following utility functions are wrappers around `graph_next_line()` and They can all be called with a NULL graph argument, in which case no graph output will be printed. -* `graph_show_commit()` calls `graph_next_line()` until it returns non-zero. - This prints all graph lines up to, and including, the line containing this - commit. Output is printed to stdout. The last line printed does not contain - a terminating newline. This should not be called if the commit line has - already been printed, or it will loop forever. +* `graph_show_commit()` calls `graph_next_line()` and + `graph_is_commit_finished()` until one of them return non-zero. This prints + all graph lines up to, and including, the line containing this commit. + Output is printed to stdout. The last line printed does not contain a + terminating newline. * `graph_show_oneline()` calls `graph_next_line()` and prints the result to stdout. The line printed does not contain a terminating newline. diff --git a/Documentation/technical/api-strbuf.txt b/Documentation/technical/api-strbuf.txt index 95a8bf3..84686b5 100644 --- a/Documentation/technical/api-strbuf.txt +++ b/Documentation/technical/api-strbuf.txt @@ -279,6 +279,22 @@ same behaviour as well. Strip whitespace from a buffer. The second parameter controls if comments are considered contents to be removed or not. +`strbuf_split_buf`:: +`strbuf_split_str`:: +`strbuf_split_max`:: +`strbuf_split`:: + + Split a string or strbuf into a list of strbufs at a specified + terminator character. The returned substrings include the + terminator characters. Some of these functions take a `max` + parameter, which, if positive, limits the output to that + number of substrings. + +`strbuf_list_free`:: + + Free a list of strbufs (for example, the return values of the + `strbuf_split()` functions). + `launch_editor`:: Launch the user preferred editor to edit a file and fill the buffer diff --git a/Documentation/technical/api-string-list.txt b/Documentation/technical/api-string-list.txt index 94d7a2b..20be348 100644 --- a/Documentation/technical/api-string-list.txt +++ b/Documentation/technical/api-string-list.txt @@ -38,7 +38,8 @@ member (you need this if you add things later) and you should set the `unsorted_string_list_delete_item`. . Can remove items not matching a criterion from a sorted or unsorted - list using `filter_string_list`. + list using `filter_string_list`, or remove empty strings using + `string_list_remove_empty_items`. . Finally it should free the list using `string_list_clear`. @@ -75,13 +76,11 @@ Functions to be deleted. Preserve the order of the items that are retained. -`string_list_longest_prefix`:: +`string_list_remove_empty_items`:: - Return the longest string within a string_list that is a - prefix (in the sense of prefixcmp()) of the specified string, - or NULL if no such prefix exists. This function does not - require the string_list to be sorted (it does a linear - search). + Remove any empty strings from the list. If free_util is true, + call free() on the util members of any items that have to be + deleted. Preserve the order of the items that are retained. `print_string_list`:: diff --git a/Documentation/user-manual.txt b/Documentation/user-manual.txt index 85651b5..1b377dc 100644 --- a/Documentation/user-manual.txt +++ b/Documentation/user-manual.txt @@ -1787,6 +1787,13 @@ $ git format-patch origin will produce a numbered series of files in the current directory, one for each patch in the current branch but not in origin/HEAD. +`git format-patch` can include an initial "cover letter". You can insert +commentary on individual patches after the three dash line which +`format-patch` places after the commit message but before the patch +itself. If you use `git notes` to track your cover letter material, +`git format-patch --notes` will include the commit's notes in a similar +manner. + You can then import these into your mail client and send them by hand. However, if you have a lot to send at once, you may prefer to use the linkgit:git-send-email[1] script to automate the process. diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index 4fae90f..e9f7abc 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -1,7 +1,7 @@ #!/bin/sh GVF=GIT-VERSION-FILE -DEF_VER=v1.8.0.3 +DEF_VER=v1.8.1.GIT LF=' ' @@ -74,10 +74,14 @@ all:: # Define NO_D_TYPE_IN_DIRENT if your platform defines DT_UNKNOWN but lacks # d_type in struct dirent (Cygwin 1.5, fixed in Cygwin 1.7). # +# Define HAVE_STRINGS_H if you have strings.h and need it for strcasecmp. +# # Define NO_STRCASESTR if you don't have strcasestr. # # Define NO_MEMMEM if you don't have memmem. # +# Define NO_GETPAGESIZE if you don't have getpagesize. +# # Define NO_STRLCPY if you don't have strlcpy. # # Define NO_STRTOUMAX if you don't have both strtoimax and strtoumax in the @@ -165,6 +169,10 @@ all:: # Define NO_POLL if you do not have or don't want to use poll(). # This also implies NO_SYS_POLL_H. # +# Define NEEDS_SYS_PARAM_H if you need to include sys/param.h to compile, +# *PLEASE* REPORT to git@vger.kernel.org if your platform needs this; +# we want to know more about the issue. +# # Define NO_PTHREADS if you do not have or do not want to use Pthreads. # # Define NO_PREAD if you have a problem with pread() system call (e.g. @@ -374,7 +382,7 @@ htmldir = share/doc/git-doc ETC_GITCONFIG = $(sysconfdir)/gitconfig ETC_GITATTRIBUTES = $(sysconfdir)/gitattributes lib = lib -# DESTDIR= +# DESTDIR = pathsep = : export prefix bindir sharedir sysconfdir gitwebdir localedir @@ -470,7 +478,7 @@ SCRIPT_PERL += git-relink.perl SCRIPT_PERL += git-send-email.perl SCRIPT_PERL += git-svn.perl -SCRIPT_PYTHON += git-remote-testgit.py +SCRIPT_PYTHON += git-remote-testpy.py SCRIPT_PYTHON += git-p4.py SCRIPTS = $(patsubst %.sh,%,$(SCRIPT_SH)) \ @@ -495,6 +503,7 @@ PROGRAM_OBJS += sh-i18n--envsubst.o PROGRAM_OBJS += shell.o PROGRAM_OBJS += show-index.o PROGRAM_OBJS += upload-pack.o +PROGRAM_OBJS += remote-testsvn.o # Binary suffix, set to .exe for Windows builds X = @@ -574,9 +583,9 @@ endif export PERL_PATH export PYTHON_PATH -LIB_FILE=libgit.a -XDIFF_LIB=xdiff/lib.a -VCSSVN_LIB=vcs-svn/lib.a +LIB_FILE = libgit.a +XDIFF_LIB = xdiff/lib.a +VCSSVN_LIB = vcs-svn/lib.a LIB_H += xdiff/xinclude.h LIB_H += xdiff/xmacros.h @@ -745,6 +754,7 @@ LIB_OBJS += editor.o LIB_OBJS += entry.o LIB_OBJS += environment.o LIB_OBJS += exec_cmd.o +LIB_OBJS += fetch-pack.o LIB_OBJS += fsck.o LIB_OBJS += gettext.o LIB_OBJS += gpg-interface.o @@ -762,6 +772,7 @@ LIB_OBJS += lockfile.o LIB_OBJS += log-tree.o LIB_OBJS += mailmap.o LIB_OBJS += match-trees.o +LIB_OBJS += merge.o LIB_OBJS += merge-file.o LIB_OBJS += merge-recursive.o LIB_OBJS += mergesort.o @@ -796,6 +807,7 @@ LIB_OBJS += rerere.o LIB_OBJS += resolve-undo.o LIB_OBJS += revision.o LIB_OBJS += run-command.o +LIB_OBJS += send-pack.o LIB_OBJS += sequencer.o LIB_OBJS += server-info.o LIB_OBJS += setup.o @@ -1082,6 +1094,7 @@ ifeq ($(uname_O),Cygwin) NO_SYMLINK_HEAD = YesPlease NO_IPV6 = YesPlease OLD_ICONV = UnfortunatelyYes + CYGWIN_V15_WIN32API = YesPlease endif NO_THREAD_SAFE_PREAD = YesPlease NEEDS_LIBICONV = YesPlease @@ -1134,7 +1147,7 @@ ifeq ($(uname_S),NetBSD) endif ifeq ($(uname_S),AIX) DEFAULT_PAGER = more - NO_STRCASESTR=YesPlease + NO_STRCASESTR = YesPlease NO_MEMMEM = YesPlease NO_MKDTEMP = YesPlease NO_MKSTEMPS = YesPlease @@ -1142,7 +1155,7 @@ ifeq ($(uname_S),AIX) NO_NSEC = YesPlease FREAD_READS_DIRECTORIES = UnfortunatelyYes INTERNAL_QSORT = UnfortunatelyYes - NEEDS_LIBICONV=YesPlease + NEEDS_LIBICONV = YesPlease BASIC_CFLAGS += -D_LARGE_FILES ifeq ($(shell expr "$(uname_V)" : '[1234]'),1) NO_PTHREADS = YesPlease @@ -1150,13 +1163,13 @@ ifeq ($(uname_S),AIX) PTHREAD_LIBS = -lpthread endif ifeq ($(shell expr "$(uname_V).$(uname_R)" : '5\.1'),3) - INLINE='' + INLINE = '' endif GIT_TEST_CMP = cmp endif ifeq ($(uname_S),GNU) # GNU/Hurd - NO_STRLCPY=YesPlease + NO_STRLCPY = YesPlease NO_MKSTEMPS = YesPlease HAVE_PATHS_H = YesPlease LIBC_CONTAINS_LIBINTL = YesPlease @@ -1182,9 +1195,9 @@ ifeq ($(uname_S),IRIX) NEEDS_LIBGEN = YesPlease endif ifeq ($(uname_S),IRIX64) - NO_SETENV=YesPlease + NO_SETENV = YesPlease NO_UNSETENV = YesPlease - NO_STRCASESTR=YesPlease + NO_STRCASESTR = YesPlease NO_MEMMEM = YesPlease NO_MKSTEMPS = YesPlease NO_MKDTEMP = YesPlease @@ -1198,14 +1211,14 @@ ifeq ($(uname_S),IRIX64) NO_REGEX = YesPlease NO_FNMATCH_CASEFOLD = YesPlease SNPRINTF_RETURNS_BOGUS = YesPlease - SHELL_PATH=/usr/gnu/bin/bash + SHELL_PATH = /usr/gnu/bin/bash NEEDS_LIBGEN = YesPlease endif ifeq ($(uname_S),HP-UX) INLINE = __inline - NO_IPV6=YesPlease - NO_SETENV=YesPlease - NO_STRCASESTR=YesPlease + NO_IPV6 = YesPlease + NO_SETENV = YesPlease + NO_STRCASESTR = YesPlease NO_MEMMEM = YesPlease NO_MKSTEMPS = YesPlease NO_STRLCPY = YesPlease @@ -1348,6 +1361,7 @@ ifeq ($(uname_S),NONSTOP_KERNEL) # Added manually, see above. NEEDS_SSL_WITH_CURL = YesPlease HAVE_LIBCHARSET_H = YesPlease + HAVE_STRINGS_H = YesPlease NEEDS_LIBICONV = YesPlease NEEDS_LIBINTL_BEFORE_LIBICONV = YesPlease NO_SYS_SELECT_H = UnfortunatelyYes @@ -1381,6 +1395,10 @@ ifeq ($(uname_S),NONSTOP_KERNEL) MKDIR_WO_TRAILING_SLASH = YesPlease # RFE 10-120912-4693 submitted to HP NonStop development. NO_SETITIMER = UnfortunatelyYes + SANE_TOOL_PATH = /usr/coreutils/bin:/usr/local/bin + SHELL_PATH = /usr/local/bin/bash + # as of H06.25/J06.14, we might better use this + #SHELL_PATH = /usr/coreutils/bin/bash endif ifneq (,$(findstring MINGW,$(uname_S))) pathsep = ; @@ -1428,7 +1446,7 @@ ifneq (,$(findstring MINGW,$(uname_S))) X = .exe SPARSE_FLAGS = -Wno-one-bit-signed-bitfield ifneq (,$(wildcard ../THIS_IS_MSYSGIT)) - htmldir=doc/git/html/ + htmldir = doc/git/html/ prefix = INSTALL = /bin/install EXTLIBS += /mingw/lib/libz.a @@ -1439,6 +1457,22 @@ else NO_CURL = YesPlease endif endif +ifeq ($(uname_S),QNX) + COMPAT_CFLAGS += -DSA_RESTART=0 + HAVE_STRINGS_H = YesPlease + NEEDS_SOCKET = YesPlease + NO_FNMATCH_CASEFOLD = YesPlease + NO_GETPAGESIZE = YesPlease + NO_ICONV = YesPlease + NO_MEMMEM = YesPlease + NO_MKDTEMP = YesPlease + NO_MKSTEMPS = YesPlease + NO_NSEC = YesPlease + NO_PTHREADS = YesPlease + NO_R_TO_GCC_LINKER = YesPlease + NO_STRCASESTR = YesPlease + NO_STRLCPY = YesPlease +endif -include config.mak.autogen -include config.mak @@ -1550,7 +1584,7 @@ else CURL_LIBCURL = -lcurl endif ifdef NEEDS_SSL_WITH_CURL - CURL_LIBCURL += -lssl + CURL_LIBCURL += -lssl ifdef NEEDS_CRYPTO_WITH_SSL CURL_LIBCURL += -lcrypto endif @@ -1646,6 +1680,9 @@ endif ifdef NO_D_INO_IN_DIRENT BASIC_CFLAGS += -DNO_D_INO_IN_DIRENT endif +ifdef NO_GECOS_IN_PWENT + BASIC_CFLAGS += -DNO_GECOS_IN_PWENT +endif ifdef NO_ST_BLOCKS_IN_STRUCT_STAT BASIC_CFLAGS += -DNO_ST_BLOCKS_IN_STRUCT_STAT endif @@ -1739,6 +1776,9 @@ endif ifdef NO_SYS_POLL_H BASIC_CFLAGS += -DNO_SYS_POLL_H endif +ifdef NEEDS_SYS_PARAM_H + BASIC_CFLAGS += -DNEEDS_SYS_PARAM_H +endif ifdef NO_INTTYPES_H BASIC_CFLAGS += -DNO_INTTYPES_H endif @@ -1759,7 +1799,7 @@ ifdef OBJECT_CREATION_USES_RENAMES endif ifdef NO_STRUCT_ITIMERVAL COMPAT_CFLAGS += -DNO_STRUCT_ITIMERVAL - NO_SETITIMER=YesPlease + NO_SETITIMER = YesPlease endif ifdef NO_SETITIMER COMPAT_CFLAGS += -DNO_SETITIMER @@ -1850,6 +1890,9 @@ ifdef NO_MEMMEM COMPAT_CFLAGS += -DNO_MEMMEM COMPAT_OBJS += compat/memmem.o endif +ifdef NO_GETPAGESIZE + COMPAT_CFLAGS += -DNO_GETPAGESIZE +endif ifdef INTERNAL_QSORT COMPAT_CFLAGS += -DINTERNAL_QSORT COMPAT_OBJS += compat/qsort.o @@ -1875,6 +1918,10 @@ ifdef HAVE_LIBCHARSET_H EXTLIBS += $(CHARSET_LIB) endif +ifdef HAVE_STRINGS_H + BASIC_CFLAGS += -DHAVE_STRINGS_H +endif + ifdef HAVE_DEV_TTY BASIC_CFLAGS += -DHAVE_DEV_TTY endif @@ -1889,6 +1936,9 @@ ifdef NO_REGEX COMPAT_CFLAGS += -Icompat/regex COMPAT_OBJS += compat/regex/regex.o endif +ifdef CYGWIN_V15_WIN32API + COMPAT_CFLAGS += -DCYGWIN_V15_WIN32API +endif ifdef USE_NED_ALLOCATOR COMPAT_CFLAGS += -Icompat/nedmalloc @@ -1908,15 +1958,15 @@ ifneq (,$(XDL_FAST_HASH)) endif ifeq ($(TCLTK_PATH),) -NO_TCLTK=NoThanks +NO_TCLTK = NoThanks endif ifeq ($(PERL_PATH),) -NO_PERL=NoThanks +NO_PERL = NoThanks endif ifeq ($(PYTHON_PATH),) -NO_PYTHON=NoThanks +NO_PYTHON = NoThanks endif QUIET_SUBDIR0 = +$(MAKE) -C # space to separate -C and subdir @@ -1963,13 +2013,13 @@ PROFILE_DIR := $(CURDIR) ifeq ("$(PROFILE)","GEN") CFLAGS += -fprofile-generate=$(PROFILE_DIR) -DNO_NORETURN=1 EXTLIBS += -lgcov - export CCACHE_DISABLE=t - V=1 + export CCACHE_DISABLE = t + V = 1 else ifneq ("$(PROFILE)","") CFLAGS += -fprofile-use=$(PROFILE_DIR) -fprofile-correction -DNO_NORETURN=1 - export CCACHE_DISABLE=t - V=1 + export CCACHE_DISABLE = t + V = 1 endif endif @@ -2171,7 +2221,7 @@ endef GIT-SCRIPT-DEFINES: FORCE @FLAGS='$(SCRIPT_DEFINES)'; \ if test x"$$FLAGS" != x"`cat $@ 2>/dev/null`" ; then \ - echo 1>&2 " * new script parameters"; \ + echo >&2 " * new script parameters"; \ echo "$$FLAGS" >$@; \ fi @@ -2233,7 +2283,7 @@ $(patsubst %.perl,%,$(SCRIPT_PERL)) git-instaweb: % : unimplemented.sh endif # NO_PERL ifndef NO_PYTHON -$(patsubst %.py,%,$(SCRIPT_PYTHON)): GIT-CFLAGS GIT-PREFIX +$(patsubst %.py,%,$(SCRIPT_PYTHON)): GIT-CFLAGS GIT-PREFIX GIT-PYTHON-VARS $(patsubst %.py,%,$(SCRIPT_PYTHON)): % : %.py $(QUIET_GEN)$(RM) $@ $@+ && \ INSTLIBDIR=`MAKEFLAGS= $(MAKE) -C git_remote_helpers -s \ @@ -2449,6 +2499,10 @@ git-http-push$X: revision.o http.o http-push.o GIT-LDFLAGS $(GITLIBS) $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \ $(LIBS) $(CURL_LIBCURL) $(EXPAT_LIBEXPAT) +git-remote-testsvn$X: remote-testsvn.o GIT-LDFLAGS $(GITLIBS) $(VCSSVN_LIB) + $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS) \ + $(VCSSVN_LIB) + $(REMOTE_CURL_ALIASES): $(REMOTE_CURL_PRIMARY) $(QUIET_LNCP)$(RM) $@ && \ ln $< $@ 2>/dev/null || \ @@ -2548,7 +2602,7 @@ TRACK_PREFIX = $(bindir_SQ):$(gitexecdir_SQ):$(template_dir_SQ):$(prefix_SQ):\ GIT-PREFIX: FORCE @FLAGS='$(TRACK_PREFIX)'; \ if test x"$$FLAGS" != x"`cat GIT-PREFIX 2>/dev/null`" ; then \ - echo 1>&2 " * new prefix flags"; \ + echo >&2 " * new prefix flags"; \ echo "$$FLAGS" >GIT-PREFIX; \ fi @@ -2557,7 +2611,7 @@ TRACK_CFLAGS = $(CC):$(subst ','\'',$(ALL_CFLAGS)):$(USE_GETTEXT_SCHEME) GIT-CFLAGS: FORCE @FLAGS='$(TRACK_CFLAGS)'; \ if test x"$$FLAGS" != x"`cat GIT-CFLAGS 2>/dev/null`" ; then \ - echo 1>&2 " * new build flags"; \ + echo >&2 " * new build flags"; \ echo "$$FLAGS" >GIT-CFLAGS; \ fi @@ -2566,7 +2620,7 @@ TRACK_LDFLAGS = $(subst ','\'',$(ALL_LDFLAGS)) GIT-LDFLAGS: FORCE @FLAGS='$(TRACK_LDFLAGS)'; \ if test x"$$FLAGS" != x"`cat GIT-LDFLAGS 2>/dev/null`" ; then \ - echo 1>&2 " * new link flags"; \ + echo >&2 " * new link flags"; \ echo "$$FLAGS" >GIT-LDFLAGS; \ fi @@ -2608,14 +2662,14 @@ ifdef GIT_PERF_MAKE_OPTS @echo GIT_PERF_MAKE_OPTS=\''$(subst ','\'',$(subst ','\'',$(GIT_PERF_MAKE_OPTS)))'\' >>$@ endif -### Detect Tck/Tk interpreter path changes -ifndef NO_TCLTK -TRACK_VARS = $(subst ','\'',-DTCLTK_PATH='$(TCLTK_PATH_SQ)') +### Detect Python interpreter path changes +ifndef NO_PYTHON +TRACK_PYTHON = $(subst ','\'',-DPYTHON_PATH='$(PYTHON_PATH_SQ)') -GIT-GUI-VARS: FORCE - @VARS='$(TRACK_VARS)'; \ +GIT-PYTHON-VARS: FORCE + @VARS='$(TRACK_PYTHON)'; \ if test x"$$VARS" != x"`cat $@ 2>/dev/null`" ; then \ - echo 1>&2 " * new Tcl/Tk interpreter location"; \ + echo >&2 " * new Python interpreter location"; \ echo "$$VARS" >$@; \ fi endif @@ -2814,7 +2868,7 @@ git.spec: git.spec.in GIT-VERSION-FILE sed -e 's/@@VERSION@@/$(GIT_VERSION)/g' < $< > $@+ mv $@+ $@ -GIT_TARNAME=git-$(GIT_VERSION) +GIT_TARNAME = git-$(GIT_VERSION) dist: git.spec git-archive$(X) configure ./git-archive --format=tar \ --prefix=$(GIT_TARNAME)/ HEAD^{tree} > $(GIT_TARNAME).tar @@ -2894,8 +2948,8 @@ ifndef NO_TCLTK $(MAKE) -C gitk-git clean $(MAKE) -C git-gui clean endif - $(RM) GIT-VERSION-FILE GIT-CFLAGS GIT-LDFLAGS GIT-GUI-VARS GIT-BUILD-OPTIONS - $(RM) GIT-USER-AGENT GIT-PREFIX GIT-SCRIPT-DEFINES + $(RM) GIT-VERSION-FILE GIT-CFLAGS GIT-LDFLAGS GIT-BUILD-OPTIONS + $(RM) GIT-USER-AGENT GIT-PREFIX GIT-SCRIPT-DEFINES GIT-PYTHON-VARS .PHONY: all install profile-clean clean strip .PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell @@ -1 +1 @@ -Documentation/RelNotes/1.8.0.3.txt
\ No newline at end of file +Documentation/RelNotes/1.8.2.txt
\ No newline at end of file @@ -15,16 +15,34 @@ int is_directory(const char *path) #define MAXDEPTH 5 /* - * Use this to get the real path, i.e. resolve links. If you want an - * absolute path but don't mind links, use absolute_path. + * Return the real path (i.e., absolute path, with symlinks resolved + * and extra slashes removed) equivalent to the specified path. (If + * you want an absolute path but don't mind links, use + * absolute_path().) The return value is a pointer to a static + * buffer. + * + * The input and all intermediate paths must be shorter than MAX_PATH. + * The directory part of path (i.e., everything up to the last + * dir_sep) must denote a valid, existing directory, but the last + * component need not exist. If die_on_error is set, then die with an + * informative error message if there is a problem. Otherwise, return + * NULL on errors (without generating any output). * * If path is our buffer, then return path, as it's already what the * user wants. */ -const char *real_path(const char *path) +static const char *real_path_internal(const char *path, int die_on_error) { static char bufs[2][PATH_MAX + 1], *buf = bufs[0], *next_buf = bufs[1]; + char *retval = NULL; + + /* + * If we have to temporarily chdir(), store the original CWD + * here so that we can chdir() back to it at the end of the + * function: + */ char cwd[1024] = ""; + int buf_index = 1; int depth = MAXDEPTH; @@ -35,11 +53,19 @@ const char *real_path(const char *path) if (path == buf || path == next_buf) return path; - if (!*path) - die("The empty string is not a valid path"); + if (!*path) { + if (die_on_error) + die("The empty string is not a valid path"); + else + goto error_out; + } - if (strlcpy(buf, path, PATH_MAX) >= PATH_MAX) - die ("Too long path: %.*s", 60, path); + if (strlcpy(buf, path, PATH_MAX) >= PATH_MAX) { + if (die_on_error) + die("Too long path: %.*s", 60, path); + else + goto error_out; + } while (depth--) { if (!is_directory(buf)) { @@ -54,20 +80,36 @@ const char *real_path(const char *path) } if (*buf) { - if (!*cwd && !getcwd(cwd, sizeof(cwd))) - die_errno ("Could not get current working directory"); + if (!*cwd && !getcwd(cwd, sizeof(cwd))) { + if (die_on_error) + die_errno("Could not get current working directory"); + else + goto error_out; + } - if (chdir(buf)) - die_errno ("Could not switch to '%s'", buf); + if (chdir(buf)) { + if (die_on_error) + die_errno("Could not switch to '%s'", buf); + else + goto error_out; + } + } + if (!getcwd(buf, PATH_MAX)) { + if (die_on_error) + die_errno("Could not get current working directory"); + else + goto error_out; } - if (!getcwd(buf, PATH_MAX)) - die_errno ("Could not get current working directory"); if (last_elem) { size_t len = strlen(buf); - if (len + strlen(last_elem) + 2 > PATH_MAX) - die ("Too long path name: '%s/%s'", - buf, last_elem); + if (len + strlen(last_elem) + 2 > PATH_MAX) { + if (die_on_error) + die("Too long path name: '%s/%s'", + buf, last_elem); + else + goto error_out; + } if (len && !is_dir_sep(buf[len-1])) buf[len++] = '/'; strcpy(buf + len, last_elem); @@ -77,10 +119,18 @@ const char *real_path(const char *path) if (!lstat(buf, &st) && S_ISLNK(st.st_mode)) { ssize_t len = readlink(buf, next_buf, PATH_MAX); - if (len < 0) - die_errno ("Invalid symlink '%s'", buf); - if (PATH_MAX <= len) - die("symbolic link too long: %s", buf); + if (len < 0) { + if (die_on_error) + die_errno("Invalid symlink '%s'", buf); + else + goto error_out; + } + if (PATH_MAX <= len) { + if (die_on_error) + die("symbolic link too long: %s", buf); + else + goto error_out; + } next_buf[len] = '\0'; buf = next_buf; buf_index = 1 - buf_index; @@ -89,10 +139,23 @@ const char *real_path(const char *path) break; } + retval = buf; +error_out: + free(last_elem); if (*cwd && chdir(cwd)) die_errno ("Could not change back to '%s'", cwd); - return buf; + return retval; +} + +const char *real_path(const char *path) +{ + return real_path_internal(path, 1); +} + +const char *real_path_if_valid(const char *path) +{ + return real_path_internal(path, 0); } static const char *get_pwd_cwd(void) @@ -1,9 +1,10 @@ #include "cache.h" -int advice_push_nonfastforward = 1; +int advice_push_update_rejected = 1; int advice_push_non_ff_current = 1; int advice_push_non_ff_default = 1; int advice_push_non_ff_matching = 1; +int advice_push_already_exists = 1; int advice_status_hints = 1; int advice_commit_before_merge = 1; int advice_resolve_conflict = 1; @@ -14,15 +15,19 @@ static struct { const char *name; int *preference; } advice_config[] = { - { "pushnonfastforward", &advice_push_nonfastforward }, + { "pushupdaterejected", &advice_push_update_rejected }, { "pushnonffcurrent", &advice_push_non_ff_current }, { "pushnonffdefault", &advice_push_non_ff_default }, { "pushnonffmatching", &advice_push_non_ff_matching }, + { "pushalreadyexists", &advice_push_already_exists }, { "statushints", &advice_status_hints }, { "commitbeforemerge", &advice_commit_before_merge }, { "resolveconflict", &advice_resolve_conflict }, { "implicitidentity", &advice_implicit_identity }, { "detachedhead", &advice_detached_head }, + + /* make this an alias for backward compatibility */ + { "pushnonfastforward", &advice_push_update_rejected } }; void advise(const char *advice, ...) @@ -3,10 +3,11 @@ #include "git-compat-util.h" -extern int advice_push_nonfastforward; +extern int advice_push_update_rejected; extern int advice_push_non_ff_current; extern int advice_push_non_ff_default; extern int advice_push_non_ff_matching; +extern int advice_push_already_exists; extern int advice_status_hints; extern int advice_commit_before_merge; extern int advice_resolve_conflict; @@ -120,6 +120,8 @@ static int write_archive_entry(const unsigned char *sha1, const char *base, strbuf_add(&path, args->base, args->baselen); strbuf_add(&path, base, baselen); strbuf_addstr(&path, filename); + if (S_ISDIR(mode) || S_ISGITLINK(mode)) + strbuf_addch(&path, '/'); path_without_prefix = path.buf + args->baselen; setup_archive_check(check); @@ -130,7 +132,6 @@ static int write_archive_entry(const unsigned char *sha1, const char *base, } if (S_ISDIR(mode) || S_ISGITLINK(mode)) { - strbuf_addch(&path, '/'); if (args->verbose) fprintf(stderr, "%.*s\n", (int)path.len, path.buf); err = write_entry(args, sha1, path.buf, path.len, mode); diff --git a/argv-array.c b/argv-array.c index 256741d..9e960d5 100644 --- a/argv-array.c +++ b/argv-array.c @@ -68,3 +68,23 @@ void argv_array_clear(struct argv_array *array) } argv_array_init(array); } + +const char **argv_array_detach(struct argv_array *array, int *argc) +{ + const char **argv = + array->argv == empty_argv || array->argc == 0 ? NULL : array->argv; + if (argc) + *argc = array->argc; + argv_array_init(array); + return argv; +} + +void argv_array_free_detached(const char **argv) +{ + if (argv) { + int i; + for (i = 0; argv[i]; i++) + free((char **)argv[i]); + free(argv); + } +} diff --git a/argv-array.h b/argv-array.h index f4b9866..40248d4 100644 --- a/argv-array.h +++ b/argv-array.h @@ -18,5 +18,7 @@ void argv_array_pushf(struct argv_array *, const char *fmt, ...); void argv_array_pushl(struct argv_array *, ...); void argv_array_pop(struct argv_array *); void argv_array_clear(struct argv_array *); +const char **argv_array_detach(struct argv_array *array, int *argc); +void argv_array_free_detached(const char **argv); #endif /* ARGV_ARRAY_H */ @@ -115,6 +115,13 @@ struct attr_state { const char *setto; }; +struct pattern { + const char *pattern; + int patternlen; + int nowildcardlen; + int flags; /* EXC_FLAG_* */ +}; + /* * One rule, as from a .gitattributes file. * @@ -131,7 +138,7 @@ struct attr_state { */ struct match_attr { union { - char *pattern; + struct pattern pat; struct git_attr *attr; } u; char is_macro; @@ -241,9 +248,16 @@ static struct match_attr *parse_attr_line(const char *line, const char *src, if (is_macro) res->u.attr = git_attr_internal(name, namelen); else { - res->u.pattern = (char *)&(res->state[num_attr]); - memcpy(res->u.pattern, name, namelen); - res->u.pattern[namelen] = 0; + char *p = (char *)&(res->state[num_attr]); + memcpy(p, name, namelen); + res->u.pat.pattern = p; + parse_exclude_pattern(&res->u.pat.pattern, + &res->u.pat.patternlen, + &res->u.pat.flags, + &res->u.pat.nowildcardlen); + if (res->u.pat.flags & EXC_FLAG_NEGATIVE) + die(_("Negative patterns are forbidden in git attributes\n" + "Use '\\!' for literal leading exclamation.")); } res->is_macro = is_macro; res->num_attr = num_attr; @@ -277,6 +291,7 @@ static struct match_attr *parse_attr_line(const char *line, const char *src, static struct attr_stack { struct attr_stack *prev; char *origin; + size_t originlen; unsigned num_matches; unsigned alloc; struct match_attr **attrs; @@ -535,6 +550,7 @@ static void bootstrap_attr_stack(void) if (!is_bare_repository() || direction == GIT_ATTR_INDEX) { elem = read_attr(GITATTRIBUTES_FILE, 1); elem->origin = xstrdup(""); + elem->originlen = 0; elem->prev = attr_stack; attr_stack = elem; debug_push(elem); @@ -548,17 +564,24 @@ static void bootstrap_attr_stack(void) attr_stack = elem; } +static const char *find_basename(const char *path) +{ + const char *cp, *last_slash = NULL; + + for (cp = path; *cp; cp++) { + if (*cp == '/' && cp[1]) + last_slash = cp; + } + return last_slash ? last_slash + 1 : path; +} + static void prepare_attr_stack(const char *path) { struct attr_stack *elem, *info; int dirlen, len; const char *cp; - cp = strrchr(path, '/'); - if (!cp) - dirlen = 0; - else - dirlen = cp - path; + dirlen = find_basename(path) - path; /* * At the bottom of the attribute stack is the built-in @@ -628,7 +651,7 @@ static void prepare_attr_stack(const char *path) strbuf_addstr(&pathbuf, GITATTRIBUTES_FILE); elem = read_attr(pathbuf.buf, 0); strbuf_setlen(&pathbuf, cp - path); - elem->origin = strbuf_detach(&pathbuf, NULL); + elem->origin = strbuf_detach(&pathbuf, &elem->originlen); elem->prev = attr_stack; attr_stack = elem; debug_push(elem); @@ -645,28 +668,26 @@ static void prepare_attr_stack(const char *path) } static int path_matches(const char *pathname, int pathlen, - const char *pattern, + const char *basename, + const struct pattern *pat, const char *base, int baselen) { - if (!strchr(pattern, '/')) { - /* match basename */ - const char *basename = strrchr(pathname, '/'); - basename = basename ? basename + 1 : pathname; - return (fnmatch_icase(pattern, basename, 0) == 0); - } - /* - * match with FNM_PATHNAME; the pattern has base implicitly - * in front of it. - */ - if (*pattern == '/') - pattern++; - if (pathlen < baselen || - (baselen && pathname[baselen] != '/') || - strncmp(pathname, base, baselen)) + const char *pattern = pat->pattern; + int prefix = pat->nowildcardlen; + + if ((pat->flags & EXC_FLAG_MUSTBEDIR) && + ((!pathlen) || (pathname[pathlen-1] != '/'))) return 0; - if (baselen != 0) - baselen++; - return fnmatch_icase(pattern, pathname + baselen, FNM_PATHNAME) == 0; + + if (pat->flags & EXC_FLAG_NODIR) { + return match_basename(basename, + pathlen - (basename - pathname), + pattern, prefix, + pat->patternlen, pat->flags); + } + return match_pathname(pathname, pathlen, + base, baselen, + pattern, prefix, pat->patternlen, pat->flags); } static int macroexpand_one(int attr_nr, int rem); @@ -693,7 +714,8 @@ static int fill_one(const char *what, struct match_attr *a, int rem) return rem; } -static int fill(const char *path, int pathlen, struct attr_stack *stk, int rem) +static int fill(const char *path, int pathlen, const char *basename, + struct attr_stack *stk, int rem) { int i; const char *base = stk->origin ? stk->origin : ""; @@ -702,8 +724,8 @@ static int fill(const char *path, int pathlen, struct attr_stack *stk, int rem) struct match_attr *a = stk->attrs[i]; if (a->is_macro) continue; - if (path_matches(path, pathlen, - a->u.pattern, base, strlen(base))) + if (path_matches(path, pathlen, basename, + &a->u.pat, base, stk->originlen)) rem = fill_one("fill", a, rem); } return rem; @@ -741,15 +763,17 @@ static void collect_all_attrs(const char *path) { struct attr_stack *stk; int i, pathlen, rem; + const char *basename; prepare_attr_stack(path); for (i = 0; i < attr_nr; i++) check_all_attr[i].value = ATTR__UNKNOWN; + basename = find_basename(path); pathlen = strlen(path); rem = attr_nr; for (stk = attr_stack; 0 < rem && stk; stk = stk->prev) - rem = fill(path, pathlen, stk, rem); + rem = fill(path, pathlen, basename, stk, rem); } int git_check_attr(const char *path, int num, struct git_attr_check *check) @@ -956,3 +956,41 @@ int bisect_next_all(const char *prefix, int no_checkout) return bisect_checkout(bisect_rev_hex, no_checkout); } +static inline int log2i(int n) +{ + int log2 = 0; + + for (; n > 1; n >>= 1) + log2++; + + return log2; +} + +static inline int exp2i(int n) +{ + return 1 << n; +} + +/* + * Estimate the number of bisect steps left (after the current step) + * + * For any x between 0 included and 2^n excluded, the probability for + * n - 1 steps left looks like: + * + * P(2^n + x) == (2^n - x) / (2^n + x) + * + * and P(2^n + x) < 0.5 means 2^n < 3x + */ +int estimate_bisect_steps(int all) +{ + int n, x, e; + + if (all < 3) + return 0; + + n = log2i(all); + e = exp2i(n); + x = all - e; + + return (e < 3 * x) ? n : n - 1; +} @@ -11,10 +11,6 @@ extern struct commit_list *filter_skipped(struct commit_list *list, int *count, int *skipped_first); -extern void print_commit_list(struct commit_list *list, - const char *format_cur, - const char *format_last); - #define BISECT_SHOW_ALL (1<<0) #define REV_LIST_QUIET (1<<1) @@ -37,10 +37,6 @@ int copy_note_for_rewrite(struct notes_rewrite_cfg *c, const unsigned char *from_obj, const unsigned char *to_obj); void finish_copy_notes_for_rewrite(struct notes_rewrite_cfg *c); -extern int check_pager_config(const char *cmd); -struct diff_options; -extern void setup_diff_pager(struct diff_options *); - extern int textconv_object(const char *path, unsigned mode, const unsigned char *sha1, int sha1_valid, char **buf, unsigned long *buf_size); extern int cmd_add(int argc, const char **argv, const char *prefix); diff --git a/builtin/apply.c b/builtin/apply.c index 156b3ce..6c11e8b 100644 --- a/builtin/apply.c +++ b/builtin/apply.c @@ -2095,7 +2095,7 @@ static void update_pre_post_images(struct image *preimage, char *buf, size_t len, size_t postlen) { - int i, ctx; + int i, ctx, reduced; char *new, *old, *fixed; struct image fixed_preimage; @@ -2105,8 +2105,10 @@ static void update_pre_post_images(struct image *preimage, * free "oldlines". */ prepare_image(&fixed_preimage, buf, len, 1); - assert(fixed_preimage.nr == preimage->nr); - for (i = 0; i < preimage->nr; i++) + assert(postlen + ? fixed_preimage.nr == preimage->nr + : fixed_preimage.nr <= preimage->nr); + for (i = 0; i < fixed_preimage.nr; i++) fixed_preimage.line[i].flag = preimage->line[i].flag; free(preimage->line_allocated); *preimage = fixed_preimage; @@ -2126,7 +2128,8 @@ static void update_pre_post_images(struct image *preimage, else new = old; fixed = preimage->buf; - for (i = ctx = 0; i < postimage->nr; i++) { + + for (i = reduced = ctx = 0; i < postimage->nr; i++) { size_t len = postimage->line[i].len; if (!(postimage->line[i].flag & LINE_COMMON)) { /* an added line -- no counterparts in preimage */ @@ -2145,8 +2148,15 @@ static void update_pre_post_images(struct image *preimage, fixed += preimage->line[ctx].len; ctx++; } - if (preimage->nr <= ctx) - die(_("oops")); + + /* + * preimage is expected to run out, if the caller + * fixed addition of trailing blank lines. + */ + if (preimage->nr <= ctx) { + reduced++; + continue; + } /* and copy it in, while fixing the line length */ len = preimage->line[ctx].len; @@ -2159,6 +2169,7 @@ static void update_pre_post_images(struct image *preimage, /* Fix the length of the whole thing */ postimage->len = new - postimage->buf; + postimage->nr -= reduced; } static int match_fragment(struct image *img, diff --git a/builtin/blame.c b/builtin/blame.c index c27ef21..cfae569 100644 --- a/builtin/blame.c +++ b/builtin/blame.c @@ -1425,7 +1425,7 @@ static void get_commit_info(struct commit *commit, int detailed) { int len; - const char *subject; + const char *subject, *encoding; char *reencoded, *message; static char author_name[1024]; static char author_mail[1024]; @@ -1446,7 +1446,8 @@ static void get_commit_info(struct commit *commit, die("Cannot read commit %s", sha1_to_hex(commit->object.sha1)); } - reencoded = reencode_commit_message(commit, NULL); + encoding = get_log_output_encoding(); + reencoded = logmsg_reencode(commit, encoding); message = reencoded ? reencoded : commit->buffer; ret->author = author_name; ret->author_mail = author_mail; diff --git a/builtin/commit.c b/builtin/commit.c index a17a5df..d6dd3df 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -112,10 +112,11 @@ static const char *only_include_assumed; static struct strbuf message = STRBUF_INIT; static enum { + STATUS_FORMAT_NONE = 0, STATUS_FORMAT_LONG, STATUS_FORMAT_SHORT, STATUS_FORMAT_PORCELAIN -} status_format = STATUS_FORMAT_LONG; +} status_format; static int opt_parse_m(const struct option *opt, const char *arg, int unset) { @@ -454,6 +455,7 @@ static int run_status(FILE *fp, const char *index_file, const char *prefix, int case STATUS_FORMAT_PORCELAIN: wt_porcelain_print(s); break; + case STATUS_FORMAT_NONE: case STATUS_FORMAT_LONG: wt_status_print(s); break; @@ -753,7 +755,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix, ident_shown++ ? "" : "\n", author_ident->buf); - if (!user_ident_sufficiently_given()) + if (!committer_ident_sufficiently_given()) status_printf_ln(s, GIT_COLOR_NORMAL, _("%s" "Committer: %s"), @@ -1058,9 +1060,13 @@ static int parse_and_validate_options(int argc, const char *argv[], if (all && argc > 0) die(_("Paths with -a does not make sense.")); - if (s->null_termination && status_format == STATUS_FORMAT_LONG) - status_format = STATUS_FORMAT_PORCELAIN; - if (status_format != STATUS_FORMAT_LONG) + if (s->null_termination) { + if (status_format == STATUS_FORMAT_NONE) + status_format = STATUS_FORMAT_PORCELAIN; + else if (status_format == STATUS_FORMAT_LONG) + die(_("--long and -z are incompatible")); + } + if (status_format != STATUS_FORMAT_NONE) dry_run = 1; return argc; @@ -1159,6 +1165,9 @@ int cmd_status(int argc, const char **argv, const char *prefix) OPT_SET_INT(0, "porcelain", &status_format, N_("machine-readable output"), STATUS_FORMAT_PORCELAIN), + OPT_SET_INT(0, "long", &status_format, + N_("show status in long format (default)"), + STATUS_FORMAT_LONG), OPT_BOOLEAN('z', "null", &s.null_termination, N_("terminate entries with NUL")), { OPTION_STRING, 'u', "untracked-files", &untracked_files_arg, @@ -1186,8 +1195,12 @@ int cmd_status(int argc, const char **argv, const char *prefix) builtin_status_usage, 0); finalize_colopts(&s.colopts, -1); - if (s.null_termination && status_format == STATUS_FORMAT_LONG) - status_format = STATUS_FORMAT_PORCELAIN; + if (s.null_termination) { + if (status_format == STATUS_FORMAT_NONE) + status_format = STATUS_FORMAT_PORCELAIN; + else if (status_format == STATUS_FORMAT_LONG) + die(_("--long and -z are incompatible")); + } handle_untracked_files_arg(&s); if (show_ignored_in_status) @@ -1216,6 +1229,7 @@ int cmd_status(int argc, const char **argv, const char *prefix) case STATUS_FORMAT_PORCELAIN: wt_porcelain_print(&s); break; + case STATUS_FORMAT_NONE: case STATUS_FORMAT_LONG: s.verbose = verbose; s.ignore_submodule_arg = ignore_submodule_arg; @@ -1251,7 +1265,7 @@ static void print_summary(const char *prefix, const unsigned char *sha1, strbuf_addstr(&format, "\n Author: "); strbuf_addbuf_percentquote(&format, &author_ident); } - if (!user_ident_sufficiently_given()) { + if (!committer_ident_sufficiently_given()) { strbuf_addstr(&format, "\n Committer: "); strbuf_addbuf_percentquote(&format, &committer_ident); if (advice_implicit_identity) { @@ -1386,6 +1400,9 @@ int cmd_commit(int argc, const char **argv, const char *prefix) OPT_BOOLEAN(0, "branch", &s.show_branch, N_("show branch information")), OPT_SET_INT(0, "porcelain", &status_format, N_("machine-readable output"), STATUS_FORMAT_PORCELAIN), + OPT_SET_INT(0, "long", &status_format, + N_("show status in long format (default)"), + STATUS_FORMAT_LONG), OPT_BOOLEAN('z', "null", &s.null_termination, N_("terminate entries with NUL")), OPT_BOOLEAN(0, "amend", &amend, N_("amend previous commit")), diff --git a/builtin/config.c b/builtin/config.c index 505bbc7..33c9bf9 100644 --- a/builtin/config.c +++ b/builtin/config.c @@ -15,7 +15,6 @@ static int show_keys; static int use_key_regexp; static int do_all; static int do_not_match; -static int seen; static char delim = '='; static char key_delim = ' '; static char term = '\n'; @@ -95,12 +94,19 @@ static int show_all_config(const char *key_, const char *value_, void *cb) return 0; } -static int show_config(const char *key_, const char *value_, void *cb) +struct strbuf_list { + struct strbuf *items; + int nr; + int alloc; +}; + +static int collect_config(const char *key_, const char *value_, void *cb) { + struct strbuf_list *values = cb; + struct strbuf *buf; char value[256]; const char *vptr = value; int must_free_vptr = 0; - int dup_error = 0; int must_print_delim = 0; if (!use_key_regexp && strcmp(key_, key)) @@ -111,12 +117,14 @@ static int show_config(const char *key_, const char *value_, void *cb) (do_not_match ^ !!regexec(regexp, (value_?value_:""), 0, NULL, 0))) return 0; + ALLOC_GROW(values->items, values->nr + 1, values->alloc); + buf = &values->items[values->nr++]; + strbuf_init(buf, 0); + if (show_keys) { - printf("%s", key_); + strbuf_addstr(buf, key_); must_print_delim = 1; } - if (seen && !do_all) - dup_error = 1; if (types == TYPE_INT) sprintf(value, "%d", git_config_int(key_, value_?value_:"")); else if (types == TYPE_BOOL) @@ -139,16 +147,12 @@ static int show_config(const char *key_, const char *value_, void *cb) vptr = ""; must_print_delim = 0; } - seen++; - if (dup_error) { - error("More than one value for the key %s: %s", - key_, vptr); - } - else { - if (must_print_delim) - printf("%c", key_delim); - printf("%s%c", vptr, term); - } + + if (must_print_delim) + strbuf_addch(buf, key_delim); + strbuf_addstr(buf, vptr); + strbuf_addch(buf, term); + if (must_free_vptr) /* If vptr must be freed, it's a pointer to a * dynamically allocated buffer, it's safe to cast to @@ -162,19 +166,8 @@ static int show_config(const char *key_, const char *value_, void *cb) static int get_value(const char *key_, const char *regex_) { int ret = CONFIG_GENERIC_ERROR; - char *global = NULL, *xdg = NULL, *repo_config = NULL; - const char *system_wide = NULL, *local; - struct config_include_data inc = CONFIG_INCLUDE_INIT; - config_fn_t fn; - void *data; - - local = given_config_file; - if (!local) { - local = repo_config = git_pathdup("config"); - if (git_config_system()) - system_wide = git_etc_gitconfig(); - home_config_paths(&global, &xdg, "config"); - } + struct strbuf_list values = {NULL}; + int i; if (use_key_regexp) { char *tl; @@ -196,7 +189,8 @@ static int get_value(const char *key_, const char *regex_) key_regexp = (regex_t*)xmalloc(sizeof(regex_t)); if (regcomp(key_regexp, key, REG_EXTENDED)) { fprintf(stderr, "Invalid key pattern: %s\n", key_); - free(key); + free(key_regexp); + key_regexp = NULL; ret = CONFIG_INVALID_PATTERN; goto free_strings; } @@ -216,53 +210,37 @@ static int get_value(const char *key_, const char *regex_) regexp = (regex_t*)xmalloc(sizeof(regex_t)); if (regcomp(regexp, regex_, REG_EXTENDED)) { fprintf(stderr, "Invalid pattern: %s\n", regex_); + free(regexp); + regexp = NULL; ret = CONFIG_INVALID_PATTERN; goto free_strings; } } - fn = show_config; - data = NULL; - if (respect_includes) { - inc.fn = fn; - inc.data = data; - fn = git_config_include; - data = &inc; - } - - if (do_all && system_wide) - git_config_from_file(fn, system_wide, data); - if (do_all && xdg) - git_config_from_file(fn, xdg, data); - if (do_all && global) - git_config_from_file(fn, global, data); - if (do_all) - git_config_from_file(fn, local, data); - git_config_from_parameters(fn, data); - if (!do_all && !seen) - git_config_from_file(fn, local, data); - if (!do_all && !seen && global) - git_config_from_file(fn, global, data); - if (!do_all && !seen && xdg) - git_config_from_file(fn, xdg, data); - if (!do_all && !seen && system_wide) - git_config_from_file(fn, system_wide, data); + git_config_with_options(collect_config, &values, + given_config_file, respect_includes); + + ret = !values.nr; + for (i = 0; i < values.nr; i++) { + struct strbuf *buf = values.items + i; + if (do_all || i == values.nr - 1) + fwrite(buf->buf, 1, buf->len, stdout); + strbuf_release(buf); + } + free(values.items); + +free_strings: free(key); + if (key_regexp) { + regfree(key_regexp); + free(key_regexp); + } if (regexp) { regfree(regexp); free(regexp); } - if (do_all) - ret = !seen; - else - ret = (seen == 1) ? 0 : seen > 1 ? 2 : 1; - -free_strings: - free(repo_config); - free(global); - free(xdg); return ret; } diff --git a/builtin/describe.c b/builtin/describe.c index 9fe11ed..04c185b 100644 --- a/builtin/describe.c +++ b/builtin/describe.c @@ -144,7 +144,7 @@ static int get_name(const char *path, const unsigned char *sha1, int flag, void if (!all && !might_be_tag) return 0; - if (!peel_ref(path, peeled) && !is_null_sha1(peeled)) { + if (!peel_ref(path, peeled)) { is_tag = !!hashcmp(sha1, peeled); } else { hashcpy(peeled, sha1); diff --git a/builtin/diff-index.c b/builtin/diff-index.c index 2eb32bd..1c737f7 100644 --- a/builtin/diff-index.c +++ b/builtin/diff-index.c @@ -41,9 +41,13 @@ int cmd_diff_index(int argc, const char **argv, const char *prefix) if (rev.pending.nr != 1 || rev.max_count != -1 || rev.min_age != -1 || rev.max_age != -1) usage(diff_cache_usage); - if (!cached) + if (!cached) { setup_work_tree(); - if (read_cache() < 0) { + if (read_cache_preload(rev.diffopt.pathspec.raw) < 0) { + perror("read_cache_preload"); + return -1; + } + } else if (read_cache() < 0) { perror("read_cache"); return -1; } diff --git a/builtin/diff.c b/builtin/diff.c index 9650be2..8c2af6c 100644 --- a/builtin/diff.c +++ b/builtin/diff.c @@ -130,8 +130,6 @@ static int builtin_diff_index(struct rev_info *revs, usage(builtin_diff_usage); argv++; argc--; } - if (!cached) - setup_work_tree(); /* * Make sure there is one revision (i.e. pending object), * and there is no revision filtering parameters. @@ -140,8 +138,14 @@ static int builtin_diff_index(struct rev_info *revs, revs->max_count != -1 || revs->min_age != -1 || revs->max_age != -1) usage(builtin_diff_usage); - if (read_cache_preload(revs->diffopt.pathspec.raw) < 0) { - perror("read_cache_preload"); + if (!cached) { + setup_work_tree(); + if (read_cache_preload(revs->diffopt.pathspec.raw) < 0) { + perror("read_cache_preload"); + return -1; + } + } else if (read_cache() < 0) { + perror("read_cache"); return -1; } return run_diff_index(revs, cached); @@ -418,19 +422,3 @@ int cmd_diff(int argc, const char **argv, const char *prefix) refresh_index_quietly(); return result; } - -void setup_diff_pager(struct diff_options *opt) -{ - /* - * If the user asked for our exit code, then either they want --quiet - * or --exit-code. We should definitely not bother with a pager in the - * former case, as we will generate no output. Since we still properly - * report our exit code even when a pager is run, we _could_ run a - * pager with --exit-code. But since we have not done so historically, - * and because it is easy to find people oneline advising "git diff - * --exit-code" in hooks and other scripts, we do not do so. - */ - if (!DIFF_OPT_TST(opt, EXIT_WITH_STATUS) && - check_pager_config("diff") != 0) - setup_pager(); -} diff --git a/builtin/fast-export.c b/builtin/fast-export.c index 12220ad..77dffd1 100644 --- a/builtin/fast-export.c +++ b/builtin/fast-export.c @@ -474,18 +474,21 @@ static void handle_tag(const char *name, struct tag *tag) (int)message_size, (int)message_size, message ? message : ""); } -static void get_tags_and_duplicates(struct object_array *pending, +static void get_tags_and_duplicates(struct rev_cmdline_info *info, struct string_list *extra_refs) { struct tag *tag; int i; - for (i = 0; i < pending->nr; i++) { - struct object_array_entry *e = pending->objects + i; + for (i = 0; i < info->nr; i++) { + struct rev_cmdline_entry *e = info->rev + i; unsigned char sha1[20]; - struct commit *commit = commit; + struct commit *commit; char *full_name; + if (e->flags & UNINTERESTING) + continue; + if (dwim_ref(e->name, strlen(e->name), sha1, &full_name) != 1) continue; @@ -523,10 +526,14 @@ static void get_tags_and_duplicates(struct object_array *pending, typename(e->item->type)); continue; } - if (commit->util) - /* more than one name for the same object */ + + /* + * This ref will not be updated through a commit, lets make + * sure it gets properly updated eventually. + */ + if (commit->util || commit->object.flags & SHOWN) string_list_append(extra_refs, full_name)->util = commit; - else + if (!commit->util) commit->util = full_name; } } @@ -614,6 +621,10 @@ static void import_marks(char *input_file) if (object->flags & SHOWN) error("Object %s already has a mark", sha1_to_hex(sha1)); + if (object->type != OBJ_COMMIT) + /* only commits */ + continue; + mark_object(object, mark); if (last_idnum < mark) last_idnum = mark; @@ -677,7 +688,7 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix) if (import_filename && revs.prune_data.nr) full_tree = 1; - get_tags_and_duplicates(&revs.pending, &extra_refs); + get_tags_and_duplicates(&revs.cmdline, &extra_refs); if (prepare_revision_walk(&revs)) die("revision walk setup failed"); diff --git a/builtin/fetch-pack.c b/builtin/fetch-pack.c index e644398..940ae35 100644 --- a/builtin/fetch-pack.c +++ b/builtin/fetch-pack.c @@ -1,895 +1,12 @@ #include "builtin.h" -#include "refs.h" #include "pkt-line.h" -#include "commit.h" -#include "tag.h" -#include "exec_cmd.h" -#include "pack.h" -#include "sideband.h" #include "fetch-pack.h" -#include "remote.h" -#include "run-command.h" -#include "transport.h" -#include "version.h" - -static int transfer_unpack_limit = -1; -static int fetch_unpack_limit = -1; -static int unpack_limit = 100; -static int prefer_ofs_delta = 1; -static int no_done; -static int fetch_fsck_objects = -1; -static int transfer_fsck_objects = -1; -static int agent_supported; -static struct fetch_pack_args args = { - /* .uploadpack = */ "git-upload-pack", -}; static const char fetch_pack_usage[] = "git fetch-pack [--all] [--stdin] [--quiet|-q] [--keep|-k] [--thin] " "[--include-tag] [--upload-pack=<git-upload-pack>] [--depth=<n>] " "[--no-progress] [-v] [<host>:]<directory> [<refs>...]"; -#define COMPLETE (1U << 0) -#define COMMON (1U << 1) -#define COMMON_REF (1U << 2) -#define SEEN (1U << 3) -#define POPPED (1U << 4) - -static int marked; - -/* - * After sending this many "have"s if we do not get any new ACK , we - * give up traversing our history. - */ -#define MAX_IN_VAIN 256 - -static struct commit_list *rev_list; -static int non_common_revs, multi_ack, use_sideband; - -static void rev_list_push(struct commit *commit, int mark) -{ - if (!(commit->object.flags & mark)) { - commit->object.flags |= mark; - - if (!(commit->object.parsed)) - if (parse_commit(commit)) - return; - - commit_list_insert_by_date(commit, &rev_list); - - if (!(commit->object.flags & COMMON)) - non_common_revs++; - } -} - -static int rev_list_insert_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data) -{ - struct object *o = deref_tag(parse_object(sha1), refname, 0); - - if (o && o->type == OBJ_COMMIT) - rev_list_push((struct commit *)o, SEEN); - - return 0; -} - -static int clear_marks(const char *refname, const unsigned char *sha1, int flag, void *cb_data) -{ - struct object *o = deref_tag(parse_object(sha1), refname, 0); - - if (o && o->type == OBJ_COMMIT) - clear_commit_marks((struct commit *)o, - COMMON | COMMON_REF | SEEN | POPPED); - return 0; -} - -/* - This function marks a rev and its ancestors as common. - In some cases, it is desirable to mark only the ancestors (for example - when only the server does not yet know that they are common). -*/ - -static void mark_common(struct commit *commit, - int ancestors_only, int dont_parse) -{ - if (commit != NULL && !(commit->object.flags & COMMON)) { - struct object *o = (struct object *)commit; - - if (!ancestors_only) - o->flags |= COMMON; - - if (!(o->flags & SEEN)) - rev_list_push(commit, SEEN); - else { - struct commit_list *parents; - - if (!ancestors_only && !(o->flags & POPPED)) - non_common_revs--; - if (!o->parsed && !dont_parse) - if (parse_commit(commit)) - return; - - for (parents = commit->parents; - parents; - parents = parents->next) - mark_common(parents->item, 0, dont_parse); - } - } -} - -/* - Get the next rev to send, ignoring the common. -*/ - -static const unsigned char *get_rev(void) -{ - struct commit *commit = NULL; - - while (commit == NULL) { - unsigned int mark; - struct commit_list *parents; - - if (rev_list == NULL || non_common_revs == 0) - return NULL; - - commit = rev_list->item; - if (!commit->object.parsed) - parse_commit(commit); - parents = commit->parents; - - commit->object.flags |= POPPED; - if (!(commit->object.flags & COMMON)) - non_common_revs--; - - if (commit->object.flags & COMMON) { - /* do not send "have", and ignore ancestors */ - commit = NULL; - mark = COMMON | SEEN; - } else if (commit->object.flags & COMMON_REF) - /* send "have", and ignore ancestors */ - mark = COMMON | SEEN; - else - /* send "have", also for its ancestors */ - mark = SEEN; - - while (parents) { - if (!(parents->item->object.flags & SEEN)) - rev_list_push(parents->item, mark); - if (mark & COMMON) - mark_common(parents->item, 1, 0); - parents = parents->next; - } - - rev_list = rev_list->next; - } - - return commit->object.sha1; -} - -enum ack_type { - NAK = 0, - ACK, - ACK_continue, - ACK_common, - ACK_ready -}; - -static void consume_shallow_list(int fd) -{ - if (args.stateless_rpc && args.depth > 0) { - /* If we sent a depth we will get back "duplicate" - * 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))) { - if (!prefixcmp(line, "shallow ")) - continue; - if (!prefixcmp(line, "unshallow ")) - continue; - die("git fetch-pack: expected shallow list"); - } - } -} - -struct write_shallow_data { - struct strbuf *out; - int use_pack_protocol; - int count; -}; - -static int write_one_shallow(const struct commit_graft *graft, void *cb_data) -{ - struct write_shallow_data *data = cb_data; - const char *hex = sha1_to_hex(graft->sha1); - data->count++; - if (data->use_pack_protocol) - packet_buf_write(data->out, "shallow %s", hex); - else { - strbuf_addstr(data->out, hex); - strbuf_addch(data->out, '\n'); - } - return 0; -} - -static int write_shallow_commits(struct strbuf *out, int use_pack_protocol) -{ - struct write_shallow_data data; - data.out = out; - data.use_pack_protocol = use_pack_protocol; - data.count = 0; - for_each_commit_graft(write_one_shallow, &data); - return data.count; -} - -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)); - - 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 (strstr(line+45, "continue")) - return ACK_continue; - if (strstr(line+45, "common")) - return ACK_common; - if (strstr(line+45, "ready")) - return ACK_ready; - return ACK; - } - } - die("git fetch_pack: expected ACK/NAK, got '%s'", line); -} - -static void send_request(int fd, struct strbuf *buf) -{ - if (args.stateless_rpc) { - send_sideband(fd, -1, buf->buf, buf->len, LARGE_PACKET_MAX); - packet_flush(fd); - } else - safe_write(fd, buf->buf, buf->len); -} - -static void insert_one_alternate_ref(const struct ref *ref, void *unused) -{ - rev_list_insert_ref(NULL, ref->old_sha1, 0, NULL); -} - -#define INITIAL_FLUSH 16 -#define PIPESAFE_FLUSH 32 -#define LARGE_FLUSH 1024 - -static int next_flush(int count) -{ - int flush_limit = args.stateless_rpc ? LARGE_FLUSH : PIPESAFE_FLUSH; - - if (count < flush_limit) - count <<= 1; - else - count += flush_limit; - return count; -} - -static int find_common(int fd[2], unsigned char *result_sha1, - struct ref *refs) -{ - int fetching; - int count = 0, flushes = 0, flush_at = INITIAL_FLUSH, retval; - const unsigned char *sha1; - unsigned in_vain = 0; - int got_continue = 0; - int got_ready = 0; - struct strbuf req_buf = STRBUF_INIT; - size_t state_len = 0; - - if (args.stateless_rpc && multi_ack == 1) - die("--stateless-rpc requires multi_ack_detailed"); - if (marked) - for_each_ref(clear_marks, NULL); - marked = 1; - - for_each_ref(rev_list_insert_ref, NULL); - for_each_alternate_ref(insert_one_alternate_ref, NULL); - - fetching = 0; - for ( ; refs ; refs = refs->next) { - unsigned char *remote = refs->old_sha1; - const char *remote_hex; - struct object *o; - - /* - * If that object is complete (i.e. it is an ancestor of a - * local ref), we tell them we have it but do not have to - * tell them about its ancestors, which they already know - * about. - * - * We use lookup_object here because we are only - * interested in the case we *know* the object is - * reachable and we have already scanned it. - */ - if (((o = lookup_object(remote)) != NULL) && - (o->flags & COMPLETE)) { - continue; - } - - remote_hex = sha1_to_hex(remote); - if (!fetching) { - struct strbuf c = STRBUF_INIT; - if (multi_ack == 2) strbuf_addstr(&c, " multi_ack_detailed"); - if (multi_ack == 1) strbuf_addstr(&c, " multi_ack"); - if (no_done) strbuf_addstr(&c, " no-done"); - if (use_sideband == 2) strbuf_addstr(&c, " side-band-64k"); - if (use_sideband == 1) strbuf_addstr(&c, " side-band"); - if (args.use_thin_pack) strbuf_addstr(&c, " thin-pack"); - if (args.no_progress) strbuf_addstr(&c, " no-progress"); - if (args.include_tag) strbuf_addstr(&c, " include-tag"); - if (prefer_ofs_delta) strbuf_addstr(&c, " ofs-delta"); - if (agent_supported) strbuf_addf(&c, " agent=%s", - git_user_agent_sanitized()); - packet_buf_write(&req_buf, "want %s%s\n", remote_hex, c.buf); - strbuf_release(&c); - } else - packet_buf_write(&req_buf, "want %s\n", remote_hex); - fetching++; - } - - if (!fetching) { - strbuf_release(&req_buf); - packet_flush(fd[1]); - return 1; - } - - if (is_repository_shallow()) - write_shallow_commits(&req_buf, 1); - if (args.depth > 0) - packet_buf_write(&req_buf, "deepen %d", args.depth); - packet_buf_flush(&req_buf); - state_len = req_buf.len; - - if (args.depth > 0) { - char line[1024]; - unsigned char sha1[20]; - - send_request(fd[1], &req_buf); - while (packet_read_line(fd[0], line, sizeof(line))) { - if (!prefixcmp(line, "shallow ")) { - if (get_sha1_hex(line + 8, sha1)) - die("invalid shallow line: %s", line); - register_shallow(sha1); - continue; - } - if (!prefixcmp(line, "unshallow ")) { - if (get_sha1_hex(line + 10, sha1)) - die("invalid unshallow line: %s", line); - if (!lookup_object(sha1)) - die("object not found: %s", line); - /* make sure that it is parsed as shallow */ - if (!parse_object(sha1)) - die("error in object: %s", line); - if (unregister_shallow(sha1)) - die("no shallow found: %s", line); - continue; - } - die("expected shallow/unshallow, got %s", line); - } - } else if (!args.stateless_rpc) - send_request(fd[1], &req_buf); - - if (!args.stateless_rpc) { - /* If we aren't using the stateless-rpc interface - * we don't need to retain the headers. - */ - strbuf_setlen(&req_buf, 0); - state_len = 0; - } - - flushes = 0; - retval = -1; - while ((sha1 = get_rev())) { - packet_buf_write(&req_buf, "have %s\n", sha1_to_hex(sha1)); - if (args.verbose) - fprintf(stderr, "have %s\n", sha1_to_hex(sha1)); - in_vain++; - if (flush_at <= ++count) { - int ack; - - packet_buf_flush(&req_buf); - send_request(fd[1], &req_buf); - strbuf_setlen(&req_buf, state_len); - flushes++; - flush_at = next_flush(count); - - /* - * We keep one window "ahead" of the other side, and - * will wait for an ACK only on the next one - */ - if (!args.stateless_rpc && count == INITIAL_FLUSH) - continue; - - consume_shallow_list(fd[0]); - do { - ack = get_ack(fd[0], result_sha1); - if (args.verbose && ack) - fprintf(stderr, "got ack %d %s\n", ack, - sha1_to_hex(result_sha1)); - switch (ack) { - case ACK: - flushes = 0; - multi_ack = 0; - retval = 0; - goto done; - case ACK_common: - case ACK_ready: - case ACK_continue: { - struct commit *commit = - lookup_commit(result_sha1); - if (!commit) - die("invalid commit %s", sha1_to_hex(result_sha1)); - if (args.stateless_rpc - && ack == ACK_common - && !(commit->object.flags & COMMON)) { - /* We need to replay the have for this object - * on the next RPC request so the peer knows - * it is in common with us. - */ - const char *hex = sha1_to_hex(result_sha1); - packet_buf_write(&req_buf, "have %s\n", hex); - state_len = req_buf.len; - } - mark_common(commit, 0, 1); - retval = 0; - in_vain = 0; - got_continue = 1; - if (ack == ACK_ready) { - rev_list = NULL; - got_ready = 1; - } - break; - } - } - } while (ack); - flushes--; - if (got_continue && MAX_IN_VAIN < in_vain) { - if (args.verbose) - fprintf(stderr, "giving up\n"); - break; /* give up */ - } - } - } -done: - if (!got_ready || !no_done) { - packet_buf_write(&req_buf, "done\n"); - send_request(fd[1], &req_buf); - } - if (args.verbose) - fprintf(stderr, "done\n"); - if (retval != 0) { - multi_ack = 0; - flushes++; - } - strbuf_release(&req_buf); - - consume_shallow_list(fd[0]); - while (flushes || multi_ack) { - int ack = get_ack(fd[0], result_sha1); - if (ack) { - if (args.verbose) - fprintf(stderr, "got ack (%d) %s\n", ack, - sha1_to_hex(result_sha1)); - if (ack == ACK) - return 0; - multi_ack = 1; - continue; - } - flushes--; - } - /* it is no error to fetch into a completely empty repo */ - return count ? retval : 0; -} - -static struct commit_list *complete; - -static int mark_complete(const char *refname, const unsigned char *sha1, int flag, void *cb_data) -{ - struct object *o = parse_object(sha1); - - while (o && o->type == OBJ_TAG) { - struct tag *t = (struct tag *) o; - if (!t->tagged) - break; /* broken repository */ - o->flags |= COMPLETE; - o = parse_object(t->tagged->sha1); - } - if (o && o->type == OBJ_COMMIT) { - struct commit *commit = (struct commit *)o; - if (!(commit->object.flags & COMPLETE)) { - commit->object.flags |= COMPLETE; - commit_list_insert_by_date(commit, &complete); - } - } - return 0; -} - -static void mark_recent_complete_commits(unsigned long cutoff) -{ - while (complete && cutoff <= complete->item->date) { - if (args.verbose) - fprintf(stderr, "Marking %s as complete\n", - sha1_to_hex(complete->item->object.sha1)); - pop_most_recent_commit(&complete, COMPLETE); - } -} - -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 ref **refs, struct string_list *sought) -{ - struct ref *newlist = NULL; - struct ref **newtail = &newlist; - struct ref *ref, *next; - int sought_pos; - - sought_pos = 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); - 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; - } - else - sought_pos++; /* might have it; keep looking */ - } - } - - if (! keep && args.fetch_all && - (!args.depth || prefixcmp(ref->name, "refs/tags/"))) - keep = 1; - - if (keep) { - *newtail = ref; - ref->next = NULL; - newtail = &ref->next; - } else { - free(ref); - } - } - - filter_string_list(sought, 0, non_matching_ref, NULL); - *refs = newlist; -} - -static void mark_alternate_complete(const struct ref *ref, void *unused) -{ - mark_complete(NULL, ref->old_sha1, 0, NULL); -} - -static int everything_local(struct ref **refs, struct string_list *sought) -{ - struct ref *ref; - int retval; - unsigned long cutoff = 0; - - save_commit_buffer = 0; - - for (ref = *refs; ref; ref = ref->next) { - struct object *o; - - o = parse_object(ref->old_sha1); - if (!o) - continue; - - /* We already have it -- which may mean that we were - * in sync with the other side at some time after - * that (it is OK if we guess wrong here). - */ - if (o->type == OBJ_COMMIT) { - struct commit *commit = (struct commit *)o; - if (!cutoff || cutoff < commit->date) - cutoff = commit->date; - } - } - - if (!args.depth) { - for_each_ref(mark_complete, NULL); - for_each_alternate_ref(mark_alternate_complete, NULL); - if (cutoff) - mark_recent_complete_commits(cutoff); - } - - /* - * Mark all complete remote refs as common refs. - * Don't mark them common yet; the server has to be told so first. - */ - for (ref = *refs; ref; ref = ref->next) { - struct object *o = deref_tag(lookup_object(ref->old_sha1), - NULL, 0); - - if (!o || o->type != OBJ_COMMIT || !(o->flags & COMPLETE)) - continue; - - if (!(o->flags & SEEN)) { - rev_list_push((struct commit *)o, COMMON_REF | SEEN); - - mark_common((struct commit *)o, 1, 1); - } - } - - filter_refs(refs, sought); - - for (retval = 1, ref = *refs; ref ; ref = ref->next) { - const unsigned char *remote = ref->old_sha1; - unsigned char local[20]; - struct object *o; - - o = lookup_object(remote); - if (!o || !(o->flags & COMPLETE)) { - retval = 0; - if (!args.verbose) - continue; - fprintf(stderr, - "want %s (%s)\n", sha1_to_hex(remote), - ref->name); - continue; - } - - hashcpy(ref->new_sha1, local); - if (!args.verbose) - continue; - fprintf(stderr, - "already have %s (%s)\n", sha1_to_hex(remote), - ref->name); - } - return retval; -} - -static int sideband_demux(int in, int out, void *data) -{ - int *xd = data; - - int ret = recv_sideband("fetch-pack", xd[0], out); - close(out); - return ret; -} - -static int get_pack(int xd[2], char **pack_lockfile) -{ - struct async demux; - const char *argv[20]; - char keep_arg[256]; - char hdr_arg[256]; - const char **av; - int do_keep = args.keep_pack; - struct child_process cmd; - - memset(&demux, 0, sizeof(demux)); - if (use_sideband) { - /* xd[] is talking with upload-pack; subprocess reads from - * xd[0], spits out band#2 to stderr, and feeds us band#1 - * through demux->out. - */ - demux.proc = sideband_demux; - demux.data = xd; - demux.out = -1; - if (start_async(&demux)) - die("fetch-pack: unable to fork off sideband" - " demultiplexer"); - } - else - demux.out = xd[0]; - - memset(&cmd, 0, sizeof(cmd)); - cmd.argv = argv; - av = argv; - *hdr_arg = 0; - if (!args.keep_pack && unpack_limit) { - struct pack_header header; - - if (read_pack_header(demux.out, &header)) - die("protocol error: bad pack header"); - snprintf(hdr_arg, sizeof(hdr_arg), - "--pack_header=%"PRIu32",%"PRIu32, - ntohl(header.hdr_version), ntohl(header.hdr_entries)); - if (ntohl(header.hdr_entries) < unpack_limit) - do_keep = 0; - else - do_keep = 1; - } - - if (do_keep) { - if (pack_lockfile) - cmd.out = -1; - *av++ = "index-pack"; - *av++ = "--stdin"; - if (!args.quiet && !args.no_progress) - *av++ = "-v"; - if (args.use_thin_pack) - *av++ = "--fix-thin"; - if (args.lock_pack || unpack_limit) { - int s = sprintf(keep_arg, - "--keep=fetch-pack %"PRIuMAX " on ", (uintmax_t) getpid()); - if (gethostname(keep_arg + s, sizeof(keep_arg) - s)) - strcpy(keep_arg + s, "localhost"); - *av++ = keep_arg; - } - } - else { - *av++ = "unpack-objects"; - if (args.quiet || args.no_progress) - *av++ = "-q"; - } - if (*hdr_arg) - *av++ = hdr_arg; - if (fetch_fsck_objects >= 0 - ? fetch_fsck_objects - : transfer_fsck_objects >= 0 - ? transfer_fsck_objects - : 0) - *av++ = "--strict"; - *av++ = NULL; - - cmd.in = demux.out; - cmd.git_cmd = 1; - if (start_command(&cmd)) - die("fetch-pack: unable to fork off %s", argv[0]); - if (do_keep && pack_lockfile) { - *pack_lockfile = index_pack_lockfile(cmd.out); - close(cmd.out); - } - - if (finish_command(&cmd)) - die("%s failed", argv[0]); - if (use_sideband && finish_async(&demux)) - die("error in sideband demultiplexer"); - return 0; -} - -static struct ref *do_fetch_pack(int fd[2], - const struct ref *orig_ref, - struct string_list *sought, - char **pack_lockfile) -{ - struct ref *ref = copy_ref_list(orig_ref); - unsigned char sha1[20]; - const char *agent_feature; - int agent_len; - - sort_ref_list(&ref, ref_compare_name); - - if (is_repository_shallow() && !server_supports("shallow")) - die("Server does not support shallow clients"); - if (server_supports("multi_ack_detailed")) { - if (args.verbose) - fprintf(stderr, "Server supports multi_ack_detailed\n"); - multi_ack = 2; - if (server_supports("no-done")) { - if (args.verbose) - fprintf(stderr, "Server supports no-done\n"); - if (args.stateless_rpc) - no_done = 1; - } - } - else if (server_supports("multi_ack")) { - if (args.verbose) - fprintf(stderr, "Server supports multi_ack\n"); - multi_ack = 1; - } - if (server_supports("side-band-64k")) { - if (args.verbose) - fprintf(stderr, "Server supports side-band-64k\n"); - use_sideband = 2; - } - else if (server_supports("side-band")) { - if (args.verbose) - fprintf(stderr, "Server supports side-band\n"); - use_sideband = 1; - } - if (!server_supports("thin-pack")) - args.use_thin_pack = 0; - if (!server_supports("no-progress")) - args.no_progress = 0; - if (!server_supports("include-tag")) - args.include_tag = 0; - if (server_supports("ofs-delta")) { - if (args.verbose) - fprintf(stderr, "Server supports ofs-delta\n"); - } else - prefer_ofs_delta = 0; - - if ((agent_feature = server_feature_value("agent", &agent_len))) { - agent_supported = 1; - if (args.verbose && agent_len) - fprintf(stderr, "Server version is %.*s\n", - agent_len, agent_feature); - } - - if (everything_local(&ref, sought)) { - packet_flush(fd[1]); - goto all_done; - } - if (find_common(fd, sha1, ref) < 0) - if (!args.keep_pack) - /* When cloning, it is not unusual to have - * no common commit. - */ - warning("no common commits"); - - if (args.stateless_rpc) - packet_flush(fd[1]); - if (get_pack(fd, pack_lockfile)) - die("git fetch-pack: fetch failed."); - - all_done: - return ref; -} - -static int fetch_pack_config(const char *var, const char *value, void *cb) -{ - if (strcmp(var, "fetch.unpacklimit") == 0) { - fetch_unpack_limit = git_config_int(var, value); - return 0; - } - - if (strcmp(var, "transfer.unpacklimit") == 0) { - transfer_unpack_limit = git_config_int(var, value); - return 0; - } - - if (strcmp(var, "repack.usedeltabaseoffset") == 0) { - prefer_ofs_delta = git_config_bool(var, value); - return 0; - } - - if (!strcmp(var, "fetch.fsckobjects")) { - fetch_fsck_objects = git_config_bool(var, value); - return 0; - } - - if (!strcmp(var, "transfer.fsckobjects")) { - transfer_fsck_objects = git_config_bool(var, value); - return 0; - } - - return git_default_config(var, value, cb); -} - -static struct lock_file lock; - -static void fetch_pack_setup(void) -{ - static int did_setup; - if (did_setup) - return; - git_config(fetch_pack_config, NULL); - if (0 <= transfer_unpack_limit) - unpack_limit = transfer_unpack_limit; - else if (0 <= fetch_unpack_limit) - unpack_limit = fetch_unpack_limit; - did_setup = 1; -} - int cmd_fetch_pack(int argc, const char **argv, const char *prefix) { int i, ret; @@ -900,9 +17,13 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix) char *pack_lockfile = NULL; char **pack_lockfile_ptr = NULL; struct child_process *conn; + struct fetch_pack_args args; packet_trace_identity("fetch-pack"); + memset(&args, 0, sizeof(args)); + args.uploadpack = "git-upload-pack"; + for (i = 1; i < argc && *argv[i] == '-'; i++) { const char *arg = argv[i]; @@ -1038,66 +159,3 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix) return ret; } - -struct ref *fetch_pack(struct fetch_pack_args *my_args, - int fd[], struct child_process *conn, - const struct ref *ref, - const char *dest, - struct string_list *sought, - char **pack_lockfile) -{ - struct stat st; - struct ref *ref_cpy; - - fetch_pack_setup(); - if (&args != my_args) - memcpy(&args, my_args, sizeof(args)); - if (args.depth > 0) { - if (stat(git_path("shallow"), &st)) - st.st_mtime = 0; - } - - if (sought->nr) { - sort_string_list(sought); - string_list_remove_duplicates(sought, 0); - } - - if (!ref) { - packet_flush(fd[1]); - die("no matching remote head"); - } - ref_cpy = do_fetch_pack(fd, ref, sought, pack_lockfile); - - if (args.depth > 0) { - struct cache_time mtime; - struct strbuf sb = STRBUF_INIT; - char *shallow = git_path("shallow"); - int fd; - - mtime.sec = st.st_mtime; - mtime.nsec = ST_MTIME_NSEC(st); - if (stat(shallow, &st)) { - if (mtime.sec) - die("shallow file was removed during fetch"); - } else if (st.st_mtime != mtime.sec -#ifdef USE_NSEC - || ST_MTIME_NSEC(st) != mtime.nsec -#endif - ) - die("shallow file was changed during fetch"); - - fd = hold_lock_file_for_update(&lock, shallow, - LOCK_DIE_ON_ERROR); - if (!write_shallow_commits(&sb, 0) - || write_in_full(fd, sb.buf, sb.len) != sb.len) { - unlink_or_warn(shallow); - rollback_lock_file(&lock); - } else { - commit_lock_file(&lock); - } - strbuf_release(&sb); - } - - reprepare_packed_git(); - return ref_cpy; -} diff --git a/builtin/log.c b/builtin/log.c index 09cf43e..e7b7db1 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -351,7 +351,8 @@ static int git_log_config(const char *var, const char *value, void *cb) } if (!prefixcmp(var, "color.decorate.")) return parse_decorate_color_config(var, 15, value); - + if (grep_config(var, value, cb) < 0) + return -1; return git_diff_ui_config(var, value, cb); } @@ -360,6 +361,7 @@ int cmd_whatchanged(int argc, const char **argv, const char *prefix) struct rev_info rev; struct setup_revision_opt opt; + init_grep_defaults(); git_config(git_log_config, NULL); init_revisions(&rev, prefix); @@ -450,6 +452,7 @@ int cmd_show(int argc, const char **argv, const char *prefix) struct pathspec match_all; int i, count, ret = 0; + init_grep_defaults(); git_config(git_log_config, NULL); init_pathspec(&match_all, NULL); @@ -530,6 +533,7 @@ int cmd_log_reflog(int argc, const char **argv, const char *prefix) struct rev_info rev; struct setup_revision_opt opt; + init_grep_defaults(); git_config(git_log_config, NULL); init_revisions(&rev, prefix); @@ -552,6 +556,7 @@ int cmd_log(int argc, const char **argv, const char *prefix) struct rev_info rev; struct setup_revision_opt opt; + init_grep_defaults(); git_config(git_log_config, NULL); init_revisions(&rev, prefix); @@ -1121,6 +1126,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) extra_hdr.strdup_strings = 1; extra_to.strdup_strings = 1; extra_cc.strdup_strings = 1; + init_grep_defaults(); git_config(git_format_config, NULL); init_revisions(&rev, prefix); rev.commit_format = CMIT_FMT_EMAIL; diff --git a/builtin/ls-files.c b/builtin/ls-files.c index b5434af..4a9ee69 100644 --- a/builtin/ls-files.c +++ b/builtin/ls-files.c @@ -337,7 +337,7 @@ void overlay_tree_on_cache(const char *tree_name, const char *prefix) matchbuf[0] = prefix; matchbuf[1] = NULL; init_pathspec(&pathspec, matchbuf); - pathspec.items[0].use_wildcard = 0; + pathspec.items[0].nowildcard_len = pathspec.items[0].len; } else init_pathspec(&pathspec, NULL); if (read_tree(tree, 1, &pathspec)) diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c index 235c17c..fb76e38 100644 --- a/builtin/ls-tree.c +++ b/builtin/ls-tree.c @@ -168,7 +168,7 @@ int cmd_ls_tree(int argc, const char **argv, const char *prefix) init_pathspec(&pathspec, get_pathspec(prefix, argv + 1)); for (i = 0; i < pathspec.nr; i++) - pathspec.items[i].use_wildcard = 0; + pathspec.items[i].nowildcard_len = pathspec.items[i].len; pathspec.has_wildcard = 0; tree = parse_tree_indirect(sha1); if (!tree) diff --git a/builtin/merge.c b/builtin/merge.c index 0ec8f0d..a96e8ea 100644 --- a/builtin/merge.c +++ b/builtin/merge.c @@ -628,59 +628,6 @@ static void write_tree_trivial(unsigned char *sha1) die(_("git write-tree failed to write a tree")); } -static const char *merge_argument(struct commit *commit) -{ - if (commit) - return sha1_to_hex(commit->object.sha1); - else - return EMPTY_TREE_SHA1_HEX; -} - -int try_merge_command(const char *strategy, size_t xopts_nr, - const char **xopts, struct commit_list *common, - const char *head_arg, struct commit_list *remotes) -{ - const char **args; - int i = 0, x = 0, ret; - struct commit_list *j; - struct strbuf buf = STRBUF_INIT; - - args = xmalloc((4 + xopts_nr + commit_list_count(common) + - commit_list_count(remotes)) * sizeof(char *)); - strbuf_addf(&buf, "merge-%s", strategy); - args[i++] = buf.buf; - for (x = 0; x < xopts_nr; x++) { - char *s = xmalloc(strlen(xopts[x])+2+1); - strcpy(s, "--"); - strcpy(s+2, xopts[x]); - args[i++] = s; - } - for (j = common; j; j = j->next) - args[i++] = xstrdup(merge_argument(j->item)); - args[i++] = "--"; - args[i++] = head_arg; - for (j = remotes; j; j = j->next) - args[i++] = xstrdup(merge_argument(j->item)); - args[i] = NULL; - ret = run_command_v_opt(args, RUN_GIT_CMD); - strbuf_release(&buf); - i = 1; - for (x = 0; x < xopts_nr; x++) - free((void *)args[i++]); - for (j = common; j; j = j->next) - free((void *)args[i++]); - i += 2; - for (j = remotes; j; j = j->next) - free((void *)args[i++]); - free(args); - discard_cache(); - if (read_cache() < 0) - die(_("failed to read the cache")); - resolve_undo_clear(); - - return ret; -} - static int try_merge_strategy(const char *strategy, struct commit_list *common, struct commit_list *remoteheads, struct commit *head, const char *head_arg) @@ -762,56 +709,6 @@ static int count_unmerged_entries(void) return ret; } -int checkout_fast_forward(const unsigned char *head, const unsigned char *remote) -{ - struct tree *trees[MAX_UNPACK_TREES]; - struct unpack_trees_options opts; - struct tree_desc t[MAX_UNPACK_TREES]; - int i, fd, nr_trees = 0; - struct dir_struct dir; - struct lock_file *lock_file = xcalloc(1, sizeof(struct lock_file)); - - refresh_cache(REFRESH_QUIET); - - fd = hold_locked_index(lock_file, 1); - - memset(&trees, 0, sizeof(trees)); - memset(&opts, 0, sizeof(opts)); - memset(&t, 0, sizeof(t)); - if (overwrite_ignore) { - memset(&dir, 0, sizeof(dir)); - dir.flags |= DIR_SHOW_IGNORED; - setup_standard_excludes(&dir); - opts.dir = &dir; - } - - opts.head_idx = 1; - opts.src_index = &the_index; - opts.dst_index = &the_index; - opts.update = 1; - opts.verbose_update = 1; - opts.merge = 1; - opts.fn = twoway_merge; - setup_unpack_trees_porcelain(&opts, "merge"); - - trees[nr_trees] = parse_tree_indirect(head); - if (!trees[nr_trees++]) - return -1; - trees[nr_trees] = parse_tree_indirect(remote); - if (!trees[nr_trees++]) - return -1; - for (i = 0; i < nr_trees; i++) { - parse_tree(trees[i]); - init_tree_desc(t+i, trees[i]->buffer, trees[i]->size); - } - if (unpack_trees(nr_trees, t, &opts)) - return -1; - if (write_cache(fd, active_cache, active_nr) || - commit_locked_index(lock_file)) - die(_("unable to write new index file")); - return 0; -} - static void split_merge_strategies(const char *string, struct strategy **list, int *nr, int *alloc) { @@ -1424,7 +1321,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix) } if (checkout_fast_forward(head_commit->object.sha1, - commit->object.sha1)) { + commit->object.sha1, + overwrite_ignore)) { ret = 1; goto done; } diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c index 5e14064..f069462 100644 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@ -2033,7 +2033,6 @@ static int add_ref_tag(const char *path, const unsigned char *sha1, int flag, vo if (!prefixcmp(path, "refs/tags/") && /* is a tag? */ !peel_ref(path, peeled) && /* peelable? */ - !is_null_sha1(peeled) && /* annotated tag? */ locate_object_entry(peeled)) /* object packed? */ add_object_entry(sha1, OBJ_TAG, NULL, 0); return 0; diff --git a/builtin/push.c b/builtin/push.c index db9ba30..8491e43 100644 --- a/builtin/push.c +++ b/builtin/push.c @@ -220,31 +220,42 @@ static const char message_advice_checkout_pull_push[] = "(e.g. 'git pull') before pushing again.\n" "See the 'Note about fast-forwards' in 'git push --help' for details."); +static const char message_advice_ref_already_exists[] = + N_("Updates were rejected because the destination reference already exists\n" + "in the remote."); + static void advise_pull_before_push(void) { - if (!advice_push_non_ff_current || !advice_push_nonfastforward) + if (!advice_push_non_ff_current || !advice_push_update_rejected) return; advise(_(message_advice_pull_before_push)); } static void advise_use_upstream(void) { - if (!advice_push_non_ff_default || !advice_push_nonfastforward) + if (!advice_push_non_ff_default || !advice_push_update_rejected) return; advise(_(message_advice_use_upstream)); } static void advise_checkout_pull_push(void) { - if (!advice_push_non_ff_matching || !advice_push_nonfastforward) + if (!advice_push_non_ff_matching || !advice_push_update_rejected) return; advise(_(message_advice_checkout_pull_push)); } +static void advise_ref_already_exists(void) +{ + if (!advice_push_already_exists || !advice_push_update_rejected) + return; + advise(_(message_advice_ref_already_exists)); +} + static int push_with_options(struct transport *transport, int flags) { int err; - int nonfastforward; + unsigned int reject_reasons; transport_set_verbosity(transport, verbosity, progress); @@ -257,7 +268,7 @@ static int push_with_options(struct transport *transport, int flags) if (verbosity > 0) fprintf(stderr, _("Pushing to %s\n"), transport->url); err = transport_push(transport, refspec_nr, refspec, flags, - &nonfastforward); + &reject_reasons); if (err != 0) error(_("failed to push some refs to '%s'"), transport->url); @@ -265,18 +276,15 @@ static int push_with_options(struct transport *transport, int flags) if (!err) return 0; - switch (nonfastforward) { - default: - break; - case NON_FF_HEAD: + if (reject_reasons & REJECT_NON_FF_HEAD) { advise_pull_before_push(); - break; - case NON_FF_OTHER: + } else if (reject_reasons & REJECT_NON_FF_OTHER) { if (default_matching_used) advise_use_upstream(); else advise_checkout_pull_push(); - break; + } else if (reject_reasons & REJECT_ALREADY_EXISTS) { + advise_ref_already_exists(); } return 1; diff --git a/builtin/replace.c b/builtin/replace.c index e3aaf70..398ccd5 100644 --- a/builtin/replace.c +++ b/builtin/replace.c @@ -46,24 +46,27 @@ typedef int (*each_replace_name_fn)(const char *name, const char *ref, static int for_each_replace_name(const char **argv, each_replace_name_fn fn) { - const char **p; + const char **p, *full_hex; char ref[PATH_MAX]; int had_error = 0; unsigned char sha1[20]; for (p = argv; *p; p++) { - if (snprintf(ref, sizeof(ref), "refs/replace/%s", *p) - >= sizeof(ref)) { - error("replace ref name too long: %.*s...", 50, *p); + if (get_sha1(*p, sha1)) { + error("Failed to resolve '%s' as a valid ref.", *p); had_error = 1; continue; } + full_hex = sha1_to_hex(sha1); + snprintf(ref, sizeof(ref), "refs/replace/%s", full_hex); + /* read_ref() may reuse the buffer */ + full_hex = ref + strlen("refs/replace/"); if (read_ref(ref, sha1)) { - error("replace ref '%s' not found.", *p); + error("replace ref '%s' not found.", full_hex); had_error = 1; continue; } - if (fn(*p, ref, sha1)) + if (fn(full_hex, ref, sha1)) had_error = 1; } return had_error; diff --git a/builtin/rev-list.c b/builtin/rev-list.c index ff5a383..67701be 100644 --- a/builtin/rev-list.c +++ b/builtin/rev-list.c @@ -201,55 +201,6 @@ static void show_edge(struct commit *commit) printf("-%s\n", sha1_to_hex(commit->object.sha1)); } -static inline int log2i(int n) -{ - int log2 = 0; - - for (; n > 1; n >>= 1) - log2++; - - return log2; -} - -static inline int exp2i(int n) -{ - return 1 << n; -} - -/* - * Estimate the number of bisect steps left (after the current step) - * - * For any x between 0 included and 2^n excluded, the probability for - * n - 1 steps left looks like: - * - * P(2^n + x) == (2^n - x) / (2^n + x) - * - * and P(2^n + x) < 0.5 means 2^n < 3x - */ -int estimate_bisect_steps(int all) -{ - int n, x, e; - - if (all < 3) - return 0; - - n = log2i(all); - e = exp2i(n); - x = all - e; - - return (e < 3 * x) ? n : n - 1; -} - -void print_commit_list(struct commit_list *list, - const char *format_cur, - const char *format_last) -{ - for ( ; list; list = list->next) { - const char *format = list->next ? format_cur : format_last; - printf(format, sha1_to_hex(list->item->object.sha1)); - } -} - static void print_var_str(const char *var, const char *val) { printf("%s='%s'\n", var, val); diff --git a/builtin/rm.c b/builtin/rm.c index b384c4c..dabfcf6 100644 --- a/builtin/rm.c +++ b/builtin/rm.c @@ -9,6 +9,7 @@ #include "cache-tree.h" #include "tree-walk.h" #include "parse-options.h" +#include "submodule.h" static const char * const builtin_rm_usage[] = { N_("git rm [options] [--] <file>..."), @@ -17,9 +18,58 @@ static const char * const builtin_rm_usage[] = { static struct { int nr, alloc; - const char **name; + struct { + const char *name; + char is_submodule; + } *entry; } list; +static int get_ours_cache_pos(const char *path, int pos) +{ + int i = -pos - 1; + + while ((i < active_nr) && !strcmp(active_cache[i]->name, path)) { + if (ce_stage(active_cache[i]) == 2) + return i; + i++; + } + return -1; +} + +static int check_submodules_use_gitfiles(void) +{ + int i; + int errs = 0; + + for (i = 0; i < list.nr; i++) { + const char *name = list.entry[i].name; + int pos; + struct cache_entry *ce; + struct stat st; + + pos = cache_name_pos(name, strlen(name)); + if (pos < 0) { + pos = get_ours_cache_pos(name, pos); + if (pos < 0) + continue; + } + ce = active_cache[pos]; + + if (!S_ISGITLINK(ce->ce_mode) || + (lstat(ce->name, &st) < 0) || + is_empty_dir(name)) + continue; + + if (!submodule_uses_gitfile(name)) + errs = error(_("submodule '%s' (or one of its nested " + "submodules) uses a .git directory\n" + "(use 'rm -rf' if you really want to remove " + "it including all of its history)"), name); + } + + return errs; +} + static int check_local_mod(unsigned char *head, int index_only) { /* @@ -37,15 +87,26 @@ static int check_local_mod(unsigned char *head, int index_only) struct stat st; int pos; struct cache_entry *ce; - const char *name = list.name[i]; + const char *name = list.entry[i].name; unsigned char sha1[20]; unsigned mode; int local_changes = 0; int staged_changes = 0; pos = cache_name_pos(name, strlen(name)); - if (pos < 0) - continue; /* removing unmerged entry */ + if (pos < 0) { + /* + * Skip unmerged entries except for populated submodules + * that could lose history when removed. + */ + pos = get_ours_cache_pos(name, pos); + if (pos < 0) + continue; + + if (!S_ISGITLINK(active_cache[pos]->ce_mode) || + is_empty_dir(name)) + continue; + } ce = active_cache[pos]; if (lstat(ce->name, &st) < 0) { @@ -58,9 +119,10 @@ static int check_local_mod(unsigned char *head, int index_only) /* if a file was removed and it is now a * directory, that is the same as ENOENT as * far as git is concerned; we do not track - * directories. + * directories unless they are submodules. */ - continue; + if (!S_ISGITLINK(ce->ce_mode)) + continue; } /* @@ -80,8 +142,11 @@ static int check_local_mod(unsigned char *head, int index_only) /* * Is the index different from the file in the work tree? + * If it's a submodule, is its work tree modified? */ - if (ce_match_stat(ce, &st, 0)) + if (ce_match_stat(ce, &st, 0) || + (S_ISGITLINK(ce->ce_mode) && + !ok_to_remove_submodule(ce->name))) local_changes = 1; /* @@ -115,10 +180,18 @@ static int check_local_mod(unsigned char *head, int index_only) errs = error(_("'%s' has changes staged in the index\n" "(use --cached to keep the file, " "or -f to force removal)"), name); - if (local_changes) - errs = error(_("'%s' has local modifications\n" - "(use --cached to keep the file, " - "or -f to force removal)"), name); + if (local_changes) { + if (S_ISGITLINK(ce->ce_mode) && + !submodule_uses_gitfile(name)) { + errs = error(_("submodule '%s' (or one of its nested " + "submodules) uses a .git directory\n" + "(use 'rm -rf' if you really want to remove " + "it including all of its history)"), name); + } else + errs = error(_("'%s' has local modifications\n" + "(use --cached to keep the file, " + "or -f to force removal)"), name); + } } } return errs; @@ -161,6 +234,21 @@ int cmd_rm(int argc, const char **argv, const char *prefix) if (read_cache() < 0) die(_("index file corrupt")); + /* + * Drop trailing directory separators from directories so we'll find + * submodules in the index. + */ + for (i = 0; i < argc; i++) { + size_t pathlen = strlen(argv[i]); + if (pathlen && is_dir_sep(argv[i][pathlen - 1]) && + is_directory(argv[i])) { + do { + pathlen--; + } while (pathlen && is_dir_sep(argv[i][pathlen - 1])); + argv[i] = xmemdupz(argv[i], pathlen); + } + } + pathspec = get_pathspec(prefix, argv); refresh_index(&the_index, REFRESH_QUIET, pathspec, NULL, NULL); @@ -173,8 +261,9 @@ int cmd_rm(int argc, const char **argv, const char *prefix) struct cache_entry *ce = active_cache[i]; if (!match_pathspec(pathspec, ce->name, ce_namelen(ce), 0, seen)) continue; - ALLOC_GROW(list.name, list.nr + 1, list.alloc); - list.name[list.nr++] = ce->name; + ALLOC_GROW(list.entry, list.nr + 1, list.alloc); + list.entry[list.nr].name = ce->name; + list.entry[list.nr++].is_submodule = S_ISGITLINK(ce->ce_mode); } if (pathspec) { @@ -215,6 +304,9 @@ int cmd_rm(int argc, const char **argv, const char *prefix) hashclr(sha1); if (check_local_mod(sha1, index_only)) exit(1); + } else if (!index_only) { + if (check_submodules_use_gitfiles()) + exit(1); } /* @@ -222,7 +314,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix) * the index unless all of them succeed. */ for (i = 0; i < list.nr; i++) { - const char *path = list.name[i]; + const char *path = list.entry[i].name; if (!quiet) printf("rm '%s'\n", path); @@ -244,7 +336,25 @@ int cmd_rm(int argc, const char **argv, const char *prefix) if (!index_only) { int removed = 0; for (i = 0; i < list.nr; i++) { - const char *path = list.name[i]; + const char *path = list.entry[i].name; + if (list.entry[i].is_submodule) { + if (is_empty_dir(path)) { + if (!rmdir(path)) { + removed = 1; + continue; + } + } else { + struct strbuf buf = STRBUF_INIT; + strbuf_addstr(&buf, path); + if (!remove_dir_recursively(&buf, 0)) { + removed = 1; + strbuf_release(&buf); + continue; + } + strbuf_release(&buf); + /* Fallthrough and let remove_path() fail. */ + } + } if (!remove_path(path)) { removed = 1; continue; diff --git a/builtin/send-pack.c b/builtin/send-pack.c index 7d05064..f849e0a 100644 --- a/builtin/send-pack.c +++ b/builtin/send-pack.c @@ -16,164 +16,6 @@ static const char send_pack_usage[] = static struct send_pack_args args; -static int feed_object(const unsigned char *sha1, int fd, int negative) -{ - char buf[42]; - - if (negative && !has_sha1_file(sha1)) - return 1; - - memcpy(buf + negative, sha1_to_hex(sha1), 40); - if (negative) - buf[0] = '^'; - buf[40 + negative] = '\n'; - return write_or_whine(fd, buf, 41 + negative, "send-pack: send refs"); -} - -/* - * Make a pack stream and spit it out into file descriptor fd - */ -static int pack_objects(int fd, struct ref *refs, struct extra_have_objects *extra, struct send_pack_args *args) -{ - /* - * The child becomes pack-objects --revs; we feed - * the revision parameters to it via its stdin and - * let its stdout go back to the other end. - */ - const char *argv[] = { - "pack-objects", - "--all-progress-implied", - "--revs", - "--stdout", - NULL, - NULL, - NULL, - NULL, - NULL, - }; - struct child_process po; - int i; - - i = 4; - if (args->use_thin_pack) - argv[i++] = "--thin"; - if (args->use_ofs_delta) - argv[i++] = "--delta-base-offset"; - if (args->quiet || !args->progress) - argv[i++] = "-q"; - if (args->progress) - argv[i++] = "--progress"; - memset(&po, 0, sizeof(po)); - po.argv = argv; - po.in = -1; - po.out = args->stateless_rpc ? -1 : fd; - po.git_cmd = 1; - if (start_command(&po)) - die_errno("git pack-objects failed"); - - /* - * We feed the pack-objects we just spawned with revision - * parameters by writing to the pipe. - */ - for (i = 0; i < extra->nr; i++) - if (!feed_object(extra->array[i], po.in, 1)) - break; - - while (refs) { - if (!is_null_sha1(refs->old_sha1) && - !feed_object(refs->old_sha1, po.in, 1)) - break; - if (!is_null_sha1(refs->new_sha1) && - !feed_object(refs->new_sha1, po.in, 0)) - break; - refs = refs->next; - } - - close(po.in); - - if (args->stateless_rpc) { - char *buf = xmalloc(LARGE_PACKET_MAX); - while (1) { - ssize_t n = xread(po.out, buf, LARGE_PACKET_MAX); - if (n <= 0) - break; - send_sideband(fd, -1, buf, n, LARGE_PACKET_MAX); - } - free(buf); - close(po.out); - po.out = -1; - } - - if (finish_command(&po)) - return -1; - return 0; -} - -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)) - 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'; - error("unpack failed: %s", line + 7); - ret = -1; - } - hint = NULL; - while (1) { - char *refname; - char *msg; - len = packet_read_line(in, line, sizeof(line)); - if (!len) - break; - if (len < 3 || - (memcmp(line, "ok ", 3) && memcmp(line, "ng ", 3))) { - fprintf(stderr, "protocol error: %s\n", line); - ret = -1; - break; - } - - line[strlen(line)-1] = '\0'; - refname = line + 3; - msg = strchr(refname, ' '); - if (msg) - *msg++ = '\0'; - - /* first try searching at our hint, falling back to all refs */ - if (hint) - hint = find_ref_by_name(hint, refname); - if (!hint) - hint = find_ref_by_name(refs, refname); - if (!hint) { - warning("remote reported status on unknown ref: %s", - refname); - continue; - } - if (hint->status != REF_STATUS_EXPECTING_REPORT) { - warning("remote reported status on unexpected ref: %s", - refname); - continue; - } - - if (line[0] == 'o' && line[1] == 'k') - hint->status = REF_STATUS_OK; - else { - hint->status = REF_STATUS_REMOTE_REJECT; - ret = -1; - } - if (msg) - hint->remote_status = xstrdup(msg); - /* start our next search from the next ref */ - hint = hint->next; - } - return ret; -} - static void print_helper_status(struct ref *ref) { struct strbuf buf = STRBUF_INIT; @@ -202,6 +44,11 @@ static void print_helper_status(struct ref *ref) msg = "non-fast forward"; break; + case REF_STATUS_REJECT_ALREADY_EXISTS: + res = "error"; + msg = "already exists"; + break; + case REF_STATUS_REJECT_NODELETE: case REF_STATUS_REMOTE_REJECT: res = "error"; @@ -227,181 +74,6 @@ static void print_helper_status(struct ref *ref) strbuf_release(&buf); } -static int sideband_demux(int in, int out, void *data) -{ - int *fd = data, ret; -#ifdef NO_PTHREADS - close(fd[1]); -#endif - ret = recv_sideband("send-pack", fd[0], out); - close(out); - return ret; -} - -int send_pack(struct send_pack_args *args, - int fd[], struct child_process *conn, - struct ref *remote_refs, - struct extra_have_objects *extra_have) -{ - int in = fd[0]; - int out = fd[1]; - struct strbuf req_buf = STRBUF_INIT; - struct ref *ref; - int new_refs; - int allow_deleting_refs = 0; - int status_report = 0; - int use_sideband = 0; - int quiet_supported = 0; - int agent_supported = 0; - unsigned cmds_sent = 0; - int ret; - struct async demux; - - /* Does the other end support the reporting? */ - if (server_supports("report-status")) - status_report = 1; - if (server_supports("delete-refs")) - allow_deleting_refs = 1; - if (server_supports("ofs-delta")) - args->use_ofs_delta = 1; - if (server_supports("side-band-64k")) - use_sideband = 1; - if (server_supports("quiet")) - quiet_supported = 1; - if (server_supports("agent")) - agent_supported = 1; - - if (!remote_refs) { - fprintf(stderr, "No refs in common and none specified; doing nothing.\n" - "Perhaps you should specify a branch such as 'master'.\n"); - return 0; - } - - /* - * Finally, tell the other end! - */ - new_refs = 0; - for (ref = remote_refs; ref; ref = ref->next) { - if (!ref->peer_ref && !args->send_mirror) - continue; - - /* Check for statuses set by set_ref_status_for_push() */ - switch (ref->status) { - case REF_STATUS_REJECT_NONFASTFORWARD: - case REF_STATUS_UPTODATE: - continue; - default: - ; /* do nothing */ - } - - if (ref->deletion && !allow_deleting_refs) { - ref->status = REF_STATUS_REJECT_NODELETE; - continue; - } - - if (!ref->deletion) - new_refs++; - - if (args->dry_run) { - ref->status = REF_STATUS_OK; - } else { - char *old_hex = sha1_to_hex(ref->old_sha1); - char *new_hex = sha1_to_hex(ref->new_sha1); - int quiet = quiet_supported && (args->quiet || !args->progress); - - if (!cmds_sent && (status_report || use_sideband || - quiet || agent_supported)) { - packet_buf_write(&req_buf, - "%s %s %s%c%s%s%s%s%s", - old_hex, new_hex, ref->name, 0, - status_report ? " report-status" : "", - use_sideband ? " side-band-64k" : "", - quiet ? " quiet" : "", - agent_supported ? " agent=" : "", - agent_supported ? git_user_agent_sanitized() : "" - ); - } - else - packet_buf_write(&req_buf, "%s %s %s", - old_hex, new_hex, ref->name); - ref->status = status_report ? - REF_STATUS_EXPECTING_REPORT : - REF_STATUS_OK; - cmds_sent++; - } - } - - if (args->stateless_rpc) { - if (!args->dry_run && cmds_sent) { - packet_buf_flush(&req_buf); - send_sideband(out, -1, req_buf.buf, req_buf.len, LARGE_PACKET_MAX); - } - } else { - safe_write(out, req_buf.buf, req_buf.len); - packet_flush(out); - } - strbuf_release(&req_buf); - - if (use_sideband && cmds_sent) { - memset(&demux, 0, sizeof(demux)); - demux.proc = sideband_demux; - demux.data = fd; - demux.out = -1; - if (start_async(&demux)) - die("send-pack: unable to fork off sideband demultiplexer"); - in = demux.out; - } - - if (new_refs && cmds_sent) { - if (pack_objects(out, remote_refs, extra_have, args) < 0) { - for (ref = remote_refs; ref; ref = ref->next) - ref->status = REF_STATUS_NONE; - if (args->stateless_rpc) - close(out); - if (git_connection_is_socket(conn)) - shutdown(fd[0], SHUT_WR); - if (use_sideband) - finish_async(&demux); - return -1; - } - } - if (args->stateless_rpc && cmds_sent) - packet_flush(out); - - if (status_report && cmds_sent) - ret = receive_status(in, remote_refs); - else - ret = 0; - if (args->stateless_rpc) - packet_flush(out); - - if (use_sideband && cmds_sent) { - if (finish_async(&demux)) { - error("error in sideband demultiplexer"); - ret = -1; - } - close(demux.out); - } - - if (ret < 0) - return ret; - - if (args->porcelain) - return 0; - - for (ref = remote_refs; ref; ref = ref->next) { - switch (ref->status) { - case REF_STATUS_NONE: - case REF_STATUS_UPTODATE: - case REF_STATUS_OK: - break; - default: - return -1; - } - } - return 0; -} - int cmd_send_pack(int argc, const char **argv, const char *prefix) { int i, nr_refspecs = 0; @@ -418,7 +90,7 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix) int send_all = 0; const char *receivepack = "git-receive-pack"; int flags; - int nonfastforward = 0; + unsigned int reject_reasons; int progress = -1; argv++; @@ -556,7 +228,7 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix) ret |= finish_connect(conn); if (!helper_status) - transport_print_push_status(dest, remote_refs, args.verbose, 0, &nonfastforward); + transport_print_push_status(dest, remote_refs, args.verbose, 0, &reject_reasons); if (!args.dry_run && remote) { struct ref *ref; diff --git a/builtin/shortlog.c b/builtin/shortlog.c index b316cf3..8360514 100644 --- a/builtin/shortlog.c +++ b/builtin/shortlog.c @@ -306,9 +306,8 @@ parse_done: static void add_wrapped_shortlog_msg(struct strbuf *sb, const char *s, const struct shortlog *log) { - int col = strbuf_add_wrapped_text(sb, s, log->in1, log->in2, log->wrap); - if (col != log->wrap) - strbuf_addch(sb, '\n'); + strbuf_add_wrapped_text(sb, s, log->in1, log->in2, log->wrap); + strbuf_addch(sb, '\n'); } void shortlog_output(struct shortlog *log) diff --git a/builtin/show-ref.c b/builtin/show-ref.c index 4eb016d..8d9b76a 100644 --- a/builtin/show-ref.c +++ b/builtin/show-ref.c @@ -28,7 +28,6 @@ static void show_one(const char *refname, const unsigned char *sha1) static int show_ref(const char *refname, const unsigned char *sha1, int flag, void *cbdata) { - struct object *obj; const char *hex; unsigned char peeled[20]; @@ -79,25 +78,9 @@ match: if (!deref_tags) return 0; - if ((flag & REF_ISPACKED) && !peel_ref(refname, peeled)) { - if (!is_null_sha1(peeled)) { - hex = find_unique_abbrev(peeled, abbrev); - printf("%s %s^{}\n", hex, refname); - } - } - else { - obj = parse_object(sha1); - if (!obj) - die("git show-ref: bad ref %s (%s)", refname, - sha1_to_hex(sha1)); - if (obj->type == OBJ_TAG) { - obj = deref_tag(obj, refname, 0); - if (!obj) - die("git show-ref: bad tag at ref %s (%s)", refname, - sha1_to_hex(sha1)); - hex = find_unique_abbrev(obj->sha1, abbrev); - printf("%s %s^{}\n", hex, refname); - } + if (!peel_ref(refname, peeled)) { + hex = find_unique_abbrev(peeled, abbrev); + printf("%s %s^{}\n", hex, refname); } return 0; } diff --git a/builtin/symbolic-ref.c b/builtin/symbolic-ref.c index 9e92828..f481959 100644 --- a/builtin/symbolic-ref.c +++ b/builtin/symbolic-ref.c @@ -5,12 +5,11 @@ static const char * const git_symbolic_ref_usage[] = { N_("git symbolic-ref [options] name [ref]"), + N_("git symbolic-ref -d [-q] name"), NULL }; -static int shorten; - -static void check_symref(const char *HEAD, int quiet) +static int check_symref(const char *HEAD, int quiet, int shorten, int print) { unsigned char sha1[20]; int flag; @@ -22,20 +21,24 @@ static void check_symref(const char *HEAD, int quiet) if (!quiet) die("ref %s is not a symbolic ref", HEAD); else - exit(1); + return 1; + } + if (print) { + if (shorten) + refname = shorten_unambiguous_ref(refname, 0); + puts(refname); } - if (shorten) - refname = shorten_unambiguous_ref(refname, 0); - puts(refname); + return 0; } int cmd_symbolic_ref(int argc, const char **argv, const char *prefix) { - int quiet = 0; + int quiet = 0, delete = 0, shorten = 0, ret = 0; const char *msg = NULL; struct option options[] = { OPT__QUIET(&quiet, N_("suppress error message for non-symbolic (detached) refs")), + OPT_BOOL('d', "delete", &delete, N_("delete symbolic ref")), OPT_BOOL(0, "short", &shorten, N_("shorten ref output")), OPT_STRING('m', NULL, &msg, N_("reason"), N_("reason of the update")), OPT_END(), @@ -46,9 +49,19 @@ int cmd_symbolic_ref(int argc, const char **argv, const char *prefix) git_symbolic_ref_usage, 0); if (msg &&!*msg) die("Refusing to perform update with empty message"); + + if (delete) { + if (argc != 1) + usage_with_options(git_symbolic_ref_usage, options); + ret = check_symref(argv[0], 1, 0, 0); + if (ret) + die("Cannot delete %s, not a symbolic ref", argv[0]); + return delete_ref(argv[0], NULL, REF_NODEREF); + } + switch (argc) { case 1: - check_symref(argv[0], quiet); + ret = check_symref(argv[0], quiet, shorten, 1); break; case 2: if (!strcmp(argv[0], "HEAD") && @@ -59,5 +72,5 @@ int cmd_symbolic_ref(int argc, const char **argv, const char *prefix) default: usage_with_options(git_symbolic_ref_usage, options); } - return 0; + return ret; } diff --git a/builtin/update-index.c b/builtin/update-index.c index 74986bf..ada1dff 100644 --- a/builtin/update-index.c +++ b/builtin/update-index.c @@ -593,6 +593,7 @@ struct refresh_params { static int refresh(struct refresh_params *o, unsigned int flag) { setup_work_tree(); + read_cache_preload(NULL); *o->has_errors |= refresh_cache(o->flags | flag); return 0; } diff --git a/cache-tree.c b/cache-tree.c index 28ed657..37e4d00 100644 --- a/cache-tree.c +++ b/cache-tree.c @@ -166,12 +166,8 @@ static int verify_cache(struct cache_entry **cache, fprintf(stderr, "...\n"); break; } - if (ce_stage(ce)) - fprintf(stderr, "%s: unmerged (%s)\n", - ce->name, sha1_to_hex(ce->sha1)); - else - fprintf(stderr, "%s: not added yet\n", - ce->name); + fprintf(stderr, "%s: unmerged (%s)\n", + ce->name, sha1_to_hex(ce->sha1)); } } if (funny) @@ -242,13 +238,17 @@ static int update_one(struct cache_tree *it, int entries, const char *base, int baselen, + int *skip_count, int flags) { struct strbuf buffer; int missing_ok = flags & WRITE_TREE_MISSING_OK; int dryrun = flags & WRITE_TREE_DRY_RUN; + int to_invalidate = 0; int i; + *skip_count = 0; + if (0 <= it->entry_count && has_sha1_file(it->sha1)) return it->entry_count; @@ -263,11 +263,12 @@ static int update_one(struct cache_tree *it, /* * Find the subtrees and update them. */ - for (i = 0; i < entries; i++) { + i = 0; + while (i < entries) { struct cache_entry *ce = cache[i]; struct cache_tree_sub *sub; const char *path, *slash; - int pathlen, sublen, subcnt; + int pathlen, sublen, subcnt, subskip; path = ce->name; pathlen = ce_namelen(ce); @@ -275,8 +276,10 @@ static int update_one(struct cache_tree *it, break; /* at the end of this level */ slash = strchr(path + baselen, '/'); - if (!slash) + if (!slash) { + i++; continue; + } /* * a/bbb/c (base = a/, slash = /c) * ==> @@ -290,10 +293,13 @@ static int update_one(struct cache_tree *it, cache + i, entries - i, path, baselen + sublen + 1, + &subskip, flags); if (subcnt < 0) return subcnt; - i += subcnt - 1; + i += subcnt; + sub->count = subcnt; /* to be used in the next loop */ + *skip_count += subskip; sub->used = 1; } @@ -304,7 +310,8 @@ static int update_one(struct cache_tree *it, */ strbuf_init(&buffer, 8192); - for (i = 0; i < entries; i++) { + i = 0; + while (i < entries) { struct cache_entry *ce = cache[i]; struct cache_tree_sub *sub; const char *path, *slash; @@ -324,14 +331,17 @@ static int update_one(struct cache_tree *it, if (!sub) die("cache-tree.c: '%.*s' in '%s' not found", entlen, path + baselen, path); - i += sub->cache_tree->entry_count - 1; + i += sub->count; sha1 = sub->cache_tree->sha1; mode = S_IFDIR; + if (sub->cache_tree->entry_count < 0) + to_invalidate = 1; } else { sha1 = ce->sha1; mode = ce->ce_mode; entlen = pathlen - baselen; + i++; } if (mode != S_IFGITLINK && !missing_ok && !has_sha1_file(sha1)) { strbuf_release(&buffer); @@ -339,8 +349,25 @@ static int update_one(struct cache_tree *it, mode, sha1_to_hex(sha1), entlen+baselen, path); } - if (ce->ce_flags & (CE_REMOVE | CE_INTENT_TO_ADD)) - continue; /* entry being removed or placeholder */ + /* + * CE_REMOVE entries are removed before the index is + * written to disk. Skip them to remain consistent + * with the future on-disk index. + */ + if (ce->ce_flags & CE_REMOVE) { + *skip_count = *skip_count + 1; + continue; + } + + /* + * CE_INTENT_TO_ADD entries exist on on-disk index but + * they are not part of generated trees. Invalidate up + * to root to force cache-tree users to read elsewhere. + */ + if (ce->ce_flags & CE_INTENT_TO_ADD) { + to_invalidate = 1; + continue; + } strbuf_grow(&buffer, entlen + 100); strbuf_addf(&buffer, "%o %.*s%c", mode, entlen, path + baselen, '\0'); @@ -360,7 +387,7 @@ static int update_one(struct cache_tree *it, } strbuf_release(&buffer); - it->entry_count = i; + it->entry_count = to_invalidate ? -1 : i - *skip_count; #if DEBUG fprintf(stderr, "cache-tree update-one (%d ent, %d subtree) %s\n", it->entry_count, it->subtree_nr, @@ -374,11 +401,11 @@ int cache_tree_update(struct cache_tree *it, int entries, int flags) { - int i; + int i, skip; i = verify_cache(cache, entries, flags); if (i) return i; - i = update_one(it, cache, entries, "", 0, flags); + i = update_one(it, cache, entries, "", 0, &skip, flags); if (i < 0) return i; return 0; diff --git a/cache-tree.h b/cache-tree.h index d8cb2e9..55d0f59 100644 --- a/cache-tree.h +++ b/cache-tree.h @@ -7,6 +7,7 @@ struct cache_tree; struct cache_tree_sub { struct cache_tree *cache_tree; + int count; /* internally used by update_one() */ int namelen; int used; char name[FLEX_ARRAY]; @@ -362,6 +362,7 @@ static inline enum object_type object_type(unsigned int mode) #define GIT_NOTES_DISPLAY_REF_ENVIRONMENT "GIT_NOTES_DISPLAY_REF" #define GIT_NOTES_REWRITE_REF_ENVIRONMENT "GIT_NOTES_REWRITE_REF" #define GIT_NOTES_REWRITE_MODE_ENVIRONMENT "GIT_NOTES_REWRITE_MODE" +#define GIT_LITERAL_PATHSPECS_ENVIRONMENT "GIT_LITERAL_PATHSPECS" /* * Repository-local GIT_* environment variables @@ -473,6 +474,8 @@ extern int index_name_is_other(const struct index_state *, const char *, int); extern int ie_match_stat(const struct index_state *, struct cache_entry *, struct stat *, unsigned int); extern int ie_modified(const struct index_state *, struct cache_entry *, struct stat *, unsigned int); +#define PATHSPEC_ONESTAR 1 /* the pathspec pattern sastisfies GFNM_ONESTAR */ + struct pathspec { const char **raw; /* get_pathspec() result, not freed by free_pathspec() */ int nr; @@ -482,7 +485,8 @@ struct pathspec { struct pathspec_item { const char *match; int len; - unsigned int use_wildcard:1; + int nowildcard_len; + int flags; } *items; }; @@ -490,6 +494,8 @@ extern int init_pathspec(struct pathspec *, const char **); extern void free_pathspec(struct pathspec *); extern int ce_path_match(const struct cache_entry *ce, const struct pathspec *pathspec); +extern int limit_pathspec_to_literal(void); + #define HASH_WRITE_OBJECT 1 #define HASH_FORMAT_CHECK 2 extern int index_fd(unsigned char *sha1, int fd, struct stat *st, enum object_type type, const char *path, unsigned flags); @@ -714,10 +720,11 @@ static inline int is_absolute_path(const char *path) } int is_directory(const char *); const char *real_path(const char *path); +const char *real_path_if_valid(const char *path); const char *absolute_path(const char *path); const char *relative_path(const char *abs, const char *base); int normalize_path_copy(char *dst, const char *src); -int longest_ancestor_length(const char *path, const char *prefix_list); +int longest_ancestor_length(const char *path, struct string_list *prefixes); char *strip_path_suffix(const char *path, const char *suffix); int daemon_avoid_alias(const char *path); int offset_1st_component(const char *path); @@ -999,14 +1006,19 @@ struct ref { unsigned char old_sha1[20]; unsigned char new_sha1[20]; char *symref; - unsigned int force:1, + unsigned int + force:1, + requires_force:1, merge:1, nonfastforward:1, + not_forwardable:1, + update:1, deletion:1; enum { REF_STATUS_NONE = 0, REF_STATUS_OK, REF_STATUS_REJECT_NONFASTFORWARD, + REF_STATUS_REJECT_ALREADY_EXISTS, REF_STATUS_REJECT_NODELETE, REF_STATUS_UPTODATE, REF_STATUS_REMOTE_REJECT, @@ -1136,6 +1148,9 @@ extern int check_repository_format_version(const char *var, const char *value, v extern int git_env_bool(const char *, int); extern int git_config_system(void); extern int config_error_nonbool(const char *); +#ifdef __GNUC__ +#define config_error_nonbool(s) (config_error_nonbool(s), -1) +#endif extern const char *get_log_output_encoding(void); extern const char *get_commit_output_encoding(void); @@ -1149,15 +1164,13 @@ struct config_include_data { #define CONFIG_INCLUDE_INIT { 0 } extern int git_config_include(const char *name, const char *value, void *data); -#define IDENT_NAME_GIVEN 01 -#define IDENT_MAIL_GIVEN 02 -#define IDENT_ALL_GIVEN (IDENT_NAME_GIVEN|IDENT_MAIL_GIVEN) -extern int user_ident_explicitly_given; -extern int user_ident_sufficiently_given(void); +extern int committer_ident_sufficiently_given(void); +extern int author_ident_sufficiently_given(void); extern const char *git_commit_encoding; extern const char *git_log_output_encoding; extern const char *git_mailmap_file; +extern const char *git_mailmap_blob; /* IO helper functions */ extern void maybe_flush_or_die(FILE *, const char *); @@ -1183,6 +1196,7 @@ extern int pager_in_use(void); extern int pager_use_color; extern int term_columns(void); extern int decimal_width(int); +extern int check_pager_config(const char *cmd); extern const char *editor_program; extern const char *askpass_program; @@ -1265,8 +1279,15 @@ struct startup_info { }; extern struct startup_info *startup_info; -/* builtin/merge.c */ -int checkout_fast_forward(const unsigned char *from, const unsigned char *to); +/* merge.c */ +struct commit_list; +int try_merge_command(const char *strategy, size_t xopts_nr, + const char **xopts, struct commit_list *common, + const char *head_arg, struct commit_list *remotes); +int checkout_fast_forward(const unsigned char *from, + const unsigned char *to, + int overwrite_ignore); + int sane_execvp(const char *file, char *const argv[]); @@ -1347,3 +1347,13 @@ struct commit_list **commit_list_append(struct commit *commit, new->next = NULL; return &new->next; } + +void print_commit_list(struct commit_list *list, + const char *format_cur, + const char *format_last) +{ + for ( ; list; list = list->next) { + const char *format = list->next ? format_cur : format_last; + printf(format, sha1_to_hex(list->item->object.sha1)); + } +} @@ -86,9 +86,10 @@ struct pretty_print_context { enum date_mode date_mode; unsigned date_mode_explicit:1; int need_8bit_cte; - int show_notes; + char *notes_message; struct reflog_walk_info *reflog_info; const char *output_encoding; + int color; }; struct userformat_want { @@ -99,8 +100,6 @@ 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, const char *output_encoding); -extern char *reencode_commit_message(const struct commit *commit, - const char **encoding_p); extern void get_commit_format(const char *arg, struct rev_info *); extern const char *format_subject(struct strbuf *sb, const char *msg, const char *line_separator); @@ -222,4 +221,8 @@ struct commit *get_merge_parent(const char *name); extern int parse_signed_commit(const unsigned char *sha1, struct strbuf *message, struct strbuf *signature); +extern void print_commit_list(struct commit_list *list, + const char *format_cur, + const char *format_last); + #endif /* COMMIT_H */ diff --git a/compat/cygwin.c b/compat/cygwin.c index dfe9b30..5428858 100644 --- a/compat/cygwin.c +++ b/compat/cygwin.c @@ -1,6 +1,13 @@ #define WIN32_LEAN_AND_MEAN +#ifdef CYGWIN_V15_WIN32API #include "../git-compat-util.h" #include "win32.h" +#else +#include <sys/stat.h> +#include <sys/errno.h> +#include "win32.h" +#include "../git-compat-util.h" +#endif #include "../cache.h" /* to read configuration */ static inline void filetime_to_timespec(const FILETIME *ft, struct timespec *ts) diff --git a/compat/fnmatch/fnmatch.c b/compat/fnmatch/fnmatch.c index 0ff1d27..b8b7dc2 100644 --- a/compat/fnmatch/fnmatch.c +++ b/compat/fnmatch/fnmatch.c @@ -135,9 +135,9 @@ extern int errno; # if !defined HAVE___STRCHRNUL && !defined _LIBC static char * -__strchrnul (s, c) - const char *s; - int c; +__strchrnul (const char *s, int c) + + { char *result = strchr (s, c); if (result == NULL) @@ -159,11 +159,11 @@ static int internal_fnmatch __P ((const char *pattern, const char *string, internal_function; static int internal_function -internal_fnmatch (pattern, string, no_leading_period, flags) - const char *pattern; - const char *string; - int no_leading_period; - int flags; +internal_fnmatch (const char *pattern, const char *string, int no_leading_period, int flags) + + + + { register const char *p = pattern, *n = string; register unsigned char c; @@ -481,10 +481,10 @@ internal_fnmatch (pattern, string, no_leading_period, flags) int -fnmatch (pattern, string, flags) - const char *pattern; - const char *string; - int flags; +fnmatch (const char *pattern, const char *string, int flags) + + + { return internal_fnmatch (pattern, string, flags & FNM_PERIOD, flags); } diff --git a/compat/mingw.c b/compat/mingw.c index afc892d..b673625 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -256,6 +256,8 @@ int mingw_rmdir(const char *pathname) while ((ret = rmdir(pathname)) == -1 && tries < ARRAY_SIZE(delay)) { if (!is_file_in_use_error(GetLastError())) + errno = err_win_to_posix(GetLastError()); + if (errno != EACCES) break; if (!is_dir_empty(pathname)) { errno = ENOTEMPTY; @@ -271,7 +273,7 @@ int mingw_rmdir(const char *pathname) Sleep(delay[tries]); tries++; } - while (ret == -1 && is_file_in_use_error(GetLastError()) && + while (ret == -1 && errno == EACCES && is_file_in_use_error(GetLastError()) && ask_yes_no_if_possible("Deletion of directory '%s' failed. " "Should I try again?", pathname)) ret = rmdir(pathname); @@ -319,6 +321,31 @@ ssize_t mingw_write(int fd, const void *buf, size_t count) return write(fd, buf, min(count, 31 * 1024 * 1024)); } +static BOOL WINAPI ctrl_ignore(DWORD type) +{ + return TRUE; +} + +#undef fgetc +int mingw_fgetc(FILE *stream) +{ + int ch; + if (!isatty(_fileno(stream))) + return fgetc(stream); + + SetConsoleCtrlHandler(ctrl_ignore, TRUE); + while (1) { + ch = fgetc(stream); + if (ch != EOF || GetLastError() != ERROR_OPERATION_ABORTED) + break; + + /* Ctrl+C was pressed, simulate SIGINT and retry */ + mingw_raise(SIGINT); + } + SetConsoleCtrlHandler(ctrl_ignore, FALSE); + return ch; +} + #undef fopen FILE *mingw_fopen (const char *filename, const char *otype) { @@ -335,6 +362,28 @@ FILE *mingw_freopen (const char *filename, const char *otype, FILE *stream) return freopen(filename, otype, stream); } +#undef fflush +int mingw_fflush(FILE *stream) +{ + int ret = fflush(stream); + + /* + * write() is used behind the scenes of stdio output functions. + * Since git code does not check for errors after each stdio write + * operation, it can happen that write() is called by a later + * stdio function even if an earlier write() call failed. In the + * case of a pipe whose readable end was closed, only the first + * call to write() reports EPIPE on Windows. Subsequent write() + * calls report EINVAL. It is impossible to notice whether this + * fflush invocation triggered such a case, therefore, we have to + * catch all EINVAL errors whole-sale. + */ + if (ret && errno == EINVAL) + errno = EPIPE; + + return ret; +} + /* * The unit of FILETIME is 100-nanoseconds since January 1, 1601, UTC. * Returns the 100-nanoseconds ("hekto nanoseconds") since the epoch. @@ -1524,7 +1573,7 @@ static HANDLE timer_event; static HANDLE timer_thread; static int timer_interval; static int one_shot; -static sig_handler_t timer_fn = SIG_DFL; +static sig_handler_t timer_fn = SIG_DFL, sigint_fn = SIG_DFL; /* The timer works like this: * The thread, ticktack(), is a trivial routine that most of the time @@ -1538,10 +1587,7 @@ static sig_handler_t timer_fn = SIG_DFL; static unsigned __stdcall ticktack(void *dummy) { while (WaitForSingleObject(timer_event, timer_interval) == WAIT_TIMEOUT) { - if (timer_fn == SIG_DFL) - die("Alarm"); - if (timer_fn != SIG_IGN) - timer_fn(SIGALRM); + mingw_raise(SIGALRM); if (one_shot) break; } @@ -1632,12 +1678,49 @@ int sigaction(int sig, struct sigaction *in, struct sigaction *out) sig_handler_t mingw_signal(int sig, sig_handler_t handler) { sig_handler_t old = timer_fn; - if (sig != SIGALRM) + + switch (sig) { + case SIGALRM: + timer_fn = handler; + break; + + case SIGINT: + sigint_fn = handler; + break; + + default: return signal(sig, handler); - timer_fn = handler; + } + return old; } +#undef raise +int mingw_raise(int sig) +{ + switch (sig) { + case SIGALRM: + if (timer_fn == SIG_DFL) { + if (isatty(STDERR_FILENO)) + fputs("Alarm clock\n", stderr); + exit(128 + SIGALRM); + } else if (timer_fn != SIG_IGN) + timer_fn(SIGALRM); + return 0; + + case SIGINT: + if (sigint_fn == SIG_DFL) + exit(128 + SIGINT); + else if (sigint_fn != SIG_IGN) + sigint_fn(SIGINT); + return 0; + + default: + return raise(sig); + } +} + + static const char *make_backslash_path(const char *path) { static char buf[PATH_MAX + 1]; @@ -1699,21 +1782,6 @@ int link(const char *oldpath, const char *newpath) return 0; } -char *getpass(const char *prompt) -{ - struct strbuf buf = STRBUF_INIT; - - fputs(prompt, stderr); - for (;;) { - char c = _getch(); - if (c == '\r' || c == '\n') - break; - strbuf_addch(&buf, c); - } - fputs("\n", stderr); - return strbuf_detach(&buf, NULL); -} - pid_t waitpid(pid_t pid, int *status, int options) { HANDLE h = OpenProcess(SYNCHRONIZE | PROCESS_QUERY_INFORMATION, diff --git a/compat/mingw.h b/compat/mingw.h index 61a6521..685cd2c 100644 --- a/compat/mingw.h +++ b/compat/mingw.h @@ -55,8 +55,6 @@ struct passwd { char *pw_dir; }; -extern char *getpass(const char *prompt); - typedef void (__cdecl *sig_handler_t)(int); struct sigaction { sig_handler_t sa_handler; @@ -179,12 +177,18 @@ int mingw_open (const char *filename, int oflags, ...); ssize_t mingw_write(int fd, const void *buf, size_t count); #define write mingw_write +int mingw_fgetc(FILE *stream); +#define fgetc mingw_fgetc + FILE *mingw_fopen (const char *filename, const char *otype); #define fopen mingw_fopen FILE *mingw_freopen (const char *filename, const char *otype, FILE *stream); #define freopen mingw_freopen +int mingw_fflush(FILE *stream); +#define fflush mingw_fflush + char *mingw_getcwd(char *pointer, int len); #define getcwd mingw_getcwd @@ -287,6 +291,9 @@ static inline unsigned int git_ntohl(unsigned int x) sig_handler_t mingw_signal(int sig, sig_handler_t handler); #define signal mingw_signal +int mingw_raise(int sig); +#define raise mingw_raise + /* * ANSI emulation wrappers */ diff --git a/compat/nedmalloc/nedmalloc.c b/compat/nedmalloc/nedmalloc.c index d9a17a8..91c4e7f 100644 --- a/compat/nedmalloc/nedmalloc.c +++ b/compat/nedmalloc/nedmalloc.c @@ -603,7 +603,10 @@ static NOINLINE mstate FindMSpace(nedpool *p, threadcache *tc, int *lastUsed, si } /* We really want to make sure this goes into memory now but we have to be careful of breaking aliasing rules, so write it twice */ - *((volatile struct malloc_state **) &p->m[end])=p->m[end]=temp; + { + volatile struct malloc_state **_m=(volatile struct malloc_state **) &p->m[end]; + *_m=(p->m[end]=temp); + } ACQUIRE_LOCK(&p->m[end]->mutex); /*printf("Created mspace idx %d\n", end);*/ RELEASE_LOCK(&p->mutex); diff --git a/compat/terminal.c b/compat/terminal.c index bbb038d..9b5e3d1 100644 --- a/compat/terminal.c +++ b/compat/terminal.c @@ -3,8 +3,22 @@ #include "sigchain.h" #include "strbuf.h" +#if defined(HAVE_DEV_TTY) || defined(WIN32) + +static void restore_term(void); + +static void restore_term_on_signal(int sig) +{ + restore_term(); + sigchain_pop(sig); + raise(sig); +} + #ifdef HAVE_DEV_TTY +#define INPUT_PATH "/dev/tty" +#define OUTPUT_PATH "/dev/tty" + static int term_fd = -1; static struct termios old_term; @@ -14,58 +28,109 @@ static void restore_term(void) return; tcsetattr(term_fd, TCSAFLUSH, &old_term); + close(term_fd); term_fd = -1; } -static void restore_term_on_signal(int sig) +static int disable_echo(void) { - restore_term(); - sigchain_pop(sig); - raise(sig); + struct termios t; + + term_fd = open("/dev/tty", O_RDWR); + if (tcgetattr(term_fd, &t) < 0) + goto error; + + old_term = t; + sigchain_push_common(restore_term_on_signal); + + t.c_lflag &= ~ECHO; + if (!tcsetattr(term_fd, TCSAFLUSH, &t)) + return 0; + +error: + close(term_fd); + term_fd = -1; + return -1; +} + +#elif defined(WIN32) + +#define INPUT_PATH "CONIN$" +#define OUTPUT_PATH "CONOUT$" +#define FORCE_TEXT "t" + +static HANDLE hconin = INVALID_HANDLE_VALUE; +static DWORD cmode; + +static void restore_term(void) +{ + if (hconin == INVALID_HANDLE_VALUE) + return; + + SetConsoleMode(hconin, cmode); + CloseHandle(hconin); + hconin = INVALID_HANDLE_VALUE; } +static int disable_echo(void) +{ + hconin = CreateFile("CONIN$", GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ, NULL, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, NULL); + if (hconin == INVALID_HANDLE_VALUE) + return -1; + + GetConsoleMode(hconin, &cmode); + sigchain_push_common(restore_term_on_signal); + if (!SetConsoleMode(hconin, cmode & (~ENABLE_ECHO_INPUT))) { + CloseHandle(hconin); + hconin = INVALID_HANDLE_VALUE; + return -1; + } + + return 0; +} + +#endif + +#ifndef FORCE_TEXT +#define FORCE_TEXT +#endif + char *git_terminal_prompt(const char *prompt, int echo) { static struct strbuf buf = STRBUF_INIT; int r; - FILE *fh; + FILE *input_fh, *output_fh; - fh = fopen("/dev/tty", "w+"); - if (!fh) + input_fh = fopen(INPUT_PATH, "r" FORCE_TEXT); + if (!input_fh) return NULL; - if (!echo) { - struct termios t; - - if (tcgetattr(fileno(fh), &t) < 0) { - fclose(fh); - return NULL; - } - - old_term = t; - term_fd = fileno(fh); - sigchain_push_common(restore_term_on_signal); - - t.c_lflag &= ~ECHO; - if (tcsetattr(fileno(fh), TCSAFLUSH, &t) < 0) { - term_fd = -1; - fclose(fh); - return NULL; - } + output_fh = fopen(OUTPUT_PATH, "w" FORCE_TEXT); + if (!output_fh) { + fclose(input_fh); + return NULL; + } + + if (!echo && disable_echo()) { + fclose(input_fh); + fclose(output_fh); + return NULL; } - fputs(prompt, fh); - fflush(fh); + fputs(prompt, output_fh); + fflush(output_fh); - r = strbuf_getline(&buf, fh, '\n'); + r = strbuf_getline(&buf, input_fh, '\n'); if (!echo) { - fseek(fh, SEEK_CUR, 0); - putc('\n', fh); - fflush(fh); + putc('\n', output_fh); + fflush(output_fh); } restore_term(); - fclose(fh); + fclose(input_fh); + fclose(output_fh); if (r == EOF) return NULL; @@ -58,7 +58,7 @@ static int handle_path_include(const char *path, struct config_include_data *inc path = buf.buf; } - if (!access_or_warn(path, R_OK)) { + if (!access_or_die(path, R_OK)) { if (++inc->depth > MAX_INCLUDE_DEPTH) die(include_depth_advice, MAX_INCLUDE_DEPTH, path, cf && cf->name ? cf->name : "the command line"); @@ -839,6 +839,8 @@ static int git_default_mailmap_config(const char *var, const char *value) { if (!strcmp(var, "mailmap.file")) return git_config_string(&git_mailmap_file, var, value); + if (!strcmp(var, "mailmap.blob")) + return git_config_string(&git_mailmap_blob, var, value); /* Add other config variables here and to Documentation/config.txt. */ return 0; @@ -938,23 +940,23 @@ int git_config_early(config_fn_t fn, void *data, const char *repo_config) home_config_paths(&user_config, &xdg_config, "config"); - if (git_config_system() && !access_or_warn(git_etc_gitconfig(), R_OK)) { + if (git_config_system() && !access_or_die(git_etc_gitconfig(), R_OK)) { ret += git_config_from_file(fn, git_etc_gitconfig(), data); found += 1; } - if (xdg_config && !access_or_warn(xdg_config, R_OK)) { + if (xdg_config && !access_or_die(xdg_config, R_OK)) { ret += git_config_from_file(fn, xdg_config, data); found += 1; } - if (user_config && !access_or_warn(user_config, R_OK)) { + if (user_config && !access_or_die(user_config, R_OK)) { ret += git_config_from_file(fn, user_config, data); found += 1; } - if (repo_config && !access_or_warn(repo_config, R_OK)) { + if (repo_config && !access_or_die(repo_config, R_OK)) { ret += git_config_from_file(fn, repo_config, data); found += 1; } @@ -1279,6 +1281,7 @@ int git_config_parse_key(const char *key, char **store_key, int *baselen_) out_free_ret_1: free(*store_key); + *store_key = NULL; return -CONFIG_INVALID_KEY; } @@ -1659,6 +1662,7 @@ int git_config_rename_section(const char *old_name, const char *new_name) * Call this to report error for your variable that should not * get a boolean value (i.e. "[my] var" means "true"). */ +#undef config_error_nonbool int config_error_nonbool(const char *var) { return error("Missing value for '%s'", var); diff --git a/config.mak.in b/config.mak.in index 69d4838..e8a9bb4 100644 --- a/config.mak.in +++ b/config.mak.in @@ -18,7 +18,7 @@ datarootdir = @datarootdir@ template_dir = @datadir@/git-core/templates sysconfdir = @sysconfdir@ -mandir=@mandir@ +mandir = @mandir@ srcdir = @srcdir@ VPATH = @srcdir@ diff --git a/configure.ac b/configure.ac index c85888c..1991258 100644 --- a/configure.ac +++ b/configure.ac @@ -753,6 +753,14 @@ AC_CHECK_MEMBER(struct dirent.d_type, [#include <dirent.h>]) GIT_CONF_SUBST([NO_D_TYPE_IN_DIRENT]) # +# Define NO_GECOS_IN_PWENT if you don't have pw_gecos in struct passwd +# in the C library. +AC_CHECK_MEMBER(struct passwd.pw_gecos, +[NO_GECOS_IN_PWENT=], +[NO_GECOS_IN_PWENT=YesPlease], +[#include <pwd.h>]) +GIT_CONF_SUBST([NO_GECOS_IN_PWENT]) +# # Define NO_SOCKADDR_STORAGE if your platform does not have struct # sockaddr_storage. AC_CHECK_TYPE(struct sockaddr_storage, @@ -872,6 +880,12 @@ AC_CHECK_HEADER([libcharset.h], [HAVE_LIBCHARSET_H=YesPlease], [HAVE_LIBCHARSET_H=]) GIT_CONF_SUBST([HAVE_LIBCHARSET_H]) +# +# Define HAVE_STRINGS_H if you have strings.h +AC_CHECK_HEADER([strings.h], +[HAVE_STRINGS_H=YesPlease], +[HAVE_STRINGS_H=]) +GIT_CONF_SUBST([HAVE_STRINGS_H]) # Define CHARSET_LIB if libiconv does not export the locale_charset symbol # and libcharset does CHARSET_LIB= @@ -1021,10 +1035,20 @@ if test -n "$USER_NOPTHREAD"; then # -D_REENTRANT' or some such. elif test -z "$PTHREAD_CFLAGS"; then threads_found=no - for opt in -mt -pthread -lpthread; do + # Attempt to compile and link some code using pthreads to determine + # required linker flags. The order is somewhat important here: We + # first try it without any extra flags, to catch systems where + # pthreads are part of the C library, then go on testing various other + # flags. We do so to avoid false positives. For example, on Mac OS X + # pthreads are part of the C library; moreover, the compiler allows us + # to add "-mt" to the CFLAGS (although it will do nothing except + # trigger a warning about an unused flag). Hence if we checked for + # "-mt" before "" we would end up picking it. But unfortunately this + # would then trigger compiler warnings on every single file we compile. + for opt in "" -mt -pthread -lpthread; do old_CFLAGS="$CFLAGS" CFLAGS="$opt $CFLAGS" - AC_MSG_CHECKING([Checking for POSIX Threads with '$opt']) + AC_MSG_CHECKING([for POSIX Threads with '$opt']) AC_LINK_IFELSE([PTHREADTEST_SRC], [AC_MSG_RESULT([yes]) NO_PTHREADS= @@ -1044,7 +1068,7 @@ elif test -z "$PTHREAD_CFLAGS"; then else old_CFLAGS="$CFLAGS" CFLAGS="$PTHREAD_CFLAGS $CFLAGS" - AC_MSG_CHECKING([Checking for POSIX Threads with '$PTHREAD_CFLAGS']) + AC_MSG_CHECKING([for POSIX Threads with '$PTHREAD_CFLAGS']) AC_LINK_IFELSE([PTHREADTEST_SRC], [AC_MSG_RESULT([yes]) NO_PTHREADS= diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index cda095d..a4c48e1 100644 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -23,10 +23,6 @@ # 3) Consider changing your PS1 to also show the current branch, # see git-prompt.sh for details. -if [[ -n ${ZSH_VERSION-} ]]; then - autoload -U +X bashcompinit && bashcompinit -fi - case "$COMP_WORDBREAKS" in *:*) : great ;; *) COMP_WORDBREAKS="$COMP_WORDBREAKS:" @@ -169,7 +165,6 @@ __git_reassemble_comp_words_by_ref() } if ! type _get_comp_words_by_ref >/dev/null 2>&1; then -if [[ -z ${ZSH_VERSION:+set} ]]; then _get_comp_words_by_ref () { local exclude cur_ words_ cword_ @@ -197,32 +192,6 @@ _get_comp_words_by_ref () shift done } -else -_get_comp_words_by_ref () -{ - while [ $# -gt 0 ]; do - case "$1" in - cur) - cur=${COMP_WORDS[COMP_CWORD]} - ;; - prev) - prev=${COMP_WORDS[COMP_CWORD-1]} - ;; - words) - words=("${COMP_WORDS[@]}") - ;; - cword) - cword=$COMP_CWORD - ;; - -n) - # assume COMP_WORDBREAKS is already set sanely - shift - ;; - esac - shift - done -} -fi fi # Generates completion reply with compgen, appending a space to possible @@ -585,7 +554,7 @@ __git_list_porcelain_commands () { local i IFS=" "$'\n' __git_compute_all_commands - for i in "help" $__git_all_commands + for i in $__git_all_commands do case $i in *--*) : helper pattern;; @@ -1002,6 +971,13 @@ _git_commit () { __git_has_doubledash && return + case "$prev" in + -c|-C) + __gitcomp_nl "$(__git_refs)" "" "${cur}" + return + ;; + esac + case "$cur" in --cleanup=*) __gitcomp "default strip verbatim whitespace @@ -1118,6 +1094,14 @@ _git_fetch () __git_complete_remote_or_refspec } +__git_format_patch_options=" + --stdout --attach --no-attach --thread --thread= --output-directory + --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= +" + _git_format_patch () { case "$cur" in @@ -1128,21 +1112,7 @@ _git_format_patch () return ;; --*) - __gitcomp " - --stdout --attach --no-attach --thread --thread= - --output-directory - --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= - " + __gitcomp "$__git_format_patch_options" return ;; esac @@ -1556,6 +1526,12 @@ _git_send_email () __gitcomp "ssl tls" "" "${cur##--smtp-encryption=}" return ;; + --thread=*) + __gitcomp " + deep shallow + " "" "${cur##--thread=}" + return + ;; --*) __gitcomp "--annotate --bcc --cc --cc-cmd --chain-reply-to --compose --confirm= --dry-run --envelope-sender @@ -1565,11 +1541,12 @@ _git_send_email () --signed-off-by-cc --smtp-pass --smtp-server --smtp-server-port --smtp-encryption= --smtp-user --subject --suppress-cc= --suppress-from --thread --to - --validate --no-validate" + --validate --no-validate + $__git_format_patch_options" return ;; esac - COMPREPLY=() + __git_complete_revlist } _git_stage () @@ -2431,20 +2408,71 @@ __gitk_main () __git_complete_revlist } -__git_func_wrap () -{ - if [[ -n ${ZSH_VERSION-} ]]; then - emulate -L bash - setopt KSH_TYPESET +if [[ -n ${ZSH_VERSION-} ]]; then + echo "WARNING: this script is deprecated, please see git-completion.zsh" 1>&2 - # workaround zsh's bug that leaves 'words' as a special - # variable in versions < 4.3.12 - typeset -h words + autoload -U +X compinit && compinit - # workaround zsh's bug that quotes spaces in the COMPREPLY - # array if IFS doesn't contain spaces. - typeset -h IFS - fi + __gitcomp () + { + emulate -L zsh + + local cur_="${3-$cur}" + + case "$cur_" in + --*=) + ;; + *) + local c IFS=$' \t\n' + local -a array + for c in ${=1}; do + c="$c${4-}" + case $c in + --*=*|*.) ;; + *) c="$c " ;; + esac + array+=("$c") + done + compset -P '*[=:]' + compadd -Q -S '' -p "${2-}" -a -- array && _ret=0 + ;; + esac + } + + __gitcomp_nl () + { + emulate -L zsh + + local IFS=$'\n' + compset -P '*[=:]' + compadd -Q -S "${4- }" -p "${2-}" -- ${=1} && _ret=0 + } + + __git_zsh_helper () + { + emulate -L ksh + local cur cword prev + cur=${words[CURRENT-1]} + prev=${words[CURRENT-2]} + let cword=CURRENT-1 + __${service}_main + } + + _git () + { + emulate -L zsh + local _ret=1 + __git_zsh_helper + let _ret && _default -S '' && _ret=0 + return _ret + } + + compdef _git git gitk + return +fi + +__git_func_wrap () +{ local cur words cword prev _get_comp_words_by_ref -n =: cur words cword prev $1 diff --git a/contrib/completion/git-completion.tcsh b/contrib/completion/git-completion.tcsh new file mode 100644 index 0000000..8aafb63 --- /dev/null +++ b/contrib/completion/git-completion.tcsh @@ -0,0 +1,107 @@ +#!tcsh +# +# tcsh completion support for core Git. +# +# Copyright (C) 2012 Marc Khouzam <marc.khouzam@gmail.com> +# Distributed under the GNU General Public License, version 2.0. +# +# When sourced, this script will generate a new script that uses +# the git-completion.bash script provided by core Git. This new +# script can be used by tcsh to perform git completion. +# The current script also issues the necessary tcsh 'complete' +# commands. +# +# To use this completion script: +# +# 1) Copy both this file and the bash completion script to ${HOME}. +# You _must_ use the name ${HOME}/.git-completion.bash for the +# bash script. +# (e.g. ~/.git-completion.tcsh and ~/.git-completion.bash). +# 2) Add the following line to your .tcshrc/.cshrc: +# source ~/.git-completion.tcsh +# 3) For completion similar to bash, it is recommended to also +# add the following line to your .tcshrc/.cshrc: +# set autolist=ambiguous +# It will tell tcsh to list the possible completion choices. + +set __git_tcsh_completion_original_script = ${HOME}/.git-completion.bash +set __git_tcsh_completion_script = ${HOME}/.git-completion.tcsh.bash + +# Check that the user put the script in the right place +if ( ! -e ${__git_tcsh_completion_original_script} ) then + echo "git-completion.tcsh: Cannot find: ${__git_tcsh_completion_original_script}. Git completion will not work." + exit +endif + +cat << EOF > ${__git_tcsh_completion_script} +#!bash +# +# This script is GENERATED and will be overwritten automatically. +# Do not modify it directly. Instead, modify git-completion.tcsh +# and source it again. + +source ${__git_tcsh_completion_original_script} + +# Set COMP_WORDS in a way that can be handled by the bash script. +COMP_WORDS=(\$2) + +# The cursor is at the end of parameter #1. +# We must check for a space as the last character which will +# tell us that the previous word is complete and the cursor +# is on the next word. +if [ "\${2: -1}" == " " ]; then + # The last character is a space, so our location is at the end + # of the command-line array + COMP_CWORD=\${#COMP_WORDS[@]} +else + # The last character is not a space, so our location is on the + # last word of the command-line array, so we must decrement the + # count by 1 + COMP_CWORD=\$((\${#COMP_WORDS[@]}-1)) +fi + +# Call _git() or _gitk() of the bash script, based on the first argument +_\${1} + +IFS=\$'\n' +if [ \${#COMPREPLY[*]} -gt 0 ]; then + echo "\${COMPREPLY[*]}" | sort | uniq +else + # No completions suggested. In this case, we want tcsh to perform + # standard file completion. However, there does not seem to be way + # to tell tcsh to do that. To help the user, we try to simulate + # file completion directly in this script. + # + # Known issues: + # - Possible completions are shown with their directory prefix. + # - Completions containing shell variables are not handled. + # - Completions with ~ as the first character are not handled. + + # No file completion should be done unless we are completing beyond + # the git sub-command. An improvement on the bash completion :) + if [ \${COMP_CWORD} -gt 1 ]; then + TO_COMPLETE="\${COMP_WORDS[\${COMP_CWORD}]}" + + # We don't support ~ expansion: too tricky. + if [ "\${TO_COMPLETE:0:1}" != "~" ]; then + # Use ls so as to add the '/' at the end of directories. + RESULT=(\`ls -dp \${TO_COMPLETE}* 2> /dev/null\`) + echo \${RESULT[*]} + + # If there is a single completion and it is a directory, + # we output it a second time to trick tcsh into not adding a space + # after it. + if [ \${#RESULT[*]} -eq 1 ] && [ "\${RESULT[0]: -1}" == "/" ]; then + echo \${RESULT[*]} + fi + fi + fi +fi + +EOF + +# Don't need this variable anymore, so don't pollute the users environment +unset __git_tcsh_completion_original_script + +complete git 'p,*,`bash ${__git_tcsh_completion_script} git "${COMMAND_LINE}"`,' +complete gitk 'p,*,`bash ${__git_tcsh_completion_script} gitk "${COMMAND_LINE}"`,' diff --git a/contrib/completion/git-completion.zsh b/contrib/completion/git-completion.zsh new file mode 100644 index 0000000..4577502 --- /dev/null +++ b/contrib/completion/git-completion.zsh @@ -0,0 +1,78 @@ +#compdef git gitk + +# zsh completion wrapper for git +# +# You need git's bash completion script installed somewhere, by default on the +# same directory as this script. +# +# If your script is on ~/.git-completion.sh instead, you can configure it on +# your ~/.zshrc: +# +# zstyle ':completion:*:*:git:*' script ~/.git-completion.sh +# +# The recommended way to install this script is to copy to +# '~/.zsh/completion/_git', and then add the following to your ~/.zshrc file: +# +# fpath=(~/.zsh/completion $fpath) + +complete () +{ + # do nothing + return 0 +} + +zstyle -s ":completion:*:*:git:*" script script +test -z "$script" && script="$(dirname ${funcsourcetrace[1]%:*})"/git-completion.bash +ZSH_VERSION='' . "$script" + +__gitcomp () +{ + emulate -L zsh + + local cur_="${3-$cur}" + + case "$cur_" in + --*=) + ;; + *) + local c IFS=$' \t\n' + local -a array + for c in ${=1}; do + c="$c${4-}" + case $c in + --*=*|*.) ;; + *) c="$c " ;; + esac + array+=("$c") + done + compset -P '*[=:]' + compadd -Q -S '' -p "${2-}" -a -- array && _ret=0 + ;; + esac +} + +__gitcomp_nl () +{ + emulate -L zsh + + local IFS=$'\n' + compset -P '*[=:]' + compadd -Q -S "${4- }" -p "${2-}" -- ${=1} && _ret=0 +} + +_git () +{ + local _ret=1 + () { + emulate -L ksh + local cur cword prev + cur=${words[CURRENT-1]} + prev=${words[CURRENT-2]} + let cword=CURRENT-1 + __${service}_main + } + let _ret && _default -S '' && _ret=0 + return _ret +} + +_git diff --git a/contrib/completion/git-prompt.sh b/contrib/completion/git-prompt.sh index 5ab488c..9bef053 100644 --- a/contrib/completion/git-prompt.sh +++ b/contrib/completion/git-prompt.sh @@ -10,9 +10,22 @@ # 1) Copy this file to somewhere (e.g. ~/.git-prompt.sh). # 2) Add the following line to your .bashrc/.zshrc: # source ~/.git-prompt.sh -# 3) Change your PS1 to also show the current branch: -# Bash: PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ ' -# ZSH: PS1='[%n@%m %c$(__git_ps1 " (%s)")]\$ ' +# 3a) Change your PS1 to call __git_ps1 as +# command-substitution: +# Bash: PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ ' +# ZSH: PS1='[%n@%m %c$(__git_ps1 " (%s)")]\$ ' +# the optional argument will be used as format string. +# 3b) Alternatively, if you are using bash, __git_ps1 can be +# used for PROMPT_COMMAND with two parameters, <pre> and +# <post>, which are strings you would put in $PS1 before +# and after the status string generated by the git-prompt +# machinery. e.g. +# PROMPT_COMMAND='__git_ps1 "\u@\h:\w" "\\\$ "' +# will show username, at-sign, host, colon, cwd, then +# various status string, followed by dollar and SP, as +# your prompt. +# Optionally, you can supply a third argument with a printf +# format string to finetune the output of the branch status # # The argument to __git_ps1 will be displayed only if you are currently # in a git repository. The %s token will be the name of the current @@ -58,6 +71,10 @@ # branch relative to newer tag or branch (master~4) # describe relative to older annotated tag (v1.6.3.1-13-gdd42c2f) # default exactly matching tag +# +# If you would like a colored hint about the current dirty state, set +# GIT_PS1_SHOWCOLORHINTS to a nonempty value. The colors are based on +# the colored output of "git status -sb". # __gitdir accepts 0 or 1 arguments (i.e., location) # returns location of .git repo @@ -204,11 +221,43 @@ __git_ps1_show_upstream () # __git_ps1 accepts 0 or 1 arguments (i.e., format string) -# returns text to add to bash PS1 prompt (includes branch name) +# when called from PS1 using command substitution +# in this mode it prints text to add to bash PS1 prompt (includes branch name) +# +# __git_ps1 requires 2 or 3 arguments when called from PROMPT_COMMAND (pc) +# in that case it _sets_ PS1. The arguments are parts of a PS1 string. +# when two arguments are given, the first is prepended and the second appended +# to the state string when assigned to PS1. +# The optional third parameter will be used as printf format string to further +# customize the output of the git-status string. +# In this mode you can request colored hints using GIT_PS1_SHOWCOLORHINTS=true __git_ps1 () { + local pcmode=no + local detached=no + local ps1pc_start='\u@\h:\w ' + local ps1pc_end='\$ ' + local printf_format=' (%s)' + + case "$#" in + 2|3) pcmode=yes + ps1pc_start="$1" + ps1pc_end="$2" + printf_format="${3:-$printf_format}" + ;; + 0|1) printf_format="${1:-$printf_format}" + ;; + *) return + ;; + esac + local g="$(__gitdir)" - if [ -n "$g" ]; then + if [ -z "$g" ]; then + if [ $pcmode = yes ]; then + #In PC mode PS1 always needs to be set + PS1="$ps1pc_start$ps1pc_end" + fi + else local r="" local b="" if [ -f "$g/rebase-merge/interactive" ]; then @@ -235,7 +284,7 @@ __git_ps1 () fi b="$(git symbolic-ref HEAD 2>/dev/null)" || { - + detached=yes b="$( case "${GIT_PS1_DESCRIBE_STYLE-}" in (contains) @@ -294,6 +343,53 @@ __git_ps1 () fi local f="$w$i$s$u" - printf -- "${1:- (%s)}" "$c${b##refs/heads/}${f:+ $f}$r$p" + if [ $pcmode = yes ]; then + local gitstring= + if [ -n "${GIT_PS1_SHOWCOLORHINTS-}" ]; then + local c_red='\e[31m' + local c_green='\e[32m' + local c_lblue='\e[1;34m' + local c_clear='\e[0m' + local bad_color=$c_red + local ok_color=$c_green + local branch_color="$c_clear" + local flags_color="$c_lblue" + local branchstring="$c${b##refs/heads/}" + + if [ $detached = no ]; then + branch_color="$ok_color" + else + branch_color="$bad_color" + fi + + # Setting gitstring directly with \[ and \] around colors + # is necessary to prevent wrapping issues! + gitstring="\[$branch_color\]$branchstring\[$c_clear\]" + + if [ -n "$w$i$s$u$r$p" ]; then + gitstring="$gitstring " + fi + if [ "$w" = "*" ]; then + gitstring="$gitstring\[$bad_color\]$w" + fi + if [ -n "$i" ]; then + gitstring="$gitstring\[$ok_color\]$i" + fi + if [ -n "$s" ]; then + gitstring="$gitstring\[$flags_color\]$s" + fi + if [ -n "$u" ]; then + gitstring="$gitstring\[$bad_color\]$u" + fi + gitstring="$gitstring\[$c_clear\]$r$p" + else + gitstring="$c${b##refs/heads/}${f:+ $f}$r$p" + fi + gitstring=$(printf -- "$printf_format" "$gitstring") + PS1="$ps1pc_start$gitstring$ps1pc_end" + else + # NO color option unless in PROMPT_COMMAND mode + printf -- "$printf_format" "$c${b##refs/heads/}${f:+ $f}$r$p" + fi fi } diff --git a/contrib/emacs/git.el b/contrib/emacs/git.el index 65c95d9..5ffc506 100644 --- a/contrib/emacs/git.el +++ b/contrib/emacs/git.el @@ -1671,7 +1671,7 @@ Commands: "Entry point into git-status mode." (interactive "DSelect directory: ") (setq dir (git-get-top-dir dir)) - (if (file-directory-p (concat (file-name-as-directory dir) ".git")) + (if (file-exists-p (concat (file-name-as-directory dir) ".git")) (let ((buffer (or (and git-reuse-status-buffer (git-find-status-buffer dir)) (create-file-buffer (expand-file-name "*git-status*" dir))))) (switch-to-buffer buffer) diff --git a/contrib/remote-helpers/Makefile b/contrib/remote-helpers/Makefile new file mode 100644 index 0000000..9a76575 --- /dev/null +++ b/contrib/remote-helpers/Makefile @@ -0,0 +1,13 @@ +TESTS := $(wildcard test*.sh) + +export T := $(addprefix $(CURDIR)/,$(TESTS)) +export MAKE := $(MAKE) -e +export PATH := $(CURDIR):$(PATH) + +test: + $(MAKE) -C ../../t $@ + +$(TESTS): + $(MAKE) -C ../../t $(CURDIR)/$@ + +.PHONY: $(TESTS) diff --git a/contrib/remote-helpers/git-remote-hg b/contrib/remote-helpers/git-remote-hg new file mode 100755 index 0000000..016cdad --- /dev/null +++ b/contrib/remote-helpers/git-remote-hg @@ -0,0 +1,794 @@ +#!/usr/bin/env python +# +# Copyright (c) 2012 Felipe Contreras +# + +# Inspired by Rocco Rutte's hg-fast-export + +# Just copy to your ~/bin, or anywhere in your $PATH. +# Then you can clone with: +# git clone hg::/path/to/mercurial/repo/ + +from mercurial import hg, ui, bookmarks, context, util, encoding + +import re +import sys +import os +import json +import shutil +import subprocess +import urllib + +# +# If you want to switch to hg-git compatibility mode: +# git config --global remote-hg.hg-git-compat true +# +# git: +# Sensible defaults for git. +# hg bookmarks are exported as git branches, hg branches are prefixed +# with 'branches/', HEAD is a special case. +# +# hg: +# Emulate hg-git. +# Only hg bookmarks are exported as git branches. +# Commits are modified to preserve hg information and allow biridectionality. +# + +NAME_RE = re.compile('^([^<>]+)') +AUTHOR_RE = re.compile('^([^<>]+?)? ?<([^<>]*)>$') +AUTHOR_HG_RE = re.compile('^(.*?) ?<(.*?)(?:>(.+)?)?$') +RAW_AUTHOR_RE = re.compile('^(\w+) (?:(.+)? )?<(.*)> (\d+) ([+-]\d+)') + +def die(msg, *args): + sys.stderr.write('ERROR: %s\n' % (msg % args)) + sys.exit(1) + +def warn(msg, *args): + sys.stderr.write('WARNING: %s\n' % (msg % args)) + +def gitmode(flags): + return 'l' in flags and '120000' or 'x' in flags and '100755' or '100644' + +def gittz(tz): + return '%+03d%02d' % (-tz / 3600, -tz % 3600 / 60) + +def hgmode(mode): + m = { '0100755': 'x', '0120000': 'l' } + return m.get(mode, '') + +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): + self.path = path + self.tips = {} + self.marks = {} + self.rev_marks = {} + self.last_mark = 0 + + self.load() + + def load(self): + if not os.path.exists(self.path): + return + + tmp = json.load(open(self.path)) + + self.tips = tmp['tips'] + self.marks = tmp['marks'] + self.last_mark = tmp['last-mark'] + + for rev, mark in self.marks.iteritems(): + self.rev_marks[mark] = int(rev) + + def dict(self): + return { 'tips': self.tips, 'marks': self.marks, 'last-mark' : self.last_mark } + + def store(self): + json.dump(self.dict(), open(self.path, 'w')) + + def __str__(self): + return str(self.dict()) + + def from_rev(self, rev): + return self.marks[str(rev)] + + def to_rev(self, mark): + return self.rev_marks[mark] + + def get_mark(self, rev): + self.last_mark += 1 + self.marks[str(rev)] = self.last_mark + return self.last_mark + + def new_mark(self, rev, mark): + self.marks[str(rev)] = mark + self.rev_marks[mark] = rev + self.last_mark = mark + + def is_marked(self, rev): + return self.marks.has_key(str(rev)) + + def get_tip(self, branch): + return self.tips.get(branch, 0) + + def set_tip(self, branch, tip): + self.tips[branch] = tip + +class Parser: + + def __init__(self, repo): + self.repo = repo + self.line = self.get_line() + + def get_line(self): + return sys.stdin.readline().strip() + + def __getitem__(self, i): + return self.line.split()[i] + + def check(self, word): + return self.line.startswith(word) + + def each_block(self, separator): + while self.line != separator: + yield self.line + self.line = self.get_line() + + def __iter__(self): + return self.each_block('') + + def next(self): + self.line = self.get_line() + if self.line == 'done': + self.line = None + + def get_mark(self): + i = self.line.index(':') + 1 + return int(self.line[i:]) + + def get_data(self): + if not self.check('data'): + return None + i = self.line.index(' ') + 1 + size = int(self.line[i:]) + return sys.stdin.read(size) + + def get_author(self): + global bad_mail + + ex = None + m = RAW_AUTHOR_RE.match(self.line) + if not m: + return None + _, name, email, date, tz = m.groups() + if name and 'ext:' in name: + m = re.match('^(.+?) ext:\((.+)\)$', name) + if m: + name = m.group(1) + ex = urllib.unquote(m.group(2)) + + if email != bad_mail: + if name: + user = '%s <%s>' % (name, email) + else: + user = '<%s>' % (email) + else: + user = name + + if ex: + user += ex + + tz = int(tz) + 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 get_filechanges(repo, ctx, parent): + modified = set() + added = set() + removed = set() + + cur = ctx.manifest() + prev = repo[parent].manifest().copy() + + for fn in cur: + if fn in prev: + if (cur.flags(fn) != prev.flags(fn) or cur[fn] != prev[fn]): + modified.add(fn) + del prev[fn] + else: + added.add(fn) + removed |= set(prev.keys()) + + return added | modified, removed + +def fixup_user_git(user): + name = mail = None + user = user.replace('"', '') + m = AUTHOR_RE.match(user) + if m: + name = m.group(1) + mail = m.group(2).strip() + else: + m = NAME_RE.match(user) + if m: + name = m.group(1).strip() + return (name, mail) + +def fixup_user_hg(user): + def sanitize(name): + # stole this from hg-git + return re.sub('[<>\n]', '?', name.lstrip('< ').rstrip('> ')) + + m = AUTHOR_HG_RE.match(user) + if m: + name = sanitize(m.group(1)) + mail = sanitize(m.group(2)) + ex = m.group(3) + if ex: + name += ' ext:(' + urllib.quote(ex) + ')' + else: + name = sanitize(user) + if '@' in user: + mail = name + else: + mail = None + + return (name, mail) + +def fixup_user(user): + global mode, bad_mail + + if mode == 'git': + name, mail = fixup_user_git(user) + else: + name, mail = fixup_user_hg(user) + + if not name: + name = bad_name + if not mail: + mail = bad_mail + + return '%s <%s>' % (name, mail) + +def get_repo(url, alias): + global dirname, peer + + myui = ui.ui() + myui.setconfig('ui', 'interactive', 'off') + + 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) + repo = dstpeer.local() + else: + repo = hg.repository(myui, local_path) + peer = hg.peer(myui, {}, url) + repo.pull(peer, heads=None, force=True) + + return repo + +def rev_to_mark(rev): + global marks + return marks.from_rev(rev) + +def mark_to_rev(mark): + global marks + return marks.to_rev(mark) + +def export_ref(repo, name, kind, head): + global prefix, marks, mode + + 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 + + revs = [rev for rev in revs if not marks.is_marked(rev)] + + for rev in revs: + + c = repo[rev] + (manifest, user, (time, tz), files, desc, extra) = repo.changelog.read(c.node()) + rev_branch = extra['branch'] + + author = "%s %d %s" % (fixup_user(user), time, gittz(tz)) + if 'committer' in extra: + user, time, tz = extra['committer'].rsplit(' ', 2) + committer = "%s %s %s" % (user, time, gittz(int(tz))) + else: + committer = author + + parents = [p for p in repo.changelog.parentrevs(rev) if p >= 0] + + if len(parents) == 0: + modified = c.manifest().keys() + removed = [] + else: + modified, removed = get_filechanges(repo, c, parents[0]) + + if mode == 'hg': + extra_msg = '' + + if rev_branch != 'default': + extra_msg += 'branch : %s\n' % rev_branch + + renames = [] + for f in c.files(): + if f not in c.manifest(): + continue + rename = c.filectx(f).renamed() + if rename: + renames.append((rename[0], f)) + + for e in renames: + extra_msg += "rename : %s => %s\n" % e + + for key, value in extra.iteritems(): + if key in ('author', 'committer', 'encoding', 'message', 'branch', 'hg-git'): + continue + else: + extra_msg += "extra : %s : %s\n" % (key, urllib.quote(value)) + + desc += '\n' + if extra_msg: + desc += '\n--HG--\n' + extra_msg + + if len(parents) == 0 and rev: + print 'reset %s/%s' % (prefix, ename) + + print "commit %s/%s" % (prefix, ename) + print "mark :%d" % (marks.get_mark(rev)) + print "author %s" % (author) + print "committer %s" % (committer) + print "data %d" % (len(desc)) + print desc + + if len(parents) > 0: + print "from :%s" % (rev_to_mark(parents[0])) + if len(parents) > 1: + print "merge :%s" % (rev_to_mark(parents[1])) + + for f in modified: + export_file(c.filectx(f)) + for f in removed: + print "D %s" % (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) + print "from :%u" % rev_to_mark(rev) + print + + marks.set_tip(ename, rev) + +def export_tag(repo, tag): + export_ref(repo, tag, 'tags', repo[tag]) + +def export_bookmark(repo, bmark): + head = bmarks[bmark] + export_ref(repo, bmark, 'bookmarks', head) + +def export_branch(repo, branch): + tip = get_branch_tip(repo, branch) + head = repo[tip] + export_ref(repo, branch, 'branches', head) + +def export_head(repo): + global g_head + export_ref(repo, g_head[0], 'bookmarks', g_head[1]) + +def do_capabilities(parser): + global prefix, dirname + + print "import" + print "export" + print "refspec refs/heads/branches/*:%s/branches/*" % prefix + print "refspec refs/heads/*:%s/bookmarks/*" % prefix + print "refspec refs/tags/*:%s/tags/*" % prefix + + path = os.path.join(dirname, 'marks-git') + + if os.path.exists(path): + print "*import-marks %s" % path + print "*export-marks %s" % path + + print + +def get_branch_tip(repo, branch): + global branches + + heads = branches.get(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 heads[0] + +def list_head(repo, cur): + global g_head, bmarks + + head = bookmarks.readcurrent(repo) + if head: + node = repo[head] + else: + # fake bookmark from current branch + head = cur + node = repo['.'] + if not node: + node = repo['tip'] + if not node: + return + if head == 'default': + head = 'master' + bmarks[head] = node + + print "@refs/heads/%s HEAD" % head + g_head = (head, node) + +def do_list(parser): + global branches, bmarks, mode, track_branches + + repo = parser.repo + for bmark, node in bookmarks.listbookmarks(repo).iteritems(): + bmarks[bmark] = repo[node] + + cur = repo.dirstate.branch() + + list_head(repo, cur) + + if track_branches: + for branch in repo.branchmap(): + heads = repo.branchheads(branch) + if len(heads): + branches[branch] = heads + + for branch in branches: + print "? refs/heads/branches/%s" % branch + + for bmark in bmarks: + print "? refs/heads/%s" % bmark + + for tag, node in repo.tagslist(): + if tag == 'tip': + continue + print "? refs/tags/%s" % tag + + print + +def do_import(parser): + 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 + sys.stdout.flush() + + tmp = encoding.encoding + encoding.encoding = 'utf-8' + + # lets get all the import lines + while parser.check('import'): + ref = parser[1] + + if (ref == 'HEAD'): + export_head(repo) + elif ref.startswith('refs/heads/branches/'): + branch = ref[len('refs/heads/branches/'):] + export_branch(repo, branch) + elif ref.startswith('refs/heads/'): + bmark = ref[len('refs/heads/'):] + export_bookmark(repo, bmark) + elif ref.startswith('refs/tags/'): + tag = ref[len('refs/tags/'):] + export_tag(repo, tag) + + parser.next() + + encoding.encoding = tmp + + print 'done' + +def parse_blob(parser): + global blob_marks + + parser.next() + mark = parser.get_mark() + parser.next() + 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(): + if e not in files: + if e not in repo[p1].manifest(): + continue + f = { 'ctx' : repo[p1][e] } + files[e] = f + +def parse_commit(parser): + global marks, blob_marks, bmarks, parsed_refs + global mode + + from_mark = merge_mark = None + + ref = parser[1] + parser.next() + + commit_mark = parser.get_mark() + parser.next() + author = parser.get_author() + parser.next() + committer = parser.get_author() + parser.next() + data = parser.get_data() + parser.next() + if parser.check('from'): + from_mark = parser.get_mark() + parser.next() + if parser.check('merge'): + merge_mark = parser.get_mark() + parser.next() + if parser.check('merge'): + die('octopus merges are not supported yet') + + files = {} + + for line in parser: + if parser.check('M'): + t, m, mark_ref, path = line.split(' ', 3) + mark = int(mark_ref[1:]) + f = { 'mode' : hgmode(m), 'data' : blob_marks[mark] } + elif parser.check('D'): + t, path = line.split(' ') + f = { 'deleted' : True } + else: + die('Unknown file command: %s' % line) + files[path] = f + + def getfilectx(repo, memctx, f): + of = files[f] + if 'deleted' in of: + raise IOError + if 'ctx' in of: + return of['ctx'] + is_exec = of['mode'] == 'x' + is_link = of['mode'] == 'l' + rename = of.get('rename', None) + return context.memfilectx(f, of['data'], + is_link, is_exec, rename) + + repo = parser.repo + + user, date, tz = author + extra = {} + + if committer != author: + extra['committer'] = "%s %u %u" % committer + + if from_mark: + p1 = repo.changelog.node(mark_to_rev(from_mark)) + else: + p1 = '\0' * 20 + + if merge_mark: + p2 = repo.changelog.node(mark_to_rev(merge_mark)) + else: + p2 = '\0' * 20 + + # + # If files changed from any of the parents, hg wants to know, but in git if + # nothing changed from the first parent, nothing changed. + # + if merge_mark: + get_merge_files(repo, p1, p2, files) + + 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')]: + if k == 'rename': + old, new = v.split(' => ', 1) + files[new]['rename'] = old + elif k == 'branch': + extra[k] = v + elif k == 'extra': + ek, ev = v.split(' : ', 1) + extra[ek] = urllib.unquote(ev) + data = data[:i] + + ctx = context.memctx(repo, (p1, p2), data, + files.keys(), getfilectx, + user, (date, tz), extra) + + tmp = encoding.encoding + encoding.encoding = 'utf-8' + + node = repo.commitctx(ctx) + + encoding.encoding = tmp + + rev = repo[node].rev() + + parsed_refs[ref] = node + + marks.new_mark(rev, commit_mark) + +def parse_reset(parser): + ref = parser[1] + parser.next() + # ugh + if parser.check('commit'): + parse_commit(parser) + return + if not parser.check('from'): + return + from_mark = parser.get_mark() + parser.next() + + node = parser.repo.changelog.node(mark_to_rev(from_mark)) + parsed_refs[ref] = node + +def parse_tag(parser): + name = parser[1] + parser.next() + from_mark = parser.get_mark() + parser.next() + tagger = parser.get_author() + parser.next() + data = parser.get_data() + parser.next() + + # nothing to do + +def do_export(parser): + global parsed_refs, bmarks, peer + + parser.next() + + for line in parser.each_block('done'): + if parser.check('blob'): + parse_blob(parser) + elif parser.check('commit'): + parse_commit(parser) + elif parser.check('reset'): + parse_reset(parser) + elif parser.check('tag'): + parse_tag(parser) + elif parser.check('feature'): + pass + else: + die('unhandled export command: %s' % line) + + for ref, node in parsed_refs.iteritems(): + if ref.startswith('refs/heads/branches'): + pass + 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 + elif ref.startswith('refs/tags/'): + tag = ref[len('refs/tags/'):] + parser.repo.tag([tag], node, None, True, None, {}) + else: + # transport-helper/fast-export bugs + continue + print "ok %s" % ref + + print + + if peer: + parser.repo.push(peer, force=False) + +def main(args): + global prefix, dirname, branches, bmarks + global marks, blob_marks, parsed_refs + global peer, mode, bad_mail, bad_name + global track_branches + + 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 + + if hg_git_compat: + mode = 'hg' + bad_mail = 'none@none' + bad_name = '' + else: + mode = 'git' + bad_mail = 'unknown' + bad_name = 'Unknown' + + if alias[4:] == url: + is_tmp = True + alias = util.sha1(alias).hexdigest() + else: + is_tmp = False + + gitdir = os.environ['GIT_DIR'] + dirname = os.path.join(gitdir, 'hg', alias) + branches = {} + bmarks = {} + blob_marks = {} + parsed_refs = {} + + repo = get_repo(url, alias) + prefix = 'refs/hg/%s' % alias + + if not os.path.exists(dirname): + os.makedirs(dirname) + + marks_path = os.path.join(dirname, 'marks-hg') + marks = Marks(marks_path) + + parser = Parser(repo) + for line in parser: + if parser.check('capabilities'): + do_capabilities(parser) + elif parser.check('list'): + do_list(parser) + elif parser.check('import'): + do_import(parser) + elif parser.check('export'): + do_export(parser) + else: + die('unhandled command: %s' % line) + sys.stdout.flush() + + if not is_tmp: + marks.store() + else: + shutil.rmtree(dirname) + +sys.exit(main(sys.argv)) diff --git a/contrib/remote-helpers/test-hg-bidi.sh b/contrib/remote-helpers/test-hg-bidi.sh new file mode 100755 index 0000000..a94eb28 --- /dev/null +++ b/contrib/remote-helpers/test-hg-bidi.sh @@ -0,0 +1,243 @@ +#!/bin/sh +# +# Copyright (c) 2012 Felipe Contreras +# +# Base commands from hg-git tests: +# https://bitbucket.org/durin42/hg-git/src +# + +test_description='Test biridectionality of remote-hg' + +. ./test-lib.sh + +if ! test_have_prereq PYTHON; then + skip_all='skipping remote-hg tests; python not available' + test_done +fi + +if ! "$PYTHON_PATH" -c 'import mercurial'; then + skip_all='skipping remote-hg tests; mercurial not available' + test_done +fi + +# clone to a git repo +git_clone () { + hg -R $1 bookmark -f -r tip master && + git clone -q "hg::$PWD/$1" $2 +} + +# clone to an hg repo +hg_clone () { + ( + hg init $2 && + cd $1 && + git push -q "hg::$PWD/../$2" 'refs/tags/*:refs/tags/*' 'refs/heads/*:refs/heads/*' + ) && + + (cd $2 && hg -q update) +} + +# push an hg repo +hg_push () { + ( + cd $2 + old=$(git symbolic-ref --short HEAD) + git checkout -q -b tmp && + git fetch -q "hg::$PWD/../$1" 'refs/tags/*:refs/tags/*' 'refs/heads/*:refs/heads/*' && + git checkout -q $old && + git branch -q -D tmp 2> /dev/null || true + ) +} + +hg_log () { + hg -R $1 log --graph --debug | grep -v 'tag: *default/' +} + +setup () { + ( + echo "[ui]" + echo "username = A U Thor <author@example.com>" + echo "[defaults]" + echo "backout = -d \"0 0\"" + echo "commit = -d \"0 0\"" + echo "debugrawcommit = -d \"0 0\"" + echo "tag = -d \"0 0\"" + ) >> "$HOME"/.hgrc && + git config --global remote-hg.hg-git-compat true + + export HGEDITOR=/usr/bin/true + + export GIT_AUTHOR_DATE="2007-01-01 00:00:00 +0230" + export GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE" +} + +setup + +test_expect_success 'encoding' ' + mkdir -p tmp && cd tmp && + test_when_finished "cd .. && rm -rf tmp" && + + ( + git init -q gitrepo && + cd gitrepo && + + echo alpha > alpha && + git add alpha && + git commit -m "add älphà " && + + export GIT_AUTHOR_NAME="tést èncödîng" && + echo beta > beta && + git add beta && + git commit -m "add beta" && + + echo gamma > gamma && + git add gamma && + git commit -m "add gämmâ" && + + : TODO git config i18n.commitencoding latin-1 && + echo delta > delta && + git add delta && + git commit -m "add déltà " + ) && + + hg_clone gitrepo hgrepo && + git_clone hgrepo gitrepo2 && + hg_clone gitrepo2 hgrepo2 && + + HGENCODING=utf-8 hg_log hgrepo > expected && + HGENCODING=utf-8 hg_log hgrepo2 > actual && + + test_cmp expected actual +' + +test_expect_success 'file removal' ' + mkdir -p tmp && cd tmp && + test_when_finished "cd .. && rm -rf tmp" && + + ( + git init -q gitrepo && + cd gitrepo && + echo alpha > alpha && + git add alpha && + git commit -m "add alpha" && + echo beta > beta && + git add beta && + git commit -m "add beta" + mkdir foo && + echo blah > foo/bar && + git add foo && + git commit -m "add foo" && + git rm alpha && + git commit -m "remove alpha" && + git rm foo/bar && + git commit -m "remove foo/bar" + ) && + + hg_clone gitrepo hgrepo && + git_clone hgrepo gitrepo2 && + hg_clone gitrepo2 hgrepo2 && + + hg_log hgrepo > expected && + hg_log hgrepo2 > actual && + + test_cmp expected actual +' + +test_expect_success 'git tags' ' + mkdir -p tmp && cd tmp && + test_when_finished "cd .. && rm -rf tmp" && + + ( + git init -q gitrepo && + cd gitrepo && + git config receive.denyCurrentBranch ignore && + echo alpha > alpha && + git add alpha && + git commit -m "add alpha" && + git tag alpha && + + echo beta > beta && + git add beta && + git commit -m "add beta" && + git tag -a -m "added tag beta" beta + ) && + + hg_clone gitrepo hgrepo && + git_clone hgrepo gitrepo2 && + hg_clone gitrepo2 hgrepo2 && + + hg_log hgrepo > expected && + hg_log hgrepo2 > actual && + + test_cmp expected actual +' + +test_expect_success 'hg branch' ' + mkdir -p tmp && cd tmp && + test_when_finished "cd .. && rm -rf tmp" && + + ( + git init -q gitrepo && + cd gitrepo && + + echo alpha > alpha && + git add alpha && + git commit -q -m "add alpha" && + git checkout -q -b not-master + ) && + + ( + hg_clone gitrepo hgrepo && + + cd hgrepo && + hg -q co master && + hg mv alpha beta && + hg -q commit -m "rename alpha to beta" && + hg branch gamma | grep -v "permanent and global" && + hg -q commit -m "started branch gamma" + ) && + + hg_push hgrepo gitrepo && + hg_clone gitrepo hgrepo2 && + + : TODO, avoid "master" bookmark && + (cd hgrepo2 && hg checkout gamma) && + + hg_log hgrepo > expected && + hg_log hgrepo2 > actual && + + test_cmp expected actual +' + +test_expect_success 'hg tags' ' + mkdir -p tmp && cd tmp && + test_when_finished "cd .. && rm -rf tmp" && + + ( + git init -q gitrepo && + cd gitrepo && + + echo alpha > alpha && + git add alpha && + git commit -m "add alpha" && + git checkout -q -b not-master + ) && + + ( + hg_clone gitrepo hgrepo && + + cd hgrepo && + hg co master && + hg tag alpha + ) && + + hg_push hgrepo gitrepo && + hg_clone gitrepo hgrepo2 && + + hg_log hgrepo > expected && + hg_log hgrepo2 > actual && + + test_cmp expected actual +' + +test_done diff --git a/contrib/remote-helpers/test-hg-hg-git.sh b/contrib/remote-helpers/test-hg-hg-git.sh new file mode 100755 index 0000000..3e76d9f --- /dev/null +++ b/contrib/remote-helpers/test-hg-hg-git.sh @@ -0,0 +1,466 @@ +#!/bin/sh +# +# Copyright (c) 2012 Felipe Contreras +# +# Base commands from hg-git tests: +# https://bitbucket.org/durin42/hg-git/src +# + +test_description='Test remote-hg output compared to hg-git' + +. ./test-lib.sh + +if ! test_have_prereq PYTHON; then + skip_all='skipping remote-hg tests; python not available' + test_done +fi + +if ! "$PYTHON_PATH" -c 'import mercurial'; then + skip_all='skipping remote-hg tests; mercurial not available' + test_done +fi + +if ! "$PYTHON_PATH" -c 'import hggit'; then + skip_all='skipping remote-hg tests; hg-git not available' + test_done +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 +} + +# clone to an hg repo with git +hg_clone_git () { + ( + hg init $2 && + cd $1 && + git push -q "hg::$PWD/../$2" 'refs/tags/*:refs/tags/*' 'refs/heads/*:refs/heads/*' + ) && + + (cd $2 && hg -q update) +} + +# clone to a git repo with hg +git_clone_hg () { + ( + git init -q $2 && + cd $1 && + hg bookmark -f -r tip master && + hg -q push -r master ../$2 || true + ) +} + +# clone to an hg repo with hg +hg_clone_hg () { + hg -q clone $1 $2 +} + +# push an hg repo with git +hg_push_git () { + ( + cd $2 + old=$(git symbolic-ref --short HEAD) + git checkout -q -b tmp && + git fetch -q "hg::$PWD/../$1" 'refs/tags/*:refs/tags/*' 'refs/heads/*:refs/heads/*' && + git checkout -q $old && + git branch -q -D tmp 2> /dev/null || true + ) +} + +# push an hg git repo with hg +hg_push_hg () { + ( + cd $1 && + hg -q push ../$2 || true + ) +} + +hg_log () { + hg -R $1 log --graph --debug | grep -v 'tag: *default/' +} + +git_log () { + git --git-dir=$1/.git fast-export --branches +} + +setup () { + ( + echo "[ui]" + echo "username = A U Thor <author@example.com>" + echo "[defaults]" + echo "backout = -d \"0 0\"" + echo "commit = -d \"0 0\"" + echo "debugrawcommit = -d \"0 0\"" + echo "tag = -d \"0 0\"" + echo "[extensions]" + echo "hgext.bookmarks =" + echo "hggit =" + ) >> "$HOME"/.hgrc && + git config --global receive.denycurrentbranch warn + git config --global remote-hg.hg-git-compat true + + export HGEDITOR=/usr/bin/true + + export GIT_AUTHOR_DATE="2007-01-01 00:00:00 +0230" + export GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE" +} + +setup + +test_expect_success 'merge conflict 1' ' + mkdir -p tmp && cd tmp && + test_when_finished "cd .. && rm -rf tmp" && + + ( + hg init hgrepo1 && + cd hgrepo1 && + echo A > afile && + hg add afile && + hg ci -m "origin" && + + echo B > afile && + hg ci -m "A->B" && + + hg up -r0 && + echo C > afile && + hg ci -m "A->C" && + + hg merge -r1 || true && + echo C > afile && + hg resolve -m afile && + hg ci -m "merge to C" + ) && + + for x in hg git; do + git_clone_$x hgrepo1 gitrepo-$x && + hg_clone_$x gitrepo-$x hgrepo2-$x && + hg_log hgrepo2-$x > hg-log-$x && + git_log gitrepo-$x > git-log-$x + done && + + test_cmp hg-log-hg hg-log-git && + test_cmp git-log-hg git-log-git +' + +test_expect_success 'merge conflict 2' ' + mkdir -p tmp && cd tmp && + test_when_finished "cd .. && rm -rf tmp" && + + ( + hg init hgrepo1 && + cd hgrepo1 && + echo A > afile && + hg add afile && + hg ci -m "origin" && + + echo B > afile && + hg ci -m "A->B" && + + hg up -r0 && + echo C > afile && + hg ci -m "A->C" && + + hg merge -r1 || true && + echo B > afile && + hg resolve -m afile && + hg ci -m "merge to B" + ) && + + for x in hg git; do + git_clone_$x hgrepo1 gitrepo-$x && + hg_clone_$x gitrepo-$x hgrepo2-$x && + hg_log hgrepo2-$x > hg-log-$x && + git_log gitrepo-$x > git-log-$x + done && + + test_cmp hg-log-hg hg-log-git && + test_cmp git-log-hg git-log-git +' + +test_expect_success 'converged merge' ' + mkdir -p tmp && cd tmp && + test_when_finished "cd .. && rm -rf tmp" && + + ( + hg init hgrepo1 && + cd hgrepo1 && + echo A > afile && + hg add afile && + hg ci -m "origin" && + + echo B > afile && + hg ci -m "A->B" && + + echo C > afile && + hg ci -m "B->C" && + + hg up -r0 && + echo C > afile && + hg ci -m "A->C" && + + hg merge -r2 || true && + hg ci -m "merge" + ) && + + for x in hg git; do + git_clone_$x hgrepo1 gitrepo-$x && + hg_clone_$x gitrepo-$x hgrepo2-$x && + hg_log hgrepo2-$x > hg-log-$x && + git_log gitrepo-$x > git-log-$x + done && + + test_cmp hg-log-hg hg-log-git && + test_cmp git-log-hg git-log-git +' + +test_expect_success 'encoding' ' + mkdir -p tmp && cd tmp && + test_when_finished "cd .. && rm -rf tmp" && + + ( + git init -q gitrepo && + cd gitrepo && + + echo alpha > alpha && + git add alpha && + git commit -m "add älphà " && + + export GIT_AUTHOR_NAME="tést èncödîng" && + echo beta > beta && + git add beta && + git commit -m "add beta" && + + echo gamma > gamma && + git add gamma && + git commit -m "add gämmâ" && + + : TODO git config i18n.commitencoding latin-1 && + echo delta > delta && + git add delta && + git commit -m "add déltà " + ) && + + for x in hg git; do + hg_clone_$x gitrepo hgrepo-$x && + git_clone_$x hgrepo-$x gitrepo2-$x && + + HGENCODING=utf-8 hg_log hgrepo-$x > hg-log-$x && + git_log gitrepo2-$x > git-log-$x + done && + + test_cmp hg-log-hg hg-log-git && + test_cmp git-log-hg git-log-git +' + +test_expect_success 'file removal' ' + mkdir -p tmp && cd tmp && + test_when_finished "cd .. && rm -rf tmp" && + + ( + git init -q gitrepo && + cd gitrepo && + echo alpha > alpha && + git add alpha && + git commit -m "add alpha" && + echo beta > beta && + git add beta && + git commit -m "add beta" + mkdir foo && + echo blah > foo/bar && + git add foo && + git commit -m "add foo" && + git rm alpha && + git commit -m "remove alpha" && + git rm foo/bar && + git commit -m "remove foo/bar" + ) && + + for x in hg git; do + ( + hg_clone_$x gitrepo hgrepo-$x && + cd hgrepo-$x && + hg_log . && + hg manifest -r 3 && + hg manifest + ) > output-$x && + + git_clone_$x hgrepo-$x gitrepo2-$x && + git_log gitrepo2-$x > log-$x + done && + + test_cmp output-hg output-git && + test_cmp log-hg log-git +' + +test_expect_success 'git tags' ' + mkdir -p tmp && cd tmp && + test_when_finished "cd .. && rm -rf tmp" && + + ( + git init -q gitrepo && + cd gitrepo && + git config receive.denyCurrentBranch ignore && + echo alpha > alpha && + git add alpha && + git commit -m "add alpha" && + git tag alpha && + + echo beta > beta && + git add beta && + git commit -m "add beta" && + git tag -a -m "added tag beta" beta + ) && + + for x in hg git; do + hg_clone_$x gitrepo hgrepo-$x && + hg_log hgrepo-$x > log-$x + done && + + test_cmp log-hg log-git +' + +test_expect_success 'hg author' ' + mkdir -p tmp && cd tmp && + test_when_finished "cd .. && rm -rf tmp" && + + for x in hg git; do + ( + git init -q gitrepo-$x && + cd gitrepo-$x && + + echo alpha > alpha && + git add alpha && + git commit -m "add alpha" && + git checkout -q -b not-master + ) && + + ( + hg_clone_$x gitrepo-$x hgrepo-$x && + cd hgrepo-$x && + + hg co master && + echo beta > beta && + hg add beta && + hg commit -u "test" -m "add beta" && + + echo gamma >> beta && + hg commit -u "test <test@example.com> (comment)" -m "modify beta" && + + echo gamma > gamma && + hg add gamma && + hg commit -u "<test@example.com>" -m "add gamma" && + + echo delta > delta && + hg add delta && + hg commit -u "name<test@example.com>" -m "add delta" && + + echo epsilon > epsilon && + hg add epsilon && + hg commit -u "name <test@example.com" -m "add epsilon" && + + echo zeta > zeta && + hg add zeta && + hg commit -u " test " -m "add zeta" && + + echo eta > eta && + hg add eta && + hg commit -u "test < test@example.com >" -m "add eta" && + + echo theta > theta && + hg add theta && + hg commit -u "test >test@example.com>" -m "add theta" && + + echo iota > iota && + hg add iota && + hg commit -u "test <test <at> example <dot> com>" -m "add iota" + ) && + + hg_push_$x hgrepo-$x gitrepo-$x && + hg_clone_$x gitrepo-$x hgrepo2-$x && + + hg_log hgrepo2-$x > hg-log-$x && + 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 +' + +test_expect_success 'hg branch' ' + mkdir -p tmp && cd tmp && + test_when_finished "cd .. && rm -rf tmp" && + + for x in hg git; do + ( + git init -q gitrepo-$x && + cd gitrepo-$x && + + echo alpha > alpha && + git add alpha && + git commit -q -m "add alpha" && + git checkout -q -b not-master + ) && + + ( + hg_clone_$x gitrepo-$x hgrepo-$x && + + cd hgrepo-$x && + hg -q co master && + hg mv alpha beta && + hg -q commit -m "rename alpha to beta" && + hg branch gamma | grep -v "permanent and global" && + hg -q commit -m "started branch gamma" + ) && + + hg_push_$x hgrepo-$x gitrepo-$x && + hg_clone_$x gitrepo-$x hgrepo2-$x && + + hg_log hgrepo2-$x > hg-log-$x && + git_log gitrepo-$x > git-log-$x + done && + + test_cmp hg-log-hg hg-log-git && + test_cmp git-log-hg git-log-git +' + +test_expect_success 'hg tags' ' + mkdir -p tmp && cd tmp && + test_when_finished "cd .. && rm -rf tmp" && + + for x in hg git; do + ( + git init -q gitrepo-$x && + cd gitrepo-$x && + + echo alpha > alpha && + git add alpha && + git commit -m "add alpha" && + git checkout -q -b not-master + ) && + + ( + hg_clone_$x gitrepo-$x hgrepo-$x && + + cd hgrepo-$x && + hg co master && + hg tag alpha + ) && + + hg_push_$x hgrepo-$x gitrepo-$x && + hg_clone_$x gitrepo-$x hgrepo2-$x && + + ( + git --git-dir=gitrepo-$x/.git tag -l && + hg_log hgrepo2-$x && + cat hgrepo2-$x/.hgtags + ) > output-$x + done && + + test_cmp output-hg output-git +' + +test_done diff --git a/contrib/remote-helpers/test-hg.sh b/contrib/remote-helpers/test-hg.sh new file mode 100755 index 0000000..5f81dfa --- /dev/null +++ b/contrib/remote-helpers/test-hg.sh @@ -0,0 +1,121 @@ +#!/bin/sh +# +# Copyright (c) 2012 Felipe Contreras +# +# Base commands from hg-git tests: +# https://bitbucket.org/durin42/hg-git/src +# + +test_description='Test remote-hg' + +. ./test-lib.sh + +if ! test_have_prereq PYTHON; then + skip_all='skipping remote-hg tests; python not available' + test_done +fi + +if ! "$PYTHON_PATH" -c 'import mercurial'; then + skip_all='skipping remote-hg tests; mercurial not available' + test_done +fi + +check () { + (cd $1 && + git log --format='%s' -1 && + git symbolic-ref HEAD) > actual && + (echo $2 && + echo "refs/heads/$3") > expected && + test_cmp expected actual +} + +setup () { + ( + echo "[ui]" + echo "username = H G Wells <wells@example.com>" + ) >> "$HOME"/.hgrc +} + +setup + +test_expect_success 'cloning' ' + test_when_finished "rm -rf gitrepo*" && + + ( + hg init hgrepo && + cd hgrepo && + echo zero > content && + hg add content && + hg commit -m zero + ) && + + git clone "hg::$PWD/hgrepo" gitrepo && + check gitrepo zero master +' + +test_expect_success 'cloning with branches' ' + test_when_finished "rm -rf gitrepo*" && + + ( + cd hgrepo && + hg branch next && + echo next > content && + hg commit -m next + ) && + + git clone "hg::$PWD/hgrepo" gitrepo && + check gitrepo next next && + + (cd hgrepo && hg checkout default) && + + git clone "hg::$PWD/hgrepo" gitrepo2 && + check gitrepo2 zero master +' + +test_expect_success 'cloning with bookmarks' ' + test_when_finished "rm -rf gitrepo*" && + + ( + cd hgrepo && + hg bookmark feature-a && + echo feature-a > content && + hg commit -m feature-a + ) && + + git clone "hg::$PWD/hgrepo" gitrepo && + check gitrepo feature-a feature-a +' + +test_expect_success 'cloning with detached head' ' + test_when_finished "rm -rf gitrepo*" && + + ( + cd hgrepo && + hg update -r 0 + ) && + + git clone "hg::$PWD/hgrepo" gitrepo && + check gitrepo zero master +' + +test_expect_success 'update bookmark' ' + test_when_finished "rm -rf gitrepo*" && + + ( + cd hgrepo && + hg bookmark devel + ) && + + ( + git clone "hg::$PWD/hgrepo" gitrepo && + cd gitrepo && + git checkout devel && + echo devel > content && + git commit -a -m devel && + git push + ) && + + hg -R hgrepo bookmarks | grep "devel\s\+3:" +' + +test_done diff --git a/contrib/subtree/.gitignore b/contrib/subtree/.gitignore index 7e77c9d..91360a3 100644 --- a/contrib/subtree/.gitignore +++ b/contrib/subtree/.gitignore @@ -1,4 +1,5 @@ *~ +git-subtree git-subtree.xml git-subtree.1 mainline diff --git a/contrib/subtree/git-subtree.txt b/contrib/subtree/git-subtree.txt index 0c44fda..c5bce41 100644 --- a/contrib/subtree/git-subtree.txt +++ b/contrib/subtree/git-subtree.txt @@ -93,7 +93,7 @@ pull:: repository. push:: - Does a 'split' (see above) using the <prefix> supplied + Does a 'split' (see below) using the <prefix> supplied and then does a 'git push' to push the result to the repository and refspec. This can be used to push your subtree to different branches of the remote repository. diff --git a/contrib/svn-fe/svn-fe.c b/contrib/svn-fe/svn-fe.c index 35db24f..f363505 100644 --- a/contrib/svn-fe/svn-fe.c +++ b/contrib/svn-fe/svn-fe.c @@ -10,7 +10,8 @@ int main(int argc, char **argv) { if (svndump_init(NULL)) return 1; - svndump_read((argc > 1) ? argv[1] : NULL); + svndump_read((argc > 1) ? argv[1] : NULL, "refs/heads/master", + "refs/notes/svn/revs"); svndump_deinit(); svndump_reset(); return 0; diff --git a/contrib/svn-fe/svnrdump_sim.py b/contrib/svn-fe/svnrdump_sim.py new file mode 100755 index 0000000..1cfac4a --- /dev/null +++ b/contrib/svn-fe/svnrdump_sim.py @@ -0,0 +1,53 @@ +#!/usr/bin/python +""" +Simulates svnrdump by replaying an existing dump from a file, taking care +of the specified revision range. +To simulate incremental imports the environment variable SVNRMAX can be set +to the highest revision that should be available. +""" +import sys, os + + +def getrevlimit(): + var = 'SVNRMAX' + if os.environ.has_key(var): + return os.environ[var] + return None + +def writedump(url, lower, upper): + if url.startswith('sim://'): + filename = url[6:] + if filename[-1] == '/': filename = filename[:-1] #remove terminating slash + else: + raise ValueError('sim:// url required') + f = open(filename, 'r'); + state = 'header' + wroterev = False + while(True): + l = f.readline() + if l == '': break + if state == 'header' and l.startswith('Revision-number: '): + state = 'prefix' + if state == 'prefix' and l == 'Revision-number: %s\n' % lower: + state = 'selection' + if not upper == 'HEAD' and state == 'selection' and l == 'Revision-number: %s\n' % upper: + break; + + if state == 'header' or state == 'selection': + if state == 'selection': wroterev = True + sys.stdout.write(l) + return wroterev + +if __name__ == "__main__": + if not (len(sys.argv) in (3, 4, 5)): + print "usage: %s dump URL -rLOWER:UPPER" + sys.exit(1) + if not sys.argv[1] == 'dump': raise NotImplementedError('only "dump" is suppported.') + url = sys.argv[2] + r = ('0', 'HEAD') + if len(sys.argv) == 4 and sys.argv[3][0:2] == '-r': + r = sys.argv[3][2:].lstrip().split(':') + if not getrevlimit() is None: r[1] = getrevlimit() + if writedump(url, r[0], r[1]): ret = 0 + else: ret = 1 + sys.exit(ret) @@ -15,6 +15,7 @@ #include "sigchain.h" #include "submodule.h" #include "ll-merge.h" +#include "string-list.h" #ifdef NO_FAST_WORKING_DIRECTORY #define FAST_WORKING_DIRECTORY 0 @@ -26,6 +27,7 @@ static int diff_detect_rename_default; static int diff_rename_limit_default = 400; static int diff_suppress_blank_empty; static int diff_use_color_default = -1; +static int diff_context_default = 3; static const char *diff_word_regex_cfg; static const char *external_diff_cmd_cfg; int diff_auto_refresh_index = 1; @@ -68,26 +70,30 @@ static int parse_diff_color_slot(const char *var, int ofs) return -1; } -static int parse_dirstat_params(struct diff_options *options, const char *params, +static int parse_dirstat_params(struct diff_options *options, const char *params_string, struct strbuf *errmsg) { - const char *p = params; - int p_len, ret = 0; + char *params_copy = xstrdup(params_string); + struct string_list params = STRING_LIST_INIT_NODUP; + int ret = 0; + int i; - while (*p) { - p_len = strchrnul(p, ',') - p; - if (!memcmp(p, "changes", p_len)) { + if (*params_copy) + string_list_split_in_place(¶ms, params_copy, ',', -1); + for (i = 0; i < params.nr; i++) { + const char *p = params.items[i].string; + if (!strcmp(p, "changes")) { DIFF_OPT_CLR(options, DIRSTAT_BY_LINE); DIFF_OPT_CLR(options, DIRSTAT_BY_FILE); - } else if (!memcmp(p, "lines", p_len)) { + } else if (!strcmp(p, "lines")) { DIFF_OPT_SET(options, DIRSTAT_BY_LINE); DIFF_OPT_CLR(options, DIRSTAT_BY_FILE); - } else if (!memcmp(p, "files", p_len)) { + } else if (!strcmp(p, "files")) { DIFF_OPT_CLR(options, DIRSTAT_BY_LINE); DIFF_OPT_SET(options, DIRSTAT_BY_FILE); - } else if (!memcmp(p, "noncumulative", p_len)) { + } else if (!strcmp(p, "noncumulative")) { DIFF_OPT_CLR(options, DIRSTAT_CUMULATIVE); - } else if (!memcmp(p, "cumulative", p_len)) { + } else if (!strcmp(p, "cumulative")) { DIFF_OPT_SET(options, DIRSTAT_CUMULATIVE); } else if (isdigit(*p)) { char *end; @@ -99,27 +105,35 @@ static int parse_dirstat_params(struct diff_options *options, const char *params while (isdigit(*++end)) ; /* nothing */ } - if (end - p == p_len) + if (!*end) options->dirstat_permille = permille; else { - strbuf_addf(errmsg, _(" Failed to parse dirstat cut-off percentage '%.*s'\n"), - p_len, p); + strbuf_addf(errmsg, _(" Failed to parse dirstat cut-off percentage '%s'\n"), + p); ret++; } } else { - strbuf_addf(errmsg, _(" Unknown dirstat parameter '%.*s'\n"), - p_len, p); + strbuf_addf(errmsg, _(" Unknown dirstat parameter '%s'\n"), p); ret++; } - p += p_len; - - if (*p) - p++; /* more parameters, swallow separator */ } + string_list_clear(¶ms, 0); + free(params_copy); return ret; } +static int parse_submodule_params(struct diff_options *options, const char *value) +{ + if (!strcmp(value, "log")) + DIFF_OPT_SET(options, SUBMODULE_LOG); + else if (!strcmp(value, "short")) + DIFF_OPT_CLR(options, SUBMODULE_LOG); + else + return -1; + return 0; +} + static int git_config_rename(const char *var, const char *value) { if (!value) @@ -141,6 +155,12 @@ int git_diff_ui_config(const char *var, const char *value, void *cb) diff_use_color_default = git_config_colorbool(var, value); return 0; } + if (!strcmp(var, "diff.context")) { + diff_context_default = git_config_int(var, value); + if (diff_context_default < 0) + return -1; + return 0; + } if (!strcmp(var, "diff.renames")) { diff_detect_rename_default = git_config_rename(var, value); return 0; @@ -169,6 +189,13 @@ int git_diff_ui_config(const char *var, const char *value, void *cb) if (!strcmp(var, "diff.ignoresubmodules")) handle_ignore_submodules_arg(&default_diff_options, value); + if (!strcmp(var, "diff.submodule")) { + if (parse_submodule_params(&default_diff_options, value)) + warning(_("Unknown value for 'diff.submodule' config variable: '%s'"), + value); + return 0; + } + if (git_color_config(var, value, cb) < 0) return -1; @@ -2218,7 +2245,7 @@ static void builtin_diff(const char *name_a, mmfile_t mf1, mf2; const char *lbl[2]; char *a_one, *b_two; - const char *set = diff_get_color_opt(o, DIFF_METAINFO); + const char *meta = diff_get_color_opt(o, DIFF_METAINFO); const char *reset = diff_get_color_opt(o, DIFF_RESET); const char *a_prefix, *b_prefix; struct userdiff_driver *textconv_one = NULL; @@ -2239,7 +2266,7 @@ static void builtin_diff(const char *name_a, const char *add = diff_get_color_opt(o, DIFF_FILE_NEW); show_submodule_summary(o->file, one ? one->path : two->path, one->sha1, two->sha1, two->dirty_submodule, - del, add, reset); + meta, del, add, reset); return; } @@ -2265,24 +2292,24 @@ static void builtin_diff(const char *name_a, b_two = quote_two(b_prefix, name_b + (*name_b == '/')); lbl[0] = DIFF_FILE_VALID(one) ? a_one : "/dev/null"; lbl[1] = DIFF_FILE_VALID(two) ? b_two : "/dev/null"; - strbuf_addf(&header, "%s%sdiff --git %s %s%s\n", line_prefix, set, a_one, b_two, reset); + strbuf_addf(&header, "%s%sdiff --git %s %s%s\n", line_prefix, meta, a_one, b_two, reset); if (lbl[0][0] == '/') { /* /dev/null */ - strbuf_addf(&header, "%s%snew file mode %06o%s\n", line_prefix, set, two->mode, reset); + strbuf_addf(&header, "%s%snew file mode %06o%s\n", line_prefix, meta, two->mode, reset); if (xfrm_msg) strbuf_addstr(&header, xfrm_msg); must_show_header = 1; } else if (lbl[1][0] == '/') { - strbuf_addf(&header, "%s%sdeleted file mode %06o%s\n", line_prefix, set, one->mode, reset); + strbuf_addf(&header, "%s%sdeleted file mode %06o%s\n", line_prefix, meta, one->mode, reset); if (xfrm_msg) strbuf_addstr(&header, xfrm_msg); must_show_header = 1; } else { if (one->mode != two->mode) { - strbuf_addf(&header, "%s%sold mode %06o%s\n", line_prefix, set, one->mode, reset); - strbuf_addf(&header, "%s%snew mode %06o%s\n", line_prefix, set, two->mode, reset); + strbuf_addf(&header, "%s%sold mode %06o%s\n", line_prefix, meta, one->mode, reset); + strbuf_addf(&header, "%s%snew mode %06o%s\n", line_prefix, meta, two->mode, reset); must_show_header = 1; } if (xfrm_msg) @@ -3179,7 +3206,7 @@ void diff_setup(struct diff_options *options) options->break_opt = -1; options->rename_limit = -1; options->dirstat_permille = diff_dirstat_permille_default; - options->context = 3; + options->context = diff_context_default; DIFF_OPT_SET(options, RENAME_EMPTY); options->change = diff_change; @@ -3475,6 +3502,14 @@ static int parse_dirstat_opt(struct diff_options *options, const char *params) return 1; } +static int parse_submodule_opt(struct diff_options *options, const char *value) +{ + if (parse_submodule_params(options, value)) + die(_("Failed to parse --submodule option parameter: '%s'"), + value); + return 1; +} + int diff_opt_parse(struct diff_options *options, const char **av, int ac) { const char *arg = av[0]; @@ -3655,10 +3690,8 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac) handle_ignore_submodules_arg(options, arg + 20); } else if (!strcmp(arg, "--submodule")) DIFF_OPT_SET(options, SUBMODULE_LOG); - else if (!prefixcmp(arg, "--submodule=")) { - if (!strcmp(arg + 12, "log")) - DIFF_OPT_SET(options, SUBMODULE_LOG); - } + else if (!prefixcmp(arg, "--submodule=")) + return parse_submodule_opt(options, arg + 12); /* misc options */ else if (!strcmp(arg, "-z")) @@ -4880,3 +4913,19 @@ size_t fill_textconv(struct userdiff_driver *driver, return size; } + +void setup_diff_pager(struct diff_options *opt) +{ + /* + * If the user asked for our exit code, then either they want --quiet + * or --exit-code. We should definitely not bother with a pager in the + * former case, as we will generate no output. Since we still properly + * report our exit code even when a pager is run, we _could_ run a + * pager with --exit-code. But since we have not done so historically, + * and because it is easy to find people oneline advising "git diff + * --exit-code" in hooks and other scripts, we do not do so. + */ + if (!DIFF_OPT_TST(opt, EXIT_WITH_STATUS) && + check_pager_config("diff") != 0) + setup_pager(); +} @@ -335,5 +335,6 @@ extern int parse_rename_score(const char **cp_p); extern int print_stat_summary(FILE *fp, int files, int insertions, int deletions); +extern void setup_diff_pager(struct diff_options *); #endif /* DIFF_H */ @@ -34,10 +34,33 @@ int fnmatch_icase(const char *pattern, const char *string, int flags) return fnmatch(pattern, string, flags | (ignore_case ? FNM_CASEFOLD : 0)); } +inline int git_fnmatch(const char *pattern, const char *string, + int flags, int prefix) +{ + int fnm_flags = 0; + if (flags & GFNM_PATHNAME) + fnm_flags |= FNM_PATHNAME; + if (prefix > 0) { + if (strncmp(pattern, string, prefix)) + return FNM_NOMATCH; + pattern += prefix; + string += prefix; + } + if (flags & GFNM_ONESTAR) { + int pattern_len = strlen(++pattern); + int string_len = strlen(string); + return string_len < pattern_len || + strcmp(pattern, + string + string_len - pattern_len); + } + return fnmatch(pattern, string, fnm_flags); +} + static size_t common_prefix_len(const char **pathspec) { const char *n, *first; size_t max = 0; + int literal = limit_pathspec_to_literal(); if (!pathspec) return max; @@ -47,7 +70,7 @@ static size_t common_prefix_len(const char **pathspec) size_t i, len = 0; for (i = 0; first == n || i < max; i++) { char c = n[i]; - if (!c || c != first[i] || is_glob_special(c)) + if (!c || c != first[i] || (!literal && is_glob_special(c))) break; if (c == '/') len = i + 1; @@ -117,6 +140,7 @@ int within_depth(const char *name, int namelen, static int match_one(const char *match, const char *name, int namelen) { int matchlen; + int literal = limit_pathspec_to_literal(); /* If the match was just the prefix, we matched */ if (!*match) @@ -126,7 +150,7 @@ static int match_one(const char *match, const char *name, int namelen) for (;;) { unsigned char c1 = tolower(*match); unsigned char c2 = tolower(*name); - if (c1 == '\0' || is_glob_special(c1)) + if (c1 == '\0' || (!literal && is_glob_special(c1))) break; if (c1 != c2) return 0; @@ -138,7 +162,7 @@ static int match_one(const char *match, const char *name, int namelen) for (;;) { unsigned char c1 = *match; unsigned char c2 = *name; - if (c1 == '\0' || is_glob_special(c1)) + if (c1 == '\0' || (!literal && is_glob_special(c1))) break; if (c1 != c2) return 0; @@ -148,14 +172,16 @@ static int match_one(const char *match, const char *name, int namelen) } } - /* * If we don't match the matchstring exactly, * we need to match by fnmatch */ matchlen = strlen(match); - if (strncmp_icase(match, name, matchlen)) + if (strncmp_icase(match, name, matchlen)) { + if (literal) + return 0; return !fnmatch_icase(match, name, 0) ? MATCHED_FNMATCH : 0; + } if (namelen == matchlen) return MATCHED_EXACTLY; @@ -230,7 +256,10 @@ static int match_pathspec_item(const struct pathspec_item *item, int prefix, return MATCHED_RECURSIVELY; } - if (item->use_wildcard && !fnmatch(match, name, 0)) + if (item->nowildcard_len < item->len && + !git_fnmatch(match, name, + item->flags & PATHSPEC_ONESTAR ? GFNM_ONESTAR : 0, + item->nowildcard_len - prefix)) return MATCHED_FNMATCH; return 0; @@ -308,42 +337,69 @@ static int no_wildcard(const char *string) return string[simple_length(string)] == '\0'; } +void parse_exclude_pattern(const char **pattern, + int *patternlen, + int *flags, + int *nowildcardlen) +{ + const char *p = *pattern; + size_t i, len; + + *flags = 0; + if (*p == '!') { + *flags |= EXC_FLAG_NEGATIVE; + p++; + } + len = strlen(p); + if (len && p[len - 1] == '/') { + len--; + *flags |= EXC_FLAG_MUSTBEDIR; + } + for (i = 0; i < len; i++) { + if (p[i] == '/') + break; + } + if (i == len) + *flags |= EXC_FLAG_NODIR; + *nowildcardlen = simple_length(p); + /* + * we should have excluded the trailing slash from 'p' too, + * but that's one more allocation. Instead just make sure + * nowildcardlen does not exceed real patternlen + */ + if (*nowildcardlen > len) + *nowildcardlen = len; + if (*p == '*' && no_wildcard(p + 1)) + *flags |= EXC_FLAG_ENDSWITH; + *pattern = p; + *patternlen = len; +} + void add_exclude(const char *string, const char *base, int baselen, struct exclude_list *which) { struct exclude *x; - size_t len; - int to_exclude = 1; - int flags = 0; + int patternlen; + int flags; + int nowildcardlen; - if (*string == '!') { - to_exclude = 0; - string++; - } - len = strlen(string); - if (len && string[len - 1] == '/') { + parse_exclude_pattern(&string, &patternlen, &flags, &nowildcardlen); + if (flags & EXC_FLAG_MUSTBEDIR) { char *s; - x = xmalloc(sizeof(*x) + len); + x = xmalloc(sizeof(*x) + patternlen + 1); s = (char *)(x+1); - memcpy(s, string, len - 1); - s[len - 1] = '\0'; - string = s; + memcpy(s, string, patternlen); + s[patternlen] = '\0'; x->pattern = s; - flags = EXC_FLAG_MUSTBEDIR; } else { x = xmalloc(sizeof(*x)); x->pattern = string; } - x->to_exclude = to_exclude; - x->patternlen = strlen(string); + x->patternlen = patternlen; + x->nowildcardlen = nowildcardlen; x->base = base; x->baselen = baselen; x->flags = flags; - if (!strchr(string, '/')) - x->flags |= EXC_FLAG_NODIR; - x->nowildcardlen = simple_length(string); - if (*string == '*' && no_wildcard(string+1)) - x->flags |= EXC_FLAG_ENDSWITH; ALLOC_GROW(which->excludes, which->nr + 1, which->alloc); which->excludes[which->nr++] = x; } @@ -505,6 +561,72 @@ static void prep_exclude(struct dir_struct *dir, const char *base, int baselen) dir->basebuf[baselen] = '\0'; } +int match_basename(const char *basename, int basenamelen, + const char *pattern, int prefix, int patternlen, + int flags) +{ + if (prefix == patternlen) { + if (!strcmp_icase(pattern, basename)) + return 1; + } else if (flags & EXC_FLAG_ENDSWITH) { + if (patternlen - 1 <= basenamelen && + !strcmp_icase(pattern + 1, + basename + basenamelen - patternlen + 1)) + return 1; + } else { + if (fnmatch_icase(pattern, basename, 0) == 0) + return 1; + } + return 0; +} + +int match_pathname(const char *pathname, int pathlen, + const char *base, int baselen, + const char *pattern, int prefix, int patternlen, + int flags) +{ + const char *name; + int namelen; + + /* + * match with FNM_PATHNAME; the pattern has base implicitly + * in front of it. + */ + if (*pattern == '/') { + pattern++; + prefix--; + } + + /* + * baselen does not count the trailing slash. base[] may or + * may not end with a trailing slash though. + */ + if (pathlen < baselen + 1 || + (baselen && pathname[baselen] != '/') || + strncmp_icase(pathname, base, baselen)) + return 0; + + namelen = baselen ? pathlen - baselen - 1 : pathlen; + name = pathname + pathlen - namelen; + + if (prefix) { + /* + * if the non-wildcard part is longer than the + * remaining pathname, surely it cannot match. + */ + if (prefix > namelen) + return 0; + + if (strncmp_icase(pattern, name, prefix)) + return 0; + pattern += prefix; + name += prefix; + namelen -= prefix; + } + + return fnmatch_icase(pattern, name, FNM_PATHNAME) == 0; +} + /* Scan the list and let the last match determine the fate. * Return 1 for exclude, 0 for include and -1 for undecided. */ @@ -519,9 +641,9 @@ int excluded_from_list(const char *pathname, for (i = el->nr - 1; 0 <= i; i--) { struct exclude *x = el->excludes[i]; - const char *name, *exclude = x->pattern; - int to_exclude = x->to_exclude; - int namelen, prefix = x->nowildcardlen; + const char *exclude = x->pattern; + int to_exclude = x->flags & EXC_FLAG_NEGATIVE ? 0 : 1; + int prefix = x->nowildcardlen; if (x->flags & EXC_FLAG_MUSTBEDIR) { if (*dtype == DT_UNKNOWN) @@ -531,51 +653,18 @@ int excluded_from_list(const char *pathname, } if (x->flags & EXC_FLAG_NODIR) { - /* match basename */ - if (prefix == x->patternlen) { - if (!strcmp_icase(exclude, basename)) - return to_exclude; - } else if (x->flags & EXC_FLAG_ENDSWITH) { - if (x->patternlen - 1 <= pathlen && - !strcmp_icase(exclude + 1, pathname + pathlen - x->patternlen + 1)) - return to_exclude; - } else { - if (fnmatch_icase(exclude, basename, 0) == 0) - return to_exclude; - } + if (match_basename(basename, + pathlen - (basename - pathname), + exclude, prefix, x->patternlen, + x->flags)) + return to_exclude; continue; } - /* match with FNM_PATHNAME: - * exclude has base (baselen long) implicitly in front of it. - */ - if (*exclude == '/') { - exclude++; - prefix--; - } - - if (pathlen < x->baselen || - (x->baselen && pathname[x->baselen-1] != '/') || - strncmp_icase(pathname, x->base, x->baselen)) - continue; - - namelen = x->baselen ? pathlen - x->baselen : pathlen; - name = pathname + pathlen - namelen; - - /* if the non-wildcard part is longer than the - remaining pathname, surely it cannot match */ - if (prefix > namelen) - continue; - - if (prefix) { - if (strncmp_icase(exclude, name, prefix)) - continue; - exclude += prefix; - name += prefix; - namelen -= prefix; - } - - if (!namelen || !fnmatch_icase(exclude, name, FNM_PATHNAME)) + assert(x->baselen == 0 || x->base[x->baselen - 1] == '/'); + if (match_pathname(pathname, pathlen, + x->base, x->baselen ? x->baselen - 1 : 0, + exclude, prefix, x->patternlen, x->flags)) return to_exclude; } return -1; /* undecided */ @@ -1369,9 +1458,18 @@ int init_pathspec(struct pathspec *pathspec, const char **paths) item->match = path; item->len = strlen(path); - item->use_wildcard = !no_wildcard(path); - if (item->use_wildcard) - pathspec->has_wildcard = 1; + item->flags = 0; + if (limit_pathspec_to_literal()) { + item->nowildcard_len = item->len; + } else { + item->nowildcard_len = simple_length(path); + if (item->nowildcard_len < item->len) { + pathspec->has_wildcard = 1; + if (path[item->nowildcard_len] == '*' && + no_wildcard(path + item->nowildcard_len + 1)) + item->flags |= PATHSPEC_ONESTAR; + } + } } qsort(pathspec->items, pathspec->nr, @@ -1385,3 +1483,11 @@ void free_pathspec(struct pathspec *pathspec) free(pathspec->items); pathspec->items = NULL; } + +int limit_pathspec_to_literal(void) +{ + static int flag = -1; + if (flag < 0) + flag = git_env_bool(GIT_LITERAL_PATHSPECS_ENVIRONMENT, 0); + return flag; +} @@ -11,6 +11,7 @@ struct dir_entry { #define EXC_FLAG_NODIR 1 #define EXC_FLAG_ENDSWITH 4 #define EXC_FLAG_MUSTBEDIR 8 +#define EXC_FLAG_NEGATIVE 16 struct exclude_list { int nr; @@ -21,7 +22,6 @@ struct exclude_list { int nowildcardlen; const char *base; int baselen; - int to_exclude; int flags; } **excludes; }; @@ -81,6 +81,16 @@ extern int excluded_from_list(const char *pathname, int pathlen, const char *bas struct dir_entry *dir_add_ignored(struct dir_struct *dir, const char *pathname, int len); /* + * these implement the matching logic for dir.c:excluded_from_list and + * attr.c:path_matches() + */ +extern int match_basename(const char *, int, + const char *, int, int, int); +extern int match_pathname(const char *, int, + const char *, int, + const char *, int, int, int); + +/* * The excluded() API is meant for callers that check each level of leading * directory hierarchies with excluded() to avoid recursing into excluded * directories. Callers that do not do so should use this API instead. @@ -97,6 +107,7 @@ extern int path_excluded(struct path_exclude_check *, const char *, int namelen, extern int add_excludes_from_file_to_list(const char *fname, const char *base, int baselen, char **buf_p, struct exclude_list *which, int check_index); extern void add_excludes_from_file(struct dir_struct *, const char *fname); +extern void parse_exclude_pattern(const char **string, int *patternlen, int *flags, int *nowildcardlen); extern void add_exclude(const char *string, const char *base, int baselen, struct exclude_list *which); extern void free_excludes(struct exclude_list *el); @@ -128,4 +139,13 @@ extern int strcmp_icase(const char *a, const char *b); extern int strncmp_icase(const char *a, const char *b, size_t count); extern int fnmatch_icase(const char *pattern, const char *string, int flags); +/* + * The prefix part of pattern must not contains wildcards. + */ +#define GFNM_PATHNAME 1 /* similar to FNM_PATHNAME */ +#define GFNM_ONESTAR 2 /* there is only _one_ wildcard, a star */ + +extern int git_fnmatch(const char *pattern, const char *string, + int flags, int prefix); + #endif @@ -1,6 +1,7 @@ #include "cache.h" #include "strbuf.h" #include "run-command.h" +#include "sigchain.h" #ifndef DEFAULT_EDITOR #define DEFAULT_EDITOR "vi" @@ -37,8 +38,25 @@ int launch_editor(const char *path, struct strbuf *buffer, const char *const *en if (strcmp(editor, ":")) { const char *args[] = { editor, path, NULL }; + struct child_process p; + int ret, sig; - if (run_command_v_opt_cd_env(args, RUN_USING_SHELL, NULL, env)) + memset(&p, 0, sizeof(p)); + p.argv = args; + p.env = env; + p.use_shell = 1; + if (start_command(&p) < 0) + return error("unable to start editor '%s'", editor); + + sigchain_push(SIGINT, SIG_IGN); + sigchain_push(SIGQUIT, SIG_IGN); + ret = finish_command(&p); + sig = ret + 128; + sigchain_pop(SIGINT); + sigchain_pop(SIGQUIT); + if (sig == SIGINT || sig == SIGQUIT) + raise(sig); + if (ret) return error("There was a problem with the editor '%s'.", editor); } diff --git a/fetch-pack.c b/fetch-pack.c new file mode 100644 index 0000000..f0acdf7 --- /dev/null +++ b/fetch-pack.c @@ -0,0 +1,950 @@ +#include "cache.h" +#include "refs.h" +#include "pkt-line.h" +#include "commit.h" +#include "tag.h" +#include "exec_cmd.h" +#include "pack.h" +#include "sideband.h" +#include "fetch-pack.h" +#include "remote.h" +#include "run-command.h" +#include "transport.h" +#include "version.h" + +static int transfer_unpack_limit = -1; +static int fetch_unpack_limit = -1; +static int unpack_limit = 100; +static int prefer_ofs_delta = 1; +static int no_done; +static int fetch_fsck_objects = -1; +static int transfer_fsck_objects = -1; +static int agent_supported; + +#define COMPLETE (1U << 0) +#define COMMON (1U << 1) +#define COMMON_REF (1U << 2) +#define SEEN (1U << 3) +#define POPPED (1U << 4) + +static int marked; + +/* + * After sending this many "have"s if we do not get any new ACK , we + * give up traversing our history. + */ +#define MAX_IN_VAIN 256 + +static struct commit_list *rev_list; +static int non_common_revs, multi_ack, use_sideband; + +static void rev_list_push(struct commit *commit, int mark) +{ + if (!(commit->object.flags & mark)) { + commit->object.flags |= mark; + + if (!(commit->object.parsed)) + if (parse_commit(commit)) + return; + + commit_list_insert_by_date(commit, &rev_list); + + if (!(commit->object.flags & COMMON)) + non_common_revs++; + } +} + +static int rev_list_insert_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data) +{ + struct object *o = deref_tag(parse_object(sha1), refname, 0); + + if (o && o->type == OBJ_COMMIT) + rev_list_push((struct commit *)o, SEEN); + + return 0; +} + +static int clear_marks(const char *refname, const unsigned char *sha1, int flag, void *cb_data) +{ + struct object *o = deref_tag(parse_object(sha1), refname, 0); + + if (o && o->type == OBJ_COMMIT) + clear_commit_marks((struct commit *)o, + COMMON | COMMON_REF | SEEN | POPPED); + return 0; +} + +/* + This function marks a rev and its ancestors as common. + In some cases, it is desirable to mark only the ancestors (for example + when only the server does not yet know that they are common). +*/ + +static void mark_common(struct commit *commit, + int ancestors_only, int dont_parse) +{ + if (commit != NULL && !(commit->object.flags & COMMON)) { + struct object *o = (struct object *)commit; + + if (!ancestors_only) + o->flags |= COMMON; + + if (!(o->flags & SEEN)) + rev_list_push(commit, SEEN); + else { + struct commit_list *parents; + + if (!ancestors_only && !(o->flags & POPPED)) + non_common_revs--; + if (!o->parsed && !dont_parse) + if (parse_commit(commit)) + return; + + for (parents = commit->parents; + parents; + parents = parents->next) + mark_common(parents->item, 0, dont_parse); + } + } +} + +/* + Get the next rev to send, ignoring the common. +*/ + +static const unsigned char *get_rev(void) +{ + struct commit *commit = NULL; + + while (commit == NULL) { + unsigned int mark; + struct commit_list *parents; + + if (rev_list == NULL || non_common_revs == 0) + return NULL; + + commit = rev_list->item; + if (!commit->object.parsed) + parse_commit(commit); + parents = commit->parents; + + commit->object.flags |= POPPED; + if (!(commit->object.flags & COMMON)) + non_common_revs--; + + if (commit->object.flags & COMMON) { + /* do not send "have", and ignore ancestors */ + commit = NULL; + mark = COMMON | SEEN; + } else if (commit->object.flags & COMMON_REF) + /* send "have", and ignore ancestors */ + mark = COMMON | SEEN; + else + /* send "have", also for its ancestors */ + mark = SEEN; + + while (parents) { + if (!(parents->item->object.flags & SEEN)) + rev_list_push(parents->item, mark); + if (mark & COMMON) + mark_common(parents->item, 1, 0); + parents = parents->next; + } + + rev_list = rev_list->next; + } + + return commit->object.sha1; +} + +enum ack_type { + NAK = 0, + ACK, + ACK_continue, + ACK_common, + ACK_ready +}; + +static void consume_shallow_list(struct fetch_pack_args *args, int fd) +{ + if (args->stateless_rpc && args->depth > 0) { + /* If we sent a depth we will get back "duplicate" + * 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))) { + if (!prefixcmp(line, "shallow ")) + continue; + if (!prefixcmp(line, "unshallow ")) + continue; + die("git fetch-pack: expected shallow list"); + } + } +} + +struct write_shallow_data { + struct strbuf *out; + int use_pack_protocol; + int count; +}; + +static int write_one_shallow(const struct commit_graft *graft, void *cb_data) +{ + struct write_shallow_data *data = cb_data; + const char *hex = sha1_to_hex(graft->sha1); + data->count++; + if (data->use_pack_protocol) + packet_buf_write(data->out, "shallow %s", hex); + else { + strbuf_addstr(data->out, hex); + strbuf_addch(data->out, '\n'); + } + return 0; +} + +static int write_shallow_commits(struct strbuf *out, int use_pack_protocol) +{ + struct write_shallow_data data; + data.out = out; + data.use_pack_protocol = use_pack_protocol; + data.count = 0; + for_each_commit_graft(write_one_shallow, &data); + return data.count; +} + +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)); + + 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 (strstr(line+45, "continue")) + return ACK_continue; + if (strstr(line+45, "common")) + return ACK_common; + if (strstr(line+45, "ready")) + return ACK_ready; + return ACK; + } + } + die("git fetch_pack: expected ACK/NAK, got '%s'", line); +} + +static void send_request(struct fetch_pack_args *args, + int fd, struct strbuf *buf) +{ + if (args->stateless_rpc) { + send_sideband(fd, -1, buf->buf, buf->len, LARGE_PACKET_MAX); + packet_flush(fd); + } else + safe_write(fd, buf->buf, buf->len); +} + +static void insert_one_alternate_ref(const struct ref *ref, void *unused) +{ + rev_list_insert_ref(NULL, ref->old_sha1, 0, NULL); +} + +#define INITIAL_FLUSH 16 +#define PIPESAFE_FLUSH 32 +#define LARGE_FLUSH 1024 + +static int next_flush(struct fetch_pack_args *args, int count) +{ + int flush_limit = args->stateless_rpc ? LARGE_FLUSH : PIPESAFE_FLUSH; + + if (count < flush_limit) + count <<= 1; + else + count += flush_limit; + return count; +} + +static int find_common(struct fetch_pack_args *args, + int fd[2], unsigned char *result_sha1, + struct ref *refs) +{ + int fetching; + int count = 0, flushes = 0, flush_at = INITIAL_FLUSH, retval; + const unsigned char *sha1; + unsigned in_vain = 0; + int got_continue = 0; + int got_ready = 0; + struct strbuf req_buf = STRBUF_INIT; + size_t state_len = 0; + + if (args->stateless_rpc && multi_ack == 1) + die("--stateless-rpc requires multi_ack_detailed"); + if (marked) + for_each_ref(clear_marks, NULL); + marked = 1; + + for_each_ref(rev_list_insert_ref, NULL); + for_each_alternate_ref(insert_one_alternate_ref, NULL); + + fetching = 0; + for ( ; refs ; refs = refs->next) { + unsigned char *remote = refs->old_sha1; + const char *remote_hex; + struct object *o; + + /* + * If that object is complete (i.e. it is an ancestor of a + * local ref), we tell them we have it but do not have to + * tell them about its ancestors, which they already know + * about. + * + * We use lookup_object here because we are only + * interested in the case we *know* the object is + * reachable and we have already scanned it. + */ + if (((o = lookup_object(remote)) != NULL) && + (o->flags & COMPLETE)) { + continue; + } + + remote_hex = sha1_to_hex(remote); + if (!fetching) { + struct strbuf c = STRBUF_INIT; + if (multi_ack == 2) strbuf_addstr(&c, " multi_ack_detailed"); + if (multi_ack == 1) strbuf_addstr(&c, " multi_ack"); + if (no_done) strbuf_addstr(&c, " no-done"); + if (use_sideband == 2) strbuf_addstr(&c, " side-band-64k"); + if (use_sideband == 1) strbuf_addstr(&c, " side-band"); + if (args->use_thin_pack) strbuf_addstr(&c, " thin-pack"); + if (args->no_progress) strbuf_addstr(&c, " no-progress"); + if (args->include_tag) strbuf_addstr(&c, " include-tag"); + if (prefer_ofs_delta) strbuf_addstr(&c, " ofs-delta"); + if (agent_supported) strbuf_addf(&c, " agent=%s", + git_user_agent_sanitized()); + packet_buf_write(&req_buf, "want %s%s\n", remote_hex, c.buf); + strbuf_release(&c); + } else + packet_buf_write(&req_buf, "want %s\n", remote_hex); + fetching++; + } + + if (!fetching) { + strbuf_release(&req_buf); + packet_flush(fd[1]); + return 1; + } + + if (is_repository_shallow()) + write_shallow_commits(&req_buf, 1); + if (args->depth > 0) + packet_buf_write(&req_buf, "deepen %d", args->depth); + packet_buf_flush(&req_buf); + state_len = req_buf.len; + + if (args->depth > 0) { + char line[1024]; + unsigned char sha1[20]; + + send_request(args, fd[1], &req_buf); + while (packet_read_line(fd[0], line, sizeof(line))) { + if (!prefixcmp(line, "shallow ")) { + if (get_sha1_hex(line + 8, sha1)) + die("invalid shallow line: %s", line); + register_shallow(sha1); + continue; + } + if (!prefixcmp(line, "unshallow ")) { + if (get_sha1_hex(line + 10, sha1)) + die("invalid unshallow line: %s", line); + if (!lookup_object(sha1)) + die("object not found: %s", line); + /* make sure that it is parsed as shallow */ + if (!parse_object(sha1)) + die("error in object: %s", line); + if (unregister_shallow(sha1)) + die("no shallow found: %s", line); + continue; + } + die("expected shallow/unshallow, got %s", line); + } + } else if (!args->stateless_rpc) + send_request(args, fd[1], &req_buf); + + if (!args->stateless_rpc) { + /* If we aren't using the stateless-rpc interface + * we don't need to retain the headers. + */ + strbuf_setlen(&req_buf, 0); + state_len = 0; + } + + flushes = 0; + retval = -1; + while ((sha1 = get_rev())) { + packet_buf_write(&req_buf, "have %s\n", sha1_to_hex(sha1)); + if (args->verbose) + fprintf(stderr, "have %s\n", sha1_to_hex(sha1)); + in_vain++; + if (flush_at <= ++count) { + int ack; + + packet_buf_flush(&req_buf); + send_request(args, fd[1], &req_buf); + strbuf_setlen(&req_buf, state_len); + flushes++; + flush_at = next_flush(args, count); + + /* + * We keep one window "ahead" of the other side, and + * will wait for an ACK only on the next one + */ + if (!args->stateless_rpc && count == INITIAL_FLUSH) + continue; + + consume_shallow_list(args, fd[0]); + do { + ack = get_ack(fd[0], result_sha1); + if (args->verbose && ack) + fprintf(stderr, "got ack %d %s\n", ack, + sha1_to_hex(result_sha1)); + switch (ack) { + case ACK: + flushes = 0; + multi_ack = 0; + retval = 0; + goto done; + case ACK_common: + case ACK_ready: + case ACK_continue: { + struct commit *commit = + lookup_commit(result_sha1); + if (!commit) + die("invalid commit %s", sha1_to_hex(result_sha1)); + if (args->stateless_rpc + && ack == ACK_common + && !(commit->object.flags & COMMON)) { + /* We need to replay the have for this object + * on the next RPC request so the peer knows + * it is in common with us. + */ + const char *hex = sha1_to_hex(result_sha1); + packet_buf_write(&req_buf, "have %s\n", hex); + state_len = req_buf.len; + } + mark_common(commit, 0, 1); + retval = 0; + in_vain = 0; + got_continue = 1; + if (ack == ACK_ready) { + rev_list = NULL; + got_ready = 1; + } + break; + } + } + } while (ack); + flushes--; + if (got_continue && MAX_IN_VAIN < in_vain) { + if (args->verbose) + fprintf(stderr, "giving up\n"); + break; /* give up */ + } + } + } +done: + if (!got_ready || !no_done) { + packet_buf_write(&req_buf, "done\n"); + send_request(args, fd[1], &req_buf); + } + if (args->verbose) + fprintf(stderr, "done\n"); + if (retval != 0) { + multi_ack = 0; + flushes++; + } + strbuf_release(&req_buf); + + consume_shallow_list(args, fd[0]); + while (flushes || multi_ack) { + int ack = get_ack(fd[0], result_sha1); + if (ack) { + if (args->verbose) + fprintf(stderr, "got ack (%d) %s\n", ack, + sha1_to_hex(result_sha1)); + if (ack == ACK) + return 0; + multi_ack = 1; + continue; + } + flushes--; + } + /* it is no error to fetch into a completely empty repo */ + return count ? retval : 0; +} + +static struct commit_list *complete; + +static int mark_complete(const char *refname, const unsigned char *sha1, int flag, void *cb_data) +{ + struct object *o = parse_object(sha1); + + while (o && o->type == OBJ_TAG) { + struct tag *t = (struct tag *) o; + if (!t->tagged) + break; /* broken repository */ + o->flags |= COMPLETE; + o = parse_object(t->tagged->sha1); + } + if (o && o->type == OBJ_COMMIT) { + struct commit *commit = (struct commit *)o; + if (!(commit->object.flags & COMPLETE)) { + commit->object.flags |= COMPLETE; + commit_list_insert_by_date(commit, &complete); + } + } + return 0; +} + +static void mark_recent_complete_commits(struct fetch_pack_args *args, + unsigned long cutoff) +{ + while (complete && cutoff <= complete->item->date) { + if (args->verbose) + fprintf(stderr, "Marking %s as complete\n", + sha1_to_hex(complete->item->object.sha1)); + pop_most_recent_commit(&complete, COMPLETE); + } +} + +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 *newlist = NULL; + struct ref **newtail = &newlist; + struct ref *ref, *next; + int sought_pos; + + sought_pos = 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); + 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; + } + else + sought_pos++; /* might have it; keep looking */ + } + } + + if (! keep && args->fetch_all && + (!args->depth || prefixcmp(ref->name, "refs/tags/"))) + keep = 1; + + if (keep) { + *newtail = ref; + ref->next = NULL; + newtail = &ref->next; + } else { + free(ref); + } + } + + filter_string_list(sought, 0, non_matching_ref, NULL); + *refs = newlist; +} + +static void mark_alternate_complete(const struct ref *ref, void *unused) +{ + mark_complete(NULL, ref->old_sha1, 0, NULL); +} + +static int everything_local(struct fetch_pack_args *args, + struct ref **refs, struct string_list *sought) +{ + struct ref *ref; + int retval; + unsigned long cutoff = 0; + + save_commit_buffer = 0; + + for (ref = *refs; ref; ref = ref->next) { + struct object *o; + + o = parse_object(ref->old_sha1); + if (!o) + continue; + + /* We already have it -- which may mean that we were + * in sync with the other side at some time after + * that (it is OK if we guess wrong here). + */ + if (o->type == OBJ_COMMIT) { + struct commit *commit = (struct commit *)o; + if (!cutoff || cutoff < commit->date) + cutoff = commit->date; + } + } + + if (!args->depth) { + for_each_ref(mark_complete, NULL); + for_each_alternate_ref(mark_alternate_complete, NULL); + if (cutoff) + mark_recent_complete_commits(args, cutoff); + } + + /* + * Mark all complete remote refs as common refs. + * Don't mark them common yet; the server has to be told so first. + */ + for (ref = *refs; ref; ref = ref->next) { + struct object *o = deref_tag(lookup_object(ref->old_sha1), + NULL, 0); + + if (!o || o->type != OBJ_COMMIT || !(o->flags & COMPLETE)) + continue; + + if (!(o->flags & SEEN)) { + rev_list_push((struct commit *)o, COMMON_REF | SEEN); + + mark_common((struct commit *)o, 1, 1); + } + } + + filter_refs(args, refs, sought); + + for (retval = 1, ref = *refs; ref ; ref = ref->next) { + const unsigned char *remote = ref->old_sha1; + unsigned char local[20]; + struct object *o; + + o = lookup_object(remote); + if (!o || !(o->flags & COMPLETE)) { + retval = 0; + if (!args->verbose) + continue; + fprintf(stderr, + "want %s (%s)\n", sha1_to_hex(remote), + ref->name); + continue; + } + + hashcpy(ref->new_sha1, local); + if (!args->verbose) + continue; + fprintf(stderr, + "already have %s (%s)\n", sha1_to_hex(remote), + ref->name); + } + return retval; +} + +static int sideband_demux(int in, int out, void *data) +{ + int *xd = data; + + int ret = recv_sideband("fetch-pack", xd[0], out); + close(out); + return ret; +} + +static int get_pack(struct fetch_pack_args *args, + int xd[2], char **pack_lockfile) +{ + struct async demux; + const char *argv[20]; + char keep_arg[256]; + char hdr_arg[256]; + const char **av; + int do_keep = args->keep_pack; + struct child_process cmd; + + memset(&demux, 0, sizeof(demux)); + if (use_sideband) { + /* xd[] is talking with upload-pack; subprocess reads from + * xd[0], spits out band#2 to stderr, and feeds us band#1 + * through demux->out. + */ + demux.proc = sideband_demux; + demux.data = xd; + demux.out = -1; + if (start_async(&demux)) + die("fetch-pack: unable to fork off sideband" + " demultiplexer"); + } + else + demux.out = xd[0]; + + memset(&cmd, 0, sizeof(cmd)); + cmd.argv = argv; + av = argv; + *hdr_arg = 0; + if (!args->keep_pack && unpack_limit) { + struct pack_header header; + + if (read_pack_header(demux.out, &header)) + die("protocol error: bad pack header"); + snprintf(hdr_arg, sizeof(hdr_arg), + "--pack_header=%"PRIu32",%"PRIu32, + ntohl(header.hdr_version), ntohl(header.hdr_entries)); + if (ntohl(header.hdr_entries) < unpack_limit) + do_keep = 0; + else + do_keep = 1; + } + + if (do_keep) { + if (pack_lockfile) + cmd.out = -1; + *av++ = "index-pack"; + *av++ = "--stdin"; + if (!args->quiet && !args->no_progress) + *av++ = "-v"; + if (args->use_thin_pack) + *av++ = "--fix-thin"; + if (args->lock_pack || unpack_limit) { + int s = sprintf(keep_arg, + "--keep=fetch-pack %"PRIuMAX " on ", (uintmax_t) getpid()); + if (gethostname(keep_arg + s, sizeof(keep_arg) - s)) + strcpy(keep_arg + s, "localhost"); + *av++ = keep_arg; + } + } + else { + *av++ = "unpack-objects"; + if (args->quiet || args->no_progress) + *av++ = "-q"; + } + if (*hdr_arg) + *av++ = hdr_arg; + if (fetch_fsck_objects >= 0 + ? fetch_fsck_objects + : transfer_fsck_objects >= 0 + ? transfer_fsck_objects + : 0) + *av++ = "--strict"; + *av++ = NULL; + + cmd.in = demux.out; + cmd.git_cmd = 1; + if (start_command(&cmd)) + die("fetch-pack: unable to fork off %s", argv[0]); + if (do_keep && pack_lockfile) { + *pack_lockfile = index_pack_lockfile(cmd.out); + close(cmd.out); + } + + if (finish_command(&cmd)) + die("%s failed", argv[0]); + if (use_sideband && finish_async(&demux)) + die("error in sideband demultiplexer"); + return 0; +} + +static struct ref *do_fetch_pack(struct fetch_pack_args *args, + int fd[2], + const struct ref *orig_ref, + struct string_list *sought, + char **pack_lockfile) +{ + struct ref *ref = copy_ref_list(orig_ref); + unsigned char sha1[20]; + const char *agent_feature; + int agent_len; + + sort_ref_list(&ref, ref_compare_name); + + if (is_repository_shallow() && !server_supports("shallow")) + die("Server does not support shallow clients"); + if (server_supports("multi_ack_detailed")) { + if (args->verbose) + fprintf(stderr, "Server supports multi_ack_detailed\n"); + multi_ack = 2; + if (server_supports("no-done")) { + if (args->verbose) + fprintf(stderr, "Server supports no-done\n"); + if (args->stateless_rpc) + no_done = 1; + } + } + else if (server_supports("multi_ack")) { + if (args->verbose) + fprintf(stderr, "Server supports multi_ack\n"); + multi_ack = 1; + } + if (server_supports("side-band-64k")) { + if (args->verbose) + fprintf(stderr, "Server supports side-band-64k\n"); + use_sideband = 2; + } + else if (server_supports("side-band")) { + if (args->verbose) + fprintf(stderr, "Server supports side-band\n"); + use_sideband = 1; + } + if (!server_supports("thin-pack")) + args->use_thin_pack = 0; + if (!server_supports("no-progress")) + args->no_progress = 0; + if (!server_supports("include-tag")) + args->include_tag = 0; + if (server_supports("ofs-delta")) { + if (args->verbose) + fprintf(stderr, "Server supports ofs-delta\n"); + } else + prefer_ofs_delta = 0; + + if ((agent_feature = server_feature_value("agent", &agent_len))) { + agent_supported = 1; + if (args->verbose && agent_len) + fprintf(stderr, "Server version is %.*s\n", + agent_len, agent_feature); + } + + if (everything_local(args, &ref, sought)) { + packet_flush(fd[1]); + goto all_done; + } + if (find_common(args, fd, sha1, ref) < 0) + if (!args->keep_pack) + /* When cloning, it is not unusual to have + * no common commit. + */ + warning("no common commits"); + + if (args->stateless_rpc) + packet_flush(fd[1]); + if (get_pack(args, fd, pack_lockfile)) + die("git fetch-pack: fetch failed."); + + all_done: + return ref; +} + +static int fetch_pack_config(const char *var, const char *value, void *cb) +{ + if (strcmp(var, "fetch.unpacklimit") == 0) { + fetch_unpack_limit = git_config_int(var, value); + return 0; + } + + if (strcmp(var, "transfer.unpacklimit") == 0) { + transfer_unpack_limit = git_config_int(var, value); + return 0; + } + + if (strcmp(var, "repack.usedeltabaseoffset") == 0) { + prefer_ofs_delta = git_config_bool(var, value); + return 0; + } + + if (!strcmp(var, "fetch.fsckobjects")) { + fetch_fsck_objects = git_config_bool(var, value); + return 0; + } + + if (!strcmp(var, "transfer.fsckobjects")) { + transfer_fsck_objects = git_config_bool(var, value); + return 0; + } + + return git_default_config(var, value, cb); +} + +static void fetch_pack_setup(void) +{ + static int did_setup; + if (did_setup) + return; + git_config(fetch_pack_config, NULL); + if (0 <= transfer_unpack_limit) + unpack_limit = transfer_unpack_limit; + else if (0 <= fetch_unpack_limit) + unpack_limit = fetch_unpack_limit; + did_setup = 1; +} + +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, + char **pack_lockfile) +{ + struct stat st; + struct ref *ref_cpy; + + fetch_pack_setup(); + if (args->depth > 0) { + if (stat(git_path("shallow"), &st)) + st.st_mtime = 0; + } + + if (sought->nr) { + sort_string_list(sought); + string_list_remove_duplicates(sought, 0); + } + + if (!ref) { + packet_flush(fd[1]); + die("no matching remote head"); + } + ref_cpy = do_fetch_pack(args, fd, ref, sought, pack_lockfile); + + if (args->depth > 0) { + static struct lock_file lock; + struct cache_time mtime; + struct strbuf sb = STRBUF_INIT; + char *shallow = git_path("shallow"); + int fd; + + mtime.sec = st.st_mtime; + mtime.nsec = ST_MTIME_NSEC(st); + if (stat(shallow, &st)) { + if (mtime.sec) + die("shallow file was removed during fetch"); + } else if (st.st_mtime != mtime.sec +#ifdef USE_NSEC + || ST_MTIME_NSEC(st) != mtime.nsec +#endif + ) + die("shallow file was changed during fetch"); + + fd = hold_lock_file_for_update(&lock, shallow, + LOCK_DIE_ON_ERROR); + if (!write_shallow_commits(&sb, 0) + || write_in_full(fd, sb.buf, sb.len) != sb.len) { + unlink_or_warn(shallow); + rollback_lock_file(&lock); + } else { + commit_lock_file(&lock); + } + strbuf_release(&sb); + } + + reprepare_packed_git(); + return ref_cpy; +} @@ -142,6 +142,9 @@ static int fsck_tree(struct tree *item, int strict, fsck_error error_func) int has_null_sha1 = 0; int has_full_path = 0; int has_empty_name = 0; + int has_dot = 0; + int has_dotdot = 0; + int has_dotgit = 0; int has_zero_pad = 0; int has_bad_modes = 0; int has_dup_entries = 0; @@ -168,6 +171,12 @@ static int fsck_tree(struct tree *item, int strict, fsck_error error_func) has_full_path = 1; if (!*name) has_empty_name = 1; + if (!strcmp(name, ".")) + has_dot = 1; + if (!strcmp(name, "..")) + has_dotdot = 1; + if (!strcmp(name, ".git")) + has_dotgit = 1; has_zero_pad |= *(char *)desc.buffer == '0'; update_tree_entry(&desc); @@ -217,6 +226,12 @@ static int fsck_tree(struct tree *item, int strict, fsck_error error_func) retval += error_func(&item->object, FSCK_WARN, "contains full pathnames"); if (has_empty_name) retval += error_func(&item->object, FSCK_WARN, "contains empty pathname"); + if (has_dot) + retval += error_func(&item->object, FSCK_WARN, "contains '.'"); + if (has_dotdot) + retval += error_func(&item->object, FSCK_WARN, "contains '..'"); + if (has_dotgit) + retval += error_func(&item->object, FSCK_WARN, "contains '.git'"); if (has_zero_pad) retval += error_func(&item->object, FSCK_WARN, "contains zero-padded file modes"); if (has_bad_modes) diff --git a/git-compat-util.h b/git-compat-util.h index 2e79b8a..2cecf56 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -75,7 +75,7 @@ # endif #elif !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__USLC__) && \ !defined(_M_UNIX) && !defined(__sgi) && !defined(__DragonFly__) && \ - !defined(__TANDEM) + !defined(__TANDEM) && !defined(__QNX__) #define _XOPEN_SOURCE 600 /* glibc2 and AIX 5.3L need 500, OpenBSD needs 600 for S_ISLNK() */ #define _XOPEN_SOURCE_EXTENDED 1 /* AIX 5.3L needs this */ #endif @@ -99,12 +99,14 @@ #include <stdlib.h> #include <stdarg.h> #include <string.h> -#ifdef __TANDEM /* or HAVE_STRINGS_H or !NO_STRINGS_H? */ +#ifdef HAVE_STRINGS_H #include <strings.h> /* for strcasecmp() */ #endif #include <errno.h> #include <limits.h> +#ifdef NEEDS_SYS_PARAM_H #include <sys/param.h> +#endif #include <sys/types.h> #include <dirent.h> #include <sys/time.h> @@ -288,6 +290,17 @@ extern NORETURN void die_errno(const char *err, ...) __attribute__((format (prin extern int error(const char *err, ...) __attribute__((format (printf, 1, 2))); extern void warning(const char *err, ...) __attribute__((format (printf, 1, 2))); +/* + * Let callers be aware of the constant return value; this can help + * gcc with -Wuninitialized analysis. We have to restrict this trick to + * gcc, though, because of the variadic macro and the magic ## comma pasting + * behavior. But since we're only trying to help gcc, anyway, it's OK; other + * compilers will fall back to using the function as usual. + */ +#ifdef __GNUC__ +#define error(fmt, ...) (error((fmt), ##__VA_ARGS__), -1) +#endif + extern void set_die_routine(NORETURN_PTR void (*routine)(const char *err, va_list params)); extern void set_error_routine(void (*routine)(const char *err, va_list params)); @@ -411,6 +424,10 @@ void *gitmemmem(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen); #endif +#ifdef NO_GETPAGESIZE +#define getpagesize() sysconf(_SC_PAGESIZE) +#endif + #ifdef FREAD_READS_DIRECTORIES #ifdef fopen #undef fopen @@ -637,8 +654,12 @@ int rmdir_or_warn(const char *path); */ int remove_or_warn(unsigned int mode, const char *path); -/* Call access(2), but warn for any error besides ENOENT. */ +/* + * Call access(2), but warn for any error except "missing file" + * (ENOENT or ENOTDIR). + */ int access_or_warn(const char *path, int mode); +int access_or_die(const char *path, int mode); /* Warn on an inaccessible file that ought to be accessible */ void warn_on_inaccessible(const char *path); diff --git a/git-cvsimport.perl b/git-cvsimport.perl index 8032f23..0a31ebd 100755 --- a/git-cvsimport.perl +++ b/git-cvsimport.perl @@ -24,14 +24,14 @@ use File::Basename qw(basename dirname); use Time::Local; use IO::Socket; use IO::Pipe; -use POSIX qw(strftime dup2 ENOENT); +use POSIX qw(strftime tzset dup2 ENOENT); use IPC::Open2; $SIG{'PIPE'}="IGNORE"; -$ENV{'TZ'}="UTC"; +set_timezone('UTC'); our ($opt_h,$opt_o,$opt_v,$opt_k,$opt_u,$opt_d,$opt_p,$opt_C,$opt_z,$opt_i,$opt_P, $opt_s,$opt_m,@opt_M,$opt_A,$opt_S,$opt_L, $opt_a, $opt_r, $opt_R); -my (%conv_author_name, %conv_author_email); +my (%conv_author_name, %conv_author_email, %conv_author_tz); sub usage(;$) { my $msg = shift; @@ -59,6 +59,14 @@ sub read_author_info($) { $conv_author_name{$user} = $2; $conv_author_email{$user} = $3; } + # or with an optional timezone: + # spawn=Simon Pawn <spawn@frog-pond.org> America/Chicago + elsif (m/^(\S+?)\s*=\s*(.+?)\s*<(.+)>\s*(\S+?)\s*$/) { + $user = $1; + $conv_author_name{$user} = $2; + $conv_author_email{$user} = $3; + $conv_author_tz{$user} = $4; + } # However, we also read from CVSROOT/users format # to ease migration. elsif (/^(\w+):(['"]?)(.+?)\2\s*$/) { @@ -84,11 +92,22 @@ sub write_author_info($) { die("Failed to open $file for writing: $!"); foreach (keys %conv_author_name) { - print $f "$_=$conv_author_name{$_} <$conv_author_email{$_}>\n"; + print $f "$_=$conv_author_name{$_} <$conv_author_email{$_}>"; + print $f " $conv_author_tz{$_}" if ($conv_author_tz{$_}); + print $f "\n"; } close ($f); } +# Versions of perl before 5.10.0 may not automatically check $TZ each +# time localtime is run (most platforms will do so only the first time). +# We can work around this by using tzset() to update the internal +# variable whenever we change the environment. +sub set_timezone { + $ENV{TZ} = shift; + tzset(); +} + # convert getopts specs for use by git config my %longmap = ( 'A:' => 'authors-file', @@ -795,7 +814,7 @@ sub write_tree () { return $tree; } -my ($patchset,$date,$author_name,$author_email,$branch,$ancestor,$tag,$logmsg); +my ($patchset,$date,$author_name,$author_email,$author_tz,$branch,$ancestor,$tag,$logmsg); my (@old,@new,@skipped,%ignorebranch,@commit_revisions); # commits that cvsps cannot place anywhere... @@ -844,7 +863,9 @@ sub commit { } } - my $commit_date = strftime("+0000 %Y-%m-%d %H:%M:%S",gmtime($date)); + set_timezone($author_tz); + my $commit_date = strftime("%s %z", localtime($date)); + set_timezone('UTC'); $ENV{GIT_AUTHOR_NAME} = $author_name; $ENV{GIT_AUTHOR_EMAIL} = $author_email; $ENV{GIT_AUTHOR_DATE} = $commit_date; @@ -945,12 +966,14 @@ while (<CVS>) { } $state=3; } elsif ($state == 3 and s/^Author:\s+//) { + $author_tz = "UTC"; s/\s+$//; if (/^(.*?)\s+<(.*)>/) { ($author_name, $author_email) = ($1, $2); } elsif ($conv_author_name{$_}) { $author_name = $conv_author_name{$_}; $author_email = $conv_author_email{$_}; + $author_tz = $conv_author_tz{$_} if ($conv_author_tz{$_}); } else { $author_name = $author_email = $_; } diff --git a/git-cvsserver.perl b/git-cvsserver.perl index b8eddab..c5ebfa0 100755 --- a/git-cvsserver.perl +++ b/git-cvsserver.perl @@ -51,6 +51,10 @@ $| = 1; #### Definition and mappings of functions #### +# NOTE: Despite the existence of req_CATCHALL and req_EMPTY unimplemented +# requests, this list is incomplete. It is missing many rarer/optional +# requests. Perhaps some clients require a claim of support for +# these specific requests for main functionality to work? my $methods = { 'Root' => \&req_Root, 'Valid-responses' => \&req_Validresponses, @@ -80,7 +84,6 @@ my $methods = { 'noop' => \&req_EMPTY, 'annotate' => \&req_annotate, 'Global_option' => \&req_Globaloption, - #'annotate' => \&req_CATCHALL, }; ############################################## @@ -499,7 +502,7 @@ sub req_Entry #$log->debug("req_Entry : $data"); - my @data = split(/\//, $data); + my @data = split(/\//, $data, -1); $state->{entries}{$state->{directory}.$data[1]} = { revision => $data[2], @@ -540,8 +543,6 @@ sub req_add my $updater = GITCVS::updater->new($state->{CVSROOT}, $state->{module}, $log); $updater->update(); - argsfromdir($updater); - my $addcount = 0; foreach my $filename ( @{$state->{args}} ) @@ -551,10 +552,10 @@ sub req_add my $meta = $updater->getmeta($filename); my $wrev = revparse($filename); - if ($wrev && $meta && ($wrev < 0)) + if ($wrev && $meta && ($wrev=~/^-/)) { # previously removed file, add back - $log->info("added file $filename was previously removed, send 1.$meta->{revision}"); + $log->info("added file $filename was previously removed, send $meta->{revision}"); print "MT +updated\n"; print "MT text U \n"; @@ -571,8 +572,8 @@ sub req_add # this is an "entries" line my $kopts = kopts_from_path($filename,"sha1",$meta->{filehash}); - $log->debug("/$filepart/1.$meta->{revision}//$kopts/"); - print "/$filepart/1.$meta->{revision}//$kopts/\n"; + $log->debug("/$filepart/$meta->{revision}//$kopts/"); + print "/$filepart/$meta->{revision}//$kopts/\n"; # permissions $log->debug("SEND : u=$meta->{mode},g=$meta->{mode},o=$meta->{mode}"); print "u=$meta->{mode},g=$meta->{mode},o=$meta->{mode}\n"; @@ -680,13 +681,13 @@ sub req_remove next; } - if ( defined($wrev) and $wrev < 0 ) + if ( defined($wrev) and ($wrev=~/^-/) ) { print "E cvs remove: file `$filename' already scheduled for removal\n"; next; } - unless ( $wrev == $meta->{revision} ) + unless ( $wrev eq $meta->{revision} ) { # TODO : not sure if the format of this message is quite correct. print "E cvs remove: Up to date check failed for `$filename'\n"; @@ -701,7 +702,7 @@ sub req_remove print "Checked-in $dirpart\n"; print "$filename\n"; my $kopts = kopts_from_path($filename,"sha1",$meta->{filehash}); - print "/$filepart/-1.$wrev//$kopts/\n"; + print "/$filepart/-$wrev//$kopts/\n"; $rmcount++; } @@ -992,7 +993,7 @@ sub req_co # this is an "entries" line my $kopts = kopts_from_path($fullName,"sha1",$git->{filehash}); - print "/$git->{name}/1.$git->{revision}//$kopts/\n"; + print "/$git->{name}/$git->{revision}//$kopts/\n"; # permissions print "u=$git->{mode},g=$git->{mode},o=$git->{mode}\n"; @@ -1080,7 +1081,7 @@ sub req_update } my $meta; - if ( defined($state->{opt}{r}) and $state->{opt}{r} =~ /^1\.(\d+)/ ) + if ( defined($state->{opt}{r}) and $state->{opt}{r} =~ /^(1\.\d+)$/ ) { $meta = $updater->getmeta($filename, $1); } else { @@ -1102,7 +1103,7 @@ sub req_update { $meta = { name => $filename, - revision => 0, + revision => '0', filehash => 'added' }; } @@ -1112,7 +1113,7 @@ sub req_update my $wrev = revparse($filename); # If the working copy is an old revision, lets get that version too for comparison. - if ( defined($wrev) and $wrev != $meta->{revision} ) + if ( defined($wrev) and $wrev ne $meta->{revision} ) { $oldmeta = $updater->getmeta($filename, $wrev); } @@ -1123,7 +1124,7 @@ sub req_update # and the working copy is unmodified _and_ the user hasn't specified -C next if ( defined ( $wrev ) and defined($meta->{revision}) - and $wrev == $meta->{revision} + and $wrev eq $meta->{revision} and $state->{entries}{$filename}{unchanged} and not exists ( $state->{opt}{C} ) ); @@ -1131,7 +1132,7 @@ sub req_update # but the working copy is modified, tell the client it's modified if ( defined ( $wrev ) and defined($meta->{revision}) - and $wrev == $meta->{revision} + and $wrev eq $meta->{revision} and defined($state->{entries}{$filename}{modified_hash}) and not exists ( $state->{opt}{C} ) ) { @@ -1144,6 +1145,10 @@ sub req_update if ( $meta->{filehash} eq "deleted" ) { + # TODO: If it has been modified in the sandbox, error out + # with the appropriate message, rather than deleting a modified + # file. + my ( $filepart, $dirpart ) = filenamesplit($filename,1); $log->info("Removing '$filename' from working copy (no longer in the repo)"); @@ -1161,7 +1166,7 @@ sub req_update { # normal update, just send the new revision (either U=Update, # or A=Add, or R=Remove) - if ( defined($wrev) && $wrev < 0 ) + if ( defined($wrev) && ($wrev=~/^-/) ) { $log->info("Tell the client the file is scheduled for removal"); print "MT text R \n"; @@ -1169,7 +1174,8 @@ sub req_update print "MT newline\n"; next; } - elsif ( (!defined($wrev) || $wrev == 0) && (!defined($meta->{revision}) || $meta->{revision} == 0) ) + elsif ( (!defined($wrev) || $wrev eq '0') && + (!defined($meta->{revision}) || $meta->{revision} eq '0') ) { $log->info("Tell the client the file is scheduled for addition"); print "MT text A \n"; @@ -1179,7 +1185,7 @@ sub req_update } else { - $log->info("Updating '$filename' to ".$meta->{revision}); + $log->info("UpdatingX3 '$filename' to ".$meta->{revision}); print "MT +updated\n"; print "MT text U \n"; print "MT fname $filename\n"; @@ -1211,8 +1217,8 @@ sub req_update # this is an "entries" line my $kopts = kopts_from_path($filename,"sha1",$meta->{filehash}); - $log->debug("/$filepart/1.$meta->{revision}//$kopts/"); - print "/$filepart/1.$meta->{revision}//$kopts/\n"; + $log->debug("/$filepart/$meta->{revision}//$kopts/"); + print "/$filepart/$meta->{revision}//$kopts/\n"; # permissions $log->debug("SEND : u=$meta->{mode},g=$meta->{mode},o=$meta->{mode}"); @@ -1222,7 +1228,6 @@ sub req_update transmitfile($meta->{filehash}); } } else { - $log->info("Updating '$filename'"); my ( $filepart, $dirpart ) = filenamesplit($meta->{name},1); my $mergeDir = setupTmpDir(); @@ -1237,7 +1242,7 @@ sub req_update # we need to merge with the local changes ( M=successful merge, C=conflict merge ) $log->info("Merging $file_local, $file_old, $file_new"); - print "M Merging differences between 1.$oldmeta->{revision} and 1.$meta->{revision} into $filename\n"; + print "M Merging differences between $oldmeta->{revision} and $meta->{revision} into $filename\n"; $log->debug("Temporary directory for merge is $mergeDir"); @@ -1260,8 +1265,8 @@ sub req_update print $state->{CVSROOT} . "/$state->{module}/$filename\n"; my $kopts = kopts_from_path("$dirpart/$filepart", "file",$mergedFile); - $log->debug("/$filepart/1.$meta->{revision}//$kopts/"); - print "/$filepart/1.$meta->{revision}//$kopts/\n"; + $log->debug("/$filepart/$meta->{revision}//$kopts/"); + print "/$filepart/$meta->{revision}//$kopts/\n"; } } elsif ( $return == 1 ) @@ -1277,7 +1282,7 @@ sub req_update print $state->{CVSROOT} . "/$state->{module}/$filename\n"; my $kopts = kopts_from_path("$dirpart/$filepart", "file",$mergedFile); - print "/$filepart/1.$meta->{revision}/+/$kopts/\n"; + print "/$filepart/$meta->{revision}/+/$kopts/\n"; } } else @@ -1380,11 +1385,12 @@ sub req_ci my $addflag = 0; my $rmflag = 0; - $rmflag = 1 if ( defined($wrev) and $wrev < 0 ); + $rmflag = 1 if ( defined($wrev) and ($wrev=~/^-/) ); $addflag = 1 unless ( -e $filename ); # Do up to date checking - unless ( $addflag or $wrev == $meta->{revision} or ( $rmflag and -$wrev == $meta->{revision} ) ) + unless ( $addflag or $wrev eq $meta->{revision} or + ( $rmflag and $wrev eq "-$meta->{revision}" ) ) { # fail everything if an up to date check fails print "error 1 Up to date check failed for $filename\n"; @@ -1421,7 +1427,7 @@ sub req_ci $log->info("Adding file '$filename'"); system("git", "update-index", "--add", $filename); } else { - $log->info("Updating file '$filename'"); + $log->info("UpdatingX2 file '$filename'"); system("git", "update-index", $filename); } } @@ -1512,7 +1518,7 @@ sub req_ci my $meta = $updater->getmeta($filename); unless (defined $meta->{revision}) { - $meta->{revision} = 1; + $meta->{revision} = "1.1"; } my ( $filepart, $dirpart ) = filenamesplit($filename, 1); @@ -1522,19 +1528,19 @@ sub req_ci print "M $state->{CVSROOT}/$state->{module}/$filename,v <-- $dirpart$filepart\n"; if ( defined $meta->{filehash} && $meta->{filehash} eq "deleted" ) { - print "M new revision: delete; previous revision: 1.$oldmeta{$filename}{revision}\n"; + print "M new revision: delete; previous revision: $oldmeta{$filename}{revision}\n"; print "Remove-entry $dirpart\n"; print "$filename\n"; } else { - if ($meta->{revision} == 1) { + if ($meta->{revision} eq "1.1") { print "M initial revision: 1.1\n"; } else { - print "M new revision: 1.$meta->{revision}; previous revision: 1.$oldmeta{$filename}{revision}\n"; + print "M new revision: $meta->{revision}; previous revision: $oldmeta{$filename}{revision}\n"; } print "Checked-in $dirpart\n"; print "$filename\n"; my $kopts = kopts_from_path($filename,"sha1",$meta->{filehash}); - print "/$filepart/1.$meta->{revision}//$kopts/\n"; + print "/$filepart/$meta->{revision}//$kopts/\n"; } } @@ -1552,10 +1558,12 @@ sub req_status #$log->debug("status state : " . Dumper($state)); # Grab a handle to the SQLite db and do any necessary updates - my $updater = GITCVS::updater->new($state->{CVSROOT}, $state->{module}, $log); + my $updater; + $updater = GITCVS::updater->new($state->{CVSROOT}, $state->{module}, $log); $updater->update(); - # if no files were specified, we need to work out what files we should be providing status on ... + # if no files were specified, we need to work out what files we should + # be providing status on ... argsfromdir($updater); # foreach file specified on the command line ... @@ -1563,67 +1571,135 @@ sub req_status { $filename = filecleanup($filename); - next if exists($state->{opt}{l}) && index($filename, '/', length($state->{prependdir})) >= 0; + if ( exists($state->{opt}{l}) && + index($filename, '/', length($state->{prependdir})) >= 0 ) + { + next; + } my $meta = $updater->getmeta($filename); my $oldmeta = $meta; my $wrev = revparse($filename); - # If the working copy is an old revision, lets get that version too for comparison. - if ( defined($wrev) and $wrev != $meta->{revision} ) + # If the working copy is an old revision, lets get that + # version too for comparison. + if ( defined($wrev) and $wrev ne $meta->{revision} ) { $oldmeta = $updater->getmeta($filename, $wrev); } # TODO : All possible statuses aren't yet implemented my $status; - # Files are up to date if the working copy and repo copy have the same revision, and the working copy is unmodified - $status = "Up-to-date" if ( defined ( $wrev ) and defined($meta->{revision}) and $wrev == $meta->{revision} - and - ( ( $state->{entries}{$filename}{unchanged} and ( not defined ( $state->{entries}{$filename}{conflict} ) or $state->{entries}{$filename}{conflict} !~ /^\+=/ ) ) - or ( defined($state->{entries}{$filename}{modified_hash}) and $state->{entries}{$filename}{modified_hash} eq $meta->{filehash} ) ) - ); - - # Need checkout if the working copy has an older revision than the repo copy, and the working copy is unmodified - $status ||= "Needs Checkout" if ( defined ( $wrev ) and defined ( $meta->{revision} ) and $meta->{revision} > $wrev - and - ( $state->{entries}{$filename}{unchanged} - or ( defined($state->{entries}{$filename}{modified_hash}) and $state->{entries}{$filename}{modified_hash} eq $oldmeta->{filehash} ) ) - ); - - # Need checkout if it exists in the repo but doesn't have a working copy - $status ||= "Needs Checkout" if ( not defined ( $wrev ) and defined ( $meta->{revision} ) ); - - # Locally modified if working copy and repo copy have the same revision but there are local changes - $status ||= "Locally Modified" if ( defined ( $wrev ) and defined($meta->{revision}) and $wrev == $meta->{revision} and $state->{entries}{$filename}{modified_filename} ); - - # Needs Merge if working copy revision is less than repo copy and there are local changes - $status ||= "Needs Merge" if ( defined ( $wrev ) and defined ( $meta->{revision} ) and $meta->{revision} > $wrev and $state->{entries}{$filename}{modified_filename} ); - - $status ||= "Locally Added" if ( defined ( $state->{entries}{$filename}{revision} ) and not defined ( $meta->{revision} ) ); - $status ||= "Locally Removed" if ( defined ( $wrev ) and defined ( $meta->{revision} ) and -$wrev == $meta->{revision} ); - $status ||= "Unresolved Conflict" if ( defined ( $state->{entries}{$filename}{conflict} ) and $state->{entries}{$filename}{conflict} =~ /^\+=/ ); - $status ||= "File had conflicts on merge" if ( 0 ); + # Files are up to date if the working copy and repo copy have + # the same revision, and the working copy is unmodified + if ( defined ( $wrev ) and defined($meta->{revision}) and + $wrev eq $meta->{revision} and + ( ( $state->{entries}{$filename}{unchanged} and + ( not defined ( $state->{entries}{$filename}{conflict} ) or + $state->{entries}{$filename}{conflict} !~ /^\+=/ ) ) or + ( defined($state->{entries}{$filename}{modified_hash}) and + $state->{entries}{$filename}{modified_hash} eq + $meta->{filehash} ) ) ) + { + $status = "Up-to-date" + } + + # Need checkout if the working copy has a different (usually + # older) revision than the repo copy, and the working copy is + # unmodified + if ( defined ( $wrev ) and defined ( $meta->{revision} ) and + $meta->{revision} ne $wrev and + ( $state->{entries}{$filename}{unchanged} or + ( defined($state->{entries}{$filename}{modified_hash}) and + $state->{entries}{$filename}{modified_hash} eq + $oldmeta->{filehash} ) ) ) + { + $status ||= "Needs Checkout"; + } + + # Need checkout if it exists in the repo but doesn't have a working + # copy + if ( not defined ( $wrev ) and defined ( $meta->{revision} ) ) + { + $status ||= "Needs Checkout"; + } + + # Locally modified if working copy and repo copy have the + # same revision but there are local changes + if ( defined ( $wrev ) and defined($meta->{revision}) and + $wrev eq $meta->{revision} and + $state->{entries}{$filename}{modified_filename} ) + { + $status ||= "Locally Modified"; + } + + # Needs Merge if working copy revision is different + # (usually older) than repo copy and there are local changes + if ( defined ( $wrev ) and defined ( $meta->{revision} ) and + $meta->{revision} ne $wrev and + $state->{entries}{$filename}{modified_filename} ) + { + $status ||= "Needs Merge"; + } + + if ( defined ( $state->{entries}{$filename}{revision} ) and + not defined ( $meta->{revision} ) ) + { + $status ||= "Locally Added"; + } + if ( defined ( $wrev ) and defined ( $meta->{revision} ) and + $wrev eq "-$meta->{revision}" ) + { + $status ||= "Locally Removed"; + } + if ( defined ( $state->{entries}{$filename}{conflict} ) and + $state->{entries}{$filename}{conflict} =~ /^\+=/ ) + { + $status ||= "Unresolved Conflict"; + } + if ( 0 ) + { + $status ||= "File had conflicts on merge"; + } $status ||= "Unknown"; my ($filepart) = filenamesplit($filename); - print "M ===================================================================\n"; + print "M =======" . ( "=" x 60 ) . "\n"; print "M File: $filepart\tStatus: $status\n"; if ( defined($state->{entries}{$filename}{revision}) ) { - print "M Working revision:\t" . $state->{entries}{$filename}{revision} . "\n"; + print "M Working revision:\t" . + $state->{entries}{$filename}{revision} . "\n"; } else { print "M Working revision:\tNo entry for $filename\n"; } if ( defined($meta->{revision}) ) { - print "M Repository revision:\t1." . $meta->{revision} . "\t$state->{CVSROOT}/$state->{module}/$filename,v\n"; - print "M Sticky Tag:\t\t(none)\n"; - print "M Sticky Date:\t\t(none)\n"; - print "M Sticky Options:\t\t(none)\n"; + print "M Repository revision:\t" . + $meta->{revision} . + "\t$state->{CVSROOT}/$state->{module}/$filename,v\n"; + my($tagOrDate)=$state->{entries}{$filename}{tag_or_date}; + my($tag)=($tagOrDate=~m/^T(.+)$/); + if( !defined($tag) ) + { + $tag="(none)"; + } + print "M Sticky Tag:\t\t$tag\n"; + my($date)=($tagOrDate=~m/^D(.+)$/); + if( !defined($date) ) + { + $date="(none)"; + } + print "M Sticky Date:\t\t$date\n"; + my($options)=$state->{entries}{$filename}{options}; + if( $options eq "" ) + { + $options="(none)"; + } + print "M Sticky Options:\t\t$options\n"; } else { print "M Repository revision:\tNo revision control file\n"; } @@ -1651,16 +1727,17 @@ sub req_diff $revision1 = $state->{opt}{r}; } - $revision1 =~ s/^1\.// if ( defined ( $revision1 ) ); - $revision2 =~ s/^1\.// if ( defined ( $revision2 ) ); - - $log->debug("Diffing revisions " . ( defined($revision1) ? $revision1 : "[NULL]" ) . " and " . ( defined($revision2) ? $revision2 : "[NULL]" ) ); + $log->debug("Diffing revisions " . + ( defined($revision1) ? $revision1 : "[NULL]" ) . + " and " . ( defined($revision2) ? $revision2 : "[NULL]" ) ); # Grab a handle to the SQLite db and do any necessary updates - my $updater = GITCVS::updater->new($state->{CVSROOT}, $state->{module}, $log); + my $updater; + $updater = GITCVS::updater->new($state->{CVSROOT}, $state->{module}, $log); $updater->update(); - # if no files were specified, we need to work out what files we should be providing status on ... + # if no files were specified, we need to work out what files we should + # be providing status on ... argsfromdir($updater); # foreach file specified on the command line ... @@ -1682,7 +1759,7 @@ sub req_diff $meta1 = $updater->getmeta($filename, $revision1); unless ( defined ( $meta1 ) and $meta1->{filehash} ne "deleted" ) { - print "E File $filename at revision 1.$revision1 doesn't exist\n"; + print "E File $filename at revision $revision1 doesn't exist\n"; next; } transmitfile($meta1->{filehash}, { targetfile => $file1 }); @@ -1703,7 +1780,7 @@ sub req_diff unless ( defined ( $meta2 ) and $meta2->{filehash} ne "deleted" ) { - print "E File $filename at revision 1.$revision2 doesn't exist\n"; + print "E File $filename at revision $revision2 doesn't exist\n"; next; } @@ -1715,7 +1792,8 @@ sub req_diff $file2 = $state->{entries}{$filename}{modified_filename}; } - # if we have been given -r, and we don't have a $file2 yet, lets get one + # if we have been given -r, and we don't have a $file2 yet, lets + # get one if ( defined ( $revision1 ) and not defined ( $file2 ) ) { ( undef, $file2 ) = tempfile( DIR => $TEMP_DIR, OPEN => 0 ); @@ -1726,21 +1804,37 @@ sub req_diff # We need to have retrieved something useful next unless ( defined ( $meta1 ) ); - # Files to date if the working copy and repo copy have the same revision, and the working copy is unmodified - next if ( not defined ( $meta2 ) and $wrev == $meta1->{revision} - and - ( ( $state->{entries}{$filename}{unchanged} and ( not defined ( $state->{entries}{$filename}{conflict} ) or $state->{entries}{$filename}{conflict} !~ /^\+=/ ) ) - or ( defined($state->{entries}{$filename}{modified_hash}) and $state->{entries}{$filename}{modified_hash} eq $meta1->{filehash} ) ) - ); + # Files to date if the working copy and repo copy have the same + # revision, and the working copy is unmodified + if ( not defined ( $meta2 ) and $wrev eq $meta1->{revision} and + ( ( $state->{entries}{$filename}{unchanged} and + ( not defined ( $state->{entries}{$filename}{conflict} ) or + $state->{entries}{$filename}{conflict} !~ /^\+=/ ) ) or + ( defined($state->{entries}{$filename}{modified_hash}) and + $state->{entries}{$filename}{modified_hash} eq + $meta1->{filehash} ) ) ) + { + next; + } # Apparently we only show diffs for locally modified files - next unless ( defined($meta2) or defined ( $state->{entries}{$filename}{modified_filename} ) ); + unless ( defined($meta2) or + defined ( $state->{entries}{$filename}{modified_filename} ) ) + { + next; + } print "M Index: $filename\n"; - print "M ===================================================================\n"; + print "M =======" . ( "=" x 60 ) . "\n"; print "M RCS file: $state->{CVSROOT}/$state->{module}/$filename,v\n"; - print "M retrieving revision 1.$meta1->{revision}\n" if ( defined ( $meta1 ) ); - print "M retrieving revision 1.$meta2->{revision}\n" if ( defined ( $meta2 ) ); + if ( defined ( $meta1 ) ) + { + print "M retrieving revision $meta1->{revision}\n" + } + if ( defined ( $meta2 ) ) + { + print "M retrieving revision $meta2->{revision}\n" + } print "M diff "; foreach my $opt ( keys %{$state->{opt}} ) { @@ -1752,18 +1846,27 @@ sub req_diff } } else { print "-$opt "; - print "$state->{opt}{$opt} " if ( defined ( $state->{opt}{$opt} ) ); + if ( defined ( $state->{opt}{$opt} ) ) + { + print "$state->{opt}{$opt} " + } } } print "$filename\n"; - $log->info("Diffing $filename -r $meta1->{revision} -r " . ( $meta2->{revision} or "workingcopy" )); + $log->info("Diffing $filename -r $meta1->{revision} -r " . + ( $meta2->{revision} or "workingcopy" )); ( $fh, $filediff ) = tempfile ( DIR => $TEMP_DIR ); if ( exists $state->{opt}{u} ) { - system("diff -u -L '$filename revision 1.$meta1->{revision}' -L '$filename " . ( defined($meta2->{revision}) ? "revision 1.$meta2->{revision}" : "working copy" ) . "' $file1 $file2 > $filediff"); + system("diff -u -L '$filename revision $meta1->{revision}'" . + " -L '$filename " . + ( defined($meta2->{revision}) ? + "revision $meta2->{revision}" : + "working copy" ) . + "' $file1 $file2 > $filediff" ); } else { system("diff $file1 $file2 > $filediff"); } @@ -1787,22 +1890,19 @@ sub req_log $log->debug("req_log : " . ( defined($data) ? $data : "[NULL]" )); #$log->debug("log state : " . Dumper($state)); - my ( $minrev, $maxrev ); - if ( defined ( $state->{opt}{r} ) and $state->{opt}{r} =~ /([\d.]+)?(::?)([\d.]+)?/ ) + my ( $revFilter ); + if ( defined ( $state->{opt}{r} ) ) { - my $control = $2; - $minrev = $1; - $maxrev = $3; - $minrev =~ s/^1\.// if ( defined ( $minrev ) ); - $maxrev =~ s/^1\.// if ( defined ( $maxrev ) ); - $minrev++ if ( defined($minrev) and $control eq "::" ); + $revFilter = $state->{opt}{r}; } # Grab a handle to the SQLite db and do any necessary updates - my $updater = GITCVS::updater->new($state->{CVSROOT}, $state->{module}, $log); + my $updater; + $updater = GITCVS::updater->new($state->{CVSROOT}, $state->{module}, $log); $updater->update(); - # if no files were specified, we need to work out what files we should be providing status on ... + # if no files were specified, we need to work out what files we + # should be providing status on ... argsfromdir($updater); # foreach file specified on the command line ... @@ -1812,53 +1912,46 @@ sub req_log my $headmeta = $updater->getmeta($filename); - my $revisions = $updater->getlog($filename); - my $totalrevisions = scalar(@$revisions); - - if ( defined ( $minrev ) ) - { - $log->debug("Removing revisions less than $minrev"); - while ( scalar(@$revisions) > 0 and $revisions->[-1]{revision} < $minrev ) - { - pop @$revisions; - } - } - if ( defined ( $maxrev ) ) - { - $log->debug("Removing revisions greater than $maxrev"); - while ( scalar(@$revisions) > 0 and $revisions->[0]{revision} > $maxrev ) - { - shift @$revisions; - } - } + my ($revisions,$totalrevisions) = $updater->getlog($filename, + $revFilter); next unless ( scalar(@$revisions) ); print "M \n"; print "M RCS file: $state->{CVSROOT}/$state->{module}/$filename,v\n"; print "M Working file: $filename\n"; - print "M head: 1.$headmeta->{revision}\n"; + print "M head: $headmeta->{revision}\n"; print "M branch:\n"; print "M locks: strict\n"; print "M access list:\n"; print "M symbolic names:\n"; print "M keyword substitution: kv\n"; - print "M total revisions: $totalrevisions;\tselected revisions: " . scalar(@$revisions) . "\n"; + print "M total revisions: $totalrevisions;\tselected revisions: " . + scalar(@$revisions) . "\n"; print "M description:\n"; foreach my $revision ( @$revisions ) { print "M ----------------------------\n"; - print "M revision 1.$revision->{revision}\n"; + print "M revision $revision->{revision}\n"; # reformat the date for log output - $revision->{modified} = sprintf('%04d/%02d/%02d %s', $3, $DATE_LIST->{$2}, $1, $4 ) if ( $revision->{modified} =~ /(\d+)\s+(\w+)\s+(\d+)\s+(\S+)/ and defined($DATE_LIST->{$2}) ); + if ( $revision->{modified} =~ /(\d+)\s+(\w+)\s+(\d+)\s+(\S+)/ and + defined($DATE_LIST->{$2}) ) + { + $revision->{modified} = sprintf('%04d/%02d/%02d %s', + $3, $DATE_LIST->{$2}, $1, $4 ); + } $revision->{author} = cvs_author($revision->{author}); - print "M date: $revision->{modified}; author: $revision->{author}; state: " . ( $revision->{filehash} eq "deleted" ? "dead" : "Exp" ) . "; lines: +2 -3\n"; - my $commitmessage = $updater->commitmessage($revision->{commithash}); + print "M date: $revision->{modified};" . + " author: $revision->{author}; state: " . + ( $revision->{filehash} eq "deleted" ? "dead" : "Exp" ) . + "; lines: +2 -3\n"; + my $commitmessage; + $commitmessage = $updater->commitmessage($revision->{commithash}); $commitmessage =~ s/^/M /mg; print $commitmessage . "\n"; } - print "M =============================================================================\n"; + print "M =======" . ( "=" x 70 ) . "\n"; } print "ok\n"; @@ -1964,7 +2057,7 @@ sub req_annotate $metadata->{$commithash}{author} = cvs_author($metadata->{$commithash}{author}); $metadata->{$commithash}{modified} = sprintf("%02d-%s-%02d", $1, $2, $3) if ( $metadata->{$commithash}{modified} =~ /^(\d+)\s(\w+)\s\d\d(\d\d)/ ); } - printf("M 1.%-5d (%-8s %10s): %s\n", + printf("M %-7s (%-8s %10s): %s\n", $metadata->{$commithash}{revision}, $metadata->{$commithash}{author}, $metadata->{$commithash}{modified}, @@ -2085,7 +2178,7 @@ sub argsfromdir # push added files foreach my $file (keys %{$state->{entries}}) { if ( exists $state->{entries}{$file}{revision} && - $state->{entries}{$file}{revision} == 0 ) + $state->{entries}{$file}{revision} eq '0' ) { push @gethead, { name => $file, filehash => 'added' }; } @@ -2129,16 +2222,15 @@ sub statecleanup $state->{entries} = {}; } +# Return working directory CVS revision "1.X" out +# of the the working directory "entries" state, for the given filename. +# This is prefixed with a dash if the file is scheduled for removal +# when it is committed. sub revparse { my $filename = shift; - return undef unless ( defined ( $state->{entries}{$filename}{revision} ) ); - - return $1 if ( $state->{entries}{$filename}{revision} =~ /^1\.(\d+)/ ); - return -$1 if ( $state->{entries}{$filename}{revision} =~ /^-1\.(\d+)/ ); - - return undef; + return $state->{entries}{$filename}{revision}; } # This method takes a file hash and does a CVS "file transfer". Its @@ -2444,42 +2536,14 @@ sub kopts_from_path } elsif( ($cfg->{gitcvs}{allbinary} =~ /^\s*guess\s*$/i) ) { - if( $srcType eq "sha1Or-k" && - !defined($name) ) + if( is_binary($srcType,$name) ) { - my ($ret)=$state->{entries}{$path}{options}; - if( !defined($ret) ) - { - $ret=$state->{opt}{k}; - if(defined($ret)) - { - $ret="-k$ret"; - } - else - { - $ret=""; - } - } - if( ! ($ret=~/^(|-kb|-kkv|-kkvl|-kk|-ko|-kv)$/) ) - { - print "E Bad -k option\n"; - $log->warn("Bad -k option: $ret"); - die "Error: Bad -k option: $ret\n"; - } - - return $ret; + $log->debug("... as binary"); + return "-kb"; } else { - if( is_binary($srcType,$name) ) - { - $log->debug("... as binary"); - return "-kb"; - } - else - { - $log->debug("... as text"); - } + $log->debug("... as text"); } } } @@ -2586,7 +2650,7 @@ sub open_blob_or_die die "Unable to open file $name: $!\n"; } } - elsif( $srcType eq "sha1" || $srcType eq "sha1Or-k" ) + elsif( $srcType eq "sha1" ) { unless ( defined ( $name ) and $name =~ /^[a-zA-Z0-9]{40}$/ ) { @@ -2929,6 +2993,16 @@ sub new } # Construct the revision table if required + # The revision table stores an entry for each file, each time that file + # changes. + # numberOfRecords = O( numCommits * averageNumChangedFilesPerCommit ) + # This is not sufficient to support "-r {commithash}" for any + # files except files that were modified by that commit (also, + # some places in the code ignore/effectively strip out -r in + # some cases, before it gets passed to getmeta()). + # The "filehash" field typically has a git blob hash, but can also + # be set to "dead" to indicate that the given version of the file + # should not exist in the sandbox. unless ( $self->{tables}{$self->tablename("revision")} ) { my $tablename = $self->tablename("revision"); @@ -2956,6 +3030,15 @@ sub new } # Construct the head table if required + # The head table (along with the "last_commit" entry in the property + # table) is the persisted working state of the "sub update" subroutine. + # All of it's data is read entirely first, and completely recreated + # last, every time "sub update" runs. + # This is also used by "sub getmeta" when it is asked for the latest + # version of a file (as opposed to some specific version). + # Another way of thinking about it is as a single slice out of + # "revisions", giving just the most recent revision information for + # each file. unless ( $self->{tables}{$self->tablename("head")} ) { my $tablename = $self->tablename("head"); @@ -2978,6 +3061,7 @@ sub new } # Construct the properties table if required + # - "last_commit" - Used by "sub update". unless ( $self->{tables}{$self->tablename("properties")} ) { my $tablename = $self->tablename("properties"); @@ -2990,6 +3074,11 @@ sub new } # Construct the commitmsgs table if required + # The commitmsgs table is only used for merge commits, since + # "sub update" will only keep one branch of parents. Shortlogs + # for ignored commits (i.e. not on the chosen branch) will be used + # to construct a replacement "collapsed" merge commit message, + # which will be stored in this table. See also "sub commitmessage". unless ( $self->{tables}{$self->tablename("commitmsgs")} ) { my $tablename = $self->tablename("commitmsgs"); @@ -3021,6 +3110,14 @@ sub tablename =head2 update +Bring the database up to date with the latest changes from +the git repository. + +Internal working state is read out of the "head" table and the +"last_commit" property, then it updates "revisions" based on that, and +finally it writes the new internal state back to the "head" table +so it can be used as a starting point the next time update is called. + =cut sub update { @@ -3116,7 +3213,7 @@ sub update my $commitcount = 0; # Load the head table into $head (for cached lookups during the update process) - foreach my $file ( @{$self->gethead()} ) + foreach my $file ( @{$self->gethead(1)} ) { $head->{$file->{name}} = $file; } @@ -3134,17 +3231,18 @@ sub update next; } elsif (@{$commit->{parents}} > 1) { # it is a merge commit, for each parent that is - # not $lastpicked, see if we can get a log + # not $lastpicked (not given a CVS revision number), + # see if we can get a log # from the merge-base to that parent to put it # in the message as a merge summary. my @parents = @{$commit->{parents}}; foreach my $parent (@parents) { - # git-merge-base can potentially (but rarely) throw - # several candidate merge bases. let's assume - # that the first one is the best one. if ($parent eq $lastpicked) { next; } + # git-merge-base can potentially (but rarely) throw + # several candidate merge bases. let's assume + # that the first one is the best one. my $base = eval { safe_pipe_capture('git', 'merge-base', $lastpicked, $parent); @@ -3426,19 +3524,6 @@ sub insert_head $insert_head->execute($name, $revision, $filehash, $commithash, $modified, $author, $mode); } -sub _headrev -{ - my $self = shift; - my $filename = shift; - my $tablename = $self->tablename("head"); - - my $db_query = $self->{dbh}->prepare_cached("SELECT filehash, revision, mode FROM $tablename WHERE name=?",{},1); - $db_query->execute($filename); - my ( $hash, $revision, $mode ) = $db_query->fetchrow_array; - - return ( $hash, $revision, $mode ); -} - sub _get_prop { my $self = shift; @@ -3478,6 +3563,7 @@ sub _set_prop sub gethead { my $self = shift; + my $intRev = shift; my $tablename = $self->tablename("head"); return $self->{gethead_cache} if ( defined ( $self->{gethead_cache} ) ); @@ -3488,6 +3574,10 @@ sub gethead my $tree = []; while ( my $file = $db_query->fetchrow_hashref ) { + if(!$intRev) + { + $file->{revision} = "1.$file->{revision}" + } push @$tree, $file; } @@ -3498,24 +3588,57 @@ sub gethead =head2 getlog +See also gethistorydense(). + =cut sub getlog { my $self = shift; my $filename = shift; + my $revFilter = shift; + my $tablename = $self->tablename("revision"); + # Filters: + # TODO: date, state, or by specific logins filters? + # TODO: Handle comma-separated list of revFilter items, each item + # can be a range [only case currently handled] or individual + # rev or branch or "branch.". + # TODO: Adjust $db_query WHERE clause based on revFilter, instead of + # manually filtering the results of the query? + my ( $minrev, $maxrev ); + if( defined($revFilter) and + $state->{opt}{r} =~ /^(1.(\d+))?(::?)(1.(\d.+))?$/ ) + { + my $control = $3; + $minrev = $2; + $maxrev = $5; + $minrev++ if ( defined($minrev) and $control eq "::" ); + } + my $db_query = $self->{dbh}->prepare_cached("SELECT name, filehash, author, mode, revision, modified, commithash FROM $tablename WHERE name=? ORDER BY revision DESC",{},1); $db_query->execute($filename); + my $totalRevs=0; my $tree = []; while ( my $file = $db_query->fetchrow_hashref ) { + $totalRevs++; + if( defined($minrev) and $file->{revision} < $minrev ) + { + next; + } + if( defined($maxrev) and $file->{revision} > $maxrev ) + { + next; + } + + $file->{revision} = "1." . $file->{revision}; push @$tree, $file; } - return $tree; + return ($tree,$totalRevs); } =head2 getmeta @@ -3534,10 +3657,11 @@ sub getmeta my $tablename_head = $self->tablename("head"); my $db_query; - if ( defined($revision) and $revision =~ /^\d+$/ ) + if ( defined($revision) and $revision =~ /^1\.(\d+)$/ ) { + my ($intRev) = $1; $db_query = $self->{dbh}->prepare_cached("SELECT * FROM $tablename_rev WHERE name=? AND revision=?",{},1); - $db_query->execute($filename, $revision); + $db_query->execute($filename, $intRev); } elsif ( defined($revision) and $revision =~ /^[a-zA-Z0-9]{40}$/ ) { @@ -3548,7 +3672,12 @@ sub getmeta $db_query->execute($filename); } - return $db_query->fetchrow_hashref; + my $meta = $db_query->fetchrow_hashref; + if($meta) + { + $meta->{revision} = "1.$meta->{revision}"; + } + return $meta; } =head2 commitmessage @@ -3583,25 +3712,6 @@ sub commitmessage return $message; } -=head2 gethistory - -This function takes a filename (with path) argument and returns an arrayofarrays -containing revision,filehash,commithash ordered by revision descending - -=cut -sub gethistory -{ - my $self = shift; - my $filename = shift; - my $tablename = $self->tablename("revision"); - - my $db_query; - $db_query = $self->{dbh}->prepare_cached("SELECT revision, filehash, commithash FROM $tablename WHERE name=? ORDER BY revision DESC",{},1); - $db_query->execute($filename); - - return $db_query->fetchall_arrayref; -} - =head2 gethistorydense This function takes a filename (with path) argument and returns an arrayofarrays @@ -3611,6 +3721,8 @@ This version of gethistory skips deleted entries -- so it is useful for annotate The 'dense' part is a reference to a '--dense' option available for git-rev-list and other git tools that depend on it. +See also getlog(). + =cut sub gethistorydense { @@ -3622,7 +3734,15 @@ sub gethistorydense $db_query = $self->{dbh}->prepare_cached("SELECT revision, filehash, commithash FROM $tablename WHERE name=? AND filehash!='deleted' ORDER BY revision DESC",{},1); $db_query->execute($filename); - return $db_query->fetchall_arrayref; + my $result = $db_query->fetchall_arrayref; + + my $i; + for($i=0 ; $i<scalar(@$result) ; $i++) + { + $result->[$i][0]="1." . $result->[$i][0]; + } + + return $result; } =head2 in_array() diff --git a/git-filter-branch.sh b/git-filter-branch.sh index 178e453..5314249 100755 --- a/git-filter-branch.sh +++ b/git-filter-branch.sh @@ -64,37 +64,19 @@ EOF eval "$functions" -# When piped a commit, output a script to set the ident of either -# "author" or "committer +finish_ident() { + # Ensure non-empty id name. + echo "case \"\$GIT_$1_NAME\" in \"\") GIT_$1_NAME=\"\${GIT_$1_EMAIL%%@*}\" && export GIT_$1_NAME;; esac" + # And make sure everything is exported. + echo "export GIT_$1_NAME" + echo "export GIT_$1_EMAIL" + echo "export GIT_$1_DATE" +} set_ident () { - lid="$(echo "$1" | tr "[A-Z]" "[a-z]")" - uid="$(echo "$1" | tr "[a-z]" "[A-Z]")" - pick_id_script=' - /^'$lid' /{ - s/'\''/'\''\\'\'\''/g - h - s/^'$lid' \([^<]*\) <[^>]*> .*$/\1/ - s/'\''/'\''\'\'\''/g - s/.*/GIT_'$uid'_NAME='\''&'\''; export GIT_'$uid'_NAME/p - - g - s/^'$lid' [^<]* <\([^>]*\)> .*$/\1/ - s/'\''/'\''\'\'\''/g - s/.*/GIT_'$uid'_EMAIL='\''&'\''; export GIT_'$uid'_EMAIL/p - - g - s/^'$lid' [^<]* <[^>]*> \(.*\)$/@\1/ - s/'\''/'\''\'\'\''/g - s/.*/GIT_'$uid'_DATE='\''&'\''; export GIT_'$uid'_DATE/p - - q - } - ' - - LANG=C LC_ALL=C sed -ne "$pick_id_script" - # Ensure non-empty id name. - echo "case \"\$GIT_${uid}_NAME\" in \"\") GIT_${uid}_NAME=\"\${GIT_${uid}_EMAIL%%@*}\" && export GIT_${uid}_NAME;; esac" + parse_ident_from_commit author AUTHOR committer COMMITTER + finish_ident AUTHOR + finish_ident COMMITTER } USAGE="[--env-filter <command>] [--tree-filter <command>] @@ -320,10 +302,8 @@ while read commit parents; do git cat-file commit "$commit" >../commit || die "Cannot read commit $commit" - eval "$(set_ident AUTHOR <../commit)" || - die "setting author failed for commit $commit" - eval "$(set_ident COMMITTER <../commit)" || - die "setting committer failed for commit $commit" + eval "$(set_ident <../commit)" || + die "setting author/committer failed for commit $commit" eval "$filter_env" < /dev/null || die "env filter failed: $filter_env" @@ -129,6 +129,25 @@ def p4_has_command(cmd): p.communicate() return p.returncode == 0 +def p4_has_move_command(): + """See if the move command exists, that it supports -k, and that + it has not been administratively disabled. The arguments + must be correct, but the filenames do not have to exist. Use + ones with wildcards so even if they exist, it will fail.""" + + if not p4_has_command("move"): + return False + cmd = p4_build_cmd(["move", "-k", "@from", "@to"]) + p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + (out, err) = p.communicate() + # return code will be 1 in either case + if err.find("Invalid option") >= 0: + return False + if err.find("disabled") >= 0: + return False + # assume it failed because @... was invalid changelist + return True + def system(cmd): expand = isinstance(cmd,basestring) if verbose: @@ -169,6 +188,29 @@ def p4_reopen(type, f): def p4_move(src, dest): p4_system(["move", "-k", wildcard_encode(src), wildcard_encode(dest)]) +def p4_describe(change): + """Make sure it returns a valid result by checking for + the presence of field "time". Return a dict of the + results.""" + + ds = p4CmdList(["describe", "-s", str(change)]) + if len(ds) != 1: + die("p4 describe -s %d did not return 1 result: %s" % (change, str(ds))) + + d = ds[0] + + if "p4ExitCode" in d: + die("p4 describe -s %d exited with %d: %s" % (change, d["p4ExitCode"], + str(d))) + if "code" in d: + if d["code"] == "error": + die("p4 describe -s %d returned error code: %s" % (change, str(d))) + + if "time" not in d: + die("p4 describe -s %d returned no \"time\": %s" % (change, str(d))) + + return d + # # Canonicalize the p4 type and return a tuple of the # base type, plus any modifiers. See "p4 help filetypes" @@ -871,7 +913,7 @@ class P4Submit(Command, P4UserMap): self.conflict_behavior = None self.isWindows = (platform.system() == "Windows") self.exportLabels = False - self.p4HasMoveCommand = p4_has_command("move") + self.p4HasMoveCommand = p4_has_move_command() def check(self): if len(p4CmdList("opened ...")) > 0: @@ -2097,6 +2139,29 @@ class P4Sync(Command, P4UserMap): # handle another chunk of streaming data def streamP4FilesCb(self, marshalled): + # catch p4 errors and complain + err = None + if "code" in marshalled: + if marshalled["code"] == "error": + if "data" in marshalled: + err = marshalled["data"].rstrip() + if err: + f = None + if self.stream_have_file_info: + if "depotFile" in self.stream_file: + f = self.stream_file["depotFile"] + # force a failure in fast-import, else an empty + # commit will be made + self.gitStream.write("\n") + self.gitStream.write("die-now\n") + self.gitStream.close() + # ignore errors, but make sure it exits first + self.importProcess.wait() + if f: + die("Error from p4 print for %s: %s" % (f, err)) + else: + die("Error from p4 print: %s" % err) + if marshalled.has_key('depotFile') and self.stream_have_file_info: # start of a new file - output the old one first self.streamOneP4File(self.stream_file, self.stream_contents) @@ -2341,7 +2406,7 @@ class P4Sync(Command, P4UserMap): try: tmwhen = time.strptime(labelDetails['Update'], "%Y/%m/%d %H:%M:%S") except ValueError: - print "Could not convert label time %s" % labelDetail['Update'] + print "Could not convert label time %s" % labelDetails['Update'] tmwhen = 1 when = int(time.mktime(tmwhen)) @@ -2543,7 +2608,7 @@ class P4Sync(Command, P4UserMap): def importChanges(self, changes): cnt = 1 for change in changes: - description = p4Cmd(["describe", str(change)]) + description = p4_describe(change) self.updateOptionDict(description) if not self.silent: @@ -2667,14 +2732,8 @@ class P4Sync(Command, P4UserMap): # Use time from top-most change so that all git p4 clones of # the same p4 repo have the same commit SHA1s. - res = p4CmdList("describe -s %d" % newestRevision) - newestTime = None - for r in res: - if r.has_key('time'): - newestTime = int(r['time']) - if newestTime is None: - die("\"describe -s\" on newest change %d did not give a time") - details["time"] = newestTime + res = p4_describe(newestRevision) + details["time"] = res["time"] self.updateOptionDict(details) try: @@ -2864,12 +2923,13 @@ class P4Sync(Command, P4UserMap): self.tz = "%+03d%02d" % (- time.timezone / 3600, ((- time.timezone % 3600) / 60)) - importProcess = subprocess.Popen(["git", "fast-import"], - stdin=subprocess.PIPE, stdout=subprocess.PIPE, - stderr=subprocess.PIPE); - self.gitOutput = importProcess.stdout - self.gitStream = importProcess.stdin - self.gitError = importProcess.stderr + self.importProcess = subprocess.Popen(["git", "fast-import"], + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE); + self.gitOutput = self.importProcess.stdout + self.gitStream = self.importProcess.stdin + self.gitError = self.importProcess.stderr if revision: self.importHeadRevision(revision) @@ -2929,7 +2989,7 @@ class P4Sync(Command, P4UserMap): self.importP4Labels(self.gitStream, missingP4Labels) self.gitStream.close() - if importProcess.wait() != 0: + if self.importProcess.wait() != 0: die("fast-import failed: %s" % self.gitError.read()) self.gitOutput.close() self.gitError.close() @@ -3128,7 +3188,6 @@ def main(): printUsage(commands.keys()) sys.exit(2) - cmd = "" cmdName = sys.argv[1] try: klass = commands[cmdName] diff --git a/git-remote-testgit b/git-remote-testgit new file mode 100755 index 0000000..b395c8d --- /dev/null +++ b/git-remote-testgit @@ -0,0 +1,90 @@ +#!/usr/bin/env bash +# Copyright (c) 2012 Felipe Contreras + +alias=$1 +url=$2 + +dir="$GIT_DIR/testgit/$alias" +prefix="refs/testgit/$alias" + +default_refspec="refs/heads/*:${prefix}/heads/*" + +refspec="${GIT_REMOTE_TESTGIT_REFSPEC-$default_refspec}" + +test -z "$refspec" && prefix="refs" + +export GIT_DIR="$url/.git" + +mkdir -p "$dir" + +if test -z "$GIT_REMOTE_TESTGIT_NO_MARKS" +then + gitmarks="$dir/git.marks" + testgitmarks="$dir/testgit.marks" + test -e "$gitmarks" || >"$gitmarks" + test -e "$testgitmarks" || >"$testgitmarks" + testgitmarks_args=( "--"{import,export}"-marks=$testgitmarks" ) +fi + +while read line +do + case $line in + capabilities) + echo 'import' + echo 'export' + test -n "$refspec" && echo "refspec $refspec" + if test -n "$gitmarks" + then + echo "*import-marks $gitmarks" + echo "*export-marks $gitmarks" + fi + echo + ;; + list) + git for-each-ref --format='? %(refname)' 'refs/heads/' + head=$(git symbolic-ref HEAD) + echo "@$head HEAD" + echo + ;; + import*) + # read all import lines + while true + do + ref="${line#* }" + refs="$refs $ref" + read line + test "${line%% *}" != "import" && break + done + + if test -n "$gitmarks" + then + echo "feature import-marks=$gitmarks" + echo "feature export-marks=$gitmarks" + fi + echo "feature done" + git fast-export "${testgitmarks_args[@]}" $refs | + sed -e "s#refs/heads/#${prefix}/heads/#g" + echo "done" + ;; + export) + before=$(git for-each-ref --format='%(refname) %(objectname)') + + git fast-import "${testgitmarks_args[@]}" --quiet + + after=$(git for-each-ref --format='%(refname) %(objectname)') + + # 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 + do + test $a == $b && continue + echo "ok $ref" + done + + echo + ;; + '') + exit + ;; + esac +done diff --git a/git-remote-testgit.py b/git-remote-testpy.py index 5f3ebd2..ade797b 100644 --- a/git-remote-testgit.py +++ b/git-remote-testpy.py @@ -91,7 +91,7 @@ def do_capabilities(repo, args): if not os.path.exists(dirname): os.makedirs(dirname) - path = os.path.join(dirname, 'testgit.marks') + path = os.path.join(dirname, 'git.marks') print "*export-marks %s" % path if os.path.exists(path): diff --git a/git-send-email.perl b/git-send-email.perl index aea66a0..94c7f76 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -56,6 +56,7 @@ git send-email [options] <file | directory | rev-list options > --in-reply-to <str> * Email "In-Reply-To:" --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 Sending: @@ -198,6 +199,7 @@ my ($identity, $aliasfiletype, @alias_files, $smtp_domain); my ($validate, $confirm); my (@suppress_cc); my ($auto_8bit_encoding); +my ($compose_encoding); my ($debug_net_smtp) = 0; # Net::SMTP, see send_message() @@ -231,6 +233,7 @@ my %config_settings = ( "confirm" => \$confirm, "from" => \$sender, "assume8bitencoding" => \$auto_8bit_encoding, + "composeencoding" => \$compose_encoding, ); my %config_path_settings = ( @@ -315,6 +318,7 @@ my $rc = GetOptions("h" => \$help, "validate!" => \$validate, "format-patch!" => \$format_patch, "8bit-encoding=s" => \$auto_8bit_encoding, + "compose-encoding=s" => \$compose_encoding, "force" => \$force, ); @@ -632,6 +636,9 @@ EOT my $need_8bit_cte = file_has_nonascii($compose_filename); my $in_body = 0; my $summary_empty = 1; + if (!defined $compose_encoding) { + $compose_encoding = "UTF-8"; + } while(<$c>) { next if m/^GIT:/; if ($in_body) { @@ -641,7 +648,7 @@ EOT if ($need_8bit_cte) { print $c2 "MIME-Version: 1.0\n", "Content-Type: text/plain; ", - "charset=UTF-8\n", + "charset=$compose_encoding\n", "Content-Transfer-Encoding: 8bit\n"; } } elsif (/^MIME-Version:/i) { @@ -650,9 +657,7 @@ EOT $initial_subject = $1; my $subject = $initial_subject; $_ = "Subject: " . - ($subject =~ /[^[:ascii:]]/ ? - quote_rfc2047($subject) : - $subject) . + quote_subject($subject, $compose_encoding) . "\n"; } elsif (/^In-Reply-To:\s*(.+)\s*$/i) { $initial_reply_to = $1; @@ -748,16 +753,11 @@ if (!$force) { } } -my $prompting = 0; if (!defined $sender) { $sender = $repoauthor || $repocommitter || ''; - $sender = ask("Who should the emails appear to be from? [$sender] ", - default => $sender, - valid_re => qr/\@.*\./, confirm_only => 1); - print "Emails will be sent from: ", $sender, "\n"; - $prompting++; } +my $prompting = 0; if (!@initial_to && !defined $to_cmd) { my $to = ask("Who should the emails be sent to (if any)? ", default => "", @@ -781,9 +781,11 @@ sub expand_one_alias { } @initial_to = expand_aliases(@initial_to); -@initial_to = (map { sanitize_address($_) } @initial_to); +@initial_to = validate_address_list(sanitize_address_list(@initial_to)); @initial_cc = expand_aliases(@initial_cc); +@initial_cc = validate_address_list(sanitize_address_list(@initial_cc)); @bcclist = expand_aliases(@bcclist); +@bcclist = validate_address_list(sanitize_address_list(@bcclist)); if ($thread && !defined $initial_reply_to && $prompting) { $initial_reply_to = ask( @@ -826,12 +828,45 @@ sub extract_valid_address { $address =~ s/^\s*<(.*)>\s*$/$1/; if ($have_email_valid) { return scalar Email::Valid->address($address); - } else { - # less robust/correct than the monster regexp in Email::Valid, - # but still does a 99% job, and one less dependency - $address =~ /($local_part_regexp\@$domain_regexp)/; - return $1; } + + # less robust/correct than the monster regexp in Email::Valid, + # but still does a 99% job, and one less dependency + return $1 if $address =~ /($local_part_regexp\@$domain_regexp)/; + return undef; +} + +sub extract_valid_address_or_die { + my $address = shift; + $address = extract_valid_address($address); + die "error: unable to extract a valid address from: $address\n" + if !$address; + return $address; +} + +sub validate_address { + my $address = shift; + while (!extract_valid_address($address)) { + print STDERR "error: unable to extract a valid address from: $address\n"; + $_ = ask("What to do with this address? ([q]uit|[d]rop|[e]dit): ", + valid_re => qr/^(?:quit|q|drop|d|edit|e)/i, + default => 'q'); + if (/^d/i) { + return undef; + } elsif (/^q/i) { + cleanup_compose_files(); + exit(0); + } + $address = ask("Who should the email be sent to (if any)? ", + default => "", + valid_re => qr/\@.*\./, confirm_only => 1); + } + return $address; +} + +sub validate_address_list { + return (grep { defined $_ } + map { validate_address($_) } @_); } # Usually don't need to change anything below here. @@ -900,9 +935,29 @@ sub is_rfc2047_quoted { $s =~ m/^(?:"[[:ascii:]]*"|=\?$token\?$token\?$encoded_text\?=)$/o; } +sub subject_needs_rfc2047_quoting { + my $s = shift; + + return ($s =~ /[^[:ascii:]]/) || ($s =~ /=\?/); +} + +sub quote_subject { + local $subject = shift; + my $encoding = shift || 'UTF-8'; + + if (subject_needs_rfc2047_quoting($subject)) { + return quote_rfc2047($subject, $encoding); + } + return $subject; +} + # use the simplest quoting being able to handle the recipient sub sanitize_address { my ($recipient) = @_; + + # remove garbage after email address + $recipient =~ s/(.*>).*$/$1/; + my ($recipient_name, $recipient_addr) = ($recipient =~ /^(.*?)\s*(<.*)/); if (not $recipient_name) { @@ -930,6 +985,10 @@ sub sanitize_address { } +sub sanitize_address_list { + return (map { sanitize_address($_) } @_); +} + # Returns the local Fully Qualified Domain Name (FQDN) if available. # # Tightly configured MTAa require that a caller sends a real DNS @@ -992,14 +1051,13 @@ sub maildomain { sub send_message { my @recipients = unique_email_list(@to); - @cc = (grep { my $cc = extract_valid_address($_); + @cc = (grep { my $cc = extract_valid_address_or_die($_); not grep { $cc eq $_ || $_ =~ /<\Q${cc}\E>$/ } @recipients } - map { sanitize_address($_) } @cc); my $to = join (",\n\t", @recipients); @recipients = unique_email_list(@recipients,@cc,@bcclist); - @recipients = (map { extract_valid_address($_) } @recipients); + @recipients = (map { extract_valid_address_or_die($_) } @recipients); my $date = format_2822_time($time++); my $gitversion = '@@GIT_VERSION@@'; if ($gitversion =~ m/..GIT_VERSION../) { @@ -1242,7 +1300,7 @@ foreach my $t (@files) { foreach my $addr (parse_address_line($1)) { printf("(mbox) Adding to: %s from line '%s'\n", $addr, $_) unless $quiet; - push @to, sanitize_address($addr); + push @to, $addr; } } elsif (/^Cc:\s+(.*)$/) { @@ -1321,7 +1379,7 @@ foreach my $t (@files) { } if ($broken_encoding{$t} && !is_rfc2047_quoted($subject)) { - $subject = quote_rfc2047($subject, $auto_8bit_encoding); + $subject = quote_subject($subject, $auto_8bit_encoding); } if (defined $author and $author ne $sender) { @@ -1351,6 +1409,9 @@ foreach my $t (@files) { ($confirm =~ /^(?:auto|compose)$/ && $compose && $message_num == 1)); $needs_confirm = "inform" if ($needs_confirm && $confirm_unconfigured && @cc); + @to = validate_address_list(sanitize_address_list(@to)); + @cc = validate_address_list(sanitize_address_list(@cc)); + @to = (@initial_to, @to); @cc = (@initial_cc, @cc); @@ -1406,14 +1467,10 @@ sub unique_email_list { my @emails; foreach my $entry (@_) { - if (my $clean = extract_valid_address($entry)) { - $seen{$clean} ||= 0; - next if $seen{$clean}++; - push @emails, $entry; - } else { - print STDERR "W: unable to extract a valid address", - " from: $entry\n"; - } + my $clean = extract_valid_address_or_die($entry); + $seen{$clean} ||= 0; + next if $seen{$clean}++; + push @emails, $entry; } return @emails; } diff --git a/git-sh-setup.sh b/git-sh-setup.sh index ee0e0bc..795edd2 100644 --- a/git-sh-setup.sh +++ b/git-sh-setup.sh @@ -12,8 +12,11 @@ # But we protect ourselves from such a user mistake nevertheless. unset CDPATH -# Similarly for IFS -unset IFS +# Similarly for IFS, but some shells (e.g. FreeBSD 7.2) are buggy and +# do not equate an unset IFS with IFS with the default, so here is +# an explicit SP HT LF. +IFS=' +' git_broken_path_fix () { case ":$PATH:" in @@ -191,28 +194,52 @@ require_clean_work_tree () { fi } +# Generate a sed script to parse identities from a commit. +# +# Reads the commit from stdin, which should be in raw format (e.g., from +# cat-file or "--pretty=raw"). +# +# The first argument specifies the ident line to parse (e.g., "author"), and +# the second specifies the environment variable to put it in (e.g., "AUTHOR" +# for "GIT_AUTHOR_*"). Multiple pairs can be given to parse author and +# committer. +pick_ident_script () { + while test $# -gt 0 + do + lid=$1; shift + uid=$1; shift + printf '%s' " + /^$lid /{ + s/'/'\\\\''/g + h + s/^$lid "'\([^<]*\) <[^>]*> .*$/\1/'" + s/.*/GIT_${uid}_NAME='&'/p + + g + s/^$lid "'[^<]* <\([^>]*\)> .*$/\1/'" + s/.*/GIT_${uid}_EMAIL='&'/p + + g + s/^$lid "'[^<]* <[^>]*> \(.*\)$/@\1/'" + s/.*/GIT_${uid}_DATE='&'/p + } + " + done + echo '/^$/q' +} + +# Create a pick-script as above and feed it to sed. Stdout is suitable for +# feeding to eval. +parse_ident_from_commit () { + LANG=C LC_ALL=C sed -ne "$(pick_ident_script "$@")" +} + +# Parse the author from a commit given as an argument. Stdout is suitable for +# feeding to eval to set the usual GIT_* ident variables. get_author_ident_from_commit () { - pick_author_script=' - /^author /{ - s/'\''/'\''\\'\'\''/g - h - s/^author \([^<]*\) <[^>]*> .*$/\1/ - s/.*/GIT_AUTHOR_NAME='\''&'\''/p - - g - s/^author [^<]* <\([^>]*\)> .*$/\1/ - s/.*/GIT_AUTHOR_EMAIL='\''&'\''/p - - g - s/^author [^<]* <[^>]*> \(.*\)$/@\1/ - s/.*/GIT_AUTHOR_DATE='\''&'\''/p - - q - } - ' encoding=$(git config i18n.commitencoding || echo UTF-8) git show -s --pretty=raw --encoding="$encoding" "$1" -- | - LANG=C LC_ALL=C sed -ne "$pick_author_script" + parse_ident_from_commit author AUTHOR } # Clear repo-local GIT_* environment variables. Useful when switching to diff --git a/git-submodule.sh b/git-submodule.sh index 02f82e9..22ec5b6 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -5,13 +5,13 @@ # Copyright (c) 2007 Lars Hjemli dashless=$(basename "$0" | sed -e 's/-/ /') -USAGE="[--quiet] add [-b <branch>] [-f|--force] [--reference <repository>] [--] <repository> [<path>] +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] update [--init] [-N|--no-fetch] [-f|--force] [--rebase] [--reference <repository>] [--merge] [--recursive] [--] [<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> - or: $dashless [--quiet] sync [--] [<path>...]" + or: $dashless [--quiet] sync [--recursive] [--] [<path>...]" OPTIONS_SPEC= . git-sh-setup . git-sh-i18n @@ -26,9 +26,11 @@ cached= recursive= init= files= +remote= nofetch= update= prefix= +custom_name= # The function takes at most 2 arguments. The first argument is the # URL that navigates to the submodule origin repo. When relative, this URL @@ -152,6 +154,32 @@ die_if_unmatched () } # +# Print a submodule configuration setting +# +# $1 = submodule name +# $2 = option name +# $3 = default value +# +# Checks in the usual git-config places first (for overrides), +# otherwise it falls back on .gitmodules. This allows you to +# distribute project-wide defaults in .gitmodules, while still +# customizing individual repositories if necessary. If the option is +# not in .gitmodules either, print a default value. +# +get_submodule_config () { + name="$1" + option="$2" + default="$3" + value=$(git config submodule."$name"."$option") + if test -z "$value" + then + value=$(git config -f .gitmodules submodule."$name"."$option") + fi + printf '%s' "${value:-$default}" +} + + +# # Map submodule path to submodule name # # $1 = path @@ -179,8 +207,9 @@ module_name() module_clone() { sm_path=$1 - url=$2 - reference="$3" + name=$2 + url=$3 + reference="$4" quiet= if test -n "$GIT_QUIET" then @@ -189,8 +218,6 @@ module_clone() gitdir= gitdir_base= - name=$(module_name "$sm_path" 2>/dev/null) - test -n "$name" || name="$sm_path" base_name=$(dirname "$name") gitdir=$(git rev-parse --git-dir) @@ -270,6 +297,10 @@ cmd_add() ;; --reference=*) reference="$1" + ;; + --name) + case "$2" in '') usage ;; esac + custom_name=$2 shift ;; --) @@ -336,6 +367,13 @@ Use -f if you really want to add it." >&2 exit 1 fi + if test -n "$custom_name" + then + sm_name="$custom_name" + else + sm_name="$sm_path" + fi + # perhaps the path exists and is already a git repo, else clone it if test -e "$sm_path" then @@ -347,8 +385,21 @@ Use -f if you really want to add it." >&2 fi else - - module_clone "$sm_path" "$realrepo" "$reference" || exit + if test -d ".git/modules/$sm_name" + then + if test -z "$force" + then + echo >&2 "$(eval_gettext "A git directory for '\$sm_name' is found locally with remote(s):")" + GIT_DIR=".git/modules/$sm_name" GIT_WORK_TREE=. git remote -v | grep '(fetch)' | sed -e s,^," ", -e s,' (fetch)',, >&2 + echo >&2 "$(eval_gettext "If you want to reuse this local git directory instead of cloning again from")" + echo >&2 " $realrepo" + echo >&2 "$(eval_gettext "use the '--force' option. If the local git directory is not the correct repo")" + die "$(eval_gettext "or you are unsure what this means choose another name with the '--name' option.")" + else + echo "$(eval_gettext "Reactivating local git directory for submodule '\$sm_name'.")" + fi + fi + module_clone "$sm_path" "$sm_name" "$realrepo" "$reference" || exit ( clear_local_git_env cd "$sm_path" && @@ -359,13 +410,17 @@ Use -f if you really want to add it." >&2 esac ) || die "$(eval_gettext "Unable to checkout submodule '\$sm_path'")" fi - git config submodule."$sm_path".url "$realrepo" + git config submodule."$sm_name".url "$realrepo" git add $force "$sm_path" || die "$(eval_gettext "Failed to add submodule '\$sm_path'")" - git config -f .gitmodules submodule."$sm_path".path "$sm_path" && - git config -f .gitmodules submodule."$sm_path".url "$repo" && + git config -f .gitmodules submodule."$sm_name".path "$sm_path" && + git config -f .gitmodules submodule."$sm_name".url "$repo" && + if test -n "$branch" + then + git config -f .gitmodules submodule."$sm_name".branch "$branch" + fi && git add --force .gitmodules || die "$(eval_gettext "Failed to register submodule '\$sm_path'")" } @@ -509,6 +564,9 @@ cmd_update() -i|--init) init=1 ;; + --remote) + remote=1 + ;; -N|--no-fetch) nofetch=1 ;; @@ -569,6 +627,7 @@ cmd_update() fi name=$(module_name "$sm_path") || exit url=$(git config submodule."$name".url) + branch=$(get_submodule_config "$name" branch master) if ! test -z "$update" then update_module=$update @@ -594,7 +653,7 @@ Maybe you want to use 'update --init'?")" if ! test -d "$sm_path"/.git -o -f "$sm_path"/.git then - module_clone "$sm_path" "$url" "$reference"|| exit + module_clone "$sm_path" "$name" "$url" "$reference" || exit cloned_modules="$cloned_modules;$name" subsha1= else @@ -603,6 +662,20 @@ Maybe you want to use 'update --init'?")" die "$(eval_gettext "Unable to find current revision in submodule path '\$sm_path'")" fi + if test -n "$remote" + then + if test -z "$nofetch" + then + # Fetch remote before determining tracking $sha1 + (clear_local_git_env; cd "$sm_path" && git-fetch) || + die "$(eval_gettext "Unable to fetch in submodule path '\$sm_path'")" + fi + remote_name=$(clear_local_git_env; cd "$sm_path" && get_default_remote) + sha1=$(clear_local_git_env; cd "$sm_path" && + git rev-parse --verify "${remote_name}/${branch}") || + die "$(eval_gettext "Unable to find current ${remote_name}/${branch} revision in submodule path '\$sm_path'")" + fi + if test "$subsha1" != "$sha1" -o -n "$force" then subforce=$force @@ -926,7 +999,6 @@ cmd_summary() { cmd_status() { # parse $args after "submodule ... status". - orig_flags= while test $# -ne 0 do case "$1" in @@ -950,7 +1022,6 @@ cmd_status() break ;; esac - orig_flags="$orig_flags $(git rev-parse --sq-quote "$1")" shift done @@ -990,7 +1061,7 @@ cmd_status() prefix="$displaypath/" clear_local_git_env cd "$sm_path" && - eval cmd_status "$orig_args" + eval cmd_status ) || die "$(eval_gettext "Failed to recurse into submodule path '\$sm_path'")" fi @@ -1010,6 +1081,10 @@ cmd_sync() GIT_QUIET=1 shift ;; + --recursive) + recursive=1 + shift + ;; --) shift break @@ -1051,7 +1126,7 @@ cmd_sync() if git config "submodule.$name.url" >/dev/null 2>/dev/null then - say "$(eval_gettext "Synchronizing submodule url for '\$name'")" + say "$(eval_gettext "Synchronizing submodule url for '\$prefix\$sm_path'")" git config submodule."$name".url "$super_config_url" if test -e "$sm_path"/.git @@ -1061,6 +1136,12 @@ cmd_sync() cd "$sm_path" remote=$(get_default_remote) git config remote."$remote".url "$sub_origin_url" + + if test -n "$recursive" + then + prefix="$prefix$sm_path/" + eval cmd_sync + fi ) fi fi @@ -17,39 +17,6 @@ const char git_more_info_string[] = static struct startup_info git_startup_info; static int use_pager = -1; -struct pager_config { - const char *cmd; - int want; - char *value; -}; - -static int pager_command_config(const char *var, const char *value, void *data) -{ - struct pager_config *c = data; - if (!prefixcmp(var, "pager.") && !strcmp(var + 6, c->cmd)) { - int b = git_config_maybe_bool(var, value); - if (b >= 0) - c->want = b; - else { - c->want = 1; - c->value = xstrdup(value); - } - } - return 0; -} - -/* returns 0 for "no pager", 1 for "use pager", and -1 for "not specified" */ -int check_pager_config(const char *cmd) -{ - struct pager_config c; - c.cmd = cmd; - c.want = -1; - c.value = NULL; - git_config(pager_command_config, &c); - if (c.value) - pager_program = c.value; - return c.want; -} static void commit_pager_choice(void) { switch (use_pager) { @@ -168,6 +135,14 @@ static int handle_options(const char ***argv, int *argc, int *envchanged) git_config_push_parameter((*argv)[1]); (*argv)++; (*argc)--; + } else if (!strcmp(cmd, "--literal-pathspecs")) { + setenv(GIT_LITERAL_PATHSPECS_ENVIRONMENT, "1", 1); + if (envchanged) + *envchanged = 1; + } else if (!strcmp(cmd, "--no-literal-pathspecs")) { + setenv(GIT_LITERAL_PATHSPECS_ENVIRONMENT, "0", 1); + if (envchanged) + *envchanged = 1; } else { fprintf(stderr, "Unknown option: %s\n", cmd); usage(git_usage_string); diff --git a/git_remote_helpers/git/importer.py b/git_remote_helpers/git/importer.py index 5c6b595..e28cc8f 100644 --- a/git_remote_helpers/git/importer.py +++ b/git_remote_helpers/git/importer.py @@ -39,7 +39,7 @@ class GitImporter(object): gitdir = self.repo.gitpath else: gitdir = os.path.abspath(os.path.join(dirname, '.git')) - path = os.path.abspath(os.path.join(dirname, 'git.marks')) + path = os.path.abspath(os.path.join(dirname, 'testgit.marks')) if not os.path.exists(dirname): os.makedirs(dirname) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index e8812fa..656b324 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -540,7 +540,7 @@ our %feature = ( # $feature{'remote_heads'}{'default'} = [1]; # To have project specific config enable override in $GITWEB_CONFIG # $feature{'remote_heads'}{'override'} = 1; - # and in project config gitweb.remote_heads = 0|1; + # and in project config gitweb.remoteheads = 0|1; 'remote_heads' => { 'sub' => sub { feature_bool('remote_heads', @_) }, 'override' => 0, @@ -2696,12 +2696,15 @@ sub git_get_project_config { # only subsection, if exists, is case sensitive, # and not lowercased by 'git config -z -l' if (my ($hi, $mi, $lo) = ($key =~ /^([^.]*)\.(.*)\.([^.]*)$/)) { + $lo =~ s/_//g; $key = join(".", lc($hi), $mi, lc($lo)); + return if ($lo =~ /\W/ || $hi =~ /\W/); } else { $key = lc($key); + $key =~ s/_//g; + return if ($key =~ /\W/); } $key =~ s/^gitweb\.//; - return if ($key =~ m/\W/); # type sanity check if (defined $type) { @@ -5525,23 +5528,30 @@ sub fill_project_list_info { sub sort_projects_list { my ($projlist, $order) = @_; - my @projects; - my %order_info = ( - project => { key => 'path', type => 'str' }, - descr => { key => 'descr_long', type => 'str' }, - owner => { key => 'owner', type => 'str' }, - age => { key => 'age', type => 'num' } - ); - my $oi = $order_info{$order}; - return @$projlist unless defined $oi; - if ($oi->{'type'} eq 'str') { - @projects = sort {$a->{$oi->{'key'}} cmp $b->{$oi->{'key'}}} @$projlist; - } else { - @projects = sort {$a->{$oi->{'key'}} <=> $b->{$oi->{'key'}}} @$projlist; + sub order_str { + my $key = shift; + return sub { $a->{$key} cmp $b->{$key} }; } - return @projects; + sub order_num_then_undef { + my $key = shift; + return sub { + defined $a->{$key} ? + (defined $b->{$key} ? $a->{$key} <=> $b->{$key} : -1) : + (defined $b->{$key} ? 1 : 0) + }; + } + + my %orderings = ( + project => order_str('path'), + descr => order_str('descr_long'), + owner => order_str('owner'), + age => order_num_then_undef('age'), + ); + + my $ordering = $orderings{$order}; + return defined $ordering ? sort $ordering @$projlist : @$projlist; } # returns a hash of categories, containing the list of project @@ -1227,7 +1227,7 @@ void graph_show_commit(struct git_graph *graph) if (!graph) return; - while (!shown_commit_line) { + while (!shown_commit_line && !graph_is_commit_finished(graph)) { shown_commit_line = graph_next_line(graph, &msgbuf); fwrite(msgbuf.buf, sizeof(char), msgbuf.len, stdout); if (!shown_commit_line) diff --git a/http-push.c b/http-push.c index 8701c12..9923441 100644 --- a/http-push.c +++ b/http-push.c @@ -172,28 +172,7 @@ enum dav_header_flag { static char *xml_entities(const char *s) { struct strbuf buf = STRBUF_INIT; - while (*s) { - size_t len = strcspn(s, "\"<>&"); - strbuf_add(&buf, s, len); - s += len; - switch (*s) { - case '"': - strbuf_addstr(&buf, """); - break; - case '<': - strbuf_addstr(&buf, "<"); - break; - case '>': - strbuf_addstr(&buf, ">"); - break; - case '&': - strbuf_addstr(&buf, "&"); - break; - case 0: - return strbuf_detach(&buf, NULL); - } - s++; - } + strbuf_addstr_xml_quoted(&buf, s); return strbuf_detach(&buf, NULL); } @@ -236,6 +236,7 @@ static int has_cert_password(void) return 0; if (!cert_auth.password) { cert_auth.protocol = xstrdup("cert"); + cert_auth.username = xstrdup(""); cert_auth.path = xstrdup(ssl_cert); credential_fill(&cert_auth); } @@ -757,8 +758,7 @@ char *get_remote_object_url(const char *url, const char *hex, return strbuf_detach(&buf, NULL); } -int handle_curl_result(struct active_request_slot *slot, - struct slot_results *results) +int handle_curl_result(struct slot_results *results) { if (results->curl_result == CURLE_OK) { credential_approve(&http_auth); @@ -771,7 +771,6 @@ int handle_curl_result(struct active_request_slot *slot, return HTTP_NOAUTH; } else { credential_fill(&http_auth); - init_curl_http_auth(slot->curl); return HTTP_REAUTH; } } else { @@ -833,7 +832,7 @@ static int http_request(const char *url, void *result, int target, int options) if (start_active_slot(slot)) { run_active_slot(slot); - ret = handle_curl_result(slot, &results); + ret = handle_curl_result(&results); } else { error("Unable to start HTTP request for %s", url); ret = HTTP_START_FAILED; @@ -78,8 +78,7 @@ extern int start_active_slot(struct active_request_slot *slot); extern void run_active_slot(struct active_request_slot *slot); extern void finish_active_slot(struct active_request_slot *slot); extern void finish_all_active_slots(void); -extern int handle_curl_result(struct active_request_slot *slot, - struct slot_results *results); +extern int handle_curl_result(struct slot_results *results); #ifdef USE_CURL_MULTI extern void fill_active_slots(void); @@ -10,7 +10,12 @@ static struct strbuf git_default_name = STRBUF_INIT; static struct strbuf git_default_email = STRBUF_INIT; static char git_default_date[50]; -int user_ident_explicitly_given; + +#define IDENT_NAME_GIVEN 01 +#define IDENT_MAIL_GIVEN 02 +#define IDENT_ALL_GIVEN (IDENT_NAME_GIVEN|IDENT_MAIL_GIVEN) +static int committer_ident_explicitly_given; +static int author_ident_explicitly_given; #ifdef NO_GECOS_IN_PWENT #define get_gecos(ignored) "&" @@ -109,7 +114,8 @@ const char *ident_default_email(void) if (email && email[0]) { strbuf_addstr(&git_default_email, email); - user_ident_explicitly_given |= IDENT_MAIL_GIVEN; + committer_ident_explicitly_given |= IDENT_MAIL_GIVEN; + author_ident_explicitly_given |= IDENT_MAIL_GIVEN; } else copy_email(xgetpwuid_self(), &git_default_email); strbuf_trim(&git_default_email); @@ -327,6 +333,10 @@ const char *fmt_name(const char *name, const char *email) const char *git_author_info(int flag) { + if (getenv("GIT_AUTHOR_NAME")) + author_ident_explicitly_given |= IDENT_NAME_GIVEN; + if (getenv("GIT_AUTHOR_EMAIL")) + author_ident_explicitly_given |= IDENT_MAIL_GIVEN; return fmt_ident(getenv("GIT_AUTHOR_NAME"), getenv("GIT_AUTHOR_EMAIL"), getenv("GIT_AUTHOR_DATE"), @@ -336,16 +346,16 @@ const char *git_author_info(int flag) const char *git_committer_info(int flag) { if (getenv("GIT_COMMITTER_NAME")) - user_ident_explicitly_given |= IDENT_NAME_GIVEN; + committer_ident_explicitly_given |= IDENT_NAME_GIVEN; if (getenv("GIT_COMMITTER_EMAIL")) - user_ident_explicitly_given |= IDENT_MAIL_GIVEN; + committer_ident_explicitly_given |= IDENT_MAIL_GIVEN; return fmt_ident(getenv("GIT_COMMITTER_NAME"), getenv("GIT_COMMITTER_EMAIL"), getenv("GIT_COMMITTER_DATE"), flag); } -int user_ident_sufficiently_given(void) +static int ident_is_sufficient(int user_ident_explicitly_given) { #ifndef WINDOWS return (user_ident_explicitly_given & IDENT_MAIL_GIVEN); @@ -354,6 +364,16 @@ int user_ident_sufficiently_given(void) #endif } +int committer_ident_sufficiently_given(void) +{ + return ident_is_sufficient(committer_ident_explicitly_given); +} + +int author_ident_sufficiently_given(void) +{ + return ident_is_sufficient(author_ident_explicitly_given); +} + int git_ident_config(const char *var, const char *value, void *data) { if (!strcmp(var, "user.name")) { @@ -361,7 +381,8 @@ int git_ident_config(const char *var, const char *value, void *data) return config_error_nonbool(var); strbuf_reset(&git_default_name); strbuf_addstr(&git_default_name, value); - user_ident_explicitly_given |= IDENT_NAME_GIVEN; + committer_ident_explicitly_given |= IDENT_NAME_GIVEN; + author_ident_explicitly_given |= IDENT_NAME_GIVEN; return 0; } @@ -370,7 +391,8 @@ int git_ident_config(const char *var, const char *value, void *data) return config_error_nonbool(var); strbuf_reset(&git_default_email); strbuf_addstr(&git_default_email, value); - user_ident_explicitly_given |= IDENT_MAIL_GIVEN; + committer_ident_explicitly_given |= IDENT_MAIL_GIVEN; + author_ident_explicitly_given |= IDENT_MAIL_GIVEN; return 0; } diff --git a/imap-send.c b/imap-send.c index d42e471..e521e2f 100644 --- a/imap-send.c +++ b/imap-send.c @@ -69,8 +69,7 @@ struct store { }; struct msg_data { - char *data; - int len; + struct strbuf data; unsigned char flags; }; @@ -1264,45 +1263,49 @@ static int imap_make_flags(int flags, char *buf) return d; } -static void lf_to_crlf(struct msg_data *msg) +static void lf_to_crlf(struct strbuf *msg) { + size_t new_len; char *new; int i, j, lfnum = 0; - if (msg->data[0] == '\n') + if (msg->buf[0] == '\n') lfnum++; for (i = 1; i < msg->len; i++) { - if (msg->data[i - 1] != '\r' && msg->data[i] == '\n') + if (msg->buf[i - 1] != '\r' && msg->buf[i] == '\n') lfnum++; } - new = xmalloc(msg->len + lfnum); - if (msg->data[0] == '\n') { + new_len = msg->len + lfnum; + new = xmalloc(new_len + 1); + if (msg->buf[0] == '\n') { new[0] = '\r'; new[1] = '\n'; i = 1; j = 2; } else { - new[0] = msg->data[0]; + new[0] = msg->buf[0]; i = 1; j = 1; } for ( ; i < msg->len; i++) { - if (msg->data[i] != '\n') { - new[j++] = msg->data[i]; + if (msg->buf[i] != '\n') { + new[j++] = msg->buf[i]; continue; } - if (msg->data[i - 1] != '\r') + if (msg->buf[i - 1] != '\r') new[j++] = '\r'; /* otherwise it already had CR before */ new[j++] = '\n'; } - msg->len += lfnum; - free(msg->data); - msg->data = new; + strbuf_attach(msg, new, new_len, new_len + 1); } -static int imap_store_msg(struct store *gctx, struct msg_data *data) +/* + * Store msg to IMAP. Also detach and free the data from msg->data, + * leaving msg->data empty. + */ +static int imap_store_msg(struct store *gctx, struct msg_data *msg) { struct imap_store *ctx = (struct imap_store *)gctx; struct imap *imap = ctx->imap; @@ -1311,16 +1314,15 @@ static int imap_store_msg(struct store *gctx, struct msg_data *data) int ret, d; char flagstr[128]; - lf_to_crlf(data); + lf_to_crlf(&msg->data); memset(&cb, 0, sizeof(cb)); - cb.dlen = data->len; - cb.data = xmalloc(cb.dlen); - memcpy(cb.data, data->data, data->len); + cb.dlen = msg->data.len; + cb.data = strbuf_detach(&msg->data, NULL); d = 0; - if (data->flags) { - d = imap_make_flags(data->flags, flagstr); + if (msg->flags) { + d = imap_make_flags(msg->flags, flagstr); flagstr[d++] = ' '; } flagstr[d] = 0; @@ -1337,75 +1339,46 @@ static int imap_store_msg(struct store *gctx, struct msg_data *data) return DRV_OK; } -static void encode_html_chars(struct strbuf *p) -{ - int i; - for (i = 0; i < p->len; i++) { - if (p->buf[i] == '&') - strbuf_splice(p, i, 1, "&", 5); - if (p->buf[i] == '<') - strbuf_splice(p, i, 1, "<", 4); - if (p->buf[i] == '>') - strbuf_splice(p, i, 1, ">", 4); - if (p->buf[i] == '"') - strbuf_splice(p, i, 1, """, 6); - } -} -static void wrap_in_html(struct msg_data *msg) +static void wrap_in_html(struct strbuf *msg) { struct strbuf buf = STRBUF_INIT; - struct strbuf **lines; - struct strbuf **p; static char *content_type = "Content-Type: text/html;\n"; static char *pre_open = "<pre>\n"; static char *pre_close = "</pre>\n"; - int added_header = 0; - - strbuf_attach(&buf, msg->data, msg->len, msg->len); - lines = strbuf_split(&buf, '\n'); - strbuf_release(&buf); - for (p = lines; *p; p++) { - if (! added_header) { - if ((*p)->len == 1 && *((*p)->buf) == '\n') { - strbuf_addstr(&buf, content_type); - strbuf_addbuf(&buf, *p); - strbuf_addstr(&buf, pre_open); - added_header = 1; - continue; - } - } - else - encode_html_chars(*p); - strbuf_addbuf(&buf, *p); - } + const char *body = strstr(msg->buf, "\n\n"); + + if (!body) + return; /* Headers but no body; no wrapping needed */ + + body += 2; + + strbuf_add(&buf, msg->buf, body - msg->buf - 1); + strbuf_addstr(&buf, content_type); + strbuf_addch(&buf, '\n'); + strbuf_addstr(&buf, pre_open); + strbuf_addstr_xml_quoted(&buf, body); strbuf_addstr(&buf, pre_close); - strbuf_list_free(lines); - msg->len = buf.len; - msg->data = strbuf_detach(&buf, NULL); + + strbuf_release(msg); + *msg = buf; } #define CHUNKSIZE 0x1000 -static int read_message(FILE *f, struct msg_data *msg) +static int read_message(FILE *f, struct strbuf *all_msgs) { - struct strbuf buf = STRBUF_INIT; - - memset(msg, 0, sizeof(*msg)); - do { - if (strbuf_fread(&buf, CHUNKSIZE, f) <= 0) + if (strbuf_fread(all_msgs, CHUNKSIZE, f) <= 0) break; } while (!feof(f)); - msg->len = buf.len; - msg->data = strbuf_detach(&buf, NULL); - return msg->len; + return ferror(f) ? -1 : 0; } -static int count_messages(struct msg_data *msg) +static int count_messages(struct strbuf *all_msgs) { int count = 0; - char *p = msg->data; + char *p = all_msgs->buf; while (1) { if (!prefixcmp(p, "From ")) { @@ -1426,34 +1399,39 @@ static int count_messages(struct msg_data *msg) return count; } -static int split_msg(struct msg_data *all_msgs, struct msg_data *msg, int *ofs) +/* + * Copy the next message from all_msgs, starting at offset *ofs, to + * msg. Update *ofs to the start of the following message. Return + * true iff a message was successfully copied. + */ +static int split_msg(struct strbuf *all_msgs, struct strbuf *msg, int *ofs) { char *p, *data; + size_t len; - memset(msg, 0, sizeof *msg); if (*ofs >= all_msgs->len) return 0; - data = &all_msgs->data[*ofs]; - msg->len = all_msgs->len - *ofs; + data = &all_msgs->buf[*ofs]; + len = all_msgs->len - *ofs; - if (msg->len < 5 || prefixcmp(data, "From ")) + if (len < 5 || prefixcmp(data, "From ")) return 0; p = strchr(data, '\n'); if (p) { - p = &p[1]; - msg->len -= p-data; - *ofs += p-data; + p++; + len -= p - data; + *ofs += p - data; data = p; } p = strstr(data, "\nFrom "); if (p) - msg->len = &p[1] - data; + len = &p[1] - data; - msg->data = xmemdupz(data, msg->len); - *ofs += msg->len; + strbuf_add(msg, data, len); + *ofs += len; return 1; } @@ -1504,7 +1482,8 @@ static int git_imap_config(const char *key, const char *val, void *cb) int main(int argc, char **argv) { - struct msg_data all_msgs, msg; + struct strbuf all_msgs = STRBUF_INIT; + struct msg_data msg = {STRBUF_INIT, 0}; struct store *ctx = NULL; int ofs = 0; int r; @@ -1537,7 +1516,12 @@ int main(int argc, char **argv) } /* read the messages */ - if (!read_message(stdin, &all_msgs)) { + if (read_message(stdin, &all_msgs)) { + fprintf(stderr, "error reading input\n"); + return 1; + } + + if (all_msgs.len == 0) { fprintf(stderr, "nothing to send\n"); return 1; } @@ -1559,11 +1543,12 @@ int main(int argc, char **argv) ctx->name = imap_folder; while (1) { unsigned percent = n * 100 / total; + fprintf(stderr, "%4u%% (%d/%d) done\r", percent, n, total); - if (!split_msg(&all_msgs, &msg, &ofs)) + if (!split_msg(&all_msgs, &msg.data, &ofs)) break; if (server.use_html) - wrap_in_html(&msg); + wrap_in_html(&msg.data); r = imap_store_msg(ctx, &msg); if (r != DRV_OK) break; @@ -540,7 +540,6 @@ void show_log(struct rev_info *opt) struct pretty_print_context ctx = {0}; opt->loginfo = NULL; - ctx.show_notes = opt->show_notes; if (!opt->verbose_header) { graph_show_commit(opt->graph); @@ -648,6 +647,18 @@ void show_log(struct rev_info *opt) if (!commit->buffer) return; + if (opt->show_notes) { + int raw; + struct strbuf notebuf = STRBUF_INIT; + + raw = (opt->commit_format == CMIT_FMT_USERFORMAT); + format_display_notes(commit->object.sha1, ¬ebuf, + get_log_output_encoding(), raw); + ctx.notes_message = notebuf.len + ? strbuf_detach(¬ebuf, NULL) + : xcalloc(1, 1); + } + /* * And then the pretty-printed message itself */ @@ -660,10 +671,21 @@ void show_log(struct rev_info *opt) ctx.preserve_subject = opt->preserve_subject; ctx.reflog_info = opt->reflog_info; ctx.fmt = opt->commit_format; + ctx.color = opt->diffopt.use_color; pretty_print_commit(&ctx, commit, &msgbuf); if (opt->add_signoff) append_signoff(&msgbuf, opt->add_signoff); + + if ((ctx.fmt != CMIT_FMT_USERFORMAT) && + ctx.notes_message && *ctx.notes_message) { + if (ctx.fmt == CMIT_FMT_EMAIL) { + strbuf_addstr(&msgbuf, "---\n"); + opt->shown_dashes = 1; + } + strbuf_addstr(&msgbuf, ctx.notes_message); + } + if (opt->show_log_size) { printf("log size %i\n", (int)msgbuf.len); graph_show_oneline(opt->graph); @@ -689,10 +711,12 @@ void show_log(struct rev_info *opt) } strbuf_release(&msgbuf); + free(ctx.notes_message); } int log_tree_diff_flush(struct rev_info *opt) { + opt->shown_dashes = 0; diffcore_std(&opt->diffopt); if (diff_queue_is_empty()) { @@ -704,15 +728,16 @@ int log_tree_diff_flush(struct rev_info *opt) } if (opt->loginfo && !opt->no_commit_id) { - /* When showing a verbose header (i.e. log message), - * and not in --pretty=oneline format, we would want - * an extra newline between the end of log and the - * output for readability. - */ show_log(opt); if ((opt->diffopt.output_format & ~DIFF_FORMAT_NO_OUTPUT) && opt->verbose_header && opt->commit_format != CMIT_FMT_ONELINE) { + /* + * When showing a verbose header (i.e. log message), + * and not in --pretty=oneline format, we would want + * an extra newline between the end of log and the + * diff/diffstat output for readability. + */ int pch = DIFF_FORMAT_DIFFSTAT | DIFF_FORMAT_PATCH; if (opt->diffopt.output_prefix) { struct strbuf *msg = NULL; @@ -720,9 +745,20 @@ int log_tree_diff_flush(struct rev_info *opt) opt->diffopt.output_prefix_data); fwrite(msg->buf, msg->len, 1, stdout); } - if ((pch & opt->diffopt.output_format) == pch) { + + /* + * We may have shown three-dashes line early + * between notes and the log message, in which + * case we only want a blank line after the + * notes without (an extra) three-dashes line. + * Otherwise, we show the three-dashes line if + * we are showing the patch with diffstat, but + * in that case, there is no extra blank line + * after the three-dashes line. + */ + if (!opt->shown_dashes && + (pch & opt->diffopt.output_format) == pch) printf("---"); - } putchar('\n'); } } @@ -10,6 +10,7 @@ static inline void debug_mm(const char *format, ...) {} #endif const char *git_mailmap_file; +const char *git_mailmap_blob; struct mailmap_info { char *name; @@ -129,54 +130,119 @@ static char *parse_name_and_email(char *buffer, char **name, return (*right == '\0' ? NULL : right); } -static int read_single_mailmap(struct string_list *map, const char *filename, char **repo_abbrev) +static void read_mailmap_line(struct string_list *map, char *buffer, + char **repo_abbrev) +{ + char *name1 = NULL, *email1 = NULL, *name2 = NULL, *email2 = NULL; + if (buffer[0] == '#') { + static const char abbrev[] = "# repo-abbrev:"; + int abblen = sizeof(abbrev) - 1; + int len = strlen(buffer); + + if (!repo_abbrev) + return; + + if (len && buffer[len - 1] == '\n') + buffer[--len] = 0; + if (!strncmp(buffer, abbrev, abblen)) { + char *cp; + + if (repo_abbrev) + free(*repo_abbrev); + *repo_abbrev = xmalloc(len); + + for (cp = buffer + abblen; isspace(*cp); cp++) + ; /* nothing */ + strcpy(*repo_abbrev, cp); + } + return; + } + if ((name2 = parse_name_and_email(buffer, &name1, &email1, 0)) != NULL) + parse_name_and_email(name2, &name2, &email2, 1); + + if (email1) + add_mapping(map, name1, email1, name2, email2); +} + +static int read_mailmap_file(struct string_list *map, const char *filename, + char **repo_abbrev) { char buffer[1024]; - FILE *f = (filename == NULL ? NULL : fopen(filename, "r")); + FILE *f; - if (f == NULL) - return 1; - while (fgets(buffer, sizeof(buffer), f) != NULL) { - char *name1 = NULL, *email1 = NULL, *name2 = NULL, *email2 = NULL; - if (buffer[0] == '#') { - static const char abbrev[] = "# repo-abbrev:"; - int abblen = sizeof(abbrev) - 1; - int len = strlen(buffer); - - if (!repo_abbrev) - continue; - - if (len && buffer[len - 1] == '\n') - buffer[--len] = 0; - if (!strncmp(buffer, abbrev, abblen)) { - char *cp; - - if (repo_abbrev) - free(*repo_abbrev); - *repo_abbrev = xmalloc(len); - - for (cp = buffer + abblen; isspace(*cp); cp++) - ; /* nothing */ - strcpy(*repo_abbrev, cp); - } - continue; - } - if ((name2 = parse_name_and_email(buffer, &name1, &email1, 0)) != NULL) - parse_name_and_email(name2, &name2, &email2, 1); + if (!filename) + return 0; - if (email1) - add_mapping(map, name1, email1, name2, email2); + f = fopen(filename, "r"); + if (!f) { + if (errno == ENOENT) + return 0; + return error("unable to open mailmap at %s: %s", + filename, strerror(errno)); } + + while (fgets(buffer, sizeof(buffer), f) != NULL) + read_mailmap_line(map, buffer, repo_abbrev); fclose(f); return 0; } +static void read_mailmap_buf(struct string_list *map, + const char *buf, unsigned long len, + char **repo_abbrev) +{ + while (len) { + const char *end = strchrnul(buf, '\n'); + unsigned long linelen = end - buf + 1; + char *line = xmemdupz(buf, linelen); + + read_mailmap_line(map, line, repo_abbrev); + + free(line); + buf += linelen; + len -= linelen; + } +} + +static int read_mailmap_blob(struct string_list *map, + const char *name, + char **repo_abbrev) +{ + unsigned char sha1[20]; + char *buf; + unsigned long size; + enum object_type type; + + if (!name) + return 0; + if (get_sha1(name, sha1) < 0) + return 0; + + buf = read_sha1_file(sha1, &type, &size); + if (!buf) + return error("unable to read mailmap object at %s", name); + if (type != OBJ_BLOB) + return error("mailmap is not a blob: %s", name); + + read_mailmap_buf(map, buf, size, repo_abbrev); + + free(buf); + return 0; +} + int read_mailmap(struct string_list *map, char **repo_abbrev) { + int err = 0; + map->strdup_strings = 1; - /* each failure returns 1, so >1 means both calls failed */ - return read_single_mailmap(map, ".mailmap", repo_abbrev) + - read_single_mailmap(map, git_mailmap_file, repo_abbrev) > 1; + + if (!git_mailmap_blob && is_bare_repository()) + git_mailmap_blob = "HEAD:.mailmap"; + + err |= read_mailmap_file(map, ".mailmap", repo_abbrev); + err |= read_mailmap_blob(map, git_mailmap_blob, repo_abbrev); + err |= read_mailmap_file(map, git_mailmap_file, repo_abbrev); + return err; } void clear_mailmap(struct string_list *map) diff --git a/merge-recursive.h b/merge-recursive.h index 58f3435..9e090a3 100644 --- a/merge-recursive.h +++ b/merge-recursive.h @@ -59,9 +59,4 @@ struct tree *write_tree_from_memory(struct merge_options *o); int parse_merge_opt(struct merge_options *out, const char *s); -/* builtin/merge.c */ -int try_merge_command(const char *strategy, size_t xopts_nr, - const char **xopts, struct commit_list *common, - const char *head_arg, struct commit_list *remotes); - #endif @@ -0,0 +1,112 @@ +#include "cache.h" +#include "commit.h" +#include "run-command.h" +#include "resolve-undo.h" +#include "tree-walk.h" +#include "unpack-trees.h" +#include "dir.h" + +static const char *merge_argument(struct commit *commit) +{ + if (commit) + return sha1_to_hex(commit->object.sha1); + else + return EMPTY_TREE_SHA1_HEX; +} + +int try_merge_command(const char *strategy, size_t xopts_nr, + const char **xopts, struct commit_list *common, + const char *head_arg, struct commit_list *remotes) +{ + const char **args; + int i = 0, x = 0, ret; + struct commit_list *j; + struct strbuf buf = STRBUF_INIT; + + args = xmalloc((4 + xopts_nr + commit_list_count(common) + + commit_list_count(remotes)) * sizeof(char *)); + strbuf_addf(&buf, "merge-%s", strategy); + args[i++] = buf.buf; + for (x = 0; x < xopts_nr; x++) { + char *s = xmalloc(strlen(xopts[x])+2+1); + strcpy(s, "--"); + strcpy(s+2, xopts[x]); + args[i++] = s; + } + for (j = common; j; j = j->next) + args[i++] = xstrdup(merge_argument(j->item)); + args[i++] = "--"; + args[i++] = head_arg; + for (j = remotes; j; j = j->next) + args[i++] = xstrdup(merge_argument(j->item)); + args[i] = NULL; + ret = run_command_v_opt(args, RUN_GIT_CMD); + strbuf_release(&buf); + i = 1; + for (x = 0; x < xopts_nr; x++) + free((void *)args[i++]); + for (j = common; j; j = j->next) + free((void *)args[i++]); + i += 2; + for (j = remotes; j; j = j->next) + free((void *)args[i++]); + free(args); + discard_cache(); + if (read_cache() < 0) + die(_("failed to read the cache")); + resolve_undo_clear(); + + return ret; +} + +int checkout_fast_forward(const unsigned char *head, + const unsigned char *remote, + int overwrite_ignore) +{ + struct tree *trees[MAX_UNPACK_TREES]; + struct unpack_trees_options opts; + struct tree_desc t[MAX_UNPACK_TREES]; + int i, fd, nr_trees = 0; + struct dir_struct dir; + struct lock_file *lock_file = xcalloc(1, sizeof(struct lock_file)); + + refresh_cache(REFRESH_QUIET); + + fd = hold_locked_index(lock_file, 1); + + memset(&trees, 0, sizeof(trees)); + memset(&opts, 0, sizeof(opts)); + memset(&t, 0, sizeof(t)); + if (overwrite_ignore) { + memset(&dir, 0, sizeof(dir)); + dir.flags |= DIR_SHOW_IGNORED; + setup_standard_excludes(&dir); + opts.dir = &dir; + } + + opts.head_idx = 1; + opts.src_index = &the_index; + opts.dst_index = &the_index; + opts.update = 1; + opts.verbose_update = 1; + opts.merge = 1; + opts.fn = twoway_merge; + setup_unpack_trees_porcelain(&opts, "merge"); + + trees[nr_trees] = parse_tree_indirect(head); + if (!trees[nr_trees++]) + return -1; + trees[nr_trees] = parse_tree_indirect(remote); + if (!trees[nr_trees++]) + return -1; + for (i = 0; i < nr_trees; i++) { + parse_tree(trees[i]); + init_tree_desc(t+i, trees[i]->buffer, trees[i]->size); + } + if (unpack_trees(nr_trees, t, &opts)) + return -1; + if (write_cache(fd, active_cache, active_nr) || + commit_locked_index(lock_file)) + die(_("unable to write new index file")); + return 0; +} diff --git a/mergetools/p4merge b/mergetools/p4merge index 295361a..52f7c8f 100644 --- a/mergetools/p4merge +++ b/mergetools/p4merge @@ -1,29 +1,21 @@ diff_cmd () { + empty_file= + # p4merge does not like /dev/null - rm_local= - rm_remote= if test "/dev/null" = "$LOCAL" then - LOCAL="./p4merge-dev-null.LOCAL.$$" - >"$LOCAL" - rm_local=true + LOCAL="$(create_empty_file)" fi if test "/dev/null" = "$REMOTE" then - REMOTE="./p4merge-dev-null.REMOTE.$$" - >"$REMOTE" - rm_remote=true + REMOTE="$(create_empty_file)" fi "$merge_tool_path" "$LOCAL" "$REMOTE" - if test -n "$rm_local" - then - rm -f "$LOCAL" - fi - if test -n "$rm_remote" + if test -n "$empty_file" then - rm -f "$REMOTE" + rm -f "$empty_file" fi } @@ -33,3 +25,10 @@ merge_cmd () { "$merge_tool_path" "$BASE" "$LOCAL" "$REMOTE" "$MERGED" check_unchanged } + +create_empty_file () { + empty_file="${TMPDIR:-/tmp}/git-difftool-p4merge-empty-file.$$" + >"$empty_file" + + printf "$empty_file" +} @@ -848,15 +848,16 @@ int combine_notes_ignore(unsigned char *cur_sha1, return 0; } -static int string_list_add_note_lines(struct string_list *sort_uniq_list, +/* + * Add the lines from the named object to list, with trailing + * newlines removed. + */ +static int string_list_add_note_lines(struct string_list *list, const unsigned char *sha1) { char *data; unsigned long len; enum object_type t; - struct strbuf buf = STRBUF_INIT; - struct strbuf **lines = NULL; - int i, list_index; if (is_null_sha1(sha1)) return 0; @@ -868,24 +869,14 @@ static int string_list_add_note_lines(struct string_list *sort_uniq_list, return t != OBJ_BLOB || !data; } - strbuf_attach(&buf, data, len, len + 1); - lines = strbuf_split(&buf, '\n'); - - for (i = 0; lines[i]; i++) { - if (lines[i]->buf[lines[i]->len - 1] == '\n') - strbuf_setlen(lines[i], lines[i]->len - 1); - if (!lines[i]->len) - continue; /* skip empty lines */ - list_index = string_list_find_insert_index(sort_uniq_list, - lines[i]->buf, 0); - if (list_index < 0) - continue; /* skip duplicate lines */ - string_list_insert_at_index(sort_uniq_list, list_index, - lines[i]->buf); - } - - strbuf_list_free(lines); - strbuf_release(&buf); + /* + * If the last line of the file is EOL-terminated, this will + * add an empty string to the list. But it will be removed + * later, along with any empty strings that came from empty + * lines within the file. + */ + string_list_split(list, data, '\n', -1); + free(data); return 0; } @@ -901,7 +892,7 @@ static int string_list_join_lines_helper(struct string_list_item *item, int combine_notes_cat_sort_uniq(unsigned char *cur_sha1, const unsigned char *new_sha1) { - struct string_list sort_uniq_list = { NULL, 0, 0, 1 }; + struct string_list sort_uniq_list = STRING_LIST_INIT_DUP; struct strbuf buf = STRBUF_INIT; int ret = 1; @@ -910,6 +901,9 @@ int combine_notes_cat_sort_uniq(unsigned char *cur_sha1, goto out; if (string_list_add_note_lines(&sort_uniq_list, new_sha1)) goto out; + string_list_remove_empty_items(&sort_uniq_list, 0); + sort_string_list(&sort_uniq_list); + string_list_remove_duplicates(&sort_uniq_list, 0); /* create a new blob object from sort_uniq_list */ if (for_each_string_list(&sort_uniq_list, @@ -949,23 +943,18 @@ void string_list_add_refs_by_glob(struct string_list *list, const char *glob) void string_list_add_refs_from_colon_sep(struct string_list *list, const char *globs) { - struct strbuf globbuf = STRBUF_INIT; - struct strbuf **split; + struct string_list split = STRING_LIST_INIT_NODUP; + char *globs_copy = xstrdup(globs); int i; - strbuf_addstr(&globbuf, globs); - split = strbuf_split(&globbuf, ':'); + string_list_split_in_place(&split, globs_copy, ':', -1); + string_list_remove_empty_items(&split, 0); - for (i = 0; split[i]; i++) { - if (!split[i]->len) - continue; - if (split[i]->buf[split[i]->len-1] == ':') - strbuf_setlen(split[i], split[i]->len-1); - string_list_add_refs_by_glob(list, split[i]->buf); - } + for (i = 0; i < split.nr; i++) + string_list_add_refs_by_glob(list, split.items[i].string); - strbuf_list_free(split); - strbuf_release(&globbuf); + string_list_clear(&split, 0); + free(globs_copy); } static int notes_display_config(const char *k, const char *v, void *cb) @@ -1204,10 +1193,11 @@ void free_notes(struct notes_tree *t) * If the given notes_tree is NULL, the internal/default notes_tree will be * used instead. * - * 'flags' is a bitwise combination of the flags for format_display_notes. + * (raw != 0) gives the %N userformat; otherwise, the note message is given + * for human consumption. */ static void format_note(struct notes_tree *t, const unsigned char *object_sha1, - struct strbuf *sb, const char *output_encoding, int flags) + struct strbuf *sb, const char *output_encoding, int raw) { static const char utf8[] = "utf-8"; const unsigned char *sha1; @@ -1244,7 +1234,7 @@ static void format_note(struct notes_tree *t, const unsigned char *object_sha1, if (msglen && msg[msglen - 1] == '\n') msglen--; - if (flags & NOTES_SHOW_HEADER) { + if (!raw) { const char *ref = t->ref; if (!ref || !strcmp(ref, GIT_NOTES_DEFAULT_REF)) { strbuf_addstr(sb, "\nNotes:\n"); @@ -1260,7 +1250,7 @@ static void format_note(struct notes_tree *t, const unsigned char *object_sha1, for (msg_p = msg; msg_p < msg + msglen; msg_p += linelen + 1) { linelen = strchrnul(msg_p, '\n') - msg_p; - if (flags & NOTES_INDENT) + if (!raw) strbuf_addstr(sb, " "); strbuf_add(sb, msg_p, linelen); strbuf_addch(sb, '\n'); @@ -1270,13 +1260,13 @@ static void format_note(struct notes_tree *t, const unsigned char *object_sha1, } void format_display_notes(const unsigned char *object_sha1, - struct strbuf *sb, const char *output_encoding, int flags) + struct strbuf *sb, const char *output_encoding, int raw) { int i; assert(display_notes_trees); for (i = 0; display_notes_trees[i]; i++) format_note(display_notes_trees[i], object_sha1, sb, - output_encoding, flags); + output_encoding, raw); } int copy_note(struct notes_tree *t, @@ -237,10 +237,6 @@ void prune_notes(struct notes_tree *t, int flags); */ void free_notes(struct notes_tree *t); -/* Flags controlling how notes are formatted */ -#define NOTES_SHOW_HEADER 1 -#define NOTES_INDENT 2 - struct string_list; struct display_notes_opt { @@ -274,7 +270,7 @@ void init_display_notes(struct display_notes_opt *opt); * You *must* call init_display_notes() before using this function. */ void format_display_notes(const unsigned char *object_sha1, - struct strbuf *sb, const char *output_encoding, int flags); + struct strbuf *sb, const char *output_encoding, int raw); /* * Load the notes tree from each ref listed in 'refs'. The output is @@ -6,26 +6,17 @@ #define DEFAULT_PAGER "less" #endif +struct pager_config { + const char *cmd; + int want; + char *value; +}; + /* * This is split up from the rest of git so that we can do * something different on Windows. */ -#ifndef WIN32 -static void pager_preexec(void) -{ - /* - * Work around bug in "less" by not starting it until we - * have real input - */ - fd_set in; - - FD_ZERO(&in); - FD_SET(0, &in); - select(1, &in, NULL, &in, NULL); -} -#endif - static const char *pager_argv[] = { NULL, NULL }; static struct child_process pager_process; @@ -93,9 +84,6 @@ void setup_pager(void) static const char *env[] = { "LESS=FRSX", NULL }; pager_process.env = env; } -#ifndef WIN32 - pager_process.preexec_cb = pager_preexec; -#endif if (start_command(&pager_process)) return; @@ -159,3 +147,31 @@ int decimal_width(int number) i *= 10; return width; } + +static int pager_command_config(const char *var, const char *value, void *data) +{ + struct pager_config *c = data; + if (!prefixcmp(var, "pager.") && !strcmp(var + 6, c->cmd)) { + int b = git_config_maybe_bool(var, value); + if (b >= 0) + c->want = b; + else { + c->want = 1; + c->value = xstrdup(value); + } + } + return 0; +} + +/* returns 0 for "no pager", 1 for "use pager", and -1 for "not specified" */ +int check_pager_config(const char *cmd) +{ + struct pager_config c; + c.cmd = cmd; + c.want = -1; + c.value = NULL; + git_config(pager_command_config, &c); + if (c.value) + pager_program = c.value; + return c.want; +} diff --git a/parse-options.c b/parse-options.c index c1c66bd..67e98a6 100644 --- a/parse-options.c +++ b/parse-options.c @@ -18,15 +18,6 @@ int optbug(const struct option *opt, const char *reason) return error("BUG: switch '%c' %s", opt->short_name, reason); } -int opterror(const struct option *opt, const char *reason, int flags) -{ - if (flags & OPT_SHORT) - return error("switch `%c' %s", opt->short_name, reason); - if (flags & OPT_UNSET) - return error("option `no-%s' %s", opt->long_name, reason); - return error("option `%s' %s", opt->long_name, reason); -} - static int get_arg(struct parse_opt_ctx_t *p, const struct option *opt, int flags, const char **arg) { @@ -594,3 +585,12 @@ static int parse_options_usage(struct parse_opt_ctx_t *ctx, return usage_with_options_internal(ctx, usagestr, opts, 0, err); } +#undef opterror +int opterror(const struct option *opt, const char *reason, int flags) +{ + if (flags & OPT_SHORT) + return error("switch `%c' %s", opt->short_name, reason); + if (flags & OPT_UNSET) + return error("option `no-%s' %s", opt->long_name, reason); + return error("option `%s' %s", opt->long_name, reason); +} diff --git a/parse-options.h b/parse-options.h index 71a39c6..e703853 100644 --- a/parse-options.h +++ b/parse-options.h @@ -177,6 +177,10 @@ extern NORETURN void usage_msg_opt(const char *msg, extern int optbug(const struct option *opt, const char *reason); extern int opterror(const struct option *opt, const char *reason, int flags); +#ifdef __GNUC__ +#define opterror(o,r,f) (opterror((o),(r),(f)), -1) +#endif + /*----- incremental advanced APIs -----*/ enum { @@ -12,6 +12,7 @@ */ #include "cache.h" #include "strbuf.h" +#include "string-list.h" static char bad_path[] = "/bad-path/"; @@ -569,43 +570,38 @@ int normalize_path_copy(char *dst, const char *src) /* * path = Canonical absolute path - * prefix_list = Colon-separated list of absolute paths + * prefixes = string_list containing normalized, absolute paths without + * trailing slashes (except for the root directory, which is denoted by "/"). * - * Determines, for each path in prefix_list, whether the "prefix" really + * Determines, for each path in prefixes, whether the "prefix" * is an ancestor directory of path. Returns the length of the longest * ancestor directory, excluding any trailing slashes, or -1 if no prefix - * is an ancestor. (Note that this means 0 is returned if prefix_list is - * "/".) "/foo" is not considered an ancestor of "/foobar". Directories + * is an ancestor. (Note that this means 0 is returned if prefixes is + * ["/"].) "/foo" is not considered an ancestor of "/foobar". Directories * are not considered to be their own ancestors. path must be in a * canonical form: empty components, or "." or ".." components are not - * allowed. prefix_list may be null, which is like "". + * allowed. */ -int longest_ancestor_length(const char *path, const char *prefix_list) +int longest_ancestor_length(const char *path, struct string_list *prefixes) { - char buf[PATH_MAX+1]; - const char *ceil, *colon; - int len, max_len = -1; + int i, max_len = -1; - if (prefix_list == NULL || !strcmp(path, "/")) + if (!strcmp(path, "/")) return -1; - for (colon = ceil = prefix_list; *colon; ceil = colon+1) { - for (colon = ceil; *colon && *colon != PATH_SEP; colon++); - len = colon - ceil; - if (len == 0 || len > PATH_MAX || !is_absolute_path(ceil)) - continue; - strlcpy(buf, ceil, len+1); - if (normalize_path_copy(buf, buf) < 0) - continue; - len = strlen(buf); - if (len > 0 && buf[len-1] == '/') - buf[--len] = '\0'; + for (i = 0; i < prefixes->nr; i++) { + const char *ceil = prefixes->items[i].string; + int len = strlen(ceil); - if (!strncmp(path, buf, len) && - path[len] == '/' && - len > max_len) { + if (len == 1 && ceil[0] == '/') + len = 0; /* root matches anything, with length 0 */ + else if (!strncmp(path, ceil, len) && path[len] == '/') + ; /* match of length len */ + else + continue; /* no match */ + + if (len > max_len) max_len = len; - } } return max_len; diff --git a/perl/Git.pm b/perl/Git.pm index 497f420..931047c 100644 --- a/perl/Git.pm +++ b/perl/Git.pm @@ -58,7 +58,7 @@ require Exporter; command_output_pipe command_input_pipe command_close_pipe command_bidi_pipe command_close_bidi_pipe version exec_path html_path hash_object git_cmd_try - remote_refs + remote_refs prompt temp_acquire temp_release temp_reset temp_path); @@ -511,6 +511,58 @@ C<git --html-path>). Useful mostly only internally. sub html_path { command_oneline('--html-path') } +=item prompt ( PROMPT , ISPASSWORD ) + +Query user C<PROMPT> and return answer from user. + +Honours GIT_ASKPASS and SSH_ASKPASS environment variables for querying +the user. If no *_ASKPASS variable is set or an error occoured, +the terminal is tried as a fallback. +If C<ISPASSWORD> is set and true, the terminal disables echo. + +=cut + +sub prompt { + my ($prompt, $isPassword) = @_; + my $ret; + if (exists $ENV{'GIT_ASKPASS'}) { + $ret = _prompt($ENV{'GIT_ASKPASS'}, $prompt); + } + if (!defined $ret && exists $ENV{'SSH_ASKPASS'}) { + $ret = _prompt($ENV{'SSH_ASKPASS'}, $prompt); + } + if (!defined $ret) { + print STDERR $prompt; + STDERR->flush; + if (defined $isPassword && $isPassword) { + require Term::ReadKey; + Term::ReadKey::ReadMode('noecho'); + $ret = ''; + while (defined(my $key = Term::ReadKey::ReadKey(0))) { + last if $key =~ /[\012\015]/; # \n\r + $ret .= $key; + } + Term::ReadKey::ReadMode('restore'); + print STDERR "\n"; + STDERR->flush; + } else { + chomp($ret = <STDIN>); + } + } + return $ret; +} + +sub _prompt { + my ($askpass, $prompt) = @_; + return unless length $askpass; + $prompt =~ s/\n/ /g; + my $ret; + open my $fh, "-|", $askpass, $prompt or return; + $ret = <$fh>; + $ret =~ s/[\015\012]//g; # strip \r\n, chomp does not work on all systems (i.e. windows) as expected + close ($fh); + return $ret; +} =item repo_path () diff --git a/perl/Git/SVN/Prompt.pm b/perl/Git/SVN/Prompt.pm index 3a6f8af..74daa7a 100644 --- a/perl/Git/SVN/Prompt.pm +++ b/perl/Git/SVN/Prompt.pm @@ -62,16 +62,16 @@ sub ssl_server_trust { issuer_dname fingerprint); my $choice; prompt: - print STDERR $may_save ? + my $options = $may_save ? "(R)eject, accept (t)emporarily or accept (p)ermanently? " : "(R)eject or accept (t)emporarily? "; STDERR->flush; - $choice = lc(substr(<STDIN> || 'R', 0, 1)); - if ($choice =~ /^t$/i) { + $choice = lc(substr(Git::prompt("Certificate problem.\n" . $options) || 'R', 0, 1)); + if ($choice eq 't') { $cred->may_save(undef); - } elsif ($choice =~ /^r$/i) { + } elsif ($choice eq 'r') { return -1; - } elsif ($may_save && $choice =~ /^p$/i) { + } elsif ($may_save && $choice eq 'p') { $cred->may_save($may_save); } else { goto prompt; @@ -109,9 +109,7 @@ sub username { if (defined $_username) { $username = $_username; } else { - print STDERR "Username: "; - STDERR->flush; - chomp($username = <STDIN>); + $username = Git::prompt("Username: "); } $cred->username($username); $cred->may_save($may_save); @@ -120,25 +118,7 @@ sub username { sub _read_password { my ($prompt, $realm) = @_; - my $password = ''; - if (exists $ENV{GIT_ASKPASS}) { - open(PH, "-|", $ENV{GIT_ASKPASS}, $prompt); - $password = <PH>; - $password =~ s/[\012\015]//; # \n\r - close(PH); - } else { - print STDERR $prompt; - STDERR->flush; - require Term::ReadKey; - Term::ReadKey::ReadMode('noecho'); - while (defined(my $key = Term::ReadKey::ReadKey(0))) { - last if $key =~ /[\012\015]/; # \n\r - $password .= $key; - } - Term::ReadKey::ReadMode('restore'); - print STDERR "\n"; - STDERR->flush; - } + my $password = Git::prompt($prompt, 1); $password; } @@ -1,21 +1,21 @@ # German translations for Git. -# Copyright (C) 2010-2012 Ralf Thielow <ralf.thielow@googlemail.com> +# Copyright (C) 2010-2012 Ralf Thielow <ralf.thielow@gmail.com> # This file is distributed under the same license as the Git package. -# Ralf Thielow <ralf.thielow@googlemail.com>, 2010, 2011, 2012. +# Ralf Thielow <ralf.thielow@gmail.com>, 2010, 2011, 2012. # msgid "" msgstr "" -"Project-Id-Version: git 1.7.12\n" +"Project-Id-Version: git 1.8.1\n" "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n" -"POT-Creation-Date: 2012-09-05 06:20+0800\n" -"PO-Revision-Date: 2012-03-28 18:46+0200\n" -"Last-Translator: Ralf Thielow <ralf.thielow@googlemail.com>\n" -"Language-Team: German\n" +"POT-Creation-Date: 2012-11-30 12:40+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" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" #: advice.c:40 #, c-format @@ -38,6 +38,101 @@ msgstr "" "um die Auflösung entsprechend zu markieren und einzutragen,\n" "oder benutze 'git commit -a'." +#: archive.c:10 +msgid "git archive [options] <tree-ish> [<path>...]" +msgstr "git archive [Optionen] <Versionsreferenz> [<Pfad>...]" + +#: archive.c:11 +msgid "git archive --list" +msgstr "git archive --list" + +#: archive.c:12 +msgid "" +"git archive --remote <repo> [--exec <cmd>] [options] <tree-ish> [<path>...]" +msgstr "" +"git archive --remote <Projektarchiv> [--exec <Programm>] [Optionen] " +"<Versionsreferenz> [Pfad...]" + +#: archive.c:13 +msgid "git archive --remote <repo> [--exec <cmd>] --list" +msgstr "git archive --remote <Projektarchiv> [--exec <Programm>] --list" + +#: archive.c:322 +msgid "fmt" +msgstr "Format" + +#: archive.c:322 +msgid "archive format" +msgstr "Ausgabeformat" + +#: archive.c:323 builtin/log.c:1084 +msgid "prefix" +msgstr "Prefix" + +#: archive.c:324 +msgid "prepend prefix to each pathname in the archive" +msgstr "stellt einen Präfix vor jeden Pfadnamen in der Ausgabe" + +#: archive.c:325 builtin/archive.c:91 builtin/blame.c:2390 +#: builtin/blame.c:2391 builtin/config.c:55 builtin/fast-export.c:642 +#: builtin/fast-export.c:644 builtin/grep.c:715 builtin/hash-object.c:77 +#: builtin/ls-files.c:494 builtin/ls-files.c:497 builtin/notes.c:540 +#: builtin/notes.c:697 builtin/read-tree.c:107 parse-options.h:149 +msgid "file" +msgstr "Datei" + +#: archive.c:326 builtin/archive.c:92 +msgid "write the archive to this file" +msgstr "schreibt die Ausgabe in diese Datei" + +#: archive.c:328 +msgid "read .gitattributes in working directory" +msgstr "liest .gitattributes aus dem Arbeitsverzeichnis" + +#: archive.c:329 +msgid "report archived files on stderr" +msgstr "gibt archivierte Dateien in der Standard-Fehlerausgabe aus" + +#: archive.c:330 +msgid "store only" +msgstr "nur speichern" + +#: archive.c:331 +msgid "compress faster" +msgstr "schneller komprimieren" + +#: archive.c:339 +msgid "compress better" +msgstr "besser komprimieren" + +#: archive.c:342 +msgid "list supported archive formats" +msgstr "listet unterstützte Ausgabeformate auf" + +#: archive.c:344 builtin/archive.c:93 builtin/clone.c:85 +msgid "repo" +msgstr "Projektarchiv" + +#: archive.c:345 builtin/archive.c:94 +msgid "retrieve the archive from remote repository <repo>" +msgstr "ruft das Archiv von externem Projektarchiv <Projektarchiv> ab" + +#: archive.c:346 builtin/archive.c:95 builtin/notes.c:619 +msgid "command" +msgstr "Programm" + +#: archive.c:347 builtin/archive.c:96 +msgid "path to the remote git-upload-archive command" +msgstr "Pfad zum externen \"git-upload-archive\"-Programm" + +#: attr.c:259 +msgid "" +"Negative patterns are forbidden in git attributes\n" +"Use '\\!' for literal leading exclamation." +msgstr "" +"Verneinende Muster sind in Git-Attributen verboten.\n" +"Benutze '\\!' für führende Ausrufezeichen." + #: bundle.c:36 #, c-format msgid "'%s' does not look like a v2 bundle file" @@ -48,7 +143,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:699 +#: bundle.c:89 builtin/commit.c:674 #, c-format msgid "could not open '%s'" msgstr "Konnte '%s' nicht öffnen" @@ -57,8 +152,8 @@ msgstr "Konnte '%s' nicht öffnen" msgid "Repository lacks these prerequisite commits:" msgstr "Dem Projektarchiv fehlen folgende vorausgesetzte Versionen:" -#: bundle.c:164 sequencer.c:550 sequencer.c:982 builtin/log.c:290 -#: builtin/log.c:727 builtin/log.c:1313 builtin/log.c:1529 builtin/merge.c:347 +#: bundle.c:164 sequencer.c:562 sequencer.c:994 builtin/log.c:290 +#: builtin/log.c:732 builtin/log.c:1319 builtin/log.c:1535 builtin/merge.c:347 #: builtin/shortlog.c:181 msgid "revision walk setup failed" msgstr "Einrichtung des Revisionsgangs fehlgeschlagen" @@ -85,7 +180,7 @@ msgstr[1] "Das Paket benötigt diese %d Referenzen" msgid "rev-list died" msgstr "\"rev-list\" abgebrochen" -#: bundle.c:300 builtin/log.c:1209 builtin/shortlog.c:284 +#: bundle.c:300 builtin/log.c:1215 builtin/shortlog.c:284 #, c-format msgid "unrecognized argument: %s" msgstr "nicht erkanntes Argument: %s" @@ -116,12 +211,12 @@ msgstr "kann '%s' nicht erstellen" msgid "index-pack died" msgstr "Erstellung der Paketindexdatei abgebrochen" -#: commit.c:48 +#: commit.c:50 #, c-format msgid "could not parse %s" msgstr "konnte %s nicht parsen" -#: commit.c:50 +#: commit.c:52 #, c-format msgid "%s %s is not a commit!" msgstr "%s %s ist keine Version!" @@ -211,18 +306,24 @@ msgid_plural "%lu years ago" msgstr[0] "vor %lu Jahr" msgstr[1] "vor %lu Jahren" -#: diff.c:105 +#: diff.c:111 #, c-format -msgid " Failed to parse dirstat cut-off percentage '%.*s'\n" +msgid " Failed to parse dirstat cut-off percentage '%s'\n" msgstr "" -" Fehler beim Parsen des abgeschnittenen \"dirstat\" Prozentsatzes '%.*s'\n" +" Fehler beim Parsen des abgeschnittenen \"dirstat\" Prozentsatzes '%s'\n" -#: diff.c:110 +#: diff.c:116 #, c-format -msgid " Unknown dirstat parameter '%.*s'\n" -msgstr " Unbekannter \"dirstat\" Parameter '%.*s'\n" +msgid " Unknown dirstat parameter '%s'\n" +msgstr " Unbekannter \"dirstat\" Parameter '%s'\n" -#: diff.c:210 +#: diff.c:194 +#, c-format +msgid "Unknown value for 'diff.submodule' config variable: '%s'" +msgstr "" +"Unbekannter Wert in Konfigurationsvariable 'diff.dirstat': '%s'" + +#: diff.c:237 #, c-format msgid "" "Found errors in 'diff.dirstat' config variable:\n" @@ -231,32 +332,7 @@ msgstr "" "Fehler in 'diff.dirstat' Konfigurationsvariable gefunden:\n" "%s" -#: diff.c:1401 -msgid " 0 files changed" -msgstr " 0 Dateien geändert" - -#: diff.c:1405 -#, c-format -msgid " %d file changed" -msgid_plural " %d files changed" -msgstr[0] " %d Datei geändert" -msgstr[1] " %d Dateien geändert" - -#: diff.c:1422 -#, c-format -msgid ", %d insertion(+)" -msgid_plural ", %d insertions(+)" -msgstr[0] ", %d Zeile hinzugefügt(+)" -msgstr[1] ", %d Zeilen hinzugefügt(+)" - -#: diff.c:1433 -#, c-format -msgid ", %d deletion(-)" -msgid_plural ", %d deletions(-)" -msgstr[0] ", %d Zeile entfernt(-)" -msgstr[1] ", %d Zeilen entfernt(-)" - -#: diff.c:3460 +#: diff.c:3494 #, c-format msgid "" "Failed to parse --dirstat/-X option parameter:\n" @@ -265,6 +341,12 @@ msgstr "" "Fehler beim Parsen des --dirstat/-X Optionsparameters:\n" "%s" +#: diff.c:3508 +#, c-format +msgid "Failed to parse --submodule option parameter: '%s'" +msgstr "" +"Fehler beim Parsen des --submodule Optionsparameters: '%s'" + #: gpg-interface.c:59 msgid "could not run gpg." msgstr "konnte gpg nicht ausführen" @@ -277,17 +359,17 @@ msgstr "gpg hat die Daten nicht akzeptiert" msgid "gpg failed to sign the data" msgstr "gpg beim Signieren der Daten fehlgeschlagen" -#: grep.c:1320 +#: grep.c:1622 #, c-format msgid "'%s': unable to read %s" msgstr "'%s': konnte nicht lesen %s" -#: grep.c:1337 +#: grep.c:1639 #, c-format msgid "'%s': %s" msgstr "'%s': %s" -#: grep.c:1348 +#: grep.c:1650 #, c-format msgid "'%s': short read %s" msgstr "'%s': read() zu kurz %s" @@ -347,6 +429,15 @@ msgstr[1] "" "\n" "Hast du eines von diesen gemeint?" +#: merge.c:56 +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 +msgid "unable to write new index file" +msgstr "Konnte neue Bereitstellungsdatei nicht schreiben." + #: merge-recursive.c:190 #, c-format msgid "(bad commit)\n" @@ -407,20 +498,20 @@ msgstr "Fehler beim Erstellen einer symbolischen Verknüpfung für '%s'" msgid "do not know what to do with %06o %s '%s'" msgstr "weiß nicht was mit %06o %s '%s' zu machen ist" -#: merge-recursive.c:921 +#: merge-recursive.c:922 msgid "Failed to execute internal merge" msgstr "Fehler bei Ausführung der internen Zusammenführung" -#: merge-recursive.c:925 +#: merge-recursive.c:926 #, c-format msgid "Unable to add %s to database" msgstr "Konnte %s nicht zur Datenbank hinzufügen" -#: merge-recursive.c:941 +#: merge-recursive.c:942 msgid "unsupported object type in the tree" msgstr "nicht unterstützter Objekttyp im Baum" -#: merge-recursive.c:1020 merge-recursive.c:1034 +#: merge-recursive.c:1021 merge-recursive.c:1035 #, c-format msgid "" "CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left " @@ -429,7 +520,7 @@ msgstr "" "KONFLIKT (%s/löschen): %s gelöscht in %s und %s in %s. Stand %s von %s wurde " "im Arbeitsbereich gelassen." -#: merge-recursive.c:1026 merge-recursive.c:1039 +#: merge-recursive.c:1027 merge-recursive.c:1040 #, c-format msgid "" "CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left " @@ -438,20 +529,20 @@ msgstr "" "KONFLIKT (%s/löschen): %s gelöscht in %s und %s in %s. Stand %s von %s wurde " "im Arbeitsbereich bei %s gelassen." -#: merge-recursive.c:1080 +#: merge-recursive.c:1081 msgid "rename" msgstr "umbenennen" -#: merge-recursive.c:1080 +#: merge-recursive.c:1081 msgid "renamed" msgstr "umbenannt" -#: merge-recursive.c:1136 +#: merge-recursive.c:1137 #, c-format msgid "%s is a directory in %s adding as %s instead" msgstr "%s ist ein Verzeichnis in %s, füge es stattdessen als %s hinzu" -#: merge-recursive.c:1158 +#: merge-recursive.c:1159 #, c-format msgid "" "CONFLICT (rename/rename): Rename \"%s\"->\"%s\" in branch \"%s\" rename \"%s" @@ -460,148 +551,148 @@ msgstr "" "KONFLIKT (umbenennen/umbenennen): Benenne um \"%s\"->\"%s\" in Zweig \"%s\" " "und \"%s\"->\"%s\" in Zweig \"%s\"%s" -#: merge-recursive.c:1163 +#: merge-recursive.c:1164 msgid " (left unresolved)" msgstr " (bleibt unaufgelöst)" -#: merge-recursive.c:1217 +#: merge-recursive.c:1218 #, c-format msgid "CONFLICT (rename/rename): Rename %s->%s in %s. Rename %s->%s in %s" msgstr "" "KONFLIKT (umbenennen/umbenennen): Benenne um %s->%s in %s. Benenne um %s->%s " "in %s" -#: merge-recursive.c:1247 +#: merge-recursive.c:1248 #, c-format msgid "Renaming %s to %s and %s to %s instead" msgstr "Benenne stattdessen %s nach %s und %s nach %s um" -#: merge-recursive.c:1446 +#: merge-recursive.c:1447 #, c-format msgid "CONFLICT (rename/add): Rename %s->%s in %s. %s added in %s" msgstr "" "KONFLIKT (umbenennen/hinzufügen): Benenne um %s->%s in %s. %s hinzugefügt in " "%s" -#: merge-recursive.c:1456 +#: merge-recursive.c:1457 #, c-format msgid "Adding merged %s" msgstr "Füge zusammengeführte Datei %s hinzu" -#: merge-recursive.c:1461 merge-recursive.c:1659 +#: merge-recursive.c:1462 merge-recursive.c:1660 #, c-format msgid "Adding as %s instead" msgstr "Füge stattdessen als %s hinzu" -#: merge-recursive.c:1512 +#: merge-recursive.c:1513 #, c-format msgid "cannot read object %s" msgstr "kann Objekt %s nicht lesen" -#: merge-recursive.c:1515 +#: merge-recursive.c:1516 #, c-format msgid "object %s is not a blob" msgstr "Objekt %s ist kein Blob" -#: merge-recursive.c:1563 +#: merge-recursive.c:1564 msgid "modify" msgstr "ändern" -#: merge-recursive.c:1563 +#: merge-recursive.c:1564 msgid "modified" msgstr "geändert" -#: merge-recursive.c:1573 +#: merge-recursive.c:1574 msgid "content" msgstr "Inhalt" -#: merge-recursive.c:1580 +#: merge-recursive.c:1581 msgid "add/add" msgstr "hinzufügen/hinzufügen" -#: merge-recursive.c:1614 +#: merge-recursive.c:1615 #, c-format msgid "Skipped %s (merged same as existing)" msgstr "%s ausgelassen (Ergebnis der Zusammenführung existiert bereits)" -#: merge-recursive.c:1628 +#: merge-recursive.c:1629 #, c-format msgid "Auto-merging %s" msgstr "automatische Zusammenführung von %s" -#: merge-recursive.c:1632 git-submodule.sh:869 +#: merge-recursive.c:1633 git-submodule.sh:893 msgid "submodule" msgstr "Unterprojekt" -#: merge-recursive.c:1633 +#: merge-recursive.c:1634 #, c-format msgid "CONFLICT (%s): Merge conflict in %s" msgstr "KONFLIKT (%s): Zusammenführungskonflikt in %s" -#: merge-recursive.c:1723 +#: merge-recursive.c:1724 #, c-format msgid "Removing %s" msgstr "Entferne %s" -#: merge-recursive.c:1748 +#: merge-recursive.c:1749 msgid "file/directory" msgstr "Datei/Verzeichnis" -#: merge-recursive.c:1754 +#: merge-recursive.c:1755 msgid "directory/file" msgstr "Verzeichnis/Datei" -#: merge-recursive.c:1759 +#: merge-recursive.c:1760 #, c-format msgid "CONFLICT (%s): There is a directory with name %s in %s. Adding %s as %s" msgstr "" "KONFLIKT (%s): Es existiert bereits ein Verzeichnis %s in %s. Füge %s als %s " "hinzu." -#: merge-recursive.c:1769 +#: merge-recursive.c:1770 #, c-format msgid "Adding %s" msgstr "Füge %s hinzu" -#: merge-recursive.c:1786 +#: merge-recursive.c:1787 msgid "Fatal merge failure, shouldn't happen." msgstr "Fataler Fehler bei der Zusammenführung. Sollte nicht passieren." -#: merge-recursive.c:1805 +#: merge-recursive.c:1806 msgid "Already up-to-date!" msgstr "Bereits aktuell!" -#: merge-recursive.c:1814 +#: merge-recursive.c:1815 #, c-format msgid "merging of trees %s and %s failed" msgstr "Zusammenführen der Bäume %s und %s fehlgeschlagen" -#: merge-recursive.c:1844 +#: merge-recursive.c:1845 #, c-format msgid "Unprocessed path??? %s" msgstr "unverarbeiteter Pfad??? %s" -#: merge-recursive.c:1889 +#: merge-recursive.c:1890 msgid "Merging:" msgstr "Zusammenführung:" -#: merge-recursive.c:1902 +#: merge-recursive.c:1903 #, c-format msgid "found %u common ancestor:" msgid_plural "found %u common ancestors:" msgstr[0] "%u gemeinsamen Vorfahren gefunden" msgstr[1] "%u gemeinsame Vorfahren gefunden" -#: merge-recursive.c:1939 +#: merge-recursive.c:1940 msgid "merge returned no commit" msgstr "Zusammenführung hat keine Version zurückgegeben" -#: merge-recursive.c:1996 +#: merge-recursive.c:1997 #, c-format msgid "Could not parse object '%s'" msgstr "Konnte Objekt '%s' nicht parsen." -#: merge-recursive.c:2008 builtin/merge.c:696 +#: merge-recursive.c:2009 builtin/merge.c:643 msgid "Unable to write index." msgstr "Konnte Bereitstellung nicht schreiben." @@ -633,7 +724,11 @@ msgid_plural "Your branch is ahead of '%s' by %d commits.\n" msgstr[0] "Dein Zweig ist vor '%s' um %d Version.\n" msgstr[1] "Dein Zweig ist vor '%s' um %d Versionen.\n" -#: remote.c:1638 +#: remote.c:1637 +msgid " (use \"git push\" to publish your local commits)\n" +msgstr " (benutze \"git push\" um deine lokalen Versionen herauszubringen)\n" + +#: remote.c:1640 #, c-format msgid "Your branch is behind '%s' by %d commit, and can be fast-forwarded.\n" msgid_plural "" @@ -644,7 +739,12 @@ msgstr[1] "" "Dein Zweig ist zu '%s' um %d Versionen hinterher, und kann vorgespult " "werden.\n" -#: remote.c:1646 +#: remote.c:1647 +msgid " (use \"git pull\" to update your local branch)\n" +msgstr "" +" (benutze \"git pull\" um deinen lokalen Zweig zu aktualisieren)\n" + +#: remote.c:1650 #, c-format msgid "" "Your branch and '%s' have diverged,\n" @@ -659,19 +759,24 @@ msgstr[1] "" "Dein Zweig und '%s' sind divergiert,\n" "und haben jeweils %d und %d unterschiedliche Versionen.\n" -#: sequencer.c:121 builtin/merge.c:864 builtin/merge.c:977 -#: builtin/merge.c:1087 builtin/merge.c:1097 +#: remote.c:1659 +msgid " (use \"git pull\" to merge the remote branch into yours)\n" +msgstr "" +" (benutze \"git pull\" um deinen 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 #, c-format msgid "Could not open '%s' for writing" msgstr "Konnte '%s' nicht zum Schreiben öffnen." -#: sequencer.c:123 builtin/merge.c:333 builtin/merge.c:867 -#: builtin/merge.c:1089 builtin/merge.c:1102 +#: sequencer.c:125 builtin/merge.c:333 builtin/merge.c:764 builtin/merge.c:986 +#: builtin/merge.c:999 #, c-format msgid "Could not write to '%s'" msgstr "Konnte nicht nach '%s' schreiben." -#: sequencer.c:144 +#: sequencer.c:146 msgid "" "after resolving the conflicts, mark the corrected paths\n" "with 'git add <paths>' or 'git rm <paths>'" @@ -679,7 +784,7 @@ msgstr "" "nach Auflösung der Konflikte, markiere die korrigierten Pfade\n" "mit 'git add <Pfade>' oder 'git rm <Pfade>'" -#: sequencer.c:147 +#: sequencer.c:149 msgid "" "after resolving the conflicts, mark the corrected paths\n" "with 'git add <paths>' or 'git rm <paths>'\n" @@ -689,74 +794,74 @@ msgstr "" "mit 'git add <Pfade>' oder 'git rm <Pfade>'und trage das Ergebnis ein mit " "'git commit'" -#: sequencer.c:160 sequencer.c:758 sequencer.c:841 +#: sequencer.c:162 sequencer.c:770 sequencer.c:853 #, c-format msgid "Could not write to %s" msgstr "Konnte nicht nach %s schreiben" -#: sequencer.c:163 +#: sequencer.c:165 #, c-format msgid "Error wrapping up %s" msgstr "Fehler bei Nachbereitung von %s" -#: sequencer.c:178 +#: sequencer.c:180 msgid "Your local changes would be overwritten by cherry-pick." msgstr "" "Deine lokalen Änderungen würden von \"cherry-pick\" überschrieben werden." -#: sequencer.c:180 +#: sequencer.c:182 msgid "Your local changes would be overwritten by revert." msgstr "Deine lokalen Änderungen würden von \"revert\" überschrieben werden." -#: sequencer.c:183 +#: sequencer.c:185 msgid "Commit your changes or stash them to proceed." msgstr "Trage deine Änderungen ein oder benutze \"stash\" um fortzufahren." #. TRANSLATORS: %s will be "revert" or "cherry-pick" -#: sequencer.c:233 +#: sequencer.c:235 #, c-format msgid "%s: Unable to write new index file" msgstr "%s: Konnte neue Bereitstellungsdatei nicht schreiben" -#: sequencer.c:261 +#: sequencer.c:266 msgid "Could not resolve HEAD commit\n" msgstr "Konnte Version der Zweigspitze (HEAD) nicht auflösen\n" -#: sequencer.c:282 +#: sequencer.c:287 msgid "Unable to update cache tree\n" msgstr "Konnte zwischengespeicherten Baum nicht aktualisieren\n" -#: sequencer.c:324 +#: sequencer.c:332 #, c-format msgid "Could not parse commit %s\n" msgstr "Konnte Version %s nicht parsen\n" -#: sequencer.c:329 +#: sequencer.c:337 #, c-format msgid "Could not parse parent commit %s\n" msgstr "Konnte Elternversion %s nicht parsen\n" -#: sequencer.c:395 +#: sequencer.c:403 msgid "Your index file is unmerged." msgstr "Deine Bereitstellungsdatei ist nicht zusammengeführt." -#: sequencer.c:398 +#: sequencer.c:406 msgid "You do not have a valid HEAD" msgstr "Du hast keine gültige Zweigspitze (HEAD)" -#: sequencer.c:413 +#: sequencer.c:421 #, 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:421 +#: sequencer.c:429 #, c-format msgid "Commit %s does not have parent %d" msgstr "Version %s hat keinen Elternteil %d" -#: sequencer.c:425 +#: sequencer.c:433 #, c-format msgid "Mainline was specified but commit %s is not a merge." msgstr "" @@ -764,145 +869,145 @@ msgstr "" #. TRANSLATORS: The first %s will be "revert" or #. "cherry-pick", the second %s a SHA1 -#: sequencer.c:436 +#: sequencer.c:444 #, c-format msgid "%s: cannot parse parent commit %s" msgstr "%s: kann Elternversion %s nicht parsen" -#: sequencer.c:440 +#: sequencer.c:448 #, c-format msgid "Cannot get commit message for %s" msgstr "Kann keine Versionsbeschreibung für %s bekommen" -#: sequencer.c:524 +#: sequencer.c:532 #, c-format msgid "could not revert %s... %s" msgstr "Konnte %s nicht zurücksetzen... %s" -#: sequencer.c:525 +#: sequencer.c:533 #, c-format msgid "could not apply %s... %s" msgstr "Konnte %s nicht anwenden... %s" -#: sequencer.c:553 +#: sequencer.c:565 msgid "empty commit set passed" msgstr "leere Menge von Versionen übergeben" -#: sequencer.c:561 +#: sequencer.c:573 #, c-format msgid "git %s: failed to read the index" msgstr "git %s: Fehler beim Lesen der Bereitstellung" -#: sequencer.c:566 +#: sequencer.c:578 #, c-format msgid "git %s: failed to refresh the index" msgstr "git %s: Fehler beim Aktualisieren der Bereitstellung" -#: sequencer.c:624 +#: sequencer.c:636 #, c-format msgid "Cannot %s during a %s" msgstr "Kann %s nicht während eines %s durchführen" -#: sequencer.c:646 +#: sequencer.c:658 #, c-format msgid "Could not parse line %d." msgstr "Konnte Zeile %d nicht parsen." -#: sequencer.c:651 +#: sequencer.c:663 msgid "No commits parsed." msgstr "Keine Versionen geparst." -#: sequencer.c:664 +#: sequencer.c:676 #, c-format msgid "Could not open %s" msgstr "Konnte %s nicht öffnen" -#: sequencer.c:668 +#: sequencer.c:680 #, c-format msgid "Could not read %s." msgstr "Konnte %s nicht lesen." -#: sequencer.c:675 +#: sequencer.c:687 #, c-format msgid "Unusable instruction sheet: %s" msgstr "Unbenutzbares Instruktionsblatt: %s" -#: sequencer.c:703 +#: sequencer.c:715 #, c-format msgid "Invalid key: %s" msgstr "Ungültiger Schlüssel: %s" -#: sequencer.c:706 +#: sequencer.c:718 #, c-format msgid "Invalid value for %s: %s" msgstr "Ungültiger Wert für %s: %s" -#: sequencer.c:718 +#: sequencer.c:730 #, c-format msgid "Malformed options sheet: %s" msgstr "Fehlerhaftes Optionsblatt: %s" -#: sequencer.c:739 +#: sequencer.c:751 msgid "a cherry-pick or revert is already in progress" msgstr "\"cherry-pick\" oder \"revert\" ist bereits im Gang" -#: sequencer.c:740 +#: sequencer.c:752 msgid "try \"git cherry-pick (--continue | --quit | --abort)\"" msgstr "versuche \"git cherry-pick (--continue | --quit | --abort)\"" -#: sequencer.c:744 +#: sequencer.c:756 #, c-format msgid "Could not create sequencer directory %s" msgstr "Konnte \"sequencer\"-Verzeichnis %s nicht erstellen" -#: sequencer.c:760 sequencer.c:845 +#: sequencer.c:772 sequencer.c:857 #, c-format msgid "Error wrapping up %s." msgstr "Fehler beim Einpacken von %s." -#: sequencer.c:779 sequencer.c:913 +#: sequencer.c:791 sequencer.c:925 msgid "no cherry-pick or revert in progress" msgstr "kein \"cherry-pick\" oder \"revert\" im Gang" -#: sequencer.c:781 +#: sequencer.c:793 msgid "cannot resolve HEAD" msgstr "kann Zweigspitze (HEAD) nicht auflösen" -#: sequencer.c:783 +#: sequencer.c:795 msgid "cannot abort from a branch yet to be born" msgstr "kann nicht abbrechen: bin auf einem Zweig, der noch geboren wird" -#: sequencer.c:805 builtin/apply.c:3987 +#: sequencer.c:817 builtin/apply.c:4005 #, c-format msgid "cannot open %s: %s" msgstr "Kann %s nicht öffnen: %s" -#: sequencer.c:808 +#: sequencer.c:820 #, c-format msgid "cannot read %s: %s" msgstr "Kann %s nicht lesen: %s" -#: sequencer.c:809 +#: sequencer.c:821 msgid "unexpected end of file" msgstr "Unerwartetes Dateiende" -#: sequencer.c:815 +#: sequencer.c:827 #, 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:838 +#: sequencer.c:850 #, c-format msgid "Could not format %s." msgstr "Konnte %s nicht formatieren." -#: sequencer.c:1000 +#: sequencer.c:1012 msgid "Can't revert as initial commit" msgstr "Kann nicht zu initialer Version zurücksetzen." -#: sequencer.c:1001 +#: sequencer.c:1013 msgid "Can't cherry-pick into empty head" msgstr "Kann \"cherry-pick\" nicht in einem leerem Kopf ausführen." @@ -926,12 +1031,17 @@ msgid "Upstream branch '%s' not stored as a remote-tracking branch" msgstr "" "Zweig '%s' des entfernten Projektarchivs ist kein gefolgter Ãœbernahmezweig" -#: wrapper.c:413 +#: wrapper.c:408 +#, c-format +msgid "unable to access '%s': %s" +msgstr "konnte nicht auf '%s' zugreifen: %s" + +#: wrapper.c:426 #, c-format msgid "unable to look up current user in the passwd file: %s" msgstr "konnte aktuellen Benutzer nicht in Passwort-Datei finden: %s" -#: wrapper.c:414 +#: wrapper.c:427 msgid "no such user" msgstr "kein solcher Benutzer" @@ -995,11 +1105,6 @@ msgstr "" " (trage ein oder verwerfe den unbeobachteten oder geänderten Inhalt in den " "Unterprojekten)" -#: wt-status.c:224 -#, c-format -msgid "%s files:" -msgstr "%s Dateien:" - #: wt-status.c:227 #, c-format msgid " (use \"git %s <file>...\" to include in what will be committed)" @@ -1209,12 +1314,12 @@ msgid "Initial commit" msgstr "Initiale Version" #: wt-status.c:1011 -msgid "Untracked" -msgstr "Unbeobachtete" +msgid "Untracked files" +msgstr "Unbeobachtete Dateien" #: wt-status.c:1013 -msgid "Ignored" -msgstr "Ignorierte" +msgid "Ignored files" +msgstr "Ignorierte Dateien" #: wt-status.c:1015 #, c-format @@ -1229,59 +1334,73 @@ msgstr " (benutze die Option -u um unbeobachteten Dateien anzuzeigen)" msgid "No changes" msgstr "Keine Änderungen" -#: wt-status.c:1027 +#: wt-status.c:1028 #, c-format -msgid "no changes added to commit%s\n" -msgstr "keine Änderungen zum Eintragen hinzugefügt%s\n" - -#: wt-status.c:1029 -msgid " (use \"git add\" and/or \"git commit -a\")" -msgstr " (benutze \"git add\" und/oder \"git commit -a\")" +msgid "no changes added to commit (use \"git add\" and/or \"git commit -a\")\n" +msgstr "" +"keine Änderungen zum Eintragen hinzugefügt (benutze \"git add\" und/oder " +"\"git commit -a\")\n" #: wt-status.c:1031 #, c-format -msgid "nothing added to commit but untracked files present%s\n" +msgid "no changes added to commit\n" +msgstr "keine Änderungen zum Eintragen hinzugefügt\n" + +#: wt-status.c:1034 +#, c-format +msgid "" +"nothing added to commit but untracked files present (use \"git add\" to " +"track)\n" msgstr "" -"nichts zum Eintragen hinzugefügt, aber es gibt unbeobachtete Dateien%s\n" +"nichts zum Eintragen hinzugefügt, aber es gibt unbeobachtete Dateien " +"(benutze \"git add\" zum Beobachten)\n" -#: wt-status.c:1033 -msgid " (use \"git add\" to track)" -msgstr " (benutze \"git add\" zum Beobachten)" +#: wt-status.c:1037 +#, 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:1035 wt-status.c:1038 wt-status.c:1041 +#: wt-status.c:1040 #, c-format -msgid "nothing to commit%s\n" -msgstr "nichts zum Eintragen%s\n" +msgid "nothing to commit (create/copy files and use \"git add\" to track)\n" +msgstr "" +"nichts einzutragen (Erstelle/Kopiere Dateien und benutze \"git add\" zum " +"Beobachten)\n" -#: wt-status.c:1036 -msgid " (create/copy files and use \"git add\" to track)" -msgstr " (Erstelle/Kopiere Dateien und benutze \"git add\" zum Beobachten)" +#: wt-status.c:1043 wt-status.c:1048 +#, c-format +msgid "nothing to commit\n" +msgstr "nichts einzutragen\n" -#: wt-status.c:1039 -msgid " (use -u to show untracked files)" -msgstr " (benutze die Option -u um unbeobachtete Dateien anzuzeigen)" +#: wt-status.c:1046 +#, c-format +msgid "nothing to commit (use -u to show untracked files)\n" +msgstr "" +"nichts einzutragen (benutze die Option -u, um unbeobachtete Dateien " +"anzuzeigen)\n" -#: wt-status.c:1042 -msgid " (working directory clean)" -msgstr " (Arbeitsverzeichnis sauber)" +#: wt-status.c:1050 +#, c-format +msgid "nothing to commit, working directory clean\n" +msgstr "nichts einzutragen, Arbeitsverzeichnis sauber\n" -#: wt-status.c:1150 +#: wt-status.c:1158 msgid "HEAD (no branch)" msgstr "HEAD (kein Zweig)" -#: wt-status.c:1156 +#: wt-status.c:1164 msgid "Initial commit on " msgstr "Initiale Version auf " -#: wt-status.c:1171 +#: wt-status.c:1179 msgid "behind " msgstr "hinterher " -#: wt-status.c:1174 wt-status.c:1177 +#: wt-status.c:1182 wt-status.c:1185 msgid "ahead " msgstr "voraus " -#: wt-status.c:1179 +#: wt-status.c:1187 msgid ", behind " msgstr ", hinterher " @@ -1290,19 +1409,23 @@ msgstr ", hinterher " msgid "failed to unlink '%s'" msgstr "Konnte '%s' nicht entfernen" +#: builtin/add.c:19 +msgid "git add [options] [--] <filepattern>..." +msgstr "git add [Optionen] [--] [<Dateimuster>...]" + #: builtin/add.c:62 #, c-format msgid "unexpected diff status %c" msgstr "unerwarteter Differenz-Status %c" -#: builtin/add.c:67 builtin/commit.c:229 +#: builtin/add.c:67 builtin/commit.c:231 msgid "updating files failed" msgstr "Aktualisierung der Dateien fehlgeschlagen" #: builtin/add.c:77 #, c-format msgid "remove '%s'\n" -msgstr "entferne '%s'\n" +msgstr "lösche '%s'\n" #: builtin/add.c:176 #, c-format @@ -1314,7 +1437,7 @@ msgid "Unstaged changes after refreshing the index:" msgstr "" "Nicht bereitgestellte Änderungen nach Aktualisierung der Bereitstellung:" -#: builtin/add.c:195 builtin/add.c:459 builtin/rm.c:186 +#: builtin/add.c:195 builtin/add.c:460 builtin/rm.c:275 #, c-format msgid "pathspec '%s' did not match any files" msgstr "Pfadspezifikation '%s' stimmt mit keinen Dateien überein" @@ -1351,50 +1474,105 @@ msgstr "Leerer Patch. Abgebrochen." msgid "Could not apply '%s'" msgstr "Konnte '%s' nicht anwenden." -#: builtin/add.c:312 +#: builtin/add.c:313 msgid "The following paths are ignored by one of your .gitignore files:\n" msgstr "" "Die folgenden Pfade werden durch eine deiner \".gitignore\" Dateien " "ignoriert:\n" -#: builtin/add.c:352 +#: builtin/add.c:319 builtin/clean.c:52 builtin/fetch.c:78 builtin/mv.c:63 +#: builtin/prune-packed.c:76 builtin/push.c:388 builtin/remote.c:1253 +#: builtin/rm.c:206 +msgid "dry run" +msgstr "Probelauf" + +#: builtin/add.c:320 builtin/apply.c:4354 builtin/commit.c:1160 +#: builtin/count-objects.c:82 builtin/fsck.c:613 builtin/log.c:1483 +#: builtin/mv.c:62 builtin/read-tree.c:112 +msgid "be verbose" +msgstr "erweiterte Ausgaben" + +#: builtin/add.c:322 +msgid "interactive picking" +msgstr "interaktives Auswählen" + +#: builtin/add.c:323 builtin/checkout.c:1031 builtin/reset.c:248 +msgid "select hunks interactively" +msgstr "interaktiv Bereiche auswählen" + +#: builtin/add.c:324 +msgid "edit current diff and apply" +msgstr "aktuelle Unterschiede editieren und anwenden" + +#: builtin/add.c:325 +msgid "allow adding otherwise ignored files" +msgstr "erlaubt das Hinzufügen andernfalls ignorierter Dateien" + +#: builtin/add.c:326 +msgid "update tracked files" +msgstr "aktualisiert beobachtete Dateien" + +#: builtin/add.c:327 +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:328 +msgid "add changes from all tracked and untracked files" +msgstr "" +"fügt Änderungen von allen beobachteten und unbeobachteten Dateien hinzu" + +#: builtin/add.c:329 +msgid "don't add, only refresh the index" +msgstr "fügt nichts hinzu, aktualisiert nur die Bereitstellung" + +#: builtin/add.c:330 +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:331 +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:353 #, c-format msgid "Use -f if you really want to add them.\n" msgstr "Verwende -f wenn du diese wirklich hinzufügen möchtest.\n" -#: builtin/add.c:353 +#: builtin/add.c:354 msgid "no files added" msgstr "keine Dateien hinzugefügt" -#: builtin/add.c:359 +#: builtin/add.c:360 msgid "adding files failed" msgstr "Hinzufügen von Dateien fehlgeschlagen" -#: builtin/add.c:391 +#: builtin/add.c:392 msgid "-A and -u are mutually incompatible" msgstr "-A und -u sind zueinander inkompatibel" -#: builtin/add.c:393 +#: builtin/add.c:394 msgid "Option --ignore-missing can only be used together with --dry-run" msgstr "" "Die Option --ignore-missing kann nur zusammen mit --dry-run benutzt werden." -#: builtin/add.c:413 +#: builtin/add.c:414 #, c-format msgid "Nothing specified, nothing added.\n" msgstr "Nichts spezifiziert, nichts hinzugefügt.\n" -#: builtin/add.c:414 +#: builtin/add.c:415 #, c-format msgid "Maybe you wanted to say 'git add .'?\n" msgstr "Wolltest du vielleicht 'git add .' sagen?\n" -#: builtin/add.c:420 builtin/clean.c:95 builtin/commit.c:289 builtin/mv.c:82 -#: builtin/rm.c:162 +#: builtin/add.c:421 builtin/clean.c:95 builtin/commit.c:291 builtin/mv.c:82 +#: builtin/rm.c:235 msgid "index file corrupt" msgstr "Bereitstellungsdatei beschädigt" -#: builtin/add.c:480 builtin/apply.c:4432 builtin/mv.c:229 builtin/rm.c:260 +#: builtin/add.c:481 builtin/apply.c:4450 builtin/mv.c:229 builtin/rm.c:370 msgid "Unable to write new index file" msgstr "Konnte neue Bereitstellungsdatei nicht schreiben." @@ -1451,17 +1629,17 @@ msgstr "" msgid "git apply: bad git-diff - expected /dev/null on line %d" msgstr "git apply: ungültiges 'git-diff' - erwartete /dev/null in Zeile %d" -#: builtin/apply.c:1402 +#: builtin/apply.c:1420 #, c-format msgid "recount: unexpected line: %.*s" msgstr "recount: unerwartete Zeile: %.*s" -#: builtin/apply.c:1459 +#: builtin/apply.c:1477 #, c-format msgid "patch fragment without header at line %d: %.*s" msgstr "Patch-Fragment ohne Kopfbereich bei Zeile %d: %.*s" -#: builtin/apply.c:1476 +#: builtin/apply.c:1494 #, c-format msgid "" "git diff header lacks filename information when removing %d leading pathname " @@ -1476,70 +1654,70 @@ msgstr[1] "" "Dem Kopfbereich von \"git diff\" fehlen Informationen zum Dateinamen, wenn " "%d vorangestellte Teile des Pfades entfernt werden (Zeile %d)" -#: builtin/apply.c:1636 +#: builtin/apply.c:1654 msgid "new file depends on old contents" msgstr "neue Datei hängt von alten Inhalten ab" -#: builtin/apply.c:1638 +#: builtin/apply.c:1656 msgid "deleted file still has contents" msgstr "entfernte Datei hat noch Inhalte" -#: builtin/apply.c:1664 +#: builtin/apply.c:1682 #, c-format msgid "corrupt patch at line %d" msgstr "fehlerhafter Patch bei Zeile %d" -#: builtin/apply.c:1700 +#: builtin/apply.c:1718 #, c-format msgid "new file %s depends on old contents" msgstr "neue Datei %s hängt von alten Inhalten ab" -#: builtin/apply.c:1702 +#: builtin/apply.c:1720 #, c-format msgid "deleted file %s still has contents" msgstr "entfernte Datei %s hat noch Inhalte" -#: builtin/apply.c:1705 +#: builtin/apply.c:1723 #, c-format msgid "** warning: file %s becomes empty but is not deleted" msgstr "** Warnung: Datei %s wird leer, aber nicht entfernt." -#: builtin/apply.c:1851 +#: builtin/apply.c:1869 #, c-format msgid "corrupt binary patch at line %d: %.*s" msgstr "fehlerhafter Binär-Patch bei Zeile %d: %.*s" #. there has to be one hunk (forward hunk) -#: builtin/apply.c:1880 +#: builtin/apply.c:1898 #, c-format msgid "unrecognized binary patch at line %d" msgstr "nicht erkannter Binär-Patch bei Zeile %d" -#: builtin/apply.c:1966 +#: builtin/apply.c:1984 #, c-format msgid "patch with only garbage at line %d" msgstr "Patch mit nutzlosen Informationen bei Zeile %d" -#: builtin/apply.c:2056 +#: builtin/apply.c:2074 #, c-format msgid "unable to read symlink %s" msgstr "konnte symbolische Verknüpfung %s nicht lesen" -#: builtin/apply.c:2060 +#: builtin/apply.c:2078 #, c-format msgid "unable to open or read %s" msgstr "konnte %s nicht öffnen oder lesen" -#: builtin/apply.c:2131 +#: builtin/apply.c:2149 msgid "oops" msgstr "Ups" -#: builtin/apply.c:2653 +#: builtin/apply.c:2671 #, c-format msgid "invalid start of line: '%c'" msgstr "Ungültiger Zeilenanfang: '%c'" -#: builtin/apply.c:2771 +#: builtin/apply.c:2789 #, c-format msgid "Hunk #%d succeeded at %d (offset %d line)." msgid_plural "Hunk #%d succeeded at %d (offset %d lines)." @@ -1547,12 +1725,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:2783 +#: builtin/apply.c:2801 #, 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:2789 +#: builtin/apply.c:2807 #, c-format msgid "" "while searching for:\n" @@ -1561,339 +1739,335 @@ msgstr "" "bei der Suche nach:\n" "%.*s" -#: builtin/apply.c:2808 +#: builtin/apply.c:2826 #, c-format msgid "missing binary patch data for '%s'" msgstr "keine Daten in Binär-Patch für '%s'" -#: builtin/apply.c:2911 +#: builtin/apply.c:2929 #, c-format msgid "binary patch does not apply to '%s'" msgstr "Konnte Binär-Patch nicht auf '%s' anwenden" -#: builtin/apply.c:2917 +#: builtin/apply.c:2935 #, 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:2938 +#: builtin/apply.c:2956 #, c-format msgid "patch failed: %s:%ld" msgstr "Anwendung des Patches fehlgeschlagen: %s:%ld" -#: builtin/apply.c:3060 +#: builtin/apply.c:3078 #, c-format msgid "cannot checkout %s" msgstr "kann %s nicht auschecken" -#: builtin/apply.c:3105 builtin/apply.c:3114 builtin/apply.c:3158 +#: builtin/apply.c:3123 builtin/apply.c:3132 builtin/apply.c:3176 #, c-format msgid "read of %s failed" msgstr "Konnte %s nicht lesen" -#: builtin/apply.c:3138 builtin/apply.c:3360 +#: builtin/apply.c:3156 builtin/apply.c:3378 #, c-format msgid "path %s has been renamed/deleted" msgstr "Pfad %s wurde umbenannt/gelöscht" -#: builtin/apply.c:3219 builtin/apply.c:3374 +#: builtin/apply.c:3237 builtin/apply.c:3392 #, c-format msgid "%s: does not exist in index" msgstr "%s ist nicht bereitgestellt" -#: builtin/apply.c:3223 builtin/apply.c:3366 builtin/apply.c:3388 +#: builtin/apply.c:3241 builtin/apply.c:3384 builtin/apply.c:3406 #, c-format msgid "%s: %s" msgstr "%s: %s" -#: builtin/apply.c:3228 builtin/apply.c:3382 +#: builtin/apply.c:3246 builtin/apply.c:3400 #, c-format msgid "%s: does not match index" msgstr "%s entspricht nicht der Bereitstellung" -#: builtin/apply.c:3330 +#: builtin/apply.c:3348 msgid "removal patch leaves file contents" msgstr "Lösch-Patch hinterlässt Dateiinhalte" -#: builtin/apply.c:3399 +#: builtin/apply.c:3417 #, c-format msgid "%s: wrong type" msgstr "%s: falscher Typ" -#: builtin/apply.c:3401 +#: builtin/apply.c:3419 #, c-format msgid "%s has type %o, expected %o" msgstr "%s ist vom Typ %o, erwartete %o" -#: builtin/apply.c:3502 +#: builtin/apply.c:3520 #, c-format msgid "%s: already exists in index" msgstr "%s ist bereits bereitgestellt" -#: builtin/apply.c:3505 +#: builtin/apply.c:3523 #, c-format msgid "%s: already exists in working directory" msgstr "%s existiert bereits im Arbeitsverzeichnis" -#: builtin/apply.c:3525 +#: builtin/apply.c:3543 #, 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:3530 +#: builtin/apply.c:3548 #, 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:3538 +#: builtin/apply.c:3556 #, c-format msgid "%s: patch does not apply" msgstr "%s: Patch konnte nicht angewendet werden" -#: builtin/apply.c:3551 +#: builtin/apply.c:3569 #, c-format msgid "Checking patch %s..." msgstr "Prüfe Patch %s..." -#: builtin/apply.c:3606 builtin/checkout.c:213 builtin/reset.c:158 +#: builtin/apply.c:3624 builtin/checkout.c:215 builtin/reset.c:158 #, c-format msgid "make_cache_entry failed for path '%s'" msgstr "make_cache_entry für Pfad '%s' fehlgeschlagen" -#: builtin/apply.c:3749 +#: builtin/apply.c:3767 #, c-format msgid "unable to remove %s from index" msgstr "konnte %s nicht aus der Bereitstellung entfernen" -#: builtin/apply.c:3777 +#: builtin/apply.c:3795 #, c-format msgid "corrupt patch for subproject %s" msgstr "fehlerhafter Patch für Unterprojekt %s" -#: builtin/apply.c:3781 +#: builtin/apply.c:3799 #, c-format msgid "unable to stat newly created file '%s'" msgstr "konnte neu erstellte Datei '%s' nicht lesen" -#: builtin/apply.c:3786 +#: builtin/apply.c:3804 #, 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:3789 builtin/apply.c:3897 +#: builtin/apply.c:3807 builtin/apply.c:3915 #, 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:3822 +#: builtin/apply.c:3840 #, c-format msgid "closing file '%s'" msgstr "schließe Datei '%s'" -#: builtin/apply.c:3871 +#: builtin/apply.c:3889 #, c-format msgid "unable to write file '%s' mode %o" msgstr "konnte Datei '%s' mit Modus %o nicht schreiben" -#: builtin/apply.c:3958 +#: builtin/apply.c:3976 #, c-format msgid "Applied patch %s cleanly." msgstr "Patch %s sauber angewendet" -#: builtin/apply.c:3966 +#: builtin/apply.c:3984 msgid "internal error" msgstr "interner Fehler" #. Say this even without --verbose -#: builtin/apply.c:3969 +#: builtin/apply.c:3987 #, 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:3979 +#: builtin/apply.c:3997 #, c-format msgid "truncating .rej filename to %.*s.rej" msgstr "Verkürze Name von .rej Datei zu %.*s.rej" -#: builtin/apply.c:4000 +#: builtin/apply.c:4018 #, c-format msgid "Hunk #%d applied cleanly." msgstr "Patch-Bereich #%d sauber angewendet." -#: builtin/apply.c:4003 +#: builtin/apply.c:4021 #, c-format msgid "Rejected hunk #%d." msgstr "Patch-Bereich #%d zurückgewiesen." -#: builtin/apply.c:4153 +#: builtin/apply.c:4171 msgid "unrecognized input" msgstr "nicht erkannte Eingabe" -#: builtin/apply.c:4164 +#: builtin/apply.c:4182 msgid "unable to read index file" msgstr "Konnte Bereitstellungsdatei nicht lesen" -#: builtin/apply.c:4283 builtin/apply.c:4286 +#: builtin/apply.c:4301 builtin/apply.c:4304 builtin/clone.c:91 +#: builtin/fetch.c:63 msgid "path" msgstr "Pfad" -#: builtin/apply.c:4284 +#: builtin/apply.c:4302 msgid "don't apply changes matching the given path" msgstr "wendet keine Änderungen im angegebenen Pfad an" -#: builtin/apply.c:4287 +#: builtin/apply.c:4305 msgid "apply changes matching the given path" msgstr "wendet Änderungen nur im angegebenen Pfad an" -#: builtin/apply.c:4289 +#: builtin/apply.c:4307 msgid "num" msgstr "Anzahl" -#: builtin/apply.c:4290 +#: builtin/apply.c:4308 msgid "remove <num> leading slashes from traditional diff paths" msgstr "" "entfernt <Anzahl> vorangestellte Schrägstriche von herkömmlichen " "Differenzpfaden" -#: builtin/apply.c:4293 +#: builtin/apply.c:4311 msgid "ignore additions made by the patch" msgstr "ignoriert hinzugefügte Zeilen des Patches" -#: builtin/apply.c:4295 +#: builtin/apply.c:4313 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:4299 -msgid "shows number of added and deleted lines in decimal notation" +#: builtin/apply.c:4317 +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:4301 +#: builtin/apply.c:4319 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:4303 +#: builtin/apply.c:4321 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:4305 +#: builtin/apply.c:4323 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:4307 +#: builtin/apply.c:4325 msgid "apply a patch without touching the working tree" msgstr "wendet einen Patch an, ohne Änderungen im Arbeitszweig vorzunehmen" -#: builtin/apply.c:4309 +#: builtin/apply.c:4327 msgid "also apply the patch (use with --stat/--summary/--check)" msgstr "wendet den Patch an (Benutzung mit --stat/--summary/--check)" -#: builtin/apply.c:4311 +#: builtin/apply.c:4329 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:4313 +#: builtin/apply.c:4331 msgid "build a temporary index based on embedded index information" msgstr "" "erstellt eine temporäre Bereitstellung basierend auf den integrierten " "Bereitstellungsinformationen" -#: builtin/apply.c:4315 +#: builtin/apply.c:4333 builtin/checkout-index.c:197 builtin/ls-files.c:460 msgid "paths are separated with NUL character" msgstr "Pfade sind getrennt durch NUL Zeichen" -#: builtin/apply.c:4318 +#: builtin/apply.c:4336 msgid "ensure at least <n> lines of context match" -msgstr "" -"stellt sicher, dass mindestens <Anzahl> Zeilen des Kontextes übereinstimmen" +msgstr "stellt sicher, dass mindestens <n> Zeilen des Kontextes übereinstimmen" -#: builtin/apply.c:4319 +#: builtin/apply.c:4337 msgid "action" msgstr "Aktion" -#: builtin/apply.c:4320 +#: builtin/apply.c:4338 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:4323 builtin/apply.c:4326 +#: builtin/apply.c:4341 builtin/apply.c:4344 msgid "ignore changes in whitespace when finding context" msgstr "ignoriert Änderungen in Leerzeichen bei der Suche des Kontextes" -#: builtin/apply.c:4329 +#: builtin/apply.c:4347 msgid "apply the patch in reverse" msgstr "wendet den Patch in umgekehrter Reihenfolge an" -#: builtin/apply.c:4331 +#: builtin/apply.c:4349 msgid "don't expect at least one line of context" msgstr "erwartet keinen Kontext" -#: builtin/apply.c:4333 +#: builtin/apply.c:4351 msgid "leave the rejected hunks in corresponding *.rej files" msgstr "" "hinterlässt zurückgewiesene Patch-Bereiche in den entsprechenden *.rej " "Dateien" -#: builtin/apply.c:4335 +#: builtin/apply.c:4353 msgid "allow overlapping hunks" msgstr "erlaubt sich überlappende Patch-Bereiche" -#: builtin/apply.c:4336 -msgid "be verbose" -msgstr "erweiterte Ausgaben" - -#: builtin/apply.c:4338 +#: builtin/apply.c:4356 msgid "tolerate incorrectly detected missing new-line at the end of file" msgstr "toleriert fehlerhaft erkannten fehlenden Zeilenumbruch am Dateiende" -#: builtin/apply.c:4341 +#: builtin/apply.c:4359 msgid "do not trust the line counts in the hunk headers" msgstr "vertraut nicht den Zeilennummern im Kopf des Patch-Bereiches" -#: builtin/apply.c:4343 +#: builtin/apply.c:4361 msgid "root" msgstr "Wurzelverzeichnis" -#: builtin/apply.c:4344 +#: builtin/apply.c:4362 msgid "prepend <root> to all filenames" msgstr "stellt <Wurzelverzeichnis> vor alle Dateinamen" -#: builtin/apply.c:4366 +#: builtin/apply.c:4384 msgid "--3way outside a repository" msgstr "--3way außerhalb eines Projektarchivs" -#: builtin/apply.c:4374 +#: builtin/apply.c:4392 msgid "--index outside a repository" msgstr "--index außerhalb eines Projektarchivs" -#: builtin/apply.c:4377 +#: builtin/apply.c:4395 msgid "--cached outside a repository" msgstr "--cached außerhalb eines Projektarchivs" -#: builtin/apply.c:4393 +#: builtin/apply.c:4411 #, c-format msgid "can't open patch '%s'" msgstr "kann Patch '%s' nicht öffnen" -#: builtin/apply.c:4407 +#: builtin/apply.c:4425 #, 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:4413 builtin/apply.c:4423 +#: builtin/apply.c:4431 builtin/apply.c:4441 #, c-format msgid "%d line adds whitespace errors." msgid_plural "%d lines add whitespace errors." @@ -1935,7 +2109,136 @@ msgstr "git archive: Protokollfehler" msgid "git archive: expected a flush" msgstr "git archive: erwartete eine Spülung (flush)" -#: builtin/branch.c:144 +#: builtin/bisect--helper.c:7 +msgid "git bisect--helper --next-all [--no-checkout]" +msgstr "git bisect--helper --next-all [--no-checkout]" + +#: builtin/bisect--helper.c:17 +msgid "perform 'git bisect next'" +msgstr "führt 'git bisect next' aus" + +#: builtin/bisect--helper.c:19 +msgid "update BISECT_HEAD instead of checking out the current commit" +msgstr "aktualisiert BISECT_HEAD, anstatt die aktuelle Version auszuchecken" + +#: builtin/blame.c:25 +msgid "git blame [options] [rev-opts] [rev] [--] file" +msgstr "git blame [Optionen] [rev-opts] [rev] [--] Datei" + +#: builtin/blame.c:30 builtin/shortlog.c:15 +msgid "[rev-opts] are documented in git-rev-list(1)" +msgstr "[rev-opts] sind dokumentiert in git-rev-list(1)" + +#: builtin/blame.c:2374 +msgid "Show blame entries as we find them, incrementally" +msgstr "Zeigt \"blame\"-Einträge schrittweise, während wir sie generieren" + +#: builtin/blame.c:2375 +msgid "Show blank SHA-1 for boundary commits (Default: off)" +msgstr "Zeigt leere SHA-1 für Grenzversionen (Standard: aus)" + +#: builtin/blame.c:2376 +msgid "Do not treat root commits as boundaries (Default: off)" +msgstr "Behandelt Ursprungsversionen nicht als Grenzen (Standard: aus)" + +#: builtin/blame.c:2377 +msgid "Show work cost statistics" +msgstr "Zeigt Statistiken zum Arbeitsaufwand" + +#: builtin/blame.c:2378 +msgid "Show output score for blame entries" +msgstr "Zeigt Ausgabebewertung für \"blame\"-Einträge" + +#: builtin/blame.c:2379 +msgid "Show original filename (Default: auto)" +msgstr "Zeigt ursprünglichen Dateinamen (Standard: auto)" + +#: builtin/blame.c:2380 +msgid "Show original linenumber (Default: off)" +msgstr "Zeigt ursprüngliche Zeilennummer (Standard: aus)" + +#: builtin/blame.c:2381 +msgid "Show in a format designed for machine consumption" +msgstr "Anzeige in einem Format für maschinelle Auswertung" + +#: builtin/blame.c:2382 +msgid "Show porcelain format with per-line commit information" +msgstr "" +"Anzeige in Format für Fremdprogramme mit Versionsinformationen pro Zeile" + +#: builtin/blame.c:2383 +msgid "Use the same output mode as git-annotate (Default: off)" +msgstr "Benutzt den gleichen Ausgabemodus wie \"git-annotate\" (Standard: aus)" + +#: builtin/blame.c:2384 +msgid "Show raw timestamp (Default: off)" +msgstr "Zeigt unbearbeiteten Zeitstempel (Standard: aus)" + +#: builtin/blame.c:2385 +msgid "Show long commit SHA1 (Default: off)" +msgstr "Zeigt langen Versions-SHA1 (Standard: aus)" + +#: builtin/blame.c:2386 +msgid "Suppress author name and timestamp (Default: off)" +msgstr "Unterdrückt den Namen des Autors und den Zeitstempel (Standard: aus)" + +#: builtin/blame.c:2387 +msgid "Show author email instead of name (Default: off)" +msgstr "Zeigt anstatt des Namens die Email-Adresse des Autors (Standard: aus)" + +#: builtin/blame.c:2388 +msgid "Ignore whitespace differences" +msgstr "Ignoriert Unterschiede in Leerzeichen" + +#: builtin/blame.c:2389 +msgid "Spend extra cycles to find better match" +msgstr "arbeite länger, um bessere Ãœbereinstimmungen zu finden" + +#: builtin/blame.c:2390 +msgid "Use revisions from <file> instead of calling git-rev-list" +msgstr "Benutzt Revisionen von <Datei> anstatt \"git-rev-list\" aufzurufen" + +#: builtin/blame.c:2391 +msgid "Use <file>'s contents as the final image" +msgstr "Benutzt Inhalte der <Datei>en als entgültiges Abbild" + +#: builtin/blame.c:2392 builtin/blame.c:2393 +msgid "score" +msgstr "Bewertung" + +#: builtin/blame.c:2392 +msgid "Find line copies within and across files" +msgstr "Findet kopierte Zeilen innerhalb oder zwischen Dateien" + +#: builtin/blame.c:2393 +msgid "Find line movements within and across files" +msgstr "Findet verschobene Zeilen innerhalb oder zwischen Dateien" + +#: builtin/blame.c:2394 +msgid "n,m" +msgstr "n,m" + +#: builtin/blame.c:2394 +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 +msgid "git branch [options] [-r | -a] [--merged | --no-merged]" +msgstr "git branch [Optionen] [-r | -a] [--merged | --no-merged]" + +#: builtin/branch.c:24 +msgid "git branch [options] [-l] [-f] <branchname> [<start-point>]" +msgstr "git branch [Optionen] [-l] [-f] <Zweigname> [<Startpunkt>]" + +#: builtin/branch.c:25 +msgid "git branch [options] [-r] (-d | -D) <branchname>..." +msgstr "git branch [Optionen] [-r] (-d | -D) <Zweigname>..." + +#: builtin/branch.c:26 +msgid "git branch [options] (-m | -M) [<oldbranch>] <newbranch>" +msgstr "git branch [Optionen] (-m | -M) [<alterZweig>] <neuerZweig>" + +#: builtin/branch.c:145 #, c-format msgid "" "deleting branch '%s' that has been merged to\n" @@ -1945,7 +2248,7 @@ msgstr "" " '%s', aber noch nicht mit der Zweigspitze (HEAD) zusammengeführt " "wurde." -#: builtin/branch.c:148 +#: builtin/branch.c:149 #, c-format msgid "" "not deleting branch '%s' that is not yet merged to\n" @@ -1954,169 +2257,300 @@ 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 +#, c-format +msgid "Couldn't look up commit object for '%s'" +msgstr "Konnte Versionsobjekt für '%s' nicht nachschlagen." + +#: builtin/branch.c:167 +#, 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 "" +"Der Zweig '%s' ist nicht vollständig zusammengeführt.\n" +"Wenn du sicher bist diesen Zweig zu entfernen, führe 'git branch -D %s' aus." + #: builtin/branch.c:180 +msgid "Update of config-file failed" +msgstr "Aktualisierung der Konfigurationsdatei fehlgeschlagen." + +#: builtin/branch.c:208 msgid "cannot use -a with -d" msgstr "kann -a nicht mit -d benutzen" -#: builtin/branch.c:186 +#: builtin/branch.c:214 msgid "Couldn't look up commit object for HEAD" msgstr "Konnte Versionsobjekt für Zweigspitze (HEAD) nicht nachschlagen." -#: builtin/branch.c:191 +#: builtin/branch.c:222 #, c-format msgid "Cannot delete the branch '%s' which you are currently on." msgstr "" "Kann Zweig '%s' nicht entfernen, da du dich gerade auf diesem befindest." -#: builtin/branch.c:202 +#: builtin/branch.c:235 #, c-format msgid "remote branch '%s' not found." msgstr "externer Zweig '%s' nicht gefunden" -#: builtin/branch.c:203 +#: builtin/branch.c:236 #, c-format msgid "branch '%s' not found." msgstr "Zweig '%s' nicht gefunden." -#: builtin/branch.c:210 -#, c-format -msgid "Couldn't look up commit object for '%s'" -msgstr "Konnte Versionsobjekt für '%s' nicht nachschlagen." - -#: builtin/branch.c:216 -#, 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 "" -"Der Zweig '%s' ist nicht vollständig zusammengeführt.\n" -"Wenn du sicher bist diesen Zweig zu entfernen, führe 'git branch -D %s' aus." - -#: builtin/branch.c:225 +#: builtin/branch.c:250 #, c-format msgid "Error deleting remote branch '%s'" msgstr "Fehler beim Entfernen des externen Zweiges '%s'" -#: builtin/branch.c:226 +#: builtin/branch.c:251 #, c-format msgid "Error deleting branch '%s'" msgstr "Fehler beim Entfernen des Zweiges '%s'" -#: builtin/branch.c:233 +#: builtin/branch.c:258 #, c-format msgid "Deleted remote branch %s (was %s).\n" msgstr "Externer Zweig %s entfernt (war %s).\n" -#: builtin/branch.c:234 +#: builtin/branch.c:259 #, c-format msgid "Deleted branch %s (was %s).\n" msgstr "Zweig %s entfernt (war %s).\n" -#: builtin/branch.c:239 -msgid "Update of config-file failed" -msgstr "Aktualisierung der Konfigurationsdatei fehlgeschlagen." - -#: builtin/branch.c:337 +#: builtin/branch.c:361 #, c-format msgid "branch '%s' does not point at a commit" msgstr "Zweig '%s' zeigt auf keine Version" -#: builtin/branch.c:409 +#: builtin/branch.c:433 #, c-format msgid "[%s: behind %d]" msgstr "[%s: %d hinterher]" -#: builtin/branch.c:411 +#: builtin/branch.c:435 #, c-format msgid "[behind %d]" msgstr "[%d hinterher]" -#: builtin/branch.c:415 +#: builtin/branch.c:439 #, c-format msgid "[%s: ahead %d]" msgstr "[%s: %d voraus]" -#: builtin/branch.c:417 +#: builtin/branch.c:441 #, c-format msgid "[ahead %d]" msgstr "[%d voraus]" -#: builtin/branch.c:420 +#: builtin/branch.c:444 #, c-format msgid "[%s: ahead %d, behind %d]" msgstr "[%s: %d voraus, %d hinterher]" -#: builtin/branch.c:423 +#: builtin/branch.c:447 #, c-format msgid "[ahead %d, behind %d]" msgstr "[%d voraus, %d hinterher]" -#: builtin/branch.c:535 +#: builtin/branch.c:560 msgid "(no branch)" msgstr "(kein Zweig)" -#: builtin/branch.c:600 +#: builtin/branch.c:625 msgid "some refs could not be read" msgstr "Konnte einige Referenzen nicht lesen" -#: builtin/branch.c:613 +#: builtin/branch.c:638 msgid "cannot rename the current branch while not on any." msgstr "" "Kann aktuellen Zweig nicht umbenennen, solange du dich auf keinem befindest." -#: builtin/branch.c:623 +#: builtin/branch.c:648 #, c-format msgid "Invalid branch name: '%s'" msgstr "Ungültiger Zweig-Name: '%s'" -#: builtin/branch.c:638 +#: builtin/branch.c:663 msgid "Branch rename failed" msgstr "Umbenennung des Zweiges fehlgeschlagen" -#: builtin/branch.c:642 +#: builtin/branch.c:667 #, c-format msgid "Renamed a misnamed branch '%s' away" msgstr "falsch benannten Zweig '%s' umbenannt" -#: builtin/branch.c:646 +#: builtin/branch.c:671 #, 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:653 +#: builtin/branch.c:678 msgid "Branch is renamed, but update of config-file failed" msgstr "" "Zweig ist umbenannt, aber die Aktualisierung der Konfigurationsdatei ist " "fehlgeschlagen." -#: builtin/branch.c:668 +#: builtin/branch.c:693 #, c-format msgid "malformed object name %s" msgstr "Missgebildeter Objektname %s" -#: builtin/branch.c:692 +#: builtin/branch.c:717 #, c-format msgid "could not write branch description template: %s" msgstr "Konnte Beschreibungsvorlage für Zweig nicht schreiben: %s" -#: builtin/branch.c:783 +#: builtin/branch.c:747 +msgid "Generic options" +msgstr "Allgemeine Optionen" + +#: builtin/branch.c:749 +msgid "show hash and subject, give twice for upstream branch" +msgstr "Zeigt Hash und Betreff; -vv: zusätzlich externen Ãœbernahmezweig" + +#: builtin/branch.c:750 +msgid "suppress informational messages" +msgstr "unterdrückt Informationsmeldungen" + +#: builtin/branch.c:751 +msgid "set up tracking mode (see git-pull(1))" +msgstr "stellt den Ãœbernahmemodus ein (siehe git-pull(1))" + +#: builtin/branch.c:753 +msgid "change upstream info" +msgstr "ändert Informationen zum externen Ãœbernahmezweig" + +#: builtin/branch.c:757 +msgid "use colored output" +msgstr "verwendet farbliche Ausgaben" + +#: builtin/branch.c:758 +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:1376 builtin/commit.c:1377 +#: builtin/commit.c:1378 builtin/commit.c:1379 builtin/tag.c:470 +msgid "commit" +msgstr "Version" + +#: builtin/branch.c:762 builtin/branch.c:768 +msgid "print only branches that contain the commit" +msgstr "gibt nur Zweige aus, welche diese Version beinhalten" + +#: builtin/branch.c:774 +msgid "Specific git-branch actions:" +msgstr "spezifische Aktionen für \"git-branch\":" + +#: builtin/branch.c:775 +msgid "list both remote-tracking and local branches" +msgstr "listet externe Ãœbernahmezweige und lokale Zweige auf" + +#: builtin/branch.c:777 +msgid "delete fully merged branch" +msgstr "entfernt vollständig zusammengeführten Zweig" + +#: builtin/branch.c:778 +msgid "delete branch (even if not merged)" +msgstr "löscht Zweig (auch wenn nicht zusammengeführt)" + +#: builtin/branch.c:779 +msgid "move/rename a branch and its reflog" +msgstr "verschiebt/benennt einen Zweig und dessen Referenzprotokoll um" + +#: builtin/branch.c:780 +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 +msgid "list branch names" +msgstr "listet Zweignamen auf" + +#: builtin/branch.c:782 +msgid "create the branch's reflog" +msgstr "erzeugt das Referenzprotokoll des Zweiges" + +#: builtin/branch.c:784 +msgid "edit the description for the branch" +msgstr "bearbeitet die Beschreibung für den Zweig" + +#: builtin/branch.c:785 +msgid "force creation (when already exists)" +msgstr "erzeuge auch, wenn der Zweig bereits existiert" + +#: builtin/branch.c:788 +msgid "print only not merged branches" +msgstr "gibt nur Zweige aus, die nicht zusammengeführt sind" + +#: builtin/branch.c:794 +msgid "print only merged branches" +msgstr "gibt nur Zweige aus, die zusammengeführt sind" + +#: builtin/branch.c:798 +msgid "list branches in columns" +msgstr "listet Zweige in Spalten auf" + +#: builtin/branch.c:811 msgid "Failed to resolve HEAD as a valid ref." msgstr "Konnte Zweigspitze (HEAD) nicht als gültige Referenz auflösen." -#: builtin/branch.c:788 builtin/clone.c:561 +#: builtin/branch.c:816 builtin/clone.c:561 msgid "HEAD not found below refs/heads!" msgstr "Zweigspitze (HEAD) wurde nicht unter \"refs/heads\" gefunden!" -#: builtin/branch.c:808 +#: builtin/branch.c:836 msgid "--column and --verbose are incompatible" msgstr "--column und --verbose sind inkompatibel" -#: builtin/branch.c:857 +#: builtin/branch.c:887 +#, c-format +msgid "branch '%s' does not exist" +msgstr "Zweig '%s' existiert nicht" + +#: builtin/branch.c:899 +#, c-format +msgid "Branch '%s' has no upstream information" +msgstr "Zweig '%s' hat keinen externen Ãœbernahmezweig gesetzt" + +#: builtin/branch.c:914 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' machen mit einem Zweignamen keinen " "Sinn." +#: builtin/branch.c:917 +#, c-format +msgid "" +"The --set-upstream flag is deprecated and will be removed. Consider using --" +"track or --set-upstream-to\n" +msgstr "" +"Die --set-upstream Option ist veraltet und wird entfernt. Benutze --track " +"oder --set-upstream-to\n" + +#: builtin/branch.c:934 +#, c-format +msgid "" +"\n" +"If you wanted to make '%s' track '%s', do this:\n" +"\n" +msgstr "" +"\n" +"Wenn du wolltest, dass '%s' den Zweig '%s' als externen Ãœbernahmezweig hat, " +"führe aus:\n" + +#: builtin/branch.c:935 +#, c-format +msgid " git branch -d %s\n" +msgstr " git branch -d %s\n" + +#: builtin/branch.c:936 +#, c-format +msgid " git branch --set-upstream-to %s\n" +msgstr " git branch --set-upstream-to %s\n" + #: builtin/bundle.c:47 #, c-format msgid "%s is okay\n" @@ -2130,95 +2564,228 @@ 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/checkout.c:114 builtin/checkout.c:147 +#: builtin/cat-file.c:247 +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 +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 +msgid "<type> can be one of: blob, tree, commit, tag" +msgstr "<Art> kann sein: blob, tree, commit, tag" + +#: builtin/cat-file.c:267 +msgid "show object type" +msgstr "zeigt Objektart" + +#: builtin/cat-file.c:268 +msgid "show object size" +msgstr "zeigt Objektgröße" + +#: builtin/cat-file.c:270 +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 +msgid "pretty-print object's content" +msgstr "ansprechende Anzeige des Objektinhaltes" + +#: builtin/cat-file.c:273 +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 +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 +msgid "show info about objects fed from the standard input" +msgstr "" +"Anzeige von Informationen über Objekte, gelesen von der Standard-Eingabe" + +#: builtin/check-attr.c:11 +msgid "git check-attr [-a | --all | attr...] [--] pathname..." +msgstr "git check-attr [-a | --all | Attribut...] [--] Pfadname..." + +#: builtin/check-attr.c:12 +msgid "git check-attr --stdin [-z] [-a | --all | attr...] < <list-of-paths>" +msgstr "git check-attr --stdin [-z] [-a | --all | Attribut...] < <Liste-von-Pfaden>" + +#: builtin/check-attr.c:19 +msgid "report all attributes set on file" +msgstr "gibt alle Attribute einer Datei aus" + +#: builtin/check-attr.c:20 +msgid "use .gitattributes only from the index" +msgstr "verwendet .gitattributes nur von der Bereitstellung" + +#: builtin/check-attr.c:21 builtin/hash-object.c:75 +msgid "read file names from stdin" +msgstr "liest Dateinamen von der Standard-Eingabe" + +#: builtin/check-attr.c:23 +msgid "input paths are terminated by a null character" +msgstr "Eingabepfade sind durch ein NUL Zeichen abgeschlossen" + +#: builtin/checkout-index.c:126 +msgid "git checkout-index [options] [--] [<file>...]" +msgstr "git checkout-index [Optionen] [--] [<Datei>...]" + +#: builtin/checkout-index.c:187 +msgid "check out all files in the index" +msgstr "checkt alle Dateien in der Bereitstellung aus" + +#: builtin/checkout-index.c:188 +msgid "force overwrite of existing files" +msgstr "erzwingt das Ãœberschreiben bereits existierender Dateien" + +#: builtin/checkout-index.c:190 +msgid "no warning for existing files and files not in index" +msgstr "" +"keine Warnung für existierende Dateien, und Dateien, die sich nicht in der " +"Bereitstellung befinden" + +#: builtin/checkout-index.c:192 +msgid "don't checkout new files" +msgstr "checkt keine neuen Dateien aus" + +#: builtin/checkout-index.c:194 +msgid "update stat information in the index file" +msgstr "aktualisiert Dateiinformationen in der Bereitstellungsdatei" + +#: builtin/checkout-index.c:200 +msgid "read list of paths from the standard input" +msgstr "liest eine Liste von Pfaden von der Standard-Eingabe" + +#: builtin/checkout-index.c:202 +msgid "write the content to temporary files" +msgstr "schreibt den Inhalt in temporäre Dateien" + +#: builtin/checkout-index.c:203 builtin/column.c:30 +msgid "string" +msgstr "Zeichenkette" + +#: builtin/checkout-index.c:204 +msgid "when creating files, prepend <string>" +msgstr "" +"wenn Dateien erzeugt werden, stelle <Zeichenkette> dem Dateinamen voran" + +#: builtin/checkout-index.c:207 +msgid "copy out the files from named stage" +msgstr "kopiert Dateien von dem benannten Stand" + +#: builtin/checkout.c:25 +msgid "git checkout [options] <branch>" +msgstr "git checkout [Optionen] <Zweig>" + +#: builtin/checkout.c:26 +msgid "git checkout [options] [<branch>] -- <file>..." +msgstr "git checkout [Optionen] [Zweig>] -- <Datei>..." + +#: builtin/checkout.c:116 builtin/checkout.c:149 #, c-format msgid "path '%s' does not have our version" msgstr "Pfad '%s' hat nicht unsere Version." -#: builtin/checkout.c:116 builtin/checkout.c:149 +#: builtin/checkout.c:118 builtin/checkout.c:151 #, c-format msgid "path '%s' does not have their version" msgstr "Pfad '%s' hat nicht deren Version." -#: builtin/checkout.c:132 +#: builtin/checkout.c:134 #, c-format msgid "path '%s' does not have all necessary versions" msgstr "Pfad '%s' hat nicht alle notwendigen Versionen." -#: builtin/checkout.c:176 +#: builtin/checkout.c:178 #, c-format msgid "path '%s' does not have necessary versions" msgstr "Pfad '%s' hat nicht die notwendigen Versionen." -#: builtin/checkout.c:193 +#: builtin/checkout.c:195 #, c-format msgid "path '%s': cannot merge" msgstr "Pfad '%s': kann nicht zusammenführen" -#: builtin/checkout.c:210 +#: builtin/checkout.c:212 #, c-format msgid "Unable to add merge result for '%s'" msgstr "Konnte Ergebnis der Zusammenführung von '%s' nicht hinzufügen." -#: builtin/checkout.c:235 builtin/checkout.c:392 +#: builtin/checkout.c:236 builtin/checkout.c:239 builtin/checkout.c:242 +#: builtin/checkout.c:245 +#, c-format +msgid "'%s' cannot be used with updating paths" +msgstr "'%s' kann nicht mit Pfaden benutzt werden" + +#: builtin/checkout.c:248 builtin/checkout.c:251 +#, c-format +msgid "'%s' cannot be used with %s" +msgstr "'%s' kann nicht mit '%s' benutzt werden" + +#: builtin/checkout.c:254 +#, 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 msgid "corrupt index file" msgstr "beschädigte Bereitstellungsdatei" -#: builtin/checkout.c:265 builtin/checkout.c:272 +#: builtin/checkout.c:295 builtin/checkout.c:302 #, c-format msgid "path '%s' is unmerged" msgstr "Pfad '%s' ist nicht zusammengeführt." -#: builtin/checkout.c:303 builtin/checkout.c:498 builtin/clone.c:586 -#: builtin/merge.c:811 -msgid "unable to write new index file" -msgstr "Konnte neue Bereitstellungsdatei nicht schreiben." - -#: builtin/checkout.c:414 +#: builtin/checkout.c:448 msgid "you need to resolve your current index first" msgstr "Du musst zuerst deine aktuelle Bereitstellung auflösen." -#: builtin/checkout.c:533 +#: builtin/checkout.c:569 #, c-format msgid "Can not do reflog for '%s'\n" msgstr "Konnte \"reflog\" für '%s' nicht durchführen\n" -#: builtin/checkout.c:566 +#: builtin/checkout.c:602 msgid "HEAD is now at" msgstr "Zweigspitze (HEAD) ist jetzt bei" -#: builtin/checkout.c:573 +#: builtin/checkout.c:609 #, c-format msgid "Reset branch '%s'\n" msgstr "Setze Zweig '%s' zurück\n" -#: builtin/checkout.c:576 +#: builtin/checkout.c:612 #, c-format msgid "Already on '%s'\n" msgstr "Bereits auf '%s'\n" -#: builtin/checkout.c:580 +#: builtin/checkout.c:616 #, c-format msgid "Switched to and reset branch '%s'\n" msgstr "Gewechselt zu zurückgesetztem Zweig '%s'\n" -#: builtin/checkout.c:582 +#: builtin/checkout.c:618 builtin/checkout.c:955 #, c-format msgid "Switched to a new branch '%s'\n" msgstr "Gewechselt zu einem neuen Zweig '%s'\n" -#: builtin/checkout.c:584 +#: builtin/checkout.c:620 #, c-format msgid "Switched to branch '%s'\n" msgstr "Gewechselt zu Zweig '%s'\n" -#: builtin/checkout.c:640 +#: builtin/checkout.c:676 #, c-format msgid " ... and %d more.\n" msgstr " ... und %d weitere.\n" #. The singular version -#: builtin/checkout.c:646 +#: builtin/checkout.c:682 #, c-format msgid "" "Warning: you are leaving %d commit behind, not connected to\n" @@ -2241,7 +2808,7 @@ msgstr[1] "" "\n" "%s\n" -#: builtin/checkout.c:664 +#: builtin/checkout.c:700 #, c-format msgid "" "If you want to keep them by creating a new branch, this may be a good time\n" @@ -2256,92 +2823,151 @@ msgstr "" " git branch neuer_zweig_name %s\n" "\n" -#: builtin/checkout.c:694 +#: builtin/checkout.c:730 msgid "internal error in revision walk" msgstr "interner Fehler im Revisionsgang" -#: builtin/checkout.c:698 +#: builtin/checkout.c:734 msgid "Previous HEAD position was" msgstr "Vorherige Position der Zweigspitze (HEAD) war" -#: builtin/checkout.c:724 builtin/checkout.c:919 +#: builtin/checkout.c:761 builtin/checkout.c:950 msgid "You are on a branch yet to be born" msgstr "du bist auf einem Zweig, der noch geboren wird" #. case (1) -#: builtin/checkout.c:855 +#: builtin/checkout.c:886 #, c-format msgid "invalid reference: %s" msgstr "Ungültige Referenz: %s" #. case (1): want a tree -#: builtin/checkout.c:894 +#: builtin/checkout.c:925 #, c-format msgid "reference is not a tree: %s" msgstr "Referenz ist kein Baum: %s" -#: builtin/checkout.c:976 -msgid "-B cannot be used with -b" -msgstr "-B kann nicht mit -b benutzt werden" +#: builtin/checkout.c:964 +msgid "paths cannot be used with switching branches" +msgstr "Pfade können nicht mit dem Wechseln von Zweigen benutzt werden" -#: builtin/checkout.c:985 -msgid "--patch is incompatible with all other options" -msgstr "--patch ist inkompatibel mit allen anderen Optionen" +#: builtin/checkout.c:967 builtin/checkout.c:971 +#, c-format +msgid "'%s' cannot be used with switching branches" +msgstr "'%s' kann nicht mit dem Wechseln von Zweigen benutzt werden" -#: builtin/checkout.c:988 -msgid "--detach cannot be used with -b/-B/--orphan" -msgstr "--detach kann nicht mit -b/-B/--orphan benutzt werden" +#: builtin/checkout.c:975 builtin/checkout.c:978 builtin/checkout.c:983 +#: builtin/checkout.c:986 +#, c-format +msgid "'%s' cannot be used with '%s'" +msgstr "'%s' kann nicht mit '%s' benutzt werden" -#: builtin/checkout.c:990 -msgid "--detach cannot be used with -t" -msgstr "--detach kann nicht mit -t benutzt werden" +#: builtin/checkout.c:991 +#, c-format +msgid "Cannot switch branch to a non-commit '%s'" +msgstr "Kann Zweig nicht zu Nicht-Version '%s' wechseln" -#: builtin/checkout.c:996 -msgid "--track needs a branch name" -msgstr "--track benötigt einen Zweignamen" +#: builtin/checkout.c:1012 builtin/gc.c:177 +msgid "suppress progress reporting" +msgstr "unterdrückt Fortschrittsanzeige" -#: builtin/checkout.c:1003 -msgid "Missing branch name; try -b" -msgstr "Vermisse Zweignamen; versuche -b" +#: builtin/checkout.c:1013 builtin/checkout.c:1015 builtin/clone.c:89 +#: builtin/remote.c:169 builtin/remote.c:171 +msgid "branch" +msgstr "Zweig" + +#: builtin/checkout.c:1014 +msgid "create and checkout a new branch" +msgstr "erzeugt und checkt einen neuen Zweig aus" + +#: builtin/checkout.c:1016 +msgid "create/reset and checkout a branch" +msgstr "erzeugt/setzt neu und checkt einen Zweig aus" -#: builtin/checkout.c:1009 -msgid "--orphan and -b|-B are mutually exclusive" -msgstr "--orphan und -b|-B sind gegenseitig exklusiv" +#: builtin/checkout.c:1017 +msgid "create reflog for new branch" +msgstr "erzeugt Referenzprotokoll für den neuen Zweig" -#: builtin/checkout.c:1011 -msgid "--orphan cannot be used with -t" -msgstr "--orphan kann nicht mit -t benutzt werden" +#: builtin/checkout.c:1018 +msgid "detach the HEAD at named commit" +msgstr "setzt die Zweigspitze (HEAD) zu benannter Version" + +#: builtin/checkout.c:1019 +msgid "set upstream info for new branch" +msgstr "setzt Informationen zum externen Ãœbernahmezweig für den neuen Zweig" + +#: builtin/checkout.c:1021 +msgid "new branch" +msgstr "neuer Zweig" #: builtin/checkout.c:1021 -msgid "git checkout: -f and -m are incompatible" -msgstr "git checkout: -f und -m sind inkompatibel" +msgid "new unparented branch" +msgstr "neuer Zweig ohne Elternversion" + +#: builtin/checkout.c:1022 +msgid "checkout our version for unmerged files" +msgstr "checkt unsere Variante für nicht zusammengeführte Dateien aus" + +#: builtin/checkout.c:1024 +msgid "checkout their version for unmerged files" +msgstr "checkt ihre Variante für nicht zusammengeführte Dateien aus" + +#: builtin/checkout.c:1026 +msgid "force checkout (throw away local modifications)" +msgstr "erzwingt Auschecken (verwirft lokale Änderungen)" + +#: builtin/checkout.c:1027 +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 +msgid "update ignored files (default)" +msgstr "aktualisiert ignorierte Dateien (Standard)" + +#: builtin/checkout.c:1029 builtin/log.c:1116 parse-options.h:241 +msgid "style" +msgstr "Stil" -#: builtin/checkout.c:1055 +#: builtin/checkout.c:1030 +msgid "conflict style (merge or diff3)" +msgstr "Konfliktstil (merge oder diff3)" + +#: builtin/checkout.c:1033 +msgid "second guess 'git checkout no-such-branch'" +msgstr "second guess 'git checkout no-such-branch'" + +#: builtin/checkout.c:1057 +msgid "-b, -B and --orphan are mutually exclusive" +msgstr "-b, -B und --orphan schliessen sich gegenseitig aus" + +#: builtin/checkout.c:1074 +msgid "--track needs a branch name" +msgstr "--track benötigt einen Zweignamen" + +#: builtin/checkout.c:1081 +msgid "Missing branch name; try -b" +msgstr "Vermisse Zweignamen; versuche -b" + +#: builtin/checkout.c:1116 msgid "invalid path specification" msgstr "ungültige Pfadspezifikation" -#: builtin/checkout.c:1063 +#: builtin/checkout.c:1123 #, c-format msgid "" -"git checkout: updating paths is incompatible with switching branches.\n" +"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 "" -"git checkout: Die Aktualisierung von Pfaden ist inkompatibel mit dem Wechsel " -"von Zweigen.\n" +"Kann nicht gleichzeitig Pfade aktualisieren und zu Zweig '%s' wechseln.\n" "Hast du beabsichtigt '%s' auszuchecken, welcher nicht als Version aufgelöst " "werden kann?" -#: builtin/checkout.c:1065 -msgid "git checkout: updating paths is incompatible with switching branches." -msgstr "" -"git checkout: Die Aktualisierung von Pfaden ist inkompatibel mit dem Wechsel " -"von Zweigen." - -#: builtin/checkout.c:1070 -msgid "git checkout: --detach does not take a path argument" -msgstr "git checkout: --detach nimmt kein Pfad-Argument" +#: builtin/checkout.c:1128 +#, 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:1073 +#: builtin/checkout.c:1132 msgid "" "git checkout: --ours/--theirs, --force and --merge are incompatible when\n" "checking out of the index." @@ -2349,13 +2975,38 @@ msgstr "" "git checkout: --ours/--theirs, --force und --merge sind inkompatibel wenn\n" "du aus der Bereitstellung auscheckst." -#: builtin/checkout.c:1092 -msgid "Cannot switch branch to a non-commit." -msgstr "Kann Zweig nur zu einer Version wechseln." +#: builtin/clean.c:19 +msgid "git clean [-d] [-f] [-n] [-q] [-e <pattern>] [-x | -X] [--] <paths>..." +msgstr "git clean [-d] [-f] [-n] [-q] [-e <Muster>] [-x | -X] [--] <Pfade>..." + +#: builtin/clean.c:51 +msgid "do not print names of files removed" +msgstr "gibt keine Namen von gelöschten Dateien aus" + +#: builtin/clean.c:53 +msgid "force" +msgstr "erzwingt Aktion" + +#: builtin/clean.c:55 +msgid "remove whole directories" +msgstr "löscht ganze Verzeichnisse" + +#: builtin/clean.c:56 builtin/describe.c:413 builtin/grep.c:717 +#: builtin/ls-files.c:491 builtin/name-rev.c:231 builtin/show-ref.c:182 +msgid "pattern" +msgstr "Muster" + +#: builtin/clean.c:57 +msgid "add <pattern> to ignore rules" +msgstr "fügt <Muster> zu den Regeln für ignorierte Pfade hinzu" + +#: builtin/clean.c:58 +msgid "remove ignored files, too" +msgstr "löscht auch ignorierte Dateien" -#: builtin/checkout.c:1095 -msgid "--ours/--theirs is incompatible with switching branches." -msgstr "--ours/--theirs ist inkompatibel mit den Wechseln von Zweigen." +#: builtin/clean.c:60 +msgid "remove only ignored files" +msgstr "löscht nur ignorierte Dateien" #: builtin/clean.c:78 msgid "-x and -X cannot be used together" @@ -2379,28 +3030,122 @@ msgstr "" #: builtin/clean.c:155 builtin/clean.c:176 #, c-format msgid "Would remove %s\n" -msgstr "Würde %s entfernen\n" +msgstr "Würde %s löschen\n" #: builtin/clean.c:159 builtin/clean.c:179 #, c-format msgid "Removing %s\n" -msgstr "Entferne %s\n" +msgstr "Lösche %s\n" #: builtin/clean.c:162 builtin/clean.c:182 #, c-format msgid "failed to remove %s" -msgstr "Fehler beim Entfernen von %s" +msgstr "Fehler beim Löschen von %s" #: builtin/clean.c:166 #, c-format msgid "Would not remove %s\n" -msgstr "Würde nicht entfernen %s\n" +msgstr "Würde '%s' nicht löschen\n" #: builtin/clean.c:168 #, c-format msgid "Not removing %s\n" msgstr "Entferne nicht %s\n" +#: builtin/clone.c:36 +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/push.c:399 +msgid "force progress reporting" +msgstr "erzwingt Fortschrittsanzeige" + +#: builtin/clone.c:66 +msgid "don't create a checkout" +msgstr "kein Auschecken" + +#: builtin/clone.c:67 builtin/clone.c:69 builtin/init-db.c:488 +msgid "create a bare repository" +msgstr "erstellt ein bloßes Projektarchiv" + +#: builtin/clone.c:72 +msgid "create a mirror repository (implies bare)" +msgstr "erstellt ein Spiegelarchiv (impliziert bloßes Projektarchiv)" + +#: builtin/clone.c:74 +msgid "to clone from a local repository" +msgstr "um von einem lokalen Projektarchiv zu klonen" + +#: builtin/clone.c:76 +msgid "don't use local hardlinks, always copy" +msgstr "benutzt lokal keine harten Links, immer Kopien" + +#: builtin/clone.c:78 +msgid "setup as shared repository" +msgstr "Einrichtung als verteiltes Projektarchiv" + +#: builtin/clone.c:80 builtin/clone.c:82 +msgid "initialize submodules in the clone" +msgstr "initialisiert Unterprojekte im Klon" + +#: builtin/clone.c:83 builtin/init-db.c:485 +msgid "template-directory" +msgstr "Vorlagenverzeichnis" + +#: builtin/clone.c:84 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 +msgid "reference repository" +msgstr "referenziert Projektarchiv" + +#: builtin/clone.c:87 builtin/column.c:26 builtin/merge-file.c:44 +msgid "name" +msgstr "Name" + +#: builtin/clone.c:88 +msgid "use <name> instead of 'origin' to track upstream" +msgstr "benutzt <Name> statt 'origin' für externes Projektarchiv" + +#: builtin/clone.c:90 +msgid "checkout <branch> instead of the remote's HEAD" +msgstr "" +"checkt <Zweig> aus, anstatt Zweigspitze (HEAD) des externen Projektarchivs" + +#: builtin/clone.c:92 +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 +msgid "depth" +msgstr "Tiefe" + +#: builtin/clone.c:94 +msgid "create a shallow clone of that depth" +msgstr "erstellt einen flachen Klon mit dieser Tiefe" + +#: builtin/clone.c:96 +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 +msgid "gitdir" +msgstr ".git-Verzeichnis" + +#: builtin/clone.c:98 builtin/init-db.c:495 +msgid "separate git dir from working tree" +msgstr "separiert Git-Verzeichnis vom Arbeitsbaum" + +#: builtin/clone.c:99 +msgid "key=value" +msgstr "Schlüssel=Wert" + +#: builtin/clone.c:100 +msgid "set config inside the new repository" +msgstr "setzt Konfiguration innerhalb des neuen Projektarchivs" + #: builtin/clone.c:243 #, c-format msgid "reference repository '%s' is not a local directory." @@ -2452,77 +3197,113 @@ msgstr "" "Externe Zweigspitze (HEAD) bezieht sich auf eine nicht existierende Referenz " "und kann nicht ausgecheckt werden.\n" -#: builtin/clone.c:642 +#: builtin/clone.c:690 msgid "Too many arguments." msgstr "Zu viele Argumente." -#: builtin/clone.c:646 +#: builtin/clone.c:694 msgid "You must specify a repository to clone." msgstr "Du musst ein Projektarchiv zum Klonen angeben." -#: builtin/clone.c:657 +#: builtin/clone.c:705 #, c-format msgid "--bare and --origin %s options are incompatible." msgstr "--bare und --origin %s Optionen sind inkompatibel." -#: builtin/clone.c:671 +#: builtin/clone.c:719 #, c-format msgid "repository '%s' does not exist" msgstr "Projektarchiv '%s' existiert nicht." -#: builtin/clone.c:676 +#: builtin/clone.c:724 msgid "--depth is ignored in local clones; use file:// instead." msgstr "--depth wird in lokalen Klonen ignoriert; benutze stattdessen file://." -#: builtin/clone.c:686 +#: builtin/clone.c:734 #, 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:696 +#: builtin/clone.c:744 #, c-format msgid "working tree '%s' already exists." msgstr "Arbeitsbaum '%s' existiert bereits." -#: builtin/clone.c:709 builtin/clone.c:723 +#: builtin/clone.c:757 builtin/clone.c:771 #, c-format msgid "could not create leading directories of '%s'" msgstr "Konnte führende Verzeichnisse von '%s' nicht erstellen." -#: builtin/clone.c:712 +#: builtin/clone.c:760 #, c-format msgid "could not create work tree dir '%s'." msgstr "Konnte Arbeitsverzeichnis '%s' nicht erstellen." -#: builtin/clone.c:731 +#: builtin/clone.c:779 #, c-format msgid "Cloning into bare repository '%s'...\n" msgstr "Klone in bloßes Projektarchiv '%s'...\n" -#: builtin/clone.c:733 +#: builtin/clone.c:781 #, c-format msgid "Cloning into '%s'...\n" msgstr "Klone nach '%s'...\n" -#: builtin/clone.c:789 +#: builtin/clone.c:823 #, c-format msgid "Don't know how to clone %s" msgstr "Weiß nicht wie %s zu klonen ist." -#: builtin/clone.c:838 +#: builtin/clone.c:872 #, c-format msgid "Remote branch %s not found in upstream %s" msgstr "externer Zweig %s nicht im anderen Projektarchiv %s gefunden" -#: builtin/clone.c:845 +#: builtin/clone.c:879 msgid "You appear to have cloned an empty repository." msgstr "Du scheinst ein leeres Projektarchiv geklont zu haben." +#: builtin/column.c:9 +msgid "git column [options]" +msgstr "git column [Optionen]" + +#: builtin/column.c:26 +msgid "lookup config vars" +msgstr "schlägt Konfigurationsvariablen nach" + +#: builtin/column.c:27 builtin/column.c:28 +msgid "layout to use" +msgstr "zu verwendende Anordnung" + +#: builtin/column.c:29 +msgid "Maximum width" +msgstr "maximale Breite" + +#: builtin/column.c:30 +msgid "Padding space on left border" +msgstr "Abstand zum linken Rand" + +#: builtin/column.c:31 +msgid "Padding space on right border" +msgstr "Abstand zur rechten Rand" + +#: builtin/column.c:32 +msgid "Padding space between columns" +msgstr "Abstand zwischen Spalten" + #: builtin/column.c:51 msgid "--command must be the first argument" msgstr "Option --command muss zuerst angegeben werden" -#: builtin/commit.c:43 +#: builtin/commit.c:34 +msgid "git commit [options] [--] <filepattern>..." +msgstr "git commit [Optionen] [--] <Dateimuster>..." + +#: builtin/commit.c:39 +msgid "git status [options] [--] <filepattern>..." +msgstr "git status [Optionen] [--] <Dateimuster>..." + +#: builtin/commit.c:44 msgid "" "Your name and email address were configured automatically based\n" "on your username and hostname. Please check that they are accurate.\n" @@ -2548,7 +3329,7 @@ msgstr "" "\n" " git commit --amend --reset-author\n" -#: builtin/commit.c:55 +#: builtin/commit.c:56 msgid "" "You asked to amend the most recent commit, but doing so would make\n" "it empty. You can repeat your command with --allow-empty, or you can\n" @@ -2558,7 +3339,7 @@ msgstr "" "machen. Du kannst Dein Kommando mit --allow-empty wiederholen, oder die\n" "Version mit \"git reset HEAD^\" vollständig entfernen.\n" -#: builtin/commit.c:60 +#: builtin/commit.c:61 msgid "" "The previous cherry-pick is now empty, possibly due to conflict resolution.\n" "If you wish to commit it anyway, use:\n" @@ -2575,97 +3356,97 @@ msgstr "" "\n" "Andernfalls benutze bitte 'git reset'\n" -#: builtin/commit.c:256 +#: builtin/commit.c:258 msgid "failed to unpack HEAD tree object" msgstr "Fehler beim Entpacken des Baum-Objektes der Zweigspitze (HEAD)." -#: builtin/commit.c:298 +#: builtin/commit.c:300 msgid "unable to create temporary index" msgstr "Konnte temporäre Bereitstellung nicht erstellen." -#: builtin/commit.c:304 +#: builtin/commit.c:306 msgid "interactive add failed" msgstr "interaktives Hinzufügen fehlgeschlagen" -#: builtin/commit.c:337 builtin/commit.c:358 builtin/commit.c:408 +#: builtin/commit.c:339 builtin/commit.c:360 builtin/commit.c:410 msgid "unable to write new_index file" msgstr "Konnte new_index Datei nicht schreiben" -#: builtin/commit.c:389 +#: builtin/commit.c:391 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:391 +#: builtin/commit.c:393 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:401 +#: builtin/commit.c:403 msgid "cannot read the index" msgstr "Kann Bereitstellung nicht lesen" -#: builtin/commit.c:421 +#: builtin/commit.c:423 msgid "unable to write temporary index file" msgstr "Konnte temporäre Bereitstellungsdatei nicht schreiben." -#: builtin/commit.c:496 builtin/commit.c:502 +#: builtin/commit.c:511 builtin/commit.c:517 #, c-format msgid "invalid commit: %s" msgstr "Ungültige Version: %s" -#: builtin/commit.c:525 +#: builtin/commit.c:540 msgid "malformed --author parameter" msgstr "Fehlerhafter --author Parameter" -#: builtin/commit.c:585 +#: builtin/commit.c:560 #, c-format msgid "Malformed ident string: '%s'" msgstr "Fehlerhafte Identifikations-String: '%s'" -#: builtin/commit.c:623 builtin/commit.c:656 builtin/commit.c:970 +#: builtin/commit.c:598 builtin/commit.c:631 builtin/commit.c:954 #, c-format msgid "could not lookup commit %s" msgstr "Konnte Version %s nicht nachschlagen" -#: builtin/commit.c:635 builtin/shortlog.c:296 +#: builtin/commit.c:610 builtin/shortlog.c:296 #, c-format msgid "(reading log message from standard input)\n" msgstr "(lese Log-Nachricht von Standard-Eingabe)\n" -#: builtin/commit.c:637 +#: builtin/commit.c:612 msgid "could not read log from standard input" msgstr "Konnte Log nicht von Standard-Eingabe lesen." -#: builtin/commit.c:641 +#: builtin/commit.c:616 #, c-format msgid "could not read log file '%s'" msgstr "Konnte Log-Datei '%s' nicht lesen" -#: builtin/commit.c:647 +#: builtin/commit.c:622 msgid "commit has empty message" msgstr "Version hat eine leere Beschreibung" -#: builtin/commit.c:663 +#: builtin/commit.c:638 msgid "could not read MERGE_MSG" msgstr "Konnte MERGE_MSG nicht lesen" -#: builtin/commit.c:667 +#: builtin/commit.c:642 msgid "could not read SQUASH_MSG" msgstr "Konnte SQUASH_MSG nicht lesen" -#: builtin/commit.c:671 +#: builtin/commit.c:646 #, c-format msgid "could not read '%s'" msgstr "Konnte '%s' nicht lesen" -#: builtin/commit.c:723 +#: builtin/commit.c:707 msgid "could not write commit template" msgstr "Konnte Versionsvorlage nicht schreiben" -#: builtin/commit.c:734 +#: builtin/commit.c:718 #, c-format msgid "" "\n" @@ -2676,11 +3457,11 @@ msgid "" msgstr "" "\n" "Es sieht so aus, als trägst du eine Zusammenführung ein.\n" -"Falls das nicht korrekt ist, entferne bitte die Datei\n" +"Falls das nicht korrekt ist, lösche bitte die Datei\n" "\t%s\n" "und versuche es erneut.\n" -#: builtin/commit.c:739 +#: builtin/commit.c:723 #, c-format msgid "" "\n" @@ -2691,11 +3472,11 @@ msgid "" msgstr "" "\n" "Es sieht so aus, als trägst du ein \"cherry-pick\" ein.\n" -"Falls das nicht korrekt ist, entferne bitte die Datei\n" +"Falls das nicht korrekt ist, lösche bitte die Datei\n" "\t%s\n" "und versuche es erneut.\n" -#: builtin/commit.c:751 +#: builtin/commit.c:735 msgid "" "Please enter the commit message for your changes. Lines starting\n" "with '#' will be ignored, and an empty message aborts the commit.\n" @@ -2704,7 +3485,7 @@ msgstr "" "die mit '#' beginnen, werden ignoriert, und eine leere Versionsbeschreibung\n" "bricht die Eintragung ab.\n" -#: builtin/commit.c:756 +#: builtin/commit.c:740 msgid "" "Please enter the commit message for your changes. Lines starting\n" "with '#' will be kept; you may remove them yourself if you want to.\n" @@ -2715,118 +3496,320 @@ msgstr "" "entfernen.\n" "Eine leere Versionsbeschreibung bricht die Eintragung ab.\n" -#: builtin/commit.c:769 +#: builtin/commit.c:753 #, c-format msgid "%sAuthor: %s" msgstr "%sAutor: %s" -#: builtin/commit.c:776 +#: builtin/commit.c:760 #, c-format msgid "%sCommitter: %s" msgstr "%sEintragender: %s" -#: builtin/commit.c:796 +#: builtin/commit.c:780 msgid "Cannot read index" msgstr "Kann Bereitstellung nicht lesen" -#: builtin/commit.c:833 +#: builtin/commit.c:817 msgid "Error building trees" msgstr "Fehler beim Erzeugen der Zweige" -#: builtin/commit.c:848 builtin/tag.c:361 +#: builtin/commit.c:832 builtin/tag.c:361 #, 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:945 +#: builtin/commit.c:929 #, c-format msgid "No existing author found with '%s'" msgstr "Kein existierender Autor mit '%s' gefunden." -#: builtin/commit.c:960 builtin/commit.c:1160 +#: builtin/commit.c:944 builtin/commit.c:1148 #, c-format msgid "Invalid untracked files mode '%s'" msgstr "Ungültiger Modus '%s' für unbeobachtete Dateien" -#: builtin/commit.c:1000 +#: builtin/commit.c:984 msgid "Using both --reset-author and --author does not make sense" msgstr "Verwendung von --reset-author und --author macht keinen Sinn." -#: builtin/commit.c:1011 +#: builtin/commit.c:995 msgid "You have nothing to amend." msgstr "Du hast nichts zum nachbessern." -#: builtin/commit.c:1014 +#: builtin/commit.c:998 msgid "You are in the middle of a merge -- cannot amend." msgstr "Eine Zusammenführung ist im Gange -- kann nicht nachbessern." -#: builtin/commit.c:1016 +#: builtin/commit.c:1000 msgid "You are in the middle of a cherry-pick -- cannot amend." msgstr "\"cherry-pick\" ist im Gange -- kann nicht nachbessern." -#: builtin/commit.c:1019 +#: builtin/commit.c:1003 msgid "Options --squash and --fixup cannot be used together" msgstr "" "Die Optionen --squash und --fixup können nicht gemeinsam benutzt werden." -#: builtin/commit.c:1029 +#: builtin/commit.c:1013 msgid "Only one of -c/-C/-F/--fixup can be used." msgstr "Nur eines von -c/-C/-F/--fixup kann benutzt werden." -#: builtin/commit.c:1031 +#: builtin/commit.c:1015 msgid "Option -m cannot be combined with -c/-C/-F/--fixup." msgstr "Option -m kann nicht mit -c/-C/-F/--fixup kombiniert werden" -#: builtin/commit.c:1039 +#: builtin/commit.c:1023 msgid "--reset-author can be used only with -C, -c or --amend." msgstr "--reset--author kann nur mit -C, -c oder --amend benutzt werden" -#: builtin/commit.c:1056 +#: builtin/commit.c:1040 msgid "Only one of --include/--only/--all/--interactive/--patch can be used." msgstr "" "Nur eines von --include/--only/--all/--interactive/--patch kann benutzt " "werden." -#: builtin/commit.c:1058 +#: builtin/commit.c:1042 msgid "No paths with --include/--only does not make sense." msgstr "--include/--only machen ohne Pfade keinen Sinn." -#: builtin/commit.c:1060 +#: builtin/commit.c:1044 msgid "Clever... amending the last one with dirty index." msgstr "" "Klug... die letzte Version mit einer unsauberen Bereitstellung nachbessern." -#: builtin/commit.c:1062 +#: builtin/commit.c:1046 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:1072 builtin/tag.c:577 +#: builtin/commit.c:1056 builtin/tag.c:577 #, c-format msgid "Invalid cleanup mode %s" msgstr "Ungültiger \"cleanup\" Modus %s" -#: builtin/commit.c:1077 +#: builtin/commit.c:1061 msgid "Paths with -a does not make sense." msgstr "Pfade mit -a machen keinen Sinn." -#: builtin/commit.c:1260 +#: builtin/commit.c:1067 builtin/commit.c:1202 +msgid "--long and -z are incompatible" +msgstr "--long und -z sind inkompatibel" + +#: builtin/commit.c:1162 builtin/commit.c:1398 +msgid "show status concisely" +msgstr "zeigt Status im Kurzformat" + +#: builtin/commit.c:1164 builtin/commit.c:1400 +msgid "show branch information" +msgstr "zeigt Zweiginformationen" + +#: builtin/commit.c:1166 builtin/commit.c:1402 builtin/push.c:389 +msgid "machine-readable output" +msgstr "maschinenlesbare Ausgabe" + +#: builtin/commit.c:1169 builtin/commit.c:1404 +msgid "show status in long format (default)" +msgstr "zeigt Status im Langformat (Standard)" + +#: builtin/commit.c:1172 builtin/commit.c:1407 +msgid "terminate entries with NUL" +msgstr "schließt Einträge mit NUL-Zeichen ab" + +#: builtin/commit.c:1174 builtin/commit.c:1410 builtin/fast-export.c:636 +#: builtin/fast-export.c:639 builtin/tag.c:461 +msgid "mode" +msgstr "Modus" + +#: builtin/commit.c:1175 builtin/commit.c:1410 +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:1178 +msgid "show ignored files" +msgstr "zeigt ignorierte Dateien" + +#: builtin/commit.c:1179 parse-options.h:151 +msgid "when" +msgstr "wann" + +#: builtin/commit.c:1180 +msgid "" +"ignore changes to submodules, optional when: all, dirty, untracked. " +"(Default: all)" +msgstr "" +"ignoriert Änderungen in Unterprojekten, optional wenn: all, dirty, " +"untracked. (Standard: all)" + +#: builtin/commit.c:1182 +msgid "list untracked files in columns" +msgstr "listet unbeobachtete Dateien in Spalten auf" + +#: builtin/commit.c:1256 msgid "couldn't look up newly created commit" msgstr "Konnte neu erstellte Version nicht nachschlagen." -#: builtin/commit.c:1262 +#: builtin/commit.c:1258 msgid "could not parse newly created commit" msgstr "Konnte neulich erstellte Version nicht analysieren." -#: builtin/commit.c:1303 +#: builtin/commit.c:1299 msgid "detached HEAD" msgstr "losgelöste Zweigspitze (HEAD)" -#: builtin/commit.c:1305 +#: builtin/commit.c:1301 msgid " (root-commit)" msgstr " (Basis-Version)" +#: builtin/commit.c:1368 +msgid "suppress summary after successful commit" +msgstr "unterdrückt Zusammenfassung nach erfolgreicher Eintragung" + +#: builtin/commit.c:1369 +msgid "show diff in commit message template" +msgstr "zeigt Unterschiede in Versionsbeschreibungsvorlage an" + +#: builtin/commit.c:1371 +msgid "Commit message options" +msgstr "Optionen für Versionsbeschreibung" + +#: builtin/commit.c:1372 builtin/tag.c:459 +msgid "read message from file" +msgstr "liest Beschreibung von Datei" + +#: builtin/commit.c:1373 +msgid "author" +msgstr "Autor" + +#: builtin/commit.c:1373 +msgid "override author for commit" +msgstr "überschreibt Autor von Version" + +#: builtin/commit.c:1374 builtin/gc.c:178 +msgid "date" +msgstr "Datum" + +#: builtin/commit.c:1374 +msgid "override date for commit" +msgstr "überschreibt Datum von Version" + +#: builtin/commit.c:1375 builtin/merge.c:206 builtin/notes.c:537 +#: builtin/notes.c:694 builtin/tag.c:457 +msgid "message" +msgstr "Beschreibung" + +#: builtin/commit.c:1375 +msgid "commit message" +msgstr "Versionsbeschreibung" + +#: builtin/commit.c:1376 +msgid "reuse and edit message from specified commit" +msgstr "verwendet wieder und editiert Beschreibung von der angegebenen Version" + +#: builtin/commit.c:1377 +msgid "reuse message from specified commit" +msgstr "verwendet Beschreibung der angegebenen Version wieder" + +#: builtin/commit.c:1378 +msgid "use autosquash formatted message to fixup specified commit" +msgstr "" +"benutzt eine automatisch zusammengesetzte Beschreibung zum Nachbessern der " +"angegebenen Version" + +#: builtin/commit.c:1379 +msgid "use autosquash formatted message to squash specified commit" +msgstr "" +"benutzt eine automatisch zusammengesetzte Beschreibung zum Zusammenführen " +"der angegebenen Version" + +#: builtin/commit.c:1380 +msgid "the commit is authored by me now (used with -C/-c/--amend)" +msgstr "Setze mich als Autor der Version (benutzt mit -C/-c/--amend)" + +#: builtin/commit.c:1381 builtin/log.c:1073 builtin/revert.c:109 +msgid "add Signed-off-by:" +msgstr "fügt 'Signed-off-by:'-Zeile hinzu" + +#: builtin/commit.c:1382 +msgid "use specified template file" +msgstr "benutzt angegebene Vorlagendatei" + +#: builtin/commit.c:1383 +msgid "force edit of commit" +msgstr "erzwingt Bearbeitung der Version" + +#: builtin/commit.c:1384 +msgid "default" +msgstr "Standard" + +#: builtin/commit.c:1384 builtin/tag.c:462 +msgid "how to strip spaces and #comments from message" +msgstr "" +"wie Leerzeichen und #Kommentare von der Beschreibung getrennt werden sollen" + +#: builtin/commit.c:1385 +msgid "include status in commit message template" +msgstr "fügt Status in die Versionsbeschreibungsvorlage ein" + +#: builtin/commit.c:1386 builtin/merge.c:213 builtin/tag.c:463 +msgid "key id" +msgstr "Schlüssel-ID" + +#: builtin/commit.c:1387 builtin/merge.c:214 +msgid "GPG sign commit" +msgstr "signiert Version mit GPG" + +#. end commit message options +#: builtin/commit.c:1390 +msgid "Commit contents options" +msgstr "Optionen für Versionsinhalt" + +#: builtin/commit.c:1391 +msgid "commit all changed files" +msgstr "trägt alle geänderten Dateien ein" + +#: builtin/commit.c:1392 +msgid "add specified files to index for commit" +msgstr "trägt die angegebenen Dateien zusätzlich zur Bereitstellung ein" + +#: builtin/commit.c:1393 +msgid "interactively add files" +msgstr "interaktives Hinzufügen von Dateien" + +#: builtin/commit.c:1394 +msgid "interactively add changes" +msgstr "interaktives Hinzufügen von Änderungen" + +#: builtin/commit.c:1395 +msgid "commit only specified files" +msgstr "trägt nur die angegebenen Dateien ein" + +#: builtin/commit.c:1396 +msgid "bypass pre-commit hook" +msgstr "umgeht \"pre-commit hook\"" + +#: builtin/commit.c:1397 +msgid "show what would be committed" +msgstr "zeigt an, was eingetragen werden würde" + +#: builtin/commit.c:1408 +msgid "amend previous commit" +msgstr "ändert vorherige Version" + +#: builtin/commit.c:1409 +msgid "bypass post-rewrite hook" +msgstr "umgeht \"post-rewrite hook\"" + +#: builtin/commit.c:1414 +msgid "ok to record an empty change" +msgstr "erlaubt Aufzeichnung einer leeren Änderung" + +#: builtin/commit.c:1417 +msgid "ok to record a change with an empty message" +msgstr "erlaubt Aufzeichnung einer Änderung mit einer leeren Beschreibung" + #: builtin/commit.c:1449 msgid "could not parse HEAD commit" msgstr "Konnte Version der Zweigspitze (HEAD) nicht analysieren." @@ -2860,7 +3843,7 @@ msgstr "Eintragung abgebrochen; du hast die Beschreibung nicht editiert.\n" msgid "Aborting commit due to empty commit message.\n" msgstr "Eintragung aufgrund leerer Versionsbeschreibung abgebrochen.\n" -#: builtin/commit.c:1554 builtin/merge.c:935 builtin/merge.c:960 +#: builtin/commit.c:1554 builtin/merge.c:832 builtin/merge.c:857 msgid "failed to write commit object" msgstr "Fehler beim Schreiben des Versionsobjektes." @@ -2883,6 +3866,134 @@ msgstr "" "voll und Dein Kontingent nicht aufgebraucht ist und führe\n" "anschließend \"git reset HEAD\" zu Wiederherstellung aus." +#: builtin/config.c:7 +msgid "git config [options]" +msgstr "git config [Optionen]" + +#: builtin/config.c:51 +msgid "Config file location" +msgstr "Ort der Konfigurationsdatei" + +#: builtin/config.c:52 +msgid "use global config file" +msgstr "benutzt globale Konfigurationsdatei" + +#: builtin/config.c:53 +msgid "use system config file" +msgstr "benutzt systemweite Konfigurationsdatei" + +#: builtin/config.c:54 +msgid "use repository config file" +msgstr "benutzt Konfigurationsdatei des Projektarchivs" + +#: builtin/config.c:55 +msgid "use given config file" +msgstr "benutzt die angegebene Konfigurationsdatei" + +#: builtin/config.c:56 +msgid "Action" +msgstr "Aktion" + +#: builtin/config.c:57 +msgid "get value: name [value-regex]" +msgstr "gibt Wert zurück: Name [Wert-regex]" + +#: builtin/config.c:58 +msgid "get all values: key [value-regex]" +msgstr "gibt alle Werte zurück: Schlüssel [Wert-regex]" + +#: builtin/config.c:59 +msgid "get values for regexp: name-regex [value-regex]" +msgstr "gibt Werte für den regulären Ausdruck zurück: Name-regex [Wert-regex]" + +#: builtin/config.c:60 +msgid "replace all matching variables: name value [value_regex]" +msgstr "ersetzt alle passenden Variablen: Name Wert [Wert-regex] " + +#: builtin/config.c:61 +msgid "add a new variable: name value" +msgstr "fügt neue Variable hinzu: Name Wert" + +#: builtin/config.c:62 +msgid "remove a variable: name [value-regex]" +msgstr "entfernt eine Variable: Name [Wert-regex]" + +#: builtin/config.c:63 +msgid "remove all matches: name [value-regex]" +msgstr "entfernt alle Ãœbereinstimmungen: Name [Wert-regex]" + +#: builtin/config.c:64 +msgid "rename section: old-name new-name" +msgstr "benennt eine Sektion um: alter-Name neuer-Name" + +#: builtin/config.c:65 +msgid "remove a section: name" +msgstr "entfernt eine Sektion: Name" + +#: builtin/config.c:66 +msgid "list all" +msgstr "listet alles auf" + +#: builtin/config.c:67 +msgid "open an editor" +msgstr "öffnet einen Editor" + +#: builtin/config.c:68 builtin/config.c:69 +msgid "slot" +msgstr "Slot" + +#: builtin/config.c:68 +msgid "find the color configured: [default]" +msgstr "findet die konfigurierte Farbe: [Standard]" + +#: builtin/config.c:69 +msgid "find the color setting: [stdout-is-tty]" +msgstr "findet die Farbeinstellung: [Standard-Ausgabe-ist-Terminal]" + +#: builtin/config.c:70 +msgid "Type" +msgstr "Typ" + +#: builtin/config.c:71 +msgid "value is \"true\" or \"false\"" +msgstr "Wert ist \"true\" oder \"false\"" + +#: builtin/config.c:72 +msgid "value is decimal number" +msgstr "Wert ist eine Dezimalzahl" + +#: builtin/config.c:73 +msgid "value is --bool or --int" +msgstr "Wert ist --bool oder --int" + +#: builtin/config.c:74 +msgid "value is a path (file or directory name)" +msgstr "Wert ist ein Pfad (Datei oder Verzeichnisname)" + +#: builtin/config.c:75 +msgid "Other" +msgstr "Sonstiges" + +#: builtin/config.c:76 +msgid "terminate values with NUL byte" +msgstr "schließt Werte mit NUL-Byte ab" + +#: builtin/config.c:77 +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/describe.c:15 +msgid "git describe [options] <committish>*" +msgstr "git describe [Optionen] <committish>*" + +#: builtin/describe.c:16 +msgid "git describe [options] --dirty" +msgstr "git describe [Optionen] --dirty" + #: builtin/describe.c:234 #, c-format msgid "annotated tag %s not available" @@ -2955,6 +4066,51 @@ msgstr "" "mehr als %i Markierungen gefunden; Führe die ersten %i auf\n" "Suche bei %s aufgegeben\n" +#: builtin/describe.c:403 +msgid "find the tag that comes after the commit" +msgstr "findet die Markierung, die nach der Version kommt" + +#: builtin/describe.c:404 +msgid "debug search strategy on stderr" +msgstr "protokolliert die Suchstrategie in der Standard-Fehlerausgabe" + +#: builtin/describe.c:405 +msgid "use any ref in .git/refs" +msgstr "benutzt jede Referenz in .git/refs" + +#: builtin/describe.c:406 +msgid "use any tag in .git/refs/tags" +msgstr "benutzt alle Markierungen in .git/refs/tags" + +#: builtin/describe.c:407 +msgid "always use long format" +msgstr "benutzt immer langes Format" + +#: builtin/describe.c:410 +msgid "only output exact matches" +msgstr "gibt nur exakte Ãœbereinstimmungen aus" + +#: builtin/describe.c:412 +msgid "consider <n> most recent tags (default: 10)" +msgstr "betrachtet die jüngsten <n> Markierungen (Standard: 10)" + +#: builtin/describe.c:414 +msgid "only consider tags matching <pattern>" +msgstr "betrachtet nur Markierungen die <Muster> entsprechen" + +#: builtin/describe.c:416 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 +msgid "mark" +msgstr "Kennzeichen" + +#: builtin/describe.c:418 +msgid "append <mark> on dirty working tree (default: \"-dirty\")" +msgstr "" +"fügt <Kennzeichen> bei geändertem Arbeitsbaum hinzu (Standard: \"-dirty\")" + #: builtin/describe.c:436 msgid "--long is incompatible with --abbrev=0" msgstr "--long ist inkompatibel mit --abbrev=0" @@ -2972,40 +4128,162 @@ msgstr "--dirty ist inkompatibel mit Versionen" msgid "'%s': not a regular file or symlink" msgstr "'%s': keine reguläre Datei oder symbolischer Link" -#: builtin/diff.c:224 +#: builtin/diff.c:228 #, c-format msgid "invalid option: %s" msgstr "Ungültige Option: %s" -#: builtin/diff.c:301 +#: builtin/diff.c:305 msgid "Not a git repository" msgstr "Kein Git-Projektarchiv" -#: builtin/diff.c:344 +#: builtin/diff.c:348 #, c-format msgid "invalid object '%s' given." msgstr "Objekt '%s' ist ungültig." -#: builtin/diff.c:349 +#: builtin/diff.c:353 #, c-format msgid "more than %d trees given: '%s'" msgstr "Mehr als %d Zweige angegeben: '%s'" -#: builtin/diff.c:359 +#: builtin/diff.c:363 #, c-format msgid "more than two blobs given: '%s'" msgstr "Mehr als zwei Blobs angegeben: '%s'" -#: builtin/diff.c:367 +#: builtin/diff.c:371 #, c-format msgid "unhandled object '%s' given." msgstr "unbehandeltes Objekt '%s' angegeben" -#: builtin/fetch.c:200 +#: builtin/fast-export.c:22 +msgid "git fast-export [rev-list-opts]" +msgstr "git fast-export [rev-list-opts]" + +#: builtin/fast-export.c:635 +msgid "show progress after <n> objects" +msgstr "zeigt Fortschritt nach <n> Objekten an" + +#: builtin/fast-export.c:637 +msgid "select handling of signed tags" +msgstr "wählt Behandlung von signierten Markierungen" + +#: builtin/fast-export.c:640 +msgid "select handling of tags that tag filtered objects" +msgstr "wählt Behandlung von Markierungen, die gefilterte Objekte markieren" + +#: builtin/fast-export.c:643 +msgid "Dump marks to this file" +msgstr "Schreibt Kennzeichen in diese Datei" + +#: builtin/fast-export.c:645 +msgid "Import marks from this file" +msgstr "Importiert Kennzeichen von dieser Datei" + +#: builtin/fast-export.c:647 +msgid "Fake a tagger when tags lack one" +msgstr "" +"erzeugt künstlich einen Markierungsersteller, wenn die Markierung keinen hat" + +#: builtin/fast-export.c:649 +msgid "Output full tree for each commit" +msgstr "gibt für jede Version den gesamten Baum aus" + +#: builtin/fast-export.c:651 +msgid "Use the done feature to terminate the stream" +msgstr "Benutzt die \"done\"-Funktion um den Strom abzuschließen" + +#: builtin/fast-export.c:652 +msgid "Skip output of blob data" +msgstr "Ãœberspringt Ausgabe von Blob-Daten" + +#: builtin/fetch.c:20 +msgid "git fetch [<options>] [<repository> [<refspec>...]]" +msgstr "git fetch [<Optionen>] [<Projektarchiv> [<Referenzspezifikation>...]]" + +#: builtin/fetch.c:21 +msgid "git fetch [<options>] <group>" +msgstr "git fetch [<Optionen>] <Gruppe>" + +#: builtin/fetch.c:22 +msgid "git fetch --multiple [<options>] [(<repository> | <group>)...]" +msgstr "git fetch --multiple [<Optionen>] [(<Projektarchiv> | <Gruppe>)...]" + +#: builtin/fetch.c:23 +msgid "git fetch --all [<options>]" +msgstr "git fetch --all [<Optionen>]" + +#: builtin/fetch.c:60 +msgid "fetch from all remotes" +msgstr "fordert von allen externen Projektarchiven an" + +#: builtin/fetch.c:62 +msgid "append to .git/FETCH_HEAD instead of overwriting" +msgstr "hängt an .git/FETCH_HEAD an, anstatt zu überschreiben" + +#: builtin/fetch.c:64 +msgid "path to upload pack on remote end" +msgstr "Pfad des Programms zum Hochladen von Paketen auf der Gegenseite" + +#: builtin/fetch.c:65 +msgid "force overwrite of local branch" +msgstr "erzwingt das Ãœberschreiben von lokalen Zweigen" + +#: builtin/fetch.c:67 +msgid "fetch from multiple remotes" +msgstr "fordert von mehreren externen Projektarchiven an" + +#: builtin/fetch.c:69 +msgid "fetch all tags and associated objects" +msgstr "fordert alle Markierungen und verbundene Objekte an" + +#: builtin/fetch.c:71 +msgid "do not fetch all tags (--no-tags)" +msgstr "fordert nicht alle Markierungen an (--no-tags)" + +#: builtin/fetch.c:73 +msgid "prune remote-tracking branches no longer on remote" +msgstr "" +"entfernt externe Ãœbernahmezweige, die sich nicht mehr im Fernarchiv befinden" + +#: builtin/fetch.c:74 +msgid "on-demand" +msgstr "bei-Bedarf" + +#: builtin/fetch.c:75 +msgid "control recursive fetching of submodules" +msgstr "kontrolliert rekursive Anforderungen von Unterprojekten" + +#: builtin/fetch.c:79 +msgid "keep downloaded pack" +msgstr "behält heruntergeladenes Paket" + +#: builtin/fetch.c:81 +msgid "allow updating of HEAD ref" +msgstr "erlaubt Aktualisierung der \"HEAD\"-Referenz" + +#: builtin/fetch.c:84 +msgid "deepen history of shallow clone" +msgstr "vertieft die Historie eines flachen Klon" + +#: builtin/fetch.c:85 builtin/log.c:1088 +msgid "dir" +msgstr "Verzeichnis" + +#: builtin/fetch.c:86 +msgid "prepend this to submodule path output" +msgstr "stellt dies an die Ausgabe der Unterprojekt-Pfade voran" + +#: builtin/fetch.c:89 +msgid "default mode for recursion" +msgstr "Standard-Modus für Rekursion" + +#: builtin/fetch.c:201 msgid "Couldn't find remote ref HEAD" msgstr "Konnte externe Referenz der Zweigspitze (HEAD) nicht finden." -#: builtin/fetch.c:253 +#: builtin/fetch.c:254 #, c-format msgid "object %s not found" msgstr "Objekt %s nicht gefunden" @@ -3077,7 +4355,7 @@ msgid "" " 'git remote prune %s' to remove any old, conflicting branches" msgstr "" "Einige lokale Referenzen konnten nicht aktualisiert werden; versuche\n" -"'git remote prune %s' um jeden älteren, widersprüchlichen Zweig zu entfernen." +"'git remote prune %s' um jeden älteren, widersprüchlichen Zweig zu löschen." #: builtin/fetch.c:549 #, c-format @@ -3119,17 +4397,17 @@ msgstr "Option \"%s\" Wert \"%s\" ist nicht gültig für %s" msgid "Option \"%s\" is ignored for %s\n" msgstr "Option \"%s\" wird ignoriert für %s\n" -#: builtin/fetch.c:888 +#: builtin/fetch.c:891 #, c-format msgid "Fetching %s\n" msgstr "Fordere an von %s\n" -#: builtin/fetch.c:890 builtin/remote.c:100 +#: builtin/fetch.c:893 builtin/remote.c:100 #, c-format msgid "Could not fetch %s" msgstr "Konnte nicht von %s anfordern" -#: builtin/fetch.c:907 +#: builtin/fetch.c:912 msgid "" "No remote repository specified. Please, specify either a URL or a\n" "remote name from which new revisions should be fetched." @@ -3138,29 +4416,148 @@ msgstr "" "oder den Namen des externen Archivs an, von welchem neue\n" "Versionen angefordert werden sollen." -#: builtin/fetch.c:927 +#: builtin/fetch.c:932 msgid "You need to specify a tag name." msgstr "Du musst den Namen der Markierung angeben." -#: builtin/fetch.c:979 +#: builtin/fetch.c:984 msgid "fetch --all does not take a repository argument" msgstr "fetch --all akzeptiert kein Projektarchiv als Argument" -#: builtin/fetch.c:981 +#: builtin/fetch.c:986 msgid "fetch --all does not make sense with refspecs" msgstr "fetch --all macht keinen Sinn mit Referenzspezifikationen" -#: builtin/fetch.c:992 +#: builtin/fetch.c:997 #, c-format msgid "No such remote or remote group: %s" msgstr "Kein externes Archiv (einzeln oder Gruppe): %s" -#: builtin/fetch.c:1000 +#: builtin/fetch.c:1005 msgid "Fetching a group and specifying refspecs does not make sense" msgstr "" "Abholen einer Gruppe mit Angabe von Referenzspezifikationen macht keinen " "Sinn." +#: builtin/fmt-merge-msg.c:13 +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:653 builtin/fmt-merge-msg.c:656 builtin/grep.c:701 +#: builtin/merge.c:188 builtin/show-branch.c:656 builtin/show-ref.c:175 +#: builtin/tag.c:448 parse-options.h:133 parse-options.h:235 +msgid "n" +msgstr "Anzahl" + +#: builtin/fmt-merge-msg.c:654 +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:657 +msgid "alias for --log (deprecated)" +msgstr "Alias für --log (veraltet)" + +#: builtin/fmt-merge-msg.c:660 +msgid "text" +msgstr "Text" + +#: builtin/fmt-merge-msg.c:661 +msgid "use <text> as start of message" +msgstr "benutzt <Text> als Beschreibungsanfang" + +#: builtin/fmt-merge-msg.c:662 +msgid "file to read from" +msgstr "Datei zum Einlesen" + +#: builtin/for-each-ref.c:979 +msgid "git for-each-ref [options] [<pattern>]" +msgstr "git for-each-ref [Optionen] [<Muster>]" + +#: builtin/for-each-ref.c:994 +msgid "quote placeholders suitably for shells" +msgstr "formatiert Platzhalter als Shell-String" + +#: builtin/for-each-ref.c:996 +msgid "quote placeholders suitably for perl" +msgstr "formatiert Platzhalter als Perl-String" + +#: builtin/for-each-ref.c:998 +msgid "quote placeholders suitably for python" +msgstr "formatiert Platzhalter als Python-String" + +#: builtin/for-each-ref.c:1000 +msgid "quote placeholders suitably for tcl" +msgstr "formatiert Platzhalter als TCL-String" + +#: builtin/for-each-ref.c:1003 +msgid "show only <n> matched refs" +msgstr "zeigt nur <n> passende Referenzen" + +#: builtin/for-each-ref.c:1004 +msgid "format" +msgstr "Format" + +#: builtin/for-each-ref.c:1004 +msgid "format to use for the output" +msgstr "für die Ausgabe zu verwendendes Format" + +#: builtin/for-each-ref.c:1005 +msgid "key" +msgstr "Schüssel" + +#: builtin/for-each-ref.c:1006 +msgid "field name to sort on" +msgstr "sortiere nach diesem Feld" + +#: builtin/fsck.c:608 +msgid "git fsck [options] [<object>...]" +msgstr "git fsck [Optionen] [<Objekt>...]" + +#: builtin/fsck.c:614 +msgid "show unreachable objects" +msgstr "zeigt unerreichbare Objekte" + +#: builtin/fsck.c:615 +msgid "show dangling objects" +msgstr "zeigt unreferenzierte Objekte" + +#: builtin/fsck.c:616 +msgid "report tags" +msgstr "meldet Markierungen" + +#: builtin/fsck.c:617 +msgid "report root nodes" +msgstr "meldet Hauptwurzeln" + +#: builtin/fsck.c:618 +msgid "make index objects head nodes" +msgstr "erzeugt Kopfknoten der Bereitstellungsobjekte" + +#: builtin/fsck.c:619 +msgid "make reflogs head nodes (default)" +msgstr "erzeugt Kopfknoten des Referenzprotokolls (Standard)" + +#: builtin/fsck.c:620 +msgid "also consider packs and alternate objects" +msgstr "" + +#: builtin/fsck.c:621 +msgid "enable more strict checking" +msgstr "aktiviert genauere Prüfung" + +#: builtin/fsck.c:623 +msgid "write dangling objects in .git/lost-found" +msgstr "schreibt unreferenzierte Objekte nach .git/lost-found" + +#: builtin/fsck.c:624 builtin/prune.c:134 +msgid "show progress" +msgstr "zeigt Fortschrittsanzeige" + +#: builtin/gc.c:22 +msgid "git gc [options]" +msgstr "git gc [Optionen]" + #: builtin/gc.c:63 #, c-format msgid "Invalid %s: '%s'" @@ -3171,14 +4568,19 @@ msgstr "Ungültiger %s: '%s'" msgid "insanely long object directory %.*s" msgstr "zu langes Objekt-Verzeichnis %.*s" -#: builtin/gc.c:221 -#, c-format -msgid "Auto packing the repository for optimum performance.\n" -msgstr "" -"Die Datenbank des Projektarchivs wird für eine optimale Performance " -"komprimiert.\n" +#: builtin/gc.c:179 +msgid "prune unreferenced objects" +msgstr "entfernt unreferenzierte Objekte" + +#: builtin/gc.c:181 +msgid "be more thorough (increased runtime)" +msgstr "mehr Gründlichkeit (erhöht Laufzeit)" -#: builtin/gc.c:224 +#: builtin/gc.c:182 +msgid "enable auto-gc mode" +msgstr "aktiviert \"auto-gc\" Modus" + +#: builtin/gc.c:222 #, c-format msgid "" "Auto packing the repository for optimum performance. You may also\n" @@ -3188,73 +4590,304 @@ msgstr "" "komprimiert. Du kannst auch \"git gc\" manuell ausführen.\n" "Siehe \"git help gc\" für weitere Informationen.\n" -#: builtin/gc.c:251 +#: builtin/gc.c:249 msgid "" "There are too many unreachable loose objects; run 'git prune' to remove them." msgstr "" "Es gibt zu viele unerreichbare lose Objekte; führe 'git prune' aus, um diese " -"zu entfernen." +"zu löschen." + +#: builtin/grep.c:22 +msgid "git grep [options] [-e] <pattern> [<rev>...] [[--] <path>...]" +msgstr "git grep [Optionen] [-e] <Muster> [<Version>...] [[--] <Pfad>...]" -#: builtin/grep.c:216 +#: builtin/grep.c:217 #, c-format msgid "grep: failed to create thread: %s" msgstr "grep: Fehler beim Erzeugen eines Thread: %s" -#: builtin/grep.c:454 +#: builtin/grep.c:365 #, c-format msgid "Failed to chdir: %s" msgstr "Fehler beim Verzeichniswechsel: %s" -#: builtin/grep.c:530 builtin/grep.c:564 +#: builtin/grep.c:443 builtin/grep.c:478 #, c-format msgid "unable to read tree (%s)" msgstr "konnte Zweig (%s) nicht lesen" -#: builtin/grep.c:578 +#: builtin/grep.c:493 #, c-format msgid "unable to grep from object of type %s" msgstr "kann \"grep\" nicht mit Objekten des Typs %s durchführen" -#: builtin/grep.c:636 +#: builtin/grep.c:551 #, c-format msgid "switch `%c' expects a numerical value" msgstr "Schalter '%c' erwartet einen numerischen Wert" -#: builtin/grep.c:653 +#: builtin/grep.c:568 #, c-format msgid "cannot open '%s'" msgstr "kann '%s' nicht öffnen" -#: builtin/grep.c:917 +#: builtin/grep.c:643 +msgid "search in index instead of in the work tree" +msgstr "sucht in der Bereitstellung anstatt im Arbeitsbaum" + +#: builtin/grep.c:645 +msgid "find in contents not managed by git" +msgstr "findet auch in Inhalten, die nicht von Git verwaltet werden" + +#: builtin/grep.c:647 +msgid "search in both tracked and untracked files" +msgstr "sucht in beobachteten und unbeobachteten Dateien" + +#: builtin/grep.c:649 +msgid "search also in ignored files" +msgstr "sucht auch in ignorierten Dateien" + +#: builtin/grep.c:652 +msgid "show non-matching lines" +msgstr "zeigt Zeilen ohne Ãœbereinstimmungen" + +#: builtin/grep.c:654 +msgid "case insensitive matching" +msgstr "findet Ãœbereinstimmungen unabhängig von Groß- und Kleinschreibung" + +#: builtin/grep.c:656 +msgid "match patterns only at word boundaries" +msgstr "sucht nur ganze Wörter" + +#: builtin/grep.c:658 +msgid "process binary files as text" +msgstr "verarbeitet binäre Dateien als Text" + +#: builtin/grep.c:660 +msgid "don't match patterns in binary files" +msgstr "findet keine Muster in Binärdateien" + +#: builtin/grep.c:663 +msgid "descend at most <depth> levels" +msgstr "durchläuft höchstens <Tiefe> Ebenen" + +#: builtin/grep.c:667 +msgid "use extended POSIX regular expressions" +msgstr "benutzt erweiterte reguläre Ausdrücke aus POSIX" + +#: builtin/grep.c:670 +msgid "use basic POSIX regular expressions (default)" +msgstr "benutzt grundlegende reguläre Ausdrücke aus POSIX (Standard)" + +#: builtin/grep.c:673 +msgid "interpret patterns as fixed strings" +msgstr "interpretiert Muster als feste Zeichenketten" + +#: builtin/grep.c:676 +msgid "use Perl-compatible regular expressions" +msgstr "benutzt Perl-kompatible reguläre Ausdrücke" + +#: builtin/grep.c:679 +msgid "show line numbers" +msgstr "zeigt Zeilennummern" + +#: builtin/grep.c:680 +msgid "don't show filenames" +msgstr "zeigt keine Dateinamen" + +#: builtin/grep.c:681 +msgid "show filenames" +msgstr "zeigt Dateinamen" + +#: builtin/grep.c:683 +msgid "show filenames relative to top directory" +msgstr "zeigt Dateinamen relativ zum Projektverzeichnis" + +#: builtin/grep.c:685 +msgid "show only filenames instead of matching lines" +msgstr "zeigt nur Dateinamen anstatt übereinstimmende Zeilen" + +#: builtin/grep.c:687 +msgid "synonym for --files-with-matches" +msgstr "Synonym für --files-with-matches" + +#: builtin/grep.c:690 +msgid "show only the names of files without match" +msgstr "zeigt nur die Dateinamen ohne Ãœbereinstimmungen" + +#: builtin/grep.c:692 +msgid "print NUL after filenames" +msgstr "gibt NUL-Zeichen nach Dateinamen aus" + +#: builtin/grep.c:694 +msgid "show the number of matches instead of matching lines" +msgstr "zeigt, anstatt der Zeilen, die Anzahl der übereinstimmenden Zeilen" + +#: builtin/grep.c:695 +msgid "highlight matches" +msgstr "hebt Ãœbereinstimmungen hervor" + +#: builtin/grep.c:697 +msgid "print empty line between matches from different files" +msgstr "" +"gibt eine Leerzeile zwischen Ãœbereinstimmungen in verschiedenen Dateien aus" + +#: builtin/grep.c:699 +msgid "show filename only once above matches from same file" +msgstr "" +"zeigt den Dateinamen nur einmal oberhalb der Ãœbereinstimmungen aus dieser " +"Datei an" + +#: builtin/grep.c:702 +msgid "show <n> context lines before and after matches" +msgstr "zeigt <n> Zeilen vor und nach den Ãœbereinstimmungen an" + +#: builtin/grep.c:705 +msgid "show <n> context lines before matches" +msgstr "zeigt <n> Zeilen vor den Ãœbereinstimmungen an" + +#: builtin/grep.c:707 +msgid "show <n> context lines after matches" +msgstr "zeigt <n> Zeilen nach den Ãœbereinstimmungen an" + +#: builtin/grep.c:708 +msgid "shortcut for -C NUM" +msgstr "Kurzform für -C NUM" + +#: builtin/grep.c:711 +msgid "show a line with the function name before matches" +msgstr "zeigt eine Zeile mit dem Funktionsnamen vor Ãœbereinstimmungen an" + +#: builtin/grep.c:713 +msgid "show the surrounding function" +msgstr "zeigt die umgebende Funktion an" + +#: builtin/grep.c:716 +msgid "read patterns from file" +msgstr "liest Muster von einer Datei" + +#: builtin/grep.c:718 +msgid "match <pattern>" +msgstr "findet <Muster>" + +#: builtin/grep.c:720 +msgid "combine patterns specified with -e" +msgstr "kombiniert Muster, die mit -e angegeben wurden" + +#: builtin/grep.c:732 +msgid "indicate hit with exit status without output" +msgstr "zeigt Ãœbereinstimmungen nur durch Beendigungsstatus an" + +#: builtin/grep.c:734 +msgid "show only matches from files that match all patterns" +msgstr "zeigt nur Ãœbereinstimmungen von Dateien, die allen Mustern entsprechen" + +#: builtin/grep.c:736 +msgid "show parse tree for grep expression" +msgstr "zeigt geparsten Baum für \"grep\"-Ausdruck" + +#: builtin/grep.c:740 +msgid "pager" +msgstr "Anzeigeprogramm" + +#: builtin/grep.c:740 +msgid "show matching files in the pager" +msgstr "zeigt Dateien mit Ãœbereinstimmungen im Anzeigeprogramm" + +#: builtin/grep.c:743 +msgid "allow calling of grep(1) (ignored by this build)" +msgstr "erlaubt den Aufruf von grep(1) (von dieser Programmversion ignoriert)" + +#: builtin/grep.c:744 builtin/show-ref.c:184 +msgid "show usage" +msgstr "zeigt Verwendung" + +#: builtin/grep.c:811 msgid "no pattern given." msgstr "keine Muster angegeben" -#: builtin/grep.c:931 +#: builtin/grep.c:825 #, c-format msgid "bad object %s" msgstr "ungültiges Objekt %s" -#: builtin/grep.c:972 +#: builtin/grep.c:866 msgid "--open-files-in-pager only works on the worktree" msgstr "--open-files-in-pager arbeitet nur innerhalb des Arbeitsbaums" -#: builtin/grep.c:995 +#: builtin/grep.c:889 msgid "--cached or --untracked cannot be used with --no-index." msgstr "--cached oder --untracked kann nicht mit --no-index benutzt werden" -#: builtin/grep.c:1000 +#: builtin/grep.c:894 msgid "--no-index or --untracked cannot be used with revs." msgstr "--no-index oder --untracked kann nicht mit Versionen benutzt werden" -#: builtin/grep.c:1003 +#: builtin/grep.c:897 msgid "--[no-]exclude-standard cannot be used for tracked contents." msgstr "" "--[no-]exlude-standard kann nicht mit beobachteten Inhalten benutzt werden" -#: builtin/grep.c:1011 +#: builtin/grep.c:905 msgid "both --cached and trees are given." msgstr "sowohl --cached als auch Zweige gegeben" +#: builtin/hash-object.c:60 +msgid "" +"git hash-object [-t <type>] [-w] [--path=<file>|--no-filters] [--stdin] [--] " +"<file>..." +msgstr "" +"git hash-object [-t <Art>] [-w] [--path=<Datei>|--no-filters] [--stdin] [--] " +"<Datei>..." + +#: builtin/hash-object.c:61 +msgid "git hash-object --stdin-paths < <list-of-paths>" +msgstr "git hash-object --stdin-paths < <Liste-von-Pfaden>" + +#: builtin/hash-object.c:72 +msgid "type" +msgstr "Art" + +#: builtin/hash-object.c:72 +msgid "object type" +msgstr "Art des Objektes" + +#: builtin/hash-object.c:73 +msgid "write the object into the object database" +msgstr "schreibt das Objekt in die Objektdatenbank" + +#: builtin/hash-object.c:74 +msgid "read the object from stdin" +msgstr "liest das Objekt von der Standard-Eingabe" + +#: builtin/hash-object.c:76 +msgid "store file as is without filters" +msgstr "speichert Datei wie sie ist, ohne Filter" + +#: builtin/hash-object.c:77 +msgid "process file as it were from this path" +msgstr "verarbeitet Datei, als ob sie von diesem Pfad wäre" + +#: builtin/help.c:43 +msgid "print all available commands" +msgstr "Anzeige aller vorhandenen Kommandos" + +#: builtin/help.c:44 +msgid "show man page" +msgstr "zeigt Handbuch" + +#: builtin/help.c:45 +msgid "show manual in web browser" +msgstr "zeigt Handbuch in einem Webbrowser" + +#: builtin/help.c:47 +msgid "show info page" +msgstr "zeigt Info-Seite" + +#: builtin/help.c:53 +msgid "git help [--all] [--man|--web|--info] [command]" +msgstr "git help [--all] [--man|--web|--info] [Kommando]" + #: builtin/help.c:65 #, c-format msgid "unrecognized help format '%s'" @@ -3369,6 +5002,11 @@ msgstr "Kann Paketdatei '%s' nicht öffnen" msgid "pack signature mismatch" msgstr "Paketsignatur stimmt nicht überein" +#: builtin/index-pack.c:294 +#, c-format +msgid "pack version %<PRIu32> unsupported" +msgstr "Paketversion %<PRIu32> nicht unterstützt" + #: builtin/index-pack.c:312 #, c-format msgid "pack has bad object at offset %lu: %s" @@ -3476,93 +5114,123 @@ msgstr "Fehler beim Ausführen von \"parse_pack_objects()\"" msgid "Resolving deltas" msgstr "Löse Unterschiede auf" -#: builtin/index-pack.c:1105 +#: builtin/index-pack.c:1064 +#, c-format +msgid "unable to create thread: %s" +msgstr "kann Thread nicht erzeugen: %s" + +#: builtin/index-pack.c:1106 msgid "confusion beyond insanity" msgstr "Fehler beim Auflösen der Unterschiede" -#: builtin/index-pack.c:1124 +#: builtin/index-pack.c:1112 +#, c-format +msgid "completed with %d local objects" +msgstr "vervollständigt mit %d lokalen Objekten" + +#: builtin/index-pack.c:1121 +#, c-format +msgid "Unexpected tail checksum for %s (disk corruption?)" +msgstr "Unerwartete Prüfsumme für %s (Festplattenfehler?)" + +#: builtin/index-pack.c:1125 #, 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:1149 +#: builtin/index-pack.c:1150 #, c-format msgid "unable to deflate appended object (%d)" msgstr "Konnte angehängtes Objekt (%d) nicht komprimieren" -#: builtin/index-pack.c:1228 +#: builtin/index-pack.c:1229 #, c-format msgid "local object %s is corrupt" msgstr "lokales Objekt %s ist beschädigt" -#: builtin/index-pack.c:1252 +#: builtin/index-pack.c:1253 msgid "error while closing pack file" msgstr "Fehler beim Schließen der Paketdatei" -#: builtin/index-pack.c:1265 +#: builtin/index-pack.c:1266 #, c-format msgid "cannot write keep file '%s'" msgstr "Kann Paketbeschreibungsdatei '%s' nicht schreiben" -#: builtin/index-pack.c:1273 +#: builtin/index-pack.c:1274 #, c-format msgid "cannot close written keep file '%s'" msgstr "Kann eben erstellte Paketbeschreibungsdatei '%s' nicht schließen" -#: builtin/index-pack.c:1286 +#: builtin/index-pack.c:1287 msgid "cannot store pack file" msgstr "Kann Paketdatei nicht speichern" -#: builtin/index-pack.c:1297 +#: builtin/index-pack.c:1298 msgid "cannot store index file" msgstr "Kann Indexdatei nicht speichern" -#: builtin/index-pack.c:1398 +#: builtin/index-pack.c:1331 +#, c-format +msgid "bad pack.indexversion=%<PRIu32>" +msgstr "\"pack.indexversion=%<PRIu32>\" ist ungültig" + +#: builtin/index-pack.c:1337 +#, 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 +#, c-format +msgid "no threads support, ignoring %s" +msgstr "keine Unterstützung von Threads, '%s' wird ignoriert" + +#: builtin/index-pack.c:1399 #, c-format msgid "Cannot open existing pack file '%s'" msgstr "Kann existierende Paketdatei '%s' nicht öffnen" -#: builtin/index-pack.c:1400 +#: builtin/index-pack.c:1401 #, 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:1447 +#: builtin/index-pack.c:1448 #, 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:1454 +#: builtin/index-pack.c:1455 #, 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:1481 +#: builtin/index-pack.c:1482 msgid "Cannot come back to cwd" msgstr "Kann nicht zurück zu Arbeitsverzeichnis wechseln" -#: builtin/index-pack.c:1525 builtin/index-pack.c:1528 -#: builtin/index-pack.c:1540 builtin/index-pack.c:1544 +#: builtin/index-pack.c:1526 builtin/index-pack.c:1529 +#: builtin/index-pack.c:1541 builtin/index-pack.c:1545 #, c-format msgid "bad %s" msgstr "%s ist ungültig" -#: builtin/index-pack.c:1558 +#: builtin/index-pack.c:1559 msgid "--fix-thin cannot be used without --stdin" msgstr "--fix-thin kann nicht ohne --stdin benutzt werden" -#: builtin/index-pack.c:1562 builtin/index-pack.c:1572 +#: builtin/index-pack.c:1563 builtin/index-pack.c:1573 #, c-format msgid "packfile name '%s' does not end with '.pack'" msgstr "Name der Paketdatei '%s' endet nicht mit '.pack'" -#: builtin/index-pack.c:1581 +#: builtin/index-pack.c:1582 msgid "--verify with no packfile name given" msgstr "--verify ohne Name der Paketdatei angegeben" @@ -3682,6 +5350,27 @@ msgstr " gemeinsames" msgid "cannot tell cwd" msgstr "kann aktuelles Arbeitsverzeichnis nicht ermitteln" +#: builtin/init-db.c:467 +msgid "" +"git init [-q | --quiet] [--bare] [--template=<template-directory>] [--shared" +"[=<permissions>]] [directory]" +msgstr "" +"git init [-q | --quiet] [--bare] [--template=<Vorlagenverzeichnis>] [--shared" +"[=<Berechtigungen>]] [Verzeichnis]" + +#: builtin/init-db.c:490 +msgid "permissions" +msgstr "Berechtigungen" + +#: builtin/init-db.c:491 +msgid "specify that the git repository is to be shared amongst several users" +msgstr "" +"gibt an, dass das Git-Projektarchiv mit mehreren Benutzern geteilt wird" + +#: builtin/init-db.c:493 builtin/prune-packed.c:77 +msgid "be quiet" +msgstr "weniger Ausgaben" + #: builtin/init-db.c:522 builtin/init-db.c:529 #, c-format msgid "cannot mkdir %s" @@ -3710,94 +5399,239 @@ msgstr "Kann nicht auf aktuelles Arbeitsverzeichnis zugreifen." msgid "Cannot access work tree '%s'" msgstr "Kann nicht auf Arbeitsbaum '%s' zugreifen." +#: builtin/log.c:37 +msgid "git log [<options>] [<since>..<until>] [[--] <path>...]\n" +msgstr "git log [<Optionen>] [<seit>..<bis>] [[--] <Pfad>...]\n" + +#: builtin/log.c:38 +msgid " or: git show [options] <object>..." +msgstr " oder: git show [Optionen] <Objekt>..." + +#: builtin/log.c:100 +msgid "suppress diff output" +msgstr "unterdrückt Ausgabe der Unterschiede" + +#: builtin/log.c:101 +msgid "show source" +msgstr "zeigt Quelle" + +#: builtin/log.c:102 +msgid "decorate options" +msgstr "decorate-Optionen" + #: builtin/log.c:189 #, c-format msgid "Final output: %d %s\n" msgstr "letzte Ausgabe: %d %s\n" -#: builtin/log.c:403 builtin/log.c:494 +#: builtin/log.c:405 builtin/log.c:497 #, c-format msgid "Could not read object %s" msgstr "Kann Objekt %s nicht lesen." -#: builtin/log.c:518 +#: builtin/log.c:521 #, c-format msgid "Unknown type: %d" msgstr "Unbekannter Typ: %d" -#: builtin/log.c:608 +#: builtin/log.c:613 msgid "format.headers without value" msgstr "format.headers ohne Wert" -#: builtin/log.c:682 +#: builtin/log.c:687 msgid "name of output directory is too long" msgstr "Name des Ausgabeverzeichnisses ist zu lang." -#: builtin/log.c:693 +#: builtin/log.c:698 #, c-format msgid "Cannot open patch file %s" msgstr "Kann Patch-Datei %s nicht öffnen" -#: builtin/log.c:707 +#: builtin/log.c:712 msgid "Need exactly one range." msgstr "Brauche genau einen Versionsbereich." -#: builtin/log.c:715 +#: builtin/log.c:720 msgid "Not a range." msgstr "Kein Versionsbereich." -#: builtin/log.c:789 +#: builtin/log.c:794 msgid "Cover letter needs email format" msgstr "Anschreiben benötigt E-Mail-Format" -#: builtin/log.c:862 +#: builtin/log.c:867 #, c-format msgid "insane in-reply-to: %s" msgstr "ungültiges in-reply-to: %s" -#: builtin/log.c:935 +#: builtin/log.c:895 +msgid "git format-patch [options] [<since> | <revision range>]" +msgstr "git format-patch [Optionen] [<seit> | <Versionsbereich>]" + +#: builtin/log.c:940 msgid "Two output directories?" msgstr "Zwei Ausgabeverzeichnisse?" -#: builtin/log.c:1157 +#: builtin/log.c:1068 +msgid "use [PATCH n/m] even with a single patch" +msgstr "benutzt [PATCH n/m] auch mit einzelnem Patch" + +#: builtin/log.c:1071 +msgid "use [PATCH] even with multiple patches" +msgstr "benutzt [PATCH] auch mit mehreren Patches" + +#: builtin/log.c:1075 +msgid "print patches to standard out" +msgstr "Ausgabe der Patches in Standard-Ausgabe" + +#: builtin/log.c:1077 +msgid "generate a cover letter" +msgstr "erzeugt ein Deckblatt" + +#: builtin/log.c:1079 +msgid "use simple number sequence for output file names" +msgstr "benutzt einfache Nummernfolge für die Namen der Ausgabedateien" + +#: builtin/log.c:1080 +msgid "sfx" +msgstr "Dateiendung" + +#: builtin/log.c:1081 +msgid "use <sfx> instead of '.patch'" +msgstr "verwendet <Dateiendung> anstatt '.patch'" + +#: builtin/log.c:1083 +msgid "start numbering patches at <n> instead of 1" +msgstr "beginnt die Nummerierung der Patches bei <n> anstatt bei 1" + +#: builtin/log.c:1085 +msgid "Use [<prefix>] instead of [PATCH]" +msgstr "benutzt [<Prefix>] anstatt [PATCH]" + +#: builtin/log.c:1088 +msgid "store resulting files in <dir>" +msgstr "speichert erzeugte Dateien in <Verzeichnis>" + +#: builtin/log.c:1091 +msgid "don't strip/add [PATCH]" +msgstr "[PATCH] wird nicht entfernt/hinzugefügt" + +#: builtin/log.c:1094 +msgid "don't output binary diffs" +msgstr "gibt keine binären Unterschiede aus" + +#: builtin/log.c:1096 +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:1098 +msgid "show patch format instead of default (patch + stat)" +msgstr "zeigt Patchformat anstatt des Standards (Patch + Zusammenfassung)" + +#: builtin/log.c:1100 +msgid "Messaging" +msgstr "Email-Einstellungen" + +#: builtin/log.c:1101 +msgid "header" +msgstr "Header" + +#: builtin/log.c:1102 +msgid "add email header" +msgstr "fügt Email-Header hinzu" + +#: builtin/log.c:1103 builtin/log.c:1105 +msgid "email" +msgstr "Email" + +#: builtin/log.c:1103 +msgid "add To: header" +msgstr "fügt \"To:\"-Header hinzu" + +#: builtin/log.c:1105 +msgid "add Cc: header" +msgstr "fügt \"Cc:\"-Header hinzu" + +#: builtin/log.c:1107 +msgid "message-id" +msgstr "message-id" + +#: builtin/log.c:1108 +msgid "make first mail a reply to <message-id>" +msgstr "macht aus erster Email eine Antwort zu <message-id>" + +#: builtin/log.c:1109 builtin/log.c:1112 +msgid "boundary" +msgstr "Grenze" + +#: builtin/log.c:1110 +msgid "attach the patch" +msgstr "hängt einen Patch an" + +#: builtin/log.c:1113 +msgid "inline the patch" +msgstr "fügt den Patch direkt in die Nachricht ein" + +#: builtin/log.c:1117 +msgid "enable message threading, styles: shallow, deep" +msgstr "aktiviert Nachrichtenverkettung, Stile: shallow, deep" + +#: builtin/log.c:1119 +msgid "signature" +msgstr "Signatur" + +#: builtin/log.c:1120 +msgid "add a signature" +msgstr "fügt eine Signatur hinzu" + +#: builtin/log.c:1122 +msgid "don't print the patch filenames" +msgstr "zeigt keine Dateinamen der Patches" + +#: builtin/log.c:1163 #, c-format msgid "bogus committer info %s" msgstr "unechte Einreicher-Informationen %s" -#: builtin/log.c:1202 +#: builtin/log.c:1208 msgid "-n and -k are mutually exclusive." msgstr "-n und -k schließen sich gegenseitig aus" -#: builtin/log.c:1204 +#: builtin/log.c:1210 msgid "--subject-prefix and -k are mutually exclusive." msgstr "--subject-prefix und -k schließen sich gegenseitig aus" -#: builtin/log.c:1212 +#: builtin/log.c:1218 msgid "--name-only does not make sense" msgstr "--name-only macht keinen Sinn" -#: builtin/log.c:1214 +#: builtin/log.c:1220 msgid "--name-status does not make sense" msgstr "--name-status macht keinen Sinn" -#: builtin/log.c:1216 +#: builtin/log.c:1222 msgid "--check does not make sense" msgstr "--check macht keinen Sinn" -#: builtin/log.c:1239 +#: builtin/log.c:1245 msgid "standard output, or directory, which one?" msgstr "Standard-Ausgabe oder Verzeichnis, welches von beidem?" -#: builtin/log.c:1241 +#: builtin/log.c:1247 #, c-format msgid "Could not create directory '%s'" msgstr "Konnte Verzeichnis '%s' nicht erstellen." -#: builtin/log.c:1394 +#: builtin/log.c:1400 msgid "Failed to create output files" msgstr "Fehler beim Erstellen der Ausgabedateien." -#: builtin/log.c:1498 +#: builtin/log.c:1449 +msgid "git cherry [-v] [<upstream> [<head> [<limit>]]]" +msgstr "git cherry [-v] [<Ãœbernahmezweig> [<Arbeitszweig> [<Limit>]]]" + +#: builtin/log.c:1504 #, c-format msgid "" "Could not find a tracked remote branch, please specify <upstream> manually.\n" @@ -3805,11 +5639,157 @@ msgstr "" "Konnte gefolgten, externen Zweig nicht finden, bitte gebe <upstream> manuell " "an.\n" -#: builtin/log.c:1511 builtin/log.c:1513 builtin/log.c:1525 +#: builtin/log.c:1517 builtin/log.c:1519 builtin/log.c:1531 #, c-format msgid "Unknown commit %s" msgstr "Unbekannte Version %s" +#: builtin/ls-files.c:408 +msgid "git ls-files [options] [<file>...]" +msgstr "git ls-files [Optionen] [<Datei>...]" + +#: builtin/ls-files.c:463 +msgid "identify the file status with tags" +msgstr "zeigt den Dateistatus mit Markierungen" + +#: builtin/ls-files.c:465 +msgid "use lowercase letters for 'assume unchanged' files" +msgstr "benutzt Kleinbuchstaben für Dateien mit 'assume unchanged' Markierung" + +#: builtin/ls-files.c:467 +msgid "show cached files in the output (default)" +msgstr "zeigt zwischengespeicherten Dateien in der Ausgabe an (Standard)" + +#: builtin/ls-files.c:469 +msgid "show deleted files in the output" +msgstr "zeigt entfernte Dateien in der Ausgabe an" + +#: builtin/ls-files.c:471 +msgid "show modified files in the output" +msgstr "zeigt geänderte Dateien in der Ausgabe an" + +#: builtin/ls-files.c:473 +msgid "show other files in the output" +msgstr "zeigt sonstige Dateien in der Ausgabe an" + +#: builtin/ls-files.c:475 +msgid "show ignored files in the output" +msgstr "zeigt ignorierte Dateien in der Ausgabe an" + +#: builtin/ls-files.c:478 +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:480 +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:482 +msgid "show 'other' directories' name only" +msgstr "zeigt nur Namen von 'sonstigen' Verzeichnissen an" + +#: builtin/ls-files.c:485 +msgid "don't show empty directories" +msgstr "zeigt keine leeren Verzeichnisse an" + +#: builtin/ls-files.c:488 +msgid "show unmerged files in the output" +msgstr "zeigt nicht zusammengeführte Dateien in der Ausgabe an" + +#: builtin/ls-files.c:490 +msgid "show resolve-undo information" +msgstr "zeigt 'resolve-undo' Informationen an" + +#: builtin/ls-files.c:492 +msgid "skip files matching pattern" +msgstr "lässt Dateien aus, die einem Muster entsprechen" + +#: builtin/ls-files.c:495 +msgid "exclude patterns are read from <file>" +msgstr "schließt Muster, gelesen von <Datei>, aus" + +#: builtin/ls-files.c:498 +msgid "read additional per-directory exclude patterns in <file>" +msgstr "liest zusätzliche pro-Verzeichnis Auschlussmuster aus <Datei>" + +#: builtin/ls-files.c:500 +msgid "add the standard git exclusions" +msgstr "fügt die standardmäßigen Git-Ausschlüsse hinzu" + +#: builtin/ls-files.c:503 +msgid "make the output relative to the project top directory" +msgstr "Ausgabe relativ zum Projektverzeichnis" + +#: builtin/ls-files.c:506 +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:507 +msgid "tree-ish" +msgstr "Versionsreferenz" + +#: builtin/ls-files.c:508 +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:510 +msgid "show debugging data" +msgstr "zeigt Ausgaben zur Fehlersuche an" + +#: builtin/ls-tree.c:27 +msgid "git ls-tree [<options>] <tree-ish> [<path>...]" +msgstr "git ls-tree [<Optionen>] <Versionsreferenz> [<Pfad>...]" + +#: builtin/ls-tree.c:125 +msgid "only show trees" +msgstr "zeigt nur Bäume an" + +#: builtin/ls-tree.c:127 +msgid "recurse into subtrees" +msgstr "führt Rekursion in Teilbäumen durch" + +#: builtin/ls-tree.c:129 +msgid "show trees when recursing" +msgstr "zeigt Bäume bei Rekursion an" + +#: builtin/ls-tree.c:132 +msgid "terminate entries with NUL byte" +msgstr "schließt Einträge mit NUL-Byte ab" + +#: builtin/ls-tree.c:133 +msgid "include object size" +msgstr "schließt Objektgröße ein" + +#: builtin/ls-tree.c:135 builtin/ls-tree.c:137 +msgid "list only filenames" +msgstr "listet nur Dateinamen auf" + +#: builtin/ls-tree.c:140 +msgid "use full path names" +msgstr "benutzt vollständige Pfadnamen" + +#: builtin/ls-tree.c:142 +msgid "list entire tree; not just current directory (implies --full-name)" +msgstr "" +"listet den gesamten Baum auf; nicht nur das aktuelle Verzeichnis (impliziert " +"--full-name)" + +#: builtin/merge.c:43 +msgid "git merge [options] [<commit>...]" +msgstr "git merge [Optionen] [<Version>...]" + +#: builtin/merge.c:44 +msgid "git merge [options] <msg> HEAD <commit>" +msgstr "git merge [Optionen] <Beschreibung> HEAD <Version>" + +#: builtin/merge.c:45 +msgid "git merge --abort" +msgstr "git merge --abort" + #: builtin/merge.c:90 msgid "switch `m' requires a value" msgstr "Schalter 'm' erfordert einen Wert." @@ -3829,6 +5809,75 @@ msgstr "Verfügbare Strategien sind:" msgid "Available custom strategies are:" msgstr "Verfügbare benutzerdefinierte Strategien sind:" +#: builtin/merge.c:183 +msgid "do not show a diffstat at the end of the merge" +msgstr "" +"zeigt keine Zusammenfassung der Unterschiede am Schluss der Zusammenführung " +"an" + +#: builtin/merge.c:186 +msgid "show a diffstat at the end of the merge" +msgstr "" +"zeigt eine Zusammenfassung der Unterschiede am Schluss der Zusammenführung an" + +#: builtin/merge.c:187 +msgid "(synonym to --stat)" +msgstr "(Synonym für --stat)" + +#: builtin/merge.c:189 +msgid "add (at most <n>) entries from shortlog to merge commit message" +msgstr "" +"fügt (höchstens <n>) Einträge von \"shortlog\" zur Beschreibung der " +"Zusammenführung hinzu" + +#: builtin/merge.c:192 +msgid "create a single commit instead of doing a merge" +msgstr "erzeugt eine einzelne Version anstatt einer Zusammenführung" + +#: builtin/merge.c:194 +msgid "perform a commit if the merge succeeds (default)" +msgstr "" +"führt eine Eintragung durch, wenn die Zusammenführung erfolgreich war " +"(Standard)" + +#: builtin/merge.c:196 +msgid "edit message before committing" +msgstr "Bearbeitung der Versionsbeschreibung vor der Eintragung" + +#: builtin/merge.c:198 +msgid "allow fast-forward (default)" +msgstr "erlaubt Vorspulen (Standard)" + +#: builtin/merge.c:200 +msgid "abort if fast-forward is not possible" +msgstr "bricht ab, wenn kein Vorspulen möglich ist" + +#: builtin/merge.c:202 builtin/notes.c:870 builtin/revert.c:112 +msgid "strategy" +msgstr "Strategie" + +#: builtin/merge.c:203 +msgid "merge strategy to use" +msgstr "zu verwendende Zusammenführungsstrategie" + +#: builtin/merge.c:204 +msgid "option=value" +msgstr "Option=Wert" + +#: builtin/merge.c:205 +msgid "option for selected merge strategy" +msgstr "Option für ausgewählte Zusammenführungsstrategie" + +#: builtin/merge.c:207 +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 +msgid "abort the current in-progress merge" +msgstr "bricht die sich im Gange befindliche Zusammenführung ab" + #: builtin/merge.c:240 msgid "could not run stash." msgstr "Konnte \"stash\" nicht ausführen." @@ -3884,37 +5933,33 @@ msgstr "Ungültiger branch.%s.mergeoptions String: %s" msgid "git write-tree failed to write a tree" msgstr "\"git write-tree\" schlug beim Schreiben eines Baumes fehl" -#: builtin/merge.c:678 -msgid "failed to read the cache" -msgstr "Lesen des Zwischenspeichers fehlgeschlagen" - -#: builtin/merge.c:709 +#: builtin/merge.c:656 msgid "Not handling anything other than two heads merge." msgstr "Es wird nur die Zusammenführung von zwei Zweigen behandelt." -#: builtin/merge.c:723 +#: builtin/merge.c:670 #, c-format msgid "Unknown option for merge-recursive: -X%s" msgstr "Unbekannte Option für merge-recursive: -X%s" -#: builtin/merge.c:737 +#: builtin/merge.c:684 #, c-format msgid "unable to write %s" msgstr "konnte %s nicht schreiben" -#: builtin/merge.c:876 +#: builtin/merge.c:773 #, c-format msgid "Could not read from '%s'" msgstr "konnte nicht von '%s' lesen" -#: builtin/merge.c:885 +#: builtin/merge.c:782 #, c-format msgid "Not committing merge; use 'git commit' to complete the merge.\n" msgstr "" "Zusammenführung wurde nicht eingetragen; benutze 'git commit' um die " "Zusammenführung abzuschließen.\n" -#: builtin/merge.c:891 +#: builtin/merge.c:788 msgid "" "Please enter a commit message to explain why this merge is necessary,\n" "especially if it merges an updated upstream into a topic branch.\n" @@ -3930,56 +5975,56 @@ msgstr "" "Zeilen beginnend mit '#' werden ignoriert, und eine leere Beschreibung " "bricht die Eintragung ab.\n" -#: builtin/merge.c:915 +#: builtin/merge.c:812 msgid "Empty commit message." msgstr "Leere Versionsbeschreibung" -#: builtin/merge.c:927 +#: builtin/merge.c:824 #, c-format msgid "Wonderful.\n" msgstr "Wunderbar.\n" -#: builtin/merge.c:992 +#: builtin/merge.c:889 #, c-format msgid "Automatic merge failed; fix conflicts and then commit the result.\n" msgstr "" "Automatische Zusammenführung fehlgeschlagen; behebe die Konflikte und trage " "dann das Ergebnis ein.\n" -#: builtin/merge.c:1008 +#: builtin/merge.c:905 #, c-format msgid "'%s' is not a commit" msgstr "'%s' ist keine Version" -#: builtin/merge.c:1049 +#: builtin/merge.c:946 msgid "No current branch." msgstr "Du befindest dich auf keinem Zweig." -#: builtin/merge.c:1051 +#: builtin/merge.c:948 msgid "No remote for the current branch." msgstr "Kein externes Archiv für den aktuellen Zweig." -#: builtin/merge.c:1053 +#: builtin/merge.c:950 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:1058 +#: builtin/merge.c:955 #, c-format msgid "No remote tracking branch for %s from %s" msgstr "Kein externer Ãœbernahmezweig für %s von %s" -#: builtin/merge.c:1145 builtin/merge.c:1302 +#: builtin/merge.c:1042 builtin/merge.c:1199 #, c-format msgid "%s - not something we can merge" msgstr "%s - nichts was wir zusammenführen können" -#: builtin/merge.c:1213 +#: builtin/merge.c:1110 msgid "There is no merge to abort (MERGE_HEAD missing)." msgstr "Es gibt keine Zusammenführung zum Abbrechen (vermisse MERGE_HEAD)" -#: builtin/merge.c:1229 git-pull.sh:31 +#: builtin/merge.c:1126 git-pull.sh:31 msgid "" "You have not concluded your merge (MERGE_HEAD exists).\n" "Please, commit your changes before you can merge." @@ -3987,12 +6032,12 @@ msgstr "" "Du hast deine Zusammenführung nicht abgeschlossen (MERGE_HEAD existiert).\n" "Bitte trage deine Änderungen ein, bevor du zusammenführen kannst." -#: builtin/merge.c:1232 git-pull.sh:34 +#: builtin/merge.c:1129 git-pull.sh:34 msgid "You have not concluded your merge (MERGE_HEAD exists)." msgstr "" "Du hast deine Zusammenführung nicht abgeschlossen (MERGE_HEAD existiert)." -#: builtin/merge.c:1236 +#: builtin/merge.c:1133 msgid "" "You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists).\n" "Please, commit your changes before you can merge." @@ -4000,86 +6045,186 @@ msgstr "" "Du hast \"cherry-pick\" nicht abgeschlossen (CHERRY_PICK_HEAD existiert).\n" "Bitte trage deine Änderungen ein, bevor du zusammenführen kannst." -#: builtin/merge.c:1239 +#: builtin/merge.c:1136 msgid "You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists)." msgstr "" "Du hast \"cherry-pick\" nicht abgeschlossen (CHERRY_PICK_HEAD existiert)." -#: builtin/merge.c:1248 +#: builtin/merge.c:1145 msgid "You cannot combine --squash with --no-ff." msgstr "Du kannst --squash nicht mit --no-ff kombinieren." -#: builtin/merge.c:1253 +#: builtin/merge.c:1150 msgid "You cannot combine --no-ff with --ff-only." msgstr "Du kannst --no-ff nicht mit --ff--only kombinieren." -#: builtin/merge.c:1260 +#: builtin/merge.c:1157 msgid "No commit specified and merge.defaultToUpstream not set." msgstr "Keine Version angegeben und merge.defaultToUpstream ist nicht gesetzt." -#: builtin/merge.c:1292 +#: builtin/merge.c:1189 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:1295 +#: builtin/merge.c:1192 msgid "Squash commit into empty head not supported yet" msgstr "Bin auf einem Zweig, der noch geboren wird; kann nicht quetschen." -#: builtin/merge.c:1297 +#: builtin/merge.c:1194 msgid "Non-fast-forward commit does not make sense into an empty head" msgstr "nicht vorzuspulende Version macht in einem leeren Zweig keinen Sinn" -#: builtin/merge.c:1412 +#: builtin/merge.c:1309 #, c-format msgid "Updating %s..%s\n" msgstr "Aktualisiere %s..%s\n" -#: builtin/merge.c:1450 +#: builtin/merge.c:1348 #, c-format msgid "Trying really trivial in-index merge...\n" msgstr "Probiere wirklich triviale \"in-index\"-Zusammenführung...\n" -#: builtin/merge.c:1457 +#: builtin/merge.c:1355 #, c-format msgid "Nope.\n" msgstr "Nein.\n" -#: builtin/merge.c:1489 +#: builtin/merge.c:1387 msgid "Not possible to fast-forward, aborting." msgstr "Vorspulen nicht möglich, breche ab." -#: builtin/merge.c:1512 builtin/merge.c:1591 +#: builtin/merge.c:1410 builtin/merge.c:1489 #, c-format msgid "Rewinding the tree to pristine...\n" msgstr "Rücklauf des Zweiges bis zum Ursprung...\n" -#: builtin/merge.c:1516 +#: builtin/merge.c:1414 #, c-format msgid "Trying merge strategy %s...\n" msgstr "Probiere Zusammenführungsstrategie %s...\n" -#: builtin/merge.c:1582 +#: builtin/merge.c:1480 #, c-format msgid "No merge strategy handled the merge.\n" msgstr "Keine Zusammenführungsstrategie behandelt diese Zusammenführung.\n" -#: builtin/merge.c:1584 +#: builtin/merge.c:1482 #, c-format msgid "Merge with strategy %s failed.\n" msgstr "Zusammenführung mit Strategie %s fehlgeschlagen.\n" -#: builtin/merge.c:1593 +#: builtin/merge.c:1491 #, c-format msgid "Using the %s to prepare resolving by hand.\n" msgstr "Benutze \"%s\" um die Auflösung per Hand vorzubereiten.\n" -#: builtin/merge.c:1605 +#: builtin/merge.c:1503 #, c-format msgid "Automatic merge went well; stopped before committing as requested\n" msgstr "" "Automatische Zusammenführung abgeschlossen; halte, wie gewünscht, vor der " "Eintragung an\n" +#: builtin/merge-base.c:26 +msgid "git merge-base [-a|--all] <commit> <commit>..." +msgstr "git merge-base [-a|--all] <Version> <Version>..." + +#: builtin/merge-base.c:27 +msgid "git merge-base [-a|--all] --octopus <commit>..." +msgstr "git merge-base [-a|--all] --octopus <Version>..." + +#: builtin/merge-base.c:28 +msgid "git merge-base --independent <commit>..." +msgstr "git merge-base --independent <Version>..." + +#: builtin/merge-base.c:29 +msgid "git merge-base --is-ancestor <commit> <commit>" +msgstr "git merge-base --is-ancestor <Version> <Version>" + +#: builtin/merge-base.c:98 +msgid "output all common ancestors" +msgstr "Ausgabe aller gemeinsamen Vorfahren" + +#: builtin/merge-base.c:99 +msgid "find ancestors for a single n-way merge" +msgstr "findet Vorfahren für eine einzelne n-Wege-Zusammenführung" + +#: builtin/merge-base.c:100 +msgid "list revs not reachable from others" +msgstr "listet Revisionen auf, die nicht durch Andere erreichbar sind" + +#: builtin/merge-base.c:102 +msgid "is the first one ancestor of the other?" +msgstr "ist der Erste ein Vorfahre von dem Anderen?" + +#: builtin/merge-file.c:8 +msgid "" +"git merge-file [options] [-L name1 [-L orig [-L name2]]] file1 orig_file " +"file2" +msgstr "" +"git merge-file [Optionen] [-L Name1 [-L orig [-L Name2]]] Datei1 orig_Datei " +"Datei2" + +#: builtin/merge-file.c:33 +msgid "send results to standard output" +msgstr "sendet Ergebnisse zur Standard-Ausgabe" + +#: builtin/merge-file.c:34 +msgid "use a diff3 based merge" +msgstr "benutzt eine diff3 basierte Zusammenführung" + +#: builtin/merge-file.c:35 +msgid "for conflicts, use our version" +msgstr "verwendet bei Konflikten unsere Variante" + +#: builtin/merge-file.c:37 +msgid "for conflicts, use their version" +msgstr "verwendet bei Konflikten ihre Variante" + +#: builtin/merge-file.c:39 +msgid "for conflicts, use a union version" +msgstr "verwendet bei Konflikten eine gemeinsame Variante" + +#: builtin/merge-file.c:42 +msgid "for conflicts, use this marker size" +msgstr "verwendet bei Konflikten diese Kennzeichnungslänge" + +#: builtin/merge-file.c:43 +msgid "do not warn about conflicts" +msgstr "keine Warnung bei Konflikten" + +#: builtin/merge-file.c:45 +msgid "set labels for file1/orig_file/file2" +msgstr "setzt Beschriftung für Datei1/orig_Datei/Datei2" + +#: builtin/mktree.c:67 +msgid "git mktree [-z] [--missing] [--batch]" +msgstr "git mktree [-z] [--missing] [--batch]" + +#: builtin/mktree.c:153 +msgid "input is NUL terminated" +msgstr "Eingabe ist durch NUL-Zeichen abgeschlossen" + +#: builtin/mktree.c:154 builtin/write-tree.c:24 +msgid "allow missing objects" +msgstr "erlaubt fehlende Objekte" + +#: builtin/mktree.c:155 +msgid "allow creation of more than one tree" +msgstr "erlaubt die Erstellung von mehr als einem Baum" + +#: builtin/mv.c:14 +msgid "git mv [options] <source>... <destination>" +msgstr "git mv [Optionen] <Quelle>... <Ziel>" + +#: builtin/mv.c:64 +msgid "force move/rename even if target exists" +msgstr "erzwingt Verschieben/Umbenennen, auch wenn das Ziel existiert" + +#: builtin/mv.c:65 +msgid "skip move/rename errors" +msgstr "überspringt Fehler beim Verschieben oder Umbenennen" + #: builtin/mv.c:108 #, c-format msgid "Checking rename of '%s' to '%s'\n" @@ -4142,115 +6287,288 @@ msgstr "Benenne %s nach %s um\n" msgid "renaming '%s' failed" msgstr "Umbenennung von '%s' fehlgeschlagen" -#: builtin/notes.c:139 +#: builtin/name-rev.c:175 +msgid "git name-rev [options] <commit>..." +msgstr "git name-rev [Optionen] <Version>..." + +#: builtin/name-rev.c:176 +msgid "git name-rev [options] --all" +msgstr "git name-rev [Optionen] --all" + +#: builtin/name-rev.c:177 +msgid "git name-rev [options] --stdin" +msgstr "git name-rev [Optionen] --stdin" + +#: builtin/name-rev.c:229 +msgid "print only names (no SHA-1)" +msgstr "zeigt nur Namen an (keine SHA-1)" + +#: builtin/name-rev.c:230 +msgid "only use tags to name the commits" +msgstr "benutzt nur Markierungen um die Versionen zu benennen" + +#: builtin/name-rev.c:232 +msgid "only use refs matching <pattern>" +msgstr "benutzt nur Referenzen die <Muster> entsprechen" + +#: builtin/name-rev.c:234 +msgid "list all commits reachable from all refs" +msgstr "listet alle Versionen auf, die von allen Referenzen erreichbar sind" + +#: builtin/name-rev.c:235 +msgid "read from stdin" +msgstr "liest von der Standard-Eingabe" + +#: builtin/name-rev.c:236 +msgid "allow to print `undefined` names" +msgstr "erlaubt Ausgabe von `undefinierten` Namen" + +#: builtin/notes.c:26 +msgid "git notes [--ref <notes_ref>] [list [<object>]]" +msgstr "git notes [--ref <Notiz-Referenz>] [list [<Objekt>]]" + +#: builtin/notes.c:27 +msgid "" +"git notes [--ref <notes_ref>] add [-f] [-m <msg> | -F <file> | (-c | -C) " +"<object>] [<object>]" +msgstr "" +"git notes [--ref <Notiz-Referenz>] add [-f] [-m <Nachricht> | -F <Datei> | (-" +"c | -C) <Objekt>] [<Objekt>]" + +#: builtin/notes.c:28 +msgid "git notes [--ref <notes_ref>] copy [-f] <from-object> <to-object>" +msgstr "" +"git notes [--ref <Notiz-Referenz>] copy [-f] <von-Objekt> <nach-Objekt>" + +#: builtin/notes.c:29 +msgid "" +"git notes [--ref <notes_ref>] append [-m <msg> | -F <file> | (-c | -C) " +"<object>] [<object>]" +msgstr "" +"git notes [--ref <Notiz-Referenz>] append [-m <Nachricht> | -F <Datei> | (-c " +"| -C) <Objekt>] [<Objekt>]" + +#: builtin/notes.c:30 +msgid "git notes [--ref <notes_ref>] edit [<object>]" +msgstr "git notes [--ref <Notiz-Referenz>] edit [<Objekt>]" + +#: builtin/notes.c:31 +msgid "git notes [--ref <notes_ref>] show [<object>]" +msgstr "git notes [--ref <Notiz-Referenz>] show [<Objekt>]" + +#: builtin/notes.c:32 +msgid "" +"git notes [--ref <notes_ref>] merge [-v | -q] [-s <strategy> ] <notes_ref>" +msgstr "" +"git notes [--ref <Notiz-Referenz>] merge [-v | -q] [-s <Strategie> ] <Notiz-" +"Referenz>" + +#: builtin/notes.c:33 +msgid "git notes merge --commit [-v | -q]" +msgstr "git notes merge --commit [-v | -q]" + +#: builtin/notes.c:34 +msgid "git notes merge --abort [-v | -q]" +msgstr "git notes merge --abort [-v | -q]" + +#: builtin/notes.c:35 +msgid "git notes [--ref <notes_ref>] remove [<object>...]" +msgstr "git notes [--ref <Notiz-Referenz>] remove [<Objekt>...]" + +#: builtin/notes.c:36 +msgid "git notes [--ref <notes_ref>] prune [-n | -v]" +msgstr "git notes [--ref <Notiz-Referenz>] prune [-n | -v]" + +#: builtin/notes.c:37 +msgid "git notes [--ref <notes_ref>] get-ref" +msgstr "git notes [--ref <Notiz-Referenz>] get-ref" + +#: builtin/notes.c:42 +msgid "git notes [list [<object>]]" +msgstr "git notes [list [<Objekt>]]" + +#: builtin/notes.c:47 +msgid "git notes add [<options>] [<object>]" +msgstr "git notes add [<Optionen>] [<Objekt>]" + +#: builtin/notes.c:52 +msgid "git notes copy [<options>] <from-object> <to-object>" +msgstr "git notes copy [<Optionen>] <von-Objekt> <nach-Objekt>" + +#: builtin/notes.c:53 +msgid "git notes copy --stdin [<from-object> <to-object>]..." +msgstr "git notes copy --stdin [<von-Objekt> <nach-Objekt>]..." + +#: builtin/notes.c:58 +msgid "git notes append [<options>] [<object>]" +msgstr "git notes append [<Optionen>] [<Objekt>]" + +#: builtin/notes.c:63 +msgid "git notes edit [<object>]" +msgstr "git notes edit [<Objekt>]" + +#: builtin/notes.c:68 +msgid "git notes show [<object>]" +msgstr "git notes show [<Objekt>]" + +#: builtin/notes.c:73 +msgid "git notes merge [<options>] <notes_ref>" +msgstr "git notes merge [<Optionen>] <Notiz-Referenz>" + +#: builtin/notes.c:74 +msgid "git notes merge --commit [<options>]" +msgstr "git notes merge --commit [<Optionen>]" + +#: builtin/notes.c:75 +msgid "git notes merge --abort [<options>]" +msgstr "git notes merge --abort [<Optionen>]" + +#: builtin/notes.c:80 +msgid "git notes remove [<object>]" +msgstr "git notes remove [<Objekt>]" + +#: builtin/notes.c:85 +msgid "git notes prune [<options>]" +msgstr "git notes prune [<Optionen>]" + +#: builtin/notes.c:90 +msgid "git notes get-ref" +msgstr "git notes get-ref" + +#: builtin/notes.c:142 #, c-format msgid "unable to start 'show' for object '%s'" msgstr "konnte 'show' für Objekt '%s' nicht starten" -#: builtin/notes.c:145 +#: builtin/notes.c:148 msgid "can't fdopen 'show' output fd" msgstr "konnte Datei-Deskriptor für Ausgabe von 'show' nicht öffnen" -#: builtin/notes.c:155 +#: builtin/notes.c:158 #, c-format msgid "failed to close pipe to 'show' for object '%s'" msgstr "Schließen der Verbindung zu 'show' ist für Objekt '%s' fehlgeschlagen." -#: builtin/notes.c:158 +#: builtin/notes.c:161 #, c-format msgid "failed to finish 'show' for object '%s'" msgstr "konnte 'show' für Objekt '%s' nicht abschließen" -#: builtin/notes.c:175 builtin/tag.c:347 +#: builtin/notes.c:178 builtin/tag.c:347 #, c-format msgid "could not create file '%s'" msgstr "konnte Datei '%s' nicht erstellen" -#: builtin/notes.c:189 +#: builtin/notes.c:192 msgid "Please supply the note contents using either -m or -F option" msgstr "Bitte liefere den Notiz-Inhalt unter Verwendung der Option -m oder -F." -#: builtin/notes.c:210 builtin/notes.c:973 +#: builtin/notes.c:213 builtin/notes.c:976 #, c-format msgid "Removing note for object %s\n" msgstr "Entferne Notiz für Objekt %s\n" -#: builtin/notes.c:215 +#: builtin/notes.c:218 msgid "unable to write note object" msgstr "Konnte Notiz-Objekt nicht schreiben" -#: builtin/notes.c:217 +#: builtin/notes.c:220 #, c-format msgid "The note contents has been left in %s" msgstr "Die Notiz-Inhalte wurden in %s belassen" -#: builtin/notes.c:251 builtin/tag.c:542 +#: builtin/notes.c:254 builtin/tag.c:542 #, c-format msgid "cannot read '%s'" msgstr "kann '%s' nicht lesen" -#: builtin/notes.c:253 builtin/tag.c:545 +#: builtin/notes.c:256 builtin/tag.c:545 #, c-format msgid "could not open or read '%s'" msgstr "konnte '%s' nicht öffnen oder lesen" -#: builtin/notes.c:272 builtin/notes.c:445 builtin/notes.c:447 -#: builtin/notes.c:507 builtin/notes.c:561 builtin/notes.c:644 -#: builtin/notes.c:649 builtin/notes.c:724 builtin/notes.c:766 -#: builtin/notes.c:968 builtin/reset.c:293 builtin/tag.c:558 +#: builtin/notes.c:275 builtin/notes.c:448 builtin/notes.c:450 +#: builtin/notes.c:510 builtin/notes.c:564 builtin/notes.c:647 +#: builtin/notes.c:652 builtin/notes.c:727 builtin/notes.c:769 +#: builtin/notes.c:971 builtin/reset.c:293 builtin/tag.c:558 #, c-format msgid "Failed to resolve '%s' as a valid ref." msgstr "Konnte '%s' nicht als gültige Referenz auflösen." -#: builtin/notes.c:275 +#: builtin/notes.c:278 #, c-format msgid "Failed to read object '%s'." msgstr "Fehler beim Lesen des Objektes '%s'." -#: builtin/notes.c:299 +#: builtin/notes.c:302 msgid "Cannot commit uninitialized/unreferenced notes tree" msgstr "Kann uninitialisierten/unreferenzierten Notiz-Baum nicht eintragen." -#: builtin/notes.c:340 +#: builtin/notes.c:343 #, c-format msgid "Bad notes.rewriteMode value: '%s'" msgstr "Ungültiger notes.rewriteMode Wert: '%s'" -#: builtin/notes.c:350 +#: builtin/notes.c:353 #, c-format msgid "Refusing to rewrite notes in %s (outside of refs/notes/)" msgstr "" -"Neuschreiben der Notizen in %s zurückgewiesen (außerhalb von refs/notes/)" +"Umschreiben der Notizen in %s zurückgewiesen (außerhalb von refs/notes/)" #. TRANSLATORS: The first %s is the name of the #. environment variable, the second %s is its value -#: builtin/notes.c:377 +#: builtin/notes.c:380 #, c-format msgid "Bad %s value: '%s'" msgstr "Ungültiger %s Wert: '%s'" -#: builtin/notes.c:441 +#: builtin/notes.c:444 #, c-format msgid "Malformed input line: '%s'." msgstr "Fehlerhafte Eingabezeile: '%s'." -#: builtin/notes.c:456 +#: builtin/notes.c:459 #, c-format msgid "Failed to copy notes from '%s' to '%s'" msgstr "Fehler beim Kopieren der Notizen von '%s' nach '%s'" -#: builtin/notes.c:500 builtin/notes.c:554 builtin/notes.c:627 -#: builtin/notes.c:639 builtin/notes.c:712 builtin/notes.c:759 -#: builtin/notes.c:1033 +#: builtin/notes.c:503 builtin/notes.c:557 builtin/notes.c:630 +#: builtin/notes.c:642 builtin/notes.c:715 builtin/notes.c:762 +#: builtin/notes.c:1036 msgid "too many parameters" msgstr "zu viele Parameter" -#: builtin/notes.c:513 builtin/notes.c:772 +#: builtin/notes.c:516 builtin/notes.c:775 #, c-format msgid "No note found for object %s." msgstr "Kein Notiz für Objekt %s gefunden." -#: builtin/notes.c:580 +#: builtin/notes.c:538 builtin/notes.c:695 +msgid "note contents as a string" +msgstr "Notizinhalte als Zeichenkette" + +#: builtin/notes.c:541 builtin/notes.c:698 +msgid "note contents in a file" +msgstr "Notizinhalte in einer Datei" + +#: builtin/notes.c:543 builtin/notes.c:546 builtin/notes.c:700 +#: builtin/notes.c:703 builtin/tag.c:476 +msgid "object" +msgstr "Objekt" + +#: builtin/notes.c:544 builtin/notes.c:701 +msgid "reuse and edit specified note object" +msgstr "Wiederverwendung und Bearbeitung des angegebenen Notiz-Objektes" + +#: builtin/notes.c:547 builtin/notes.c:704 +msgid "reuse specified note object" +msgstr "Wiederverwendung des angegebenen Notiz-Objektes" + +#: builtin/notes.c:549 builtin/notes.c:617 +msgid "replace existing notes" +msgstr "ersetzt existierende Notizen" + +#: builtin/notes.c:583 #, c-format msgid "" "Cannot add notes. Found existing notes for object %s. Use '-f' to overwrite " @@ -4259,16 +6577,26 @@ msgstr "" "Konnte Notizen nicht hinzufügen. Existierende Notizen für Objekt %s " "gefunden. Verwende '-f' um die existierenden Notizen zu überschreiben." -#: builtin/notes.c:585 builtin/notes.c:662 +#: builtin/notes.c:588 builtin/notes.c:665 #, c-format msgid "Overwriting existing notes for object %s\n" msgstr "Ãœberschreibe existierende Notizen für Objekt %s\n" -#: builtin/notes.c:635 +#: builtin/notes.c:618 +msgid "read objects from stdin" +msgstr "liest Objekte von der Standard-Eingabe" + +#: builtin/notes.c:620 +msgid "load rewriting config for <command> (implies --stdin)" +msgstr "" +"lädt Konfiguration für <Kommando> beim Umschreiben von Versionen (impliziert " +"--stdin)" + +#: builtin/notes.c:638 msgid "too few parameters" msgstr "zu wenig Parameter" -#: builtin/notes.c:656 +#: builtin/notes.c:659 #, c-format msgid "" "Cannot copy notes. Found existing notes for object %s. Use '-f' to overwrite " @@ -4277,12 +6605,12 @@ msgstr "" "Kann Notizen nicht kopieren. Existierende Notizen für Objekt %s gefunden. " "Verwende '-f' um die existierenden Notizen zu überschreiben." -#: builtin/notes.c:668 +#: builtin/notes.c:671 #, c-format msgid "Missing notes on source object %s. Cannot copy." msgstr "Keine Notizen für Quell-Objekt %s. Kopie nicht möglich." -#: builtin/notes.c:717 +#: builtin/notes.c:720 #, c-format msgid "" "The -m/-F/-c/-C options have been deprecated for the 'edit' subcommand.\n" @@ -4291,41 +6619,264 @@ msgstr "" "Die Optionen -m/-F/-c/-C sind für das Unterkommando 'edit' veraltet.\n" "Bitte benutze stattdessen 'git notes add -f -m/-F/-c/-C'.\n" -#: builtin/notes.c:971 +#: builtin/notes.c:867 +msgid "General options" +msgstr "Allgemeine Optionen" + +#: builtin/notes.c:869 +msgid "Merge options" +msgstr "Optionen für Zusammenführung" + +#: builtin/notes.c:871 +msgid "" +"resolve notes conflicts using the given strategy (manual/ours/theirs/union/" +"cat_sort_uniq)" +msgstr "" +"löst Konflikte bei Notizen mit der angegebenen Strategie auf (manual/ours/" +"theirs/union/cat_sort_uniq)" + +#: builtin/notes.c:873 +msgid "Committing unmerged notes" +msgstr "trägt nicht zusammengeführte Notizen ein" + +#: builtin/notes.c:875 +msgid "finalize notes merge by committing unmerged notes" +msgstr "" +"schließt Zusammenführung von Notizen ab, in dem nicht zusammengeführte " +"Notizen eingetragen werden" + +#: builtin/notes.c:877 +msgid "Aborting notes merge resolution" +msgstr "bricht Konfliktauflösung bei Zusammenführung von Notizen ab" + +#: builtin/notes.c:879 +msgid "abort notes merge" +msgstr "bricht Zusammenführung von Notizen ab" + +#: builtin/notes.c:974 #, c-format msgid "Object %s has no note\n" msgstr "Objekt %s hat keine Notiz\n" -#: builtin/notes.c:1103 builtin/remote.c:1598 +#: builtin/notes.c:986 +msgid "attempt to remove non-existent note is not an error" +msgstr "der Versuch, eine nicht existierende Notiz zu löschen, ist kein Fehler" + +#: builtin/notes.c:989 +msgid "read object names from the standard input" +msgstr "liest Objektnamen von der Standard-Eingabe" + +#: builtin/notes.c:1070 +msgid "notes_ref" +msgstr "Notiz-Referenz" + +#: builtin/notes.c:1071 +msgid "use notes from <notes_ref>" +msgstr "benutzt Notizen von <Notiz-Referenz>" + +#: builtin/notes.c:1106 builtin/remote.c:1598 #, c-format msgid "Unknown subcommand: %s" msgstr "Unbekanntes Unterkommando: %s" +#: builtin/pack-objects.c:23 +msgid "git pack-objects --stdout [options...] [< ref-list | < object-list]" +msgstr "" +"git pack-objects --stdout [Optionen...] [< Referenzliste | < Objektliste]" + +#: builtin/pack-objects.c:24 +msgid "git pack-objects [options...] base-name [< ref-list | < object-list]" +msgstr "" +"git pack-objects [Optionen...] Basis-Name [< Referenzliste | < Objektliste]" + #: builtin/pack-objects.c:183 builtin/pack-objects.c:186 #, c-format msgid "deflate error (%d)" msgstr "Fehler beim Komprimieren (%d)" -#: builtin/pack-objects.c:2398 +#: builtin/pack-objects.c:2397 #, c-format msgid "unsupported index version %s" msgstr "Nicht unterstützte Bereitstellungsversion %s" -#: builtin/pack-objects.c:2402 +#: builtin/pack-objects.c:2401 #, c-format msgid "bad index version '%s'" msgstr "Ungültige Bereitstellungsversion '%s'" -#: builtin/pack-objects.c:2425 +#: builtin/pack-objects.c:2424 #, c-format msgid "option %s does not accept negative form" msgstr "Option %s akzeptiert keine negative Form" -#: builtin/pack-objects.c:2429 +#: builtin/pack-objects.c:2428 #, c-format msgid "unable to parse value '%s' for option %s" msgstr "konnte Wert '%s' für Option %s nicht parsen" +#: builtin/pack-objects.c:2447 +msgid "do not show progress meter" +msgstr "zeigt keine Fortschrittsanzeige" + +#: builtin/pack-objects.c:2449 +msgid "show progress meter" +msgstr "zeigt Fortschrittsanzeige" + +#: builtin/pack-objects.c:2451 +msgid "show progress meter during object writing phase" +msgstr "zeigt Forschrittsanzeige während der Phase des Schreibens der Objekte" + +#: builtin/pack-objects.c:2454 +msgid "similar to --all-progress when progress meter is shown" +msgstr "ähnlich zu --all-progress wenn Fortschrittsanzeige darstellt wird" + +#: builtin/pack-objects.c:2455 +msgid "version[,offset]" +msgstr "version[,offset]" + +#: builtin/pack-objects.c:2456 +msgid "write the pack index file in the specified idx format version" +msgstr "" +"schreibt die Index-Datei des Paketes in der angegebenen Indexformat-Version" + +#: builtin/pack-objects.c:2459 +msgid "maximum size of each output pack file" +msgstr "maximale Größe für jede ausgegebene Paketdatei" + +#: builtin/pack-objects.c:2461 +msgid "ignore borrowed objects from alternate object store" +msgstr "ignoriert geliehene Objekte von alternativem Objektspeicher" + +#: builtin/pack-objects.c:2463 +msgid "ignore packed objects" +msgstr "ignoriert gepackte Objekte" + +#: builtin/pack-objects.c:2465 +msgid "limit pack window by objects" +msgstr "begrenzt Paketfenster durch Objekte" + +#: builtin/pack-objects.c:2467 +msgid "limit pack window by memory in addition to object limit" +msgstr "begrenzt Paketfenster, zusätzlich zur Objektbegrenzung, durch Speicher" + +#: builtin/pack-objects.c:2469 +msgid "maximum length of delta chain allowed in the resulting pack" +msgstr "" +"maximale Länge der erlaubten Differenzverkettung im resultierenden Paket" + +#: builtin/pack-objects.c:2471 +msgid "reuse existing deltas" +msgstr "verwendet existierende Unterschiede wieder" + +#: builtin/pack-objects.c:2473 +msgid "reuse existing objects" +msgstr "verwendet existierende Objekte wieder" + +#: builtin/pack-objects.c:2475 +msgid "use OFS_DELTA objects" +msgstr "benutzt OFS_DELTA Objekte" + +#: builtin/pack-objects.c:2477 +msgid "use threads when searching for best delta matches" +msgstr "" +"benutzt Threads bei der Suche nach den besten Ãœbereinstimmungen bei " +"Unterschieden" + +#: builtin/pack-objects.c:2479 +msgid "do not create an empty pack output" +msgstr "erzeugt keine leeren Pakete" + +#: builtin/pack-objects.c:2481 +msgid "read revision arguments from standard input" +msgstr "liest Argumente bezüglich Revisionen von der Standard-Eingabe" + +#: builtin/pack-objects.c:2483 +msgid "limit the objects to those that are not yet packed" +msgstr "begrenzt die Objekte zu solchen, die noch nicht gepackt wurden" + +#: builtin/pack-objects.c:2486 +msgid "include objects reachable from any reference" +msgstr "schließt Objekte ein, die von jeder Referenz erreichbar sind" + +#: builtin/pack-objects.c:2489 +msgid "include objects referred by reflog entries" +msgstr "" +"schließt Objekte ein, die von Einträgen des Referenzprotokolls referenziert " +"werden" + +#: builtin/pack-objects.c:2492 +msgid "output pack to stdout" +msgstr "schreibt Paket in die Standard-Ausgabe" + +#: builtin/pack-objects.c:2494 +msgid "include tag objects that refer to objects to be packed" +msgstr "" +"schließt Markierungsobjekte ein, die auf gepackte Objekte referenzieren" + +#: builtin/pack-objects.c:2496 +msgid "keep unreachable objects" +msgstr "behält nicht erreichbare Objekte" + +#: builtin/pack-objects.c:2497 parse-options.h:141 +msgid "time" +msgstr "Zeit" + +#: builtin/pack-objects.c:2498 +msgid "unpack unreachable objects newer than <time>" +msgstr "entpackt nicht erreichbare Objekte, die neuer als <Zeit> sind" + +#: builtin/pack-objects.c:2501 +msgid "create thin packs" +msgstr "erzeugt dünnere Pakete" + +#: builtin/pack-objects.c:2503 +msgid "ignore packs that have companion .keep file" +msgstr "ignoriert Pakete die .keep Dateien haben" + +#: builtin/pack-objects.c:2505 +msgid "pack compression level" +msgstr "Komprimierungsgrad für Paketierung" + +#: builtin/pack-objects.c:2507 +msgid "do not hide commits by grafts" +msgstr "verbirgt keine Versionen mit künstlichen Vorgängern (\"grafts\")" + +#: builtin/pack-refs.c:6 +msgid "git pack-refs [options]" +msgstr "git pack-refs [Optionen]" + +#: builtin/pack-refs.c:14 +msgid "pack everything" +msgstr "packt alles" + +#: builtin/pack-refs.c:15 +msgid "prune loose refs (default)" +msgstr "entfernt lose Referenzen (Standard)" + +#: builtin/prune-packed.c:7 +msgid "git prune-packed [-n|--dry-run] [-q|--quiet]" +msgstr "git prune-packed [-n|--dry-run] [-q|--quiet]" + +#: builtin/prune.c:12 +msgid "git prune [-n] [-v] [--expire <time>] [--] [<head>...]" +msgstr "git prune [-n] [-v] [--expire <Zeit>] [--] [<Zweigspitze>...]" + +#: builtin/prune.c:132 +msgid "do not remove, show only" +msgstr "nicht löschen, nur anzeigen" + +#: builtin/prune.c:133 +msgid "report pruned objects" +msgstr "meldet gelöschte Objekte" + +#: builtin/prune.c:136 +msgid "expire objects older than <time>" +msgstr "lässt Objekte älter als <Zeit> verfallen" + +#: builtin/push.c:14 +msgid "git push [<options>] [<repository> [<refspec>...]]" +msgstr "git push [<Optionen>] [<Projektarchiv> [<Referenzspezifikation>...]]" + #: builtin/push.c:45 msgid "tag shorthand without <tag>" msgstr "Kurzschrift für Markierung ohne <Markierung>" @@ -4434,20 +6985,20 @@ msgstr "" "'push.default' ist nicht gesetzt; der implizit gesetzte Wert\n" "wird in Git 2.0 von 'matching' nach 'simple' geändert. Um diese Meldung zu\n" "unterdrücken und das aktuelle Verhalten nach Änderung des Standardwertes\n" -"beizubehalten, benutze:" -"\n" +"beizubehalten, benutze:\n" " git config --global push.default matching\n" "\n" -"Um diese Meldung zu unterdrücken und das neue Verhalten jetzt zu übernehmen,\n" +"Um diese Meldung zu unterdrücken und das neue Verhalten jetzt zu " +"übernehmen,\n" "benutze:\n" "\n" " git config --global push.default simple\n" "\n" "Führe 'git help config' aus und suche nach 'push.default' für weitere " "Informationen.\n" -"(Der Modus 'simple' wurde in Git 1.7.11 eingeführt. Benutze den ähnlichen" -" Modus 'current' anstatt 'simple', falls du gelegentlich ältere Versionen von" -" Git benutzt.)" +"(Der Modus 'simple' wurde in Git 1.7.11 eingeführt. Benutze den ähnlichen " +"Modus 'current' anstatt 'simple', falls du gelegentlich ältere Versionen von " +"Git benutzt.)" #: builtin/push.c:199 msgid "" @@ -4555,6 +7106,55 @@ msgstr "--mirror kann nicht mit Referenzspezifikationen kombiniert werden" msgid "--all and --mirror are incompatible" msgstr "--all und --mirror sind inkompatibel" +#: builtin/push.c:382 +msgid "repository" +msgstr "Projektarchiv" + +#: builtin/push.c:383 +msgid "push all refs" +msgstr "versendet alle Referenzen" + +#: builtin/push.c:384 +msgid "mirror all refs" +msgstr "spiegelt alle Referenzen" + +#: builtin/push.c:386 +msgid "delete refs" +msgstr "löscht Referenzen" + +#: builtin/push.c:387 +msgid "push tags (can't be used with --all or --mirror)" +msgstr "" +"versendet Markierungen (kann nicht mit --all oder --mirror benutzt werden)" + +#: builtin/push.c:390 +msgid "force updates" +msgstr "erzwingt Aktualisierung" + +#: builtin/push.c:391 +msgid "check" +msgstr "" + +#: builtin/push.c:392 +msgid "control recursive pushing of submodules" +msgstr "steuert rekursives Versenden von Unterprojekten" + +#: builtin/push.c:394 +msgid "use thin pack" +msgstr "benutzt kleinere Pakete" + +#: builtin/push.c:395 builtin/push.c:396 +msgid "receive pack program" +msgstr "'receive pack' Programm" + +#: builtin/push.c:397 +msgid "set upstream for git pull/status" +msgstr "setzt externes Projektarchiv für \"git pull/status\"" + +#: builtin/push.c:400 +msgid "prune locally removed refs" +msgstr "entfernt lokal gelöschte Referenzen" + #: builtin/push.c:410 msgid "--delete is incompatible with --all, --mirror and --tags" msgstr "--delete ist inkompatibel mit --all, --mirror und --tags" @@ -4563,6 +7163,163 @@ msgstr "--delete ist inkompatibel mit --all, --mirror und --tags" msgid "--delete doesn't make sense without any refs" msgstr "--delete macht ohne irgendeine Referenz keinen Sinn" +#: builtin/read-tree.c:36 +msgid "" +"git read-tree [[-m [--trivial] [--aggressive] | --reset | --prefix=<prefix>] " +"[-u [--exclude-per-directory=<gitignore>] | -i]] [--no-sparse-checkout] [--" +"index-output=<file>] (--empty | <tree-ish1> [<tree-ish2> [<tree-ish3>]])" +msgstr "" +"git read-tree [[-m [--trivial] [--aggressive] | --reset | --prefix=<Prefix>] " +"[-u [--exclude-per-directory=<gitignore>] | -i]] [--no-sparse-checkout] [--" +"index-output=<Datei>] (--empty | <Versionsreferenz1> [<Versionsreferenz2> " +"[<Versionsreferenz3>]])" + +#: builtin/read-tree.c:108 +msgid "write resulting index to <file>" +msgstr "schreibt resultierende Bereitstellung nach <Datei>" + +#: builtin/read-tree.c:111 +msgid "only empty the index" +msgstr "leert die Bereitstellung" + +#: builtin/read-tree.c:113 +msgid "Merging" +msgstr "Zusammenführung" + +#: builtin/read-tree.c:115 +msgid "perform a merge in addition to a read" +msgstr "führt eine Zusammenführung zusätzlich zum Lesen aus" + +#: builtin/read-tree.c:117 +msgid "3-way merge if no file level merging required" +msgstr "" +"3-Wege-Zusammenführung, wenn keine Zusammenführung auf Dateiebene " +"erforderlich ist" + +#: builtin/read-tree.c:119 +msgid "3-way merge in presence of adds and removes" +msgstr "" +"3-Wege-Zusammenführung bei Vorhandensein von hinzugefügten/entfernten Zeilen" + +#: builtin/read-tree.c:121 +msgid "same as -m, but discard unmerged entries" +msgstr "genau wie -m, verwirft aber nicht zusammengeführte Einträge" + +#: builtin/read-tree.c:122 +msgid "<subdirectory>/" +msgstr "<Unterverzeichnis>/" + +#: builtin/read-tree.c:123 +msgid "read the tree into the index under <subdirectory>/" +msgstr "liest den Baum in die Bereitstellung unter <Unterverzeichnis>/" + +#: builtin/read-tree.c:126 +msgid "update working tree with merge result" +msgstr "aktualisiert Arbeitsbaum mit Ergebnis der Zusammenführung" + +#: builtin/read-tree.c:128 +msgid "gitignore" +msgstr "gitignore" + +#: builtin/read-tree.c:129 +msgid "allow explicitly ignored files to be overwritten" +msgstr "erlaubt explizit ignorierte Dateien zu überschreiben" + +#: builtin/read-tree.c:132 +msgid "don't check the working tree after merging" +msgstr "prüft nicht den Arbeitsbaum nach der Zusammenführung" + +#: builtin/read-tree.c:133 +msgid "don't update the index or the work tree" +msgstr "aktualisiert weder die Bereitstellung, noch den Arbeitsbaum" + +#: builtin/read-tree.c:135 +msgid "skip applying sparse checkout filter" +msgstr "überspringt Anwendung des Filters für spärliches Auschecken" + +#: builtin/read-tree.c:137 +msgid "debug unpack-trees" +msgstr "protokolliert Entpacken der Bäume" + +#: builtin/remote.c:11 +msgid "git remote [-v | --verbose]" +msgstr "git remote [-v | --verbose]" + +#: builtin/remote.c:12 +msgid "" +"git remote add [-t <branch>] [-m <master>] [-f] [--tags|--no-tags] [--" +"mirror=<fetch|push>] <name> <url>" +msgstr "" +"git remote add [-t <Zweig>] [-m <master>] [-f] [--tags|--no-tags] [--" +"mirror=<fetch|push>] <Name> <URL>" + +#: builtin/remote.c:13 builtin/remote.c:32 +msgid "git remote rename <old> <new>" +msgstr "git remote rename <alt> <neu>" + +#: builtin/remote.c:14 builtin/remote.c:37 +msgid "git remote remove <name>" +msgstr "git remote remove <Name>" + +#: builtin/remote.c:15 builtin/remote.c:42 +msgid "git remote set-head <name> (-a | -d | <branch>)" +msgstr "git remote set-head <Name> (-a | -d | <Zweig>)" + +#: builtin/remote.c:16 +msgid "git remote [-v | --verbose] show [-n] <name>" +msgstr "git remote [-v | --verbose] show [-n] <Name>" + +#: builtin/remote.c:17 +msgid "git remote prune [-n | --dry-run] <name>" +msgstr "git remote prune [-n | --dry-run] <Name>" + +#: builtin/remote.c:18 +msgid "" +"git remote [-v | --verbose] update [-p | --prune] [(<group> | <remote>)...]" +msgstr "" +"git remote [-v | --verbose] update [-p | --prune] [(<Gruppe> | " +"<externesProjektarchiv>)...]" + +#: builtin/remote.c:19 +msgid "git remote set-branches [--add] <name> <branch>..." +msgstr "git remote set-branches [--add] <Name> <Zweig>..." + +#: builtin/remote.c:20 builtin/remote.c:68 +msgid "git remote set-url [--push] <name> <newurl> [<oldurl>]" +msgstr "git remote set-url [--push] <Name> <neueURL> [<alteURL>]" + +#: builtin/remote.c:21 builtin/remote.c:69 +msgid "git remote set-url --add <name> <newurl>" +msgstr "git remote set-url --add <Name> <neueURL>" + +#: builtin/remote.c:22 builtin/remote.c:70 +msgid "git remote set-url --delete <name> <url>" +msgstr "git remote set-url --delete <Name> <URL>" + +#: builtin/remote.c:27 +msgid "git remote add [<options>] <name> <url>" +msgstr "git remote add [<Optionen>] <Name> <URL>" + +#: builtin/remote.c:47 +msgid "git remote set-branches <name> <branch>..." +msgstr "git remote set-branches <Name> <Zweig>..." + +#: builtin/remote.c:48 +msgid "git remote set-branches --add <name> <branch>..." +msgstr "git remote set-branches --add <Name> <Zweig>..." + +#: builtin/remote.c:53 +msgid "git remote show [<options>] <name>" +msgstr "git remote show [<Optionen>] <Name>" + +#: builtin/remote.c:58 +msgid "git remote prune [<options>] <name>" +msgstr "git remote prune [<Optionen>] <Name>" + +#: builtin/remote.c:63 +msgid "git remote update [<options>] [<group> | <remote>]..." +msgstr "git remote update [<Optionen>] [<Gruppe> | <externesProjektarchiv>]..." + #: builtin/remote.c:98 #, c-format msgid "Updating %s" @@ -4581,6 +7338,35 @@ msgstr "" msgid "unknown mirror argument: %s" msgstr "unbekanntes Argument für Option --mirror: %s" +#: builtin/remote.c:163 +msgid "fetch the remote branches" +msgstr "fordert die externen Zweige an" + +#: builtin/remote.c:165 +msgid "import all tags and associated objects when fetching" +msgstr "importiert alle Markierungen und verbundene Objekte beim Anfordern" + +#: builtin/remote.c:168 +msgid "or do not fetch any tag at all (--no-tags)" +msgstr "oder fordere gar keine Zweige an (--no-tags)" + +#: builtin/remote.c:170 +msgid "branch(es) to track" +msgstr "Zweige zur Ãœbernahme" + +#: builtin/remote.c:171 +msgid "master branch" +msgstr "Hauptzweig" + +#: builtin/remote.c:172 +msgid "push|fetch" +msgstr "push|fetch" + +#: builtin/remote.c:173 +msgid "set up remote as a mirror to push to or fetch from" +msgstr "" +"Aufsetzen des Fernarchivs als Spiegelarchiv zum Versenden und Anfordern" + #: builtin/remote.c:185 msgid "specifying a master branch makes no sense with --mirror" msgstr "Angabe eines Hauptzweiges macht mit --mirror keinen Sinn" @@ -4588,7 +7374,7 @@ msgstr "Angabe eines Hauptzweiges macht mit --mirror keinen Sinn" #: builtin/remote.c:187 msgid "specifying branches to track makes sense only with fetch mirrors" msgstr "" -"die Angabe von zu folgenden Zweigen macht nur mit dem Abholen von " +"die Angabe von zu folgenden Zweigen macht nur mit dem Anfordern von " "Spiegelarchiven Sinn" #: builtin/remote.c:195 builtin/remote.c:646 @@ -4679,7 +7465,7 @@ msgstr "Konnte '%s' nicht erstellen" #: builtin/remote.c:764 #, c-format msgid "Could not remove branch %s" -msgstr "Konnte Zweig %s nicht entfernen" +msgstr "Konnte Zweig %s nicht löschen" #: builtin/remote.c:834 msgid "" @@ -4690,8 +7476,8 @@ msgid_plural "" "to delete them, use:" msgstr[0] "" "Hinweis: Ein Zweig außerhalb der /refs/remotes/ Hierachie wurde nicht " -"entfernt;\n" -"um diesen zu entfernen, benutze:" +"gelöscht;\n" +"um diesen zu löschen, benutze:" msgstr[1] "" "Hinweis: Einige Zweige außer der /refs/remotes/ Hierarchie wurden nicht " "entfernt;\n" @@ -4708,7 +7494,7 @@ msgstr " gefolgt" #: builtin/remote.c:948 msgid " stale (use 'git remote prune' to remove)" -msgstr " veraltet (benutze 'git remote prune' zum Entfernen)" +msgstr " veraltet (benutze 'git remote prune' zum Löschen)" #: builtin/remote.c:950 msgid " ???" @@ -4782,6 +7568,10 @@ msgstr " %-*s erzwingt Versand nach %s" msgid " %-*s pushes to %s" msgstr " %-*s versendet nach %s" +#: builtin/remote.c:1091 +msgid "do not query remotes" +msgstr "keine Abfrage von Fernarchiven" + #: builtin/remote.c:1118 #, c-format msgid "* remote %s" @@ -4842,6 +7632,14 @@ msgid_plural " Local refs configured for 'git push'%s:" msgstr[0] " Lokale Referenz konfiguriert für 'git push'%s:" msgstr[1] " Lokale Referenzen konfiguriert für 'git push'%s:" +#: builtin/remote.c:1199 +msgid "set refs/remotes/<name>/HEAD according to remote" +msgstr "setzt refs/remotes/<Name>/HEAD gemäß dem Fernarchiv" + +#: builtin/remote.c:1201 +msgid "delete refs/remotes/<name>/HEAD" +msgstr "entfernt refs/remotes/<Name>/HEAD" + #: builtin/remote.c:1216 msgid "Cannot determine remote HEAD" msgstr "Kann Hauptzweig des externen Projektarchivs nicht bestimmen" @@ -4897,15 +7695,35 @@ msgstr " * [würde veralteten Zweig entfernen] %s" msgid " * [pruned] %s" msgstr "* [veralteten Zweig entfernt] %s" +#: builtin/remote.c:1321 +msgid "prune remotes after fetching" +msgstr "entfernt veraltete Zweige im Fernarchiv nach dem Abholen" + #: builtin/remote.c:1387 builtin/remote.c:1461 #, c-format msgid "No such remote '%s'" msgstr "Kein solches externes Projektarchiv '%s'" +#: builtin/remote.c:1407 +msgid "add branch" +msgstr "fügt Zweig hinzu" + #: builtin/remote.c:1414 msgid "no remote specified" msgstr "kein externes Projektarchiv angegeben" +#: builtin/remote.c:1436 +msgid "manipulate push URLs" +msgstr "manipuliert URLs zum Versenden" + +#: builtin/remote.c:1438 +msgid "add URL" +msgstr "fügt URL hinzu" + +#: builtin/remote.c:1440 +msgid "delete URLs" +msgstr "löscht URLs" + #: builtin/remote.c:1447 msgid "--add --delete doesn't make sense" msgstr "--add --delete macht keinen Sinn" @@ -4924,6 +7742,56 @@ msgstr "Keine solche URL gefunden: %s" msgid "Will not delete all non-push URLs" msgstr "Werde keine URLs entfernen, die nicht für den Versand bestimmt sind" +#: builtin/remote.c:1569 +msgid "be verbose; must be placed before a subcommand" +msgstr "erweiterte Ausgaben; muss vor einem Unterkommando angegeben werden" + +#: builtin/replace.c:17 +msgid "git replace [-f] <object> <replacement>" +msgstr "git replace [-f] <Objekt> <Ersetzung>" + +#: builtin/replace.c:18 +msgid "git replace -d <object>..." +msgstr "git replace -d <Objekt>..." + +#: builtin/replace.c:19 +msgid "git replace -l [<pattern>]" +msgstr "git replace -l [<Muster>]" + +#: builtin/replace.c:121 +msgid "list replace refs" +msgstr "listet ersetzende Referenzen auf" + +#: builtin/replace.c:122 +msgid "delete replace refs" +msgstr "löscht ersetzende Referenzen" + +#: builtin/replace.c:123 +msgid "replace the ref if it exists" +msgstr "ersetzt die Referenz, wenn sie existiert" + +#: builtin/rerere.c:11 +msgid "git rerere [clear | forget path... | status | remaining | diff | gc]" +msgstr "git rerere [clean | forget path... | status | remaining | diff | gc]" + +#: builtin/rerere.c:56 +msgid "register clean resolutions in index" +msgstr "registriert saubere Auflösungen in der Bereitstellung" + +#: builtin/reset.c:25 +msgid "" +"git reset [--mixed | --soft | --hard | --merge | --keep] [-q] [<commit>]" +msgstr "" +"git reset [--mixed | --soft | --hard | --merge | --keep] [-q] [<Version>]" + +#: builtin/reset.c:26 +msgid "git reset [-q] <commit> [--] <paths>..." +msgstr "git reset [-q] <Version> [--] <Pfade>..." + +#: builtin/reset.c:27 +msgid "git reset --patch [<commit>] [--] [<paths>...]" +msgstr "git reset --patch [<Version>] [--] [<Pfade>...]" + #: builtin/reset.c:33 msgid "mixed" msgstr "mixed" @@ -4981,6 +7849,26 @@ msgstr "" "Kann keine '%s' Zurücksetzung durchführen, während eine Zusammenführung im " "Gange ist." +#: builtin/reset.c:238 +msgid "be quiet, only report errors" +msgstr "weniger Ausgaben, meldet nur Fehler" + +#: builtin/reset.c:240 +msgid "reset HEAD and index" +msgstr "setzt Zweigspitze (HEAD) und Bereitstellung zurück" + +#: builtin/reset.c:241 +msgid "reset only HEAD" +msgstr "setzt nur Zweigspitze (HEAD) zurück" + +#: builtin/reset.c:243 builtin/reset.c:245 +msgid "reset HEAD, index and working tree" +msgstr "setzt Zweigspitze (HEAD), Bereitstellung und Arbeitsbaum zurück" + +#: builtin/reset.c:247 +msgid "reset HEAD but keep local changes" +msgstr "setzt Zweigspitze (HEAD) zurück, behält aber lokale Änderungen" + #: builtin/reset.c:303 #, c-format msgid "Could not parse object '%s'." @@ -5010,24 +7898,137 @@ msgstr "'%s' Zurücksetzung ist in einem bloßen Projektarchiv nicht erlaubt" msgid "Could not reset index file to revision '%s'." msgstr "Konnte Bereitstellungsdatei nicht zu Version '%s' zurücksetzen." +#: builtin/rev-parse.c:339 +msgid "git rev-parse --parseopt [options] -- [<args>...]" +msgstr "git rev-parse --parseopt [Optionen] -- [<Argumente>...]" + +#: builtin/rev-parse.c:344 +msgid "keep the `--` passed as an arg" +msgstr "lässt `--` als Argument" + +#: builtin/rev-parse.c:346 +msgid "stop parsing after the first non-option argument" +msgstr "stoppt das Parsen nach dem ersten Argument was keine Option ist" + +#: builtin/rev-parse.c:464 +msgid "" +"git rev-parse --parseopt [options] -- [<args>...]\n" +" or: git rev-parse --sq-quote [<arg>...]\n" +" or: git rev-parse [options] [<arg>...]\n" +"\n" +"Run \"git rev-parse --parseopt -h\" for more information on the first usage." +msgstr "" +"git rev-parse --parseopt [Optionen] -- [<Argumente>...]\n" +" oder: git rev-parse --sq-quote [<Argumente>...]\n" +" oder: git rev-parse [Optionen] [<Argumente>...]\n" +"\n" +"Führe \"git rev-parse --parseopt -h\" für weitere Informationen bei erster " +"Verwendung aus." + +#: builtin/revert.c:22 +msgid "git revert [options] <commit-ish>" +msgstr "git revert [options] <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>" + +#: builtin/revert.c:29 +msgid "git cherry-pick <subcommand>" +msgstr "git cherry-pick <Unterkommando>" + #: builtin/revert.c:70 builtin/revert.c:92 #, c-format msgid "%s: %s cannot be used with %s" msgstr "%s: %s kann nicht mit %s benutzt werden" -#: builtin/revert.c:131 +#: builtin/revert.c:103 +msgid "end revert or cherry-pick sequence" +msgstr "beendet \"revert\" oder \"cherry-pick\" Ablauf" + +#: builtin/revert.c:104 +msgid "resume revert or cherry-pick sequence" +msgstr "setzt \"revert\" oder \"cherry-pick\" Ablauf fort" + +#: builtin/revert.c:105 +msgid "cancel revert or cherry-pick sequence" +msgstr "bricht \"revert\" oder \"cherry-pick\" Ablauf ab" + +#: builtin/revert.c:106 +msgid "don't automatically commit" +msgstr "trägt nicht automatisch ein" + +#: builtin/revert.c:107 +msgid "edit the commit message" +msgstr "Bearbeitung der Versionsbeschreibung" + +#: builtin/revert.c:110 +msgid "parent number" +msgstr "Nummer des Elternteils" + +#: builtin/revert.c:112 +msgid "merge strategy" +msgstr "Zusammenführungsstrategie" + +#: builtin/revert.c:113 +msgid "option" +msgstr "Option" + +#: builtin/revert.c:114 +msgid "option for merge strategy" +msgstr "Option für Zusammenführungsstrategie" + +#: builtin/revert.c:125 +msgid "append commit name" +msgstr "hängt Versionsnamen an" + +#: builtin/revert.c:126 +msgid "allow fast-forward" +msgstr "erlaubt Vorspulen" + +#: builtin/revert.c:127 +msgid "preserve initially empty commits" +msgstr "erhält ursprüngliche, leere Versionen" + +#: builtin/revert.c:128 +msgid "allow commits with empty messages" +msgstr "erlaubt Version mit leerer Beschreibung" + +#: builtin/revert.c:129 +msgid "keep redundant, empty commits" +msgstr "behält redundante, leere Versionen" + +#: builtin/revert.c:133 msgid "program error" msgstr "Programmfehler" -#: builtin/revert.c:221 +#: builtin/revert.c:223 msgid "revert failed" msgstr "\"revert\" fehlgeschlagen" -#: builtin/revert.c:236 +#: builtin/revert.c:238 msgid "cherry-pick failed" msgstr "\"cherry-pick\" fehlgeschlagen" -#: builtin/rm.c:109 +#: builtin/rm.c:15 +msgid "git rm [options] [--] <file>..." +msgstr "git rm [Optionen] [--] [<Datei>...]" + +#: builtin/rm.c:64 builtin/rm.c:186 +#, c-format +msgid "" +"submodule '%s' (or one of its nested submodules) uses a .git directory\n" +"(use 'rm -rf' if you really want to remove it including all of its history)" +msgstr "" +"Unterprojekt '%s' (oder ein geschachteltes Unterprojekt hiervon) verwendet\n" +"ein .git-Verzeichnis (benutze 'rm -rf' wenn du dieses wirklich mitsamt\n" +"seiner Historie löschen möchtest)" + +#: builtin/rm.c:174 #, c-format msgid "" "'%s' has staged content different from both the file and the HEAD\n" @@ -5036,7 +8037,7 @@ msgstr "" "'%s' hat bereitgestellten Inhalt unterschiedlich zu der Datei und der\n" "Zweigspitze (HEAD) (benutze -f um die Entfernung zu erzwingen)" -#: builtin/rm.c:115 +#: builtin/rm.c:180 #, c-format msgid "" "'%s' has changes staged in the index\n" @@ -5046,7 +8047,7 @@ msgstr "" "(benutze --cached um die Datei zu behalten, oder -f um die Entfernung zu " "erzwingen)" -#: builtin/rm.c:119 +#: builtin/rm.c:191 #, c-format msgid "" "'%s' has local modifications\n" @@ -5056,21 +8057,248 @@ msgstr "" "(benutze --cached um die Datei zu behalten, oder -f um die Entfernung zu " "erzwingen)" -#: builtin/rm.c:194 +#: builtin/rm.c:207 +msgid "do not list removed files" +msgstr "listet keine gelöschten Dateien auf" + +#: builtin/rm.c:208 +msgid "only remove from the index" +msgstr "entfernt nur aus der Bereitstellung" + +#: builtin/rm.c:209 +msgid "override the up-to-date check" +msgstr "überschreibt die \"up-to-date\" Prüfung" + +#: builtin/rm.c:210 +msgid "allow recursive removal" +msgstr "erlaubt rekursive Entfernung" + +#: builtin/rm.c:212 +msgid "exit with a zero status even if nothing matched" +msgstr "beendet mit Rückgabewert 0, wenn keine Ãœbereinstimmung gefunden wurde" + +#: builtin/rm.c:283 #, c-format msgid "not removing '%s' recursively without -r" msgstr "'%s' wird nicht ohne -r rekursiv entfernt" -#: builtin/rm.c:230 +#: builtin/rm.c:322 #, c-format msgid "git rm: unable to remove %s" -msgstr "git rm: konnte %s nicht entfernen" +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>... ]" #: builtin/shortlog.c:157 #, c-format msgid "Missing author: %s" msgstr "fehlender Autor: %s" +#: builtin/shortlog.c:253 +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:255 +msgid "Suppress commit descriptions, only provides commit count" +msgstr "Unterdrückt Versionsbeschreibungen, liefert nur Anzahl der Versionen" + +#: builtin/shortlog.c:257 +msgid "Show the email address of each author" +msgstr "Zeigt die Email-Adresse von jedem Autor" + +#: builtin/shortlog.c:258 +msgid "w[,i1[,i2]]" +msgstr "w[,i1[,i2]]" + +#: builtin/shortlog.c:259 +msgid "Linewrap output" +msgstr "Ausgabe mit Zeilenumbrüchen" + +#: builtin/show-branch.c:9 +msgid "" +"git show-branch [-a|--all] [-r|--remotes] [--topo-order | --date-order] [--" +"current] [--color[=<when>] | --no-color] [--sparse] [--more=<n> | --list | --" +"independent | --merge-base] [--no-name | --sha1-name] [--topics] [(<rev> | " +"<glob>)...]" +msgstr "" +"git show-branch [-a|--all] [-r|--remotes] [--topo-order | --date-order] [--" +"current] [--color[=<Wann>] | --no-color] [--sparse] [--more=<n> | --list | --" +"independent | --merge-base] [--no-name | --sha1-name] [--topics] " +"[(<Revision> | <glob>)...]" + +#: builtin/show-branch.c:10 +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 +msgid "show remote-tracking and local branches" +msgstr "zeigt externe Ãœbernahmezweige und lokale Zweige an" + +#: builtin/show-branch.c:653 +msgid "show remote-tracking branches" +msgstr "zeigt externe Ãœbernahmezweige an" + +#: builtin/show-branch.c:655 +msgid "color '*!+-' corresponding to the branch" +msgstr "färbt '*!+-' entsprechend des Zweiges ein" + +#: builtin/show-branch.c:657 +msgid "show <n> more commits after the common ancestor" +msgstr "zeigt <n> weitere Versionen nach dem gemeinsamen Vorfahren" + +#: builtin/show-branch.c:659 +msgid "synonym to more=-1" +msgstr "Synonym für more=-1" + +#: builtin/show-branch.c:660 +msgid "suppress naming strings" +msgstr "unterdrückt Namen" + +#: builtin/show-branch.c:662 +msgid "include the current branch" +msgstr "bezieht den aktuellen Zweig ein" + +#: builtin/show-branch.c:664 +msgid "name commits with their object names" +msgstr "benennt Versionen nach ihren Objektnamen" + +#: builtin/show-branch.c:666 +msgid "show possible merge bases" +msgstr "zeigt mögliche Basen für Zusammenführung" + +#: builtin/show-branch.c:668 +msgid "show refs unreachable from any other ref" +msgstr "zeigt Referenzen die unerreichbar von allen anderen Referenzen sind" + +#: builtin/show-branch.c:670 +msgid "show commits in topological order" +msgstr "zeigt Versionen in topologischer Ordnung" + +#: builtin/show-branch.c:672 +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 +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 +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 +msgid "<n>[,<base>]" +msgstr "<n>[,<Basis>]" + +#: builtin/show-branch.c:679 +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" + +#: builtin/show-ref.c:10 +msgid "" +"git show-ref [-q|--quiet] [--verify] [--head] [-d|--dereference] [-s|--hash" +"[=<n>]] [--abbrev[=<n>]] [--tags] [--heads] [--] [pattern*] " +msgstr "" +"git show-ref [-q|--quiet] [--verify] [--head] [-d|--dereference] [-s|--hash" +"[=<n>]] [--abbrev[=<n>]] [--tags] [--heads] [--] [pattern*] " + +#: builtin/show-ref.c:11 +msgid "git show-ref --exclude-existing[=pattern] < ref-list" +msgstr "git show-ref --exclude-existing[=Muster] < ref-list" + +#: builtin/show-ref.c:165 +msgid "only show tags (can be combined with heads)" +msgstr "zeigt nur Markierungen (kann mit \"heads\" kombiniert werden)" + +#: builtin/show-ref.c:166 +msgid "only show heads (can be combined with tags)" +msgstr "zeigt nur Zweigspitzen (kann mit \"tags\" kombiniert werden)" + +#: builtin/show-ref.c:167 +msgid "stricter reference checking, requires exact ref path" +msgstr "strengere Referenzprüfung, erfordert exakten Referenzpfad" + +#: builtin/show-ref.c:170 builtin/show-ref.c:172 +msgid "show the HEAD reference" +msgstr "zeigt Referenz der Zweigspitze (HEAD)" + +#: builtin/show-ref.c:174 +msgid "dereference tags into object IDs" +msgstr "dereferenziert Markierungen in Objekt-Identifikationen" + +#: builtin/show-ref.c:176 +msgid "only show SHA1 hash using <n> digits" +msgstr "zeigt nur SHA1 Hash mit <n> Ziffern" + +#: builtin/show-ref.c:180 +msgid "do not print results to stdout (useful with --verify)" +msgstr "" +"keine Ausgabe der Ergebnisse in die Standard-Ausgabe (nützlich mit --verify)" + +#: builtin/show-ref.c:182 +msgid "show refs from stdin that aren't in local repository" +msgstr "" +"zeigt Referenzen von der Standard-Eingabe, die sich nicht im lokalen " +"Projektarchiv befinden, an" + +#: builtin/symbolic-ref.c:7 +msgid "git symbolic-ref [options] name [ref]" +msgstr "git symbolic-ref [Optionen] name [ref]" + +#: builtin/symbolic-ref.c:8 +msgid "git symbolic-ref -d [-q] name" +msgstr "git symbolic-ref -d [-q] name" + +#: builtin/symbolic-ref.c:40 +msgid "suppress error message for non-symbolic (detached) refs" +msgstr "" +"unterdrückt Fehlermeldungen für nicht-symbolische (losgelöste) Referenzen" + +#: builtin/symbolic-ref.c:41 +msgid "delete symbolic ref" +msgstr "löscht symbolische Referenzen" + +#: builtin/symbolic-ref.c:42 +msgid "shorten ref output" +msgstr "verkürzte Ausgabe der Referenzen" + +#: builtin/symbolic-ref.c:43 builtin/update-ref.c:18 +msgid "reason" +msgstr "Grund" + +#: builtin/symbolic-ref.c:43 builtin/update-ref.c:18 +msgid "reason of the update" +msgstr "Grund für die Aktualisierung" + +#: builtin/tag.c:22 +msgid "" +"git tag [-a|-s|-u <key-id>] [-f] [-m <msg>|-F <file>] <tagname> [<head>]" +msgstr "" +"git tag [-a|-s|-u <Schlüssel-id>] [-f] [-m <Nachricht>|-F <Datei>] " +"<Markierungsname> [<Zweig>]" + +#: builtin/tag.c:23 +msgid "git tag -d <tagname>..." +msgstr "git tag -d <Markierungsname>..." + +#: builtin/tag.c:24 +msgid "" +"git tag -l [-n[<num>]] [--contains <commit>] [--points-at <object>] \n" +"\t\t[<pattern>...]" +msgstr "" +"git tag -l [-n[<Nummer>]] [--contains <Version>] [--points-at <Objekt>] \n" +"\t\t[<Muster>...]" + +#: builtin/tag.c:26 +msgid "git tag -v <tagname>..." +msgstr "git tag -v <Markierungsname>..." + #: builtin/tag.c:60 #, c-format msgid "malformed object at '%s'" @@ -5160,6 +8388,62 @@ msgstr "Option 'points-at' erfordert ein Objekt" msgid "malformed object name '%s'" msgstr "fehlerhafter Objekt-Name '%s'" +#: builtin/tag.c:447 +msgid "list tag names" +msgstr "listet Markierungsnamen auf" + +#: builtin/tag.c:449 +msgid "print <n> lines of each tag message" +msgstr "zeigt <n> Zeilen jeder Markierungsbeschreibung" + +#: builtin/tag.c:451 +msgid "delete tags" +msgstr "löscht Markierungen" + +#: builtin/tag.c:452 +msgid "verify tags" +msgstr "überprüft Markierungen" + +#: builtin/tag.c:454 +msgid "Tag creation options" +msgstr "Optionen für Erstellung von Markierungen" + +#: builtin/tag.c:456 +msgid "annotated tag, needs a message" +msgstr "annotierte Markierung, benötigt eine Beschreibung" + +#: builtin/tag.c:458 +msgid "tag message" +msgstr "Markierungsbeschreibung" + +#: builtin/tag.c:460 +msgid "annotated and GPG-signed tag" +msgstr "annotierte und GPG-signierte Markierung" + +#: builtin/tag.c:464 +msgid "use another key to sign the tag" +msgstr "benutzt einen anderen Schlüssel um die Markierung zu signieren" + +#: builtin/tag.c:465 +msgid "replace the tag if exists" +msgstr "ersetzt die Markierung, wenn sie existiert" + +#: builtin/tag.c:466 +msgid "show tag list in columns" +msgstr "zeigt Liste der Markierungen in Spalten" + +#: builtin/tag.c:468 +msgid "Tag listing options" +msgstr "Optionen für Auflistung der Markierungen" + +#: builtin/tag.c:471 +msgid "print only tags that contain the commit" +msgstr "gibt nur Markierungen aus, die diese Version beinhalten" + +#: builtin/tag.c:477 +msgid "print only tags of the object" +msgstr "gibt nur Markierungen von dem Objekt aus" + #: builtin/tag.c:506 msgid "--column and -n are incompatible" msgstr "--column und -n sind inkompatibel" @@ -5209,27 +8493,191 @@ msgstr "%s: kann Referenz nicht aktualisieren" msgid "Updated tag '%s' (was %s)\n" msgstr "Aktualisierte Markierung '%s' (war %s)\n" -#: git.c:16 -msgid "See 'git help <command>' for more information on a specific command." +#: builtin/update-index.c:401 +msgid "git update-index [options] [--] [<file>...]" +msgstr "git update-index [Optionen] [--] [<Datei>...]" + +#: builtin/update-index.c:718 +msgid "continue refresh even when index needs update" msgstr "" -"Siehe 'git help <Kommando>' für weitere Informationen zu einem spezifischen " -"Kommando" +"Aktualisierung fortsetzen, auch wenn die Bereitstellung aktualisiert werden " +"muss" -#: parse-options.h:133 parse-options.h:235 -msgid "n" -msgstr "Anzahl" +#: builtin/update-index.c:721 +msgid "refresh: ignore submodules" +msgstr "Aktualisierung: ignoriert Unterprojekte" -#: parse-options.h:141 -msgid "time" -msgstr "Zeit" +#: builtin/update-index.c:724 +msgid "do not ignore new files" +msgstr "ignoriert keine neuen Dateien" -#: parse-options.h:149 -msgid "file" -msgstr "Datei" +#: builtin/update-index.c:726 +msgid "let files replace directories and vice-versa" +msgstr "lässt Dateien Verzeichnisse ersetzen, und umgedreht" -#: parse-options.h:151 -msgid "when" -msgstr "wann" +#: builtin/update-index.c:728 +msgid "notice files missing from worktree" +msgstr "beachtet fehlende Dateien im Arbeitsbaum" + +#: builtin/update-index.c:730 +msgid "refresh even if index contains unmerged entries" +msgstr "" +"aktualisiert, auch wenn die Bereitstellung nicht zusammengeführte Einträge " +"beinhaltet" + +#: builtin/update-index.c:733 +msgid "refresh stat information" +msgstr "aktualisiert Dateiinformationen" + +#: builtin/update-index.c:737 +msgid "like --refresh, but ignore assume-unchanged setting" +msgstr "wie --refresh, ignoriert aber \"assume-unchanged\" Einstellung" + +#: builtin/update-index.c:741 +msgid "<mode> <object> <path>" +msgstr "<Modus> <Objekt> <Pfad>" + +#: builtin/update-index.c:742 +msgid "add the specified entry to the index" +msgstr "stellt den angegebenen Eintrag zur Eintragung bereit" + +#: builtin/update-index.c:746 +msgid "(+/-)x" +msgstr "(+/-)x" + +#: builtin/update-index.c:747 +msgid "override the executable bit of the listed files" +msgstr "überschreibt das \"ausführbar\"-Bit der aufgelisteten Dateien" + +#: builtin/update-index.c:751 +msgid "mark files as \"not changing\"" +msgstr "betrachte diese Datei immer als unverändert" + +#: builtin/update-index.c:754 +msgid "clear assumed-unchanged bit" +msgstr "löscht \"assumed-unchanged\"-Bit" + +#: builtin/update-index.c:757 +msgid "mark files as \"index-only\"" +msgstr "markiert Dateien als \"index-only\"" + +#: builtin/update-index.c:760 +msgid "clear skip-worktree bit" +msgstr "löscht \"skip-worktree\"-Bit" + +#: builtin/update-index.c:763 +msgid "add to index only; do not add content to object database" +msgstr "" +"fügt nur der Bereitstellung hinzu; Inhalt wird nicht der Objekt-Datenbank " +"hinzugefügt" + +#: builtin/update-index.c:765 +msgid "remove named paths even if present in worktree" +msgstr "löscht benannte Pfade, auch wenn sie sich im Arbeitsbaum befinden" + +#: builtin/update-index.c:767 +msgid "with --stdin: input lines are terminated by null bytes" +msgstr "mit --stdin: eingegebene Zeilen sind durch NUL-Bytes abgeschlossen" + +#: builtin/update-index.c:769 +msgid "read list of paths to be updated from standard input" +msgstr "liest Liste der zu aktualisierenden Pfade von der Standard-Eingabe" + +#: builtin/update-index.c:773 +msgid "add entries from standard input to the index" +msgstr "fügt Einträge von der Standard-Eingabe der Bereitstellung hinzu" + +#: builtin/update-index.c:777 +msgid "repopulate stages #2 and #3 for the listed paths" +msgstr "" +"wiederholtes Einpflegen der Zustände #2 und #3 für die aufgelisteten Pfade" + +#: builtin/update-index.c:781 +msgid "only update entries that differ from HEAD" +msgstr "" +"aktualisiert nur Einträge, die unterschiedlich zur Zweigspitze (HEAD) sind" + +#: builtin/update-index.c:785 +msgid "ignore files missing from worktree" +msgstr "ignoriert fehlende Dateien im Arbeitsbaum" + +#: builtin/update-index.c:788 +msgid "report actions to standard output" +msgstr "gibt die Aktionen in der Standard-Ausgabe aus" + +#: builtin/update-index.c:790 +msgid "(for porcelains) forget saved unresolved conflicts" +msgstr "(für Fremdprogramme) keine gespeicherten, nicht aufgelöste Konflikte" + +#: builtin/update-index.c:794 +msgid "write index in this format" +msgstr "schreibt Bereitstellungsdatei in diesem Format" + +#: builtin/update-ref.c:7 +msgid "git update-ref [options] -d <refname> [<oldval>]" +msgstr "git update-ref [Optionen] -d <Referenzname> [<alterWert>]" + +#: builtin/update-ref.c:8 +msgid "git update-ref [options] <refname> <newval> [<oldval>]" +msgstr "git update-ref [Optionen] <Referenzname> <neuerWert> [<alterWert>]" + +#: builtin/update-ref.c:19 +msgid "delete the reference" +msgstr "löscht diese Referenz" + +#: builtin/update-ref.c:21 +msgid "update <refname> not the one it points to" +msgstr "aktualisiert <Referenzname>, nicht den Verweis" + +#: builtin/update-server-info.c:6 +msgid "git update-server-info [--force]" +msgstr "git update-server-info [--force]" + +#: builtin/update-server-info.c:14 +msgid "update the info files from scratch" +msgstr "aktualisiert die Informationsdateien von Grund auf" + +#: builtin/verify-pack.c:56 +msgid "git verify-pack [-v|--verbose] [-s|--stat-only] <pack>..." +msgstr "git verify-pack [-v|--verbose] [-s|--stat-only] <Paket>..." + +#: builtin/verify-pack.c:66 +msgid "verbose" +msgstr "erweiterte Ausgaben" + +#: builtin/verify-pack.c:68 +msgid "show statistics only" +msgstr "zeigt nur Statistiken" + +#: builtin/verify-tag.c:17 +msgid "git verify-tag [-v|--verbose] <tag>..." +msgstr "git verify-tag [-v|--verbose] <Markierung>..." + +#: builtin/verify-tag.c:73 +msgid "print tag contents" +msgstr "gibt Markierungsinhalte aus" + +#: builtin/write-tree.c:13 +msgid "git write-tree [--missing-ok] [--prefix=<prefix>/]" +msgstr "git write-tree [--missing-ok] [--prefix=<Prefix>/]" + +#: builtin/write-tree.c:26 +msgid "<prefix>/" +msgstr "<Prefix>/" + +#: builtin/write-tree.c:27 +msgid "write tree object for a subdirectory <prefix>" +msgstr "schreibt das Baumobjekt für ein Unterverzeichnis <Prefix>" + +#: builtin/write-tree.c:30 +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." +msgstr "" +"Siehe 'git help <Kommando>' für weitere Informationen zu einem spezifischen " +"Kommando" #: parse-options.h:156 msgid "no-op (backward compatibility)" @@ -5457,7 +8905,7 @@ msgstr "" #: git-am.sh:706 msgid "Patch does not have a valid e-mail address." -msgstr "Patch enthält keine gültige eMail-Adresse." +msgstr "Patch enthält keine gültige Email-Adresse." #: git-am.sh:753 msgid "cannot be interactive without stdin connected to a terminal." @@ -5509,6 +8957,15 @@ msgstr "Keine Änderungen -- Patches bereits angewendet." msgid "Patch failed at $msgnum $FIRSTLINE" msgstr "Anwendung des Patches fehlgeschlagen bei $msgnum $FIRSTLINE" +#: git-am.sh:858 +#, sh-format +msgid "" +"The copy of the patch that failed is found in:\n" +" $dotest/patch" +msgstr "" +"Die Kopie des fehlgeschlagenen Patches befindet sich in:\n" +" $dotest/patch" + #: git-am.sh:876 msgid "applying to an empty history" msgstr "wende zu leerer Historie an" @@ -5696,7 +9153,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:228 +#: git-pull.sh:229 #, sh-format msgid "" "Warning: fetch updated the current branch head.\n" @@ -5706,15 +9163,15 @@ msgstr "" "Warnung: Die Anforderung aktualisierte die Spitze des aktuellen Zweiges.\n" "Warnung: Spule deinen Arbeitszweig von Version $orig_head vor." -#: git-pull.sh:253 +#: git-pull.sh:254 msgid "Cannot merge multiple branches into empty head" msgstr "Kann nicht mehrere Zweige in einen ungeborenen Zweig zusammenführen" -#: git-pull.sh:257 +#: git-pull.sh:258 msgid "Cannot rebase onto multiple branches" msgstr "kann nicht auf mehrere Zweige neu aufbauen" -#: git-rebase.sh:52 +#: git-rebase.sh:53 msgid "" "When you have resolved this problem, run \"git rebase --continue\".\n" "If you prefer to skip this patch, run \"git rebase --skip\" instead.\n" @@ -5728,27 +9185,32 @@ msgstr "" "abzubrechen,\n" "führe \"git rebase --abort\" aus." -#: git-rebase.sh:159 +#: git-rebase.sh:160 msgid "The pre-rebase hook refused to rebase." msgstr "Der \"pre-rebase hook\" hat den Neuaufbau zurückgewiesen." -#: git-rebase.sh:164 +#: git-rebase.sh:165 msgid "It looks like git-am is in progress. Cannot rebase." msgstr "\"git-am\" scheint im Gange zu sein. Kann nicht neu aufbauen." -#: git-rebase.sh:295 +#: git-rebase.sh:296 msgid "The --exec option must be used with the --interactive option" msgstr "Die --exec Option muss mit der --interactive Option benutzt werden" -#: git-rebase.sh:300 +#: git-rebase.sh:301 msgid "No rebase in progress?" msgstr "Kein Neuaufbau im Gange?" -#: git-rebase.sh:313 +#: git-rebase.sh:312 +msgid "The --edit-todo action can only be used during interactive rebase." +msgstr "Die --edit-todo Aktion kann nur während eines interaktiven " +"Neuaufbaus benutzt werden." + +#: git-rebase.sh:319 msgid "Cannot read HEAD" msgstr "Kann Zweigspitze (HEAD) nicht lesen" -#: git-rebase.sh:316 +#: git-rebase.sh:322 msgid "" "You must edit all merge conflicts and then\n" "mark them as resolved using git add" @@ -5756,12 +9218,12 @@ msgstr "" "Du musst alle Zusammenführungskonflikte editieren und diese dann\n" "mittels \"git add\" als aufgelöst markieren" -#: git-rebase.sh:334 +#: git-rebase.sh:340 #, sh-format msgid "Could not move back to $head_name" msgstr "Konnte nicht zu $head_name zurückgehen" -#: git-rebase.sh:350 +#: git-rebase.sh:359 #, sh-format msgid "" "It seems that there is already a $state_dir_base directory, and\n" @@ -5782,59 +9244,59 @@ msgstr "" "und führe dieses Kommando nochmal aus. Es wird angehalten, falls noch\n" "etwas Schützenswertes vorhanden ist." -#: git-rebase.sh:395 +#: git-rebase.sh:404 #, sh-format msgid "invalid upstream $upstream_name" msgstr "ungültiger Ãœbernahmezweig $upstream_name" -#: git-rebase.sh:419 +#: git-rebase.sh:428 #, sh-format msgid "$onto_name: there are more than one merge bases" msgstr "$onto_name: es gibt mehr als eine Zusammenführungsbasis" -#: git-rebase.sh:422 git-rebase.sh:426 +#: git-rebase.sh:431 git-rebase.sh:435 #, sh-format msgid "$onto_name: there is no merge base" msgstr "$onto_name: es gibt keine Zusammenführungsbasis" -#: git-rebase.sh:431 +#: git-rebase.sh:440 #, sh-format msgid "Does not point to a valid commit: $onto_name" msgstr "$onto_name zeigt auf keine gültige Version" -#: git-rebase.sh:454 +#: git-rebase.sh:463 #, sh-format msgid "fatal: no such branch: $branch_name" msgstr "fatal: Zweig $branch_name nicht gefunden" -#: git-rebase.sh:474 +#: git-rebase.sh:483 msgid "Please commit or stash them." msgstr "Bitte trage die Änderungen ein oder benutze \"stash\"." -#: git-rebase.sh:492 +#: git-rebase.sh:501 #, sh-format msgid "Current branch $branch_name is up to date." msgstr "Aktueller Zweig $branch_name ist auf dem neusten Stand." -#: git-rebase.sh:495 +#: git-rebase.sh:504 #, sh-format msgid "Current branch $branch_name is up to date, rebase forced." msgstr "" "Aktueller Zweig $branch_name ist auf dem neusten Stand, Neuaufbau erzwungen." -#: git-rebase.sh:506 +#: git-rebase.sh:515 #, sh-format msgid "Changes from $mb to $onto:" msgstr "Änderungen von $mb zu $onto:" #. Detach HEAD and reset the tree -#: git-rebase.sh:515 +#: git-rebase.sh:524 msgid "First, rewinding head to replay your work on top of it..." msgstr "" "Zunächst wird die Zweigspitze zurückgespult, um deine Änderungen\n" "darauf neu anzuwenden..." -#: git-rebase.sh:523 +#: git-rebase.sh:532 #, sh-format msgid "Fast-forwarded $branch_name to $onto_name." msgstr "$branch_name zu $onto_name vorgespult." @@ -5861,7 +9323,7 @@ msgstr "Keine Änderungen ausgewählt" #: git-stash.sh:143 msgid "Cannot remove temporary index (can't happen)" -msgstr "Kann temporäre Bereitstellung nicht entfernen (kann nicht passieren)" +msgstr "Kann temporäre Bereitstellung nicht löschen (kann nicht passieren)" #: git-stash.sh:156 msgid "Cannot record working tree state" @@ -5901,7 +9363,7 @@ msgstr "Kann den aktuellen Status nicht speichern" #: git-stash.sh:253 msgid "Cannot remove worktree changes" -msgstr "Kann Änderungen am Arbeitsbaum nicht entfernen" +msgstr "Kann Änderungen am Arbeitsbaum nicht löschen" #: git-stash.sh:352 msgid "No stash found." @@ -5948,34 +9410,34 @@ msgstr "Konnte Bereitstellungsbaum nicht speichern" msgid "Cannot unstage modified files" msgstr "Kann geänderte Dateien nicht aus der Bereitstellung herausnehmen" -#: git-stash.sh:474 +#: git-stash.sh:475 msgid "Index was not unstashed." msgstr "Bereitstellung wurde nicht ausgelagert." -#: git-stash.sh:491 +#: git-stash.sh:492 #, sh-format msgid "Dropped ${REV} ($s)" msgstr "Gelöscht ${REV} ($s)" -#: git-stash.sh:492 +#: git-stash.sh:493 #, sh-format msgid "${REV}: Could not drop stash entry" msgstr "${REV}: Konnte \"stash\"-Eintrag nicht löschen" -#: git-stash.sh:499 +#: git-stash.sh:500 msgid "No branch name specified" msgstr "Kein Zweigname spezifiziert" -#: git-stash.sh:570 +#: git-stash.sh:571 msgid "(To restore them type \"git stash apply\")" msgstr "(Zur Wiederherstellung gebe \"git stash apply\" ein)" -#: git-submodule.sh:88 +#: git-submodule.sh:89 #, sh-format msgid "cannot strip one component off url '$remoteurl'" msgstr "Kann eine Komponente von URL '$remoteurl' nicht extrahieren" -#: git-submodule.sh:167 +#: git-submodule.sh:168 #, sh-format msgid "No submodule mapping found in .gitmodules for path '$sm_path'" msgstr "" @@ -5992,17 +9454,17 @@ 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:312 +#: git-submodule.sh:316 #, 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:329 +#: git-submodule.sh:333 #, sh-format msgid "'$sm_path' already exists in the index" msgstr "'$sm_path' existiert bereits in der Bereitstellung" -#: git-submodule.sh:333 +#: git-submodule.sh:337 #, sh-format msgid "" "The following path is ignored by one of your .gitignore files:\n" @@ -6013,65 +9475,101 @@ msgstr "" "$sm_path\n" "Benutze -f wenn du diesen wirklich hinzufügen möchtest." -#: git-submodule.sh:344 +#: git-submodule.sh:355 #, 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:346 +#: git-submodule.sh:357 #, 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:360 +#: git-submodule.sh:365 +#, 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:367 +#, sh-format +msgid "" +"If you want to reuse this local git directory instead of cloning again from" +msgstr "" +"Wenn du dieses lokale Git-Verzeichnis wiederverwenden möchtest, anstatt " +"erneut zu klonen" + +#: git-submodule.sh:369 +#, sh-format +msgid "" +"use the '--force' option. If the local git directory is not the correct repo" +msgstr "" +"benutze die Option '--force'. Wenn das lokale Git-Verzeichnis nicht das " +"korrekte Projektarchiv ist" + +#: git-submodule.sh:370 +#, sh-format +msgid "" +"or you are unsure what this means choose another name with the '--name' " +"option." +msgstr "" +"oder du dir unsicher bist, was das bedeutet, wähle einen anderen Namen mit " +"der Option '--name'." + +#: git-submodule.sh:372 +#, sh-format +msgid "Reactivating local git directory for submodule '$sm_name'." +msgstr "Reaktiviere lokales Git-Verzeichnis für Unterprojekt '$sm_name'." + +#: git-submodule.sh:384 #, sh-format msgid "Unable to checkout submodule '$sm_path'" msgstr "Unfähig Unterprojekt '$sm_path' auszuchecken" -#: git-submodule.sh:365 +#: git-submodule.sh:389 #, sh-format msgid "Failed to add submodule '$sm_path'" msgstr "Hinzufügen von Unterprojekt '$sm_path' fehlgeschlagen" -#: git-submodule.sh:370 +#: git-submodule.sh:394 #, sh-format msgid "Failed to register submodule '$sm_path'" msgstr "Registierung von Unterprojekt '$sm_path' fehlgeschlagen" -#: git-submodule.sh:413 +#: git-submodule.sh:437 #, sh-format msgid "Entering '$prefix$sm_path'" msgstr "Betrete '$prefix$sm_path'" -#: git-submodule.sh:427 +#: git-submodule.sh:451 #, 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:471 +#: git-submodule.sh:495 #, 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:480 +#: git-submodule.sh:504 #, sh-format msgid "Failed to register url for submodule path '$sm_path'" msgstr "Registrierung der URL für Unterprojekt-Pfad '$sm_path' fehlgeschlagen" -#: git-submodule.sh:482 +#: git-submodule.sh:506 #, sh-format msgid "Submodule '$name' ($url) registered for path '$sm_path'" msgstr "Unterprojekt '$name' ($url) ist für Pfad '$sm_path' registriert" -#: git-submodule.sh:490 +#: git-submodule.sh:514 #, sh-format msgid "Failed to register update mode for submodule path '$sm_path'" msgstr "" "Registrierung des Aktualisierungsmodus für Unterprojekt-Pfad '$sm_path' " "fehlgeschlagen" -#: git-submodule.sh:590 +#: git-submodule.sh:614 #, sh-format msgid "" "Submodule path '$sm_path' not initialized\n" @@ -6080,94 +9578,150 @@ msgstr "" "Unterprojekt-Pfad '$sm_path' ist nicht initialisiert\n" "Vielleicht möchtest du 'update --init' benutzen?" -#: git-submodule.sh:603 +#: git-submodule.sh:627 #, sh-format msgid "Unable to find current revision in submodule path '$sm_path'" msgstr "Konnte aktuelle Version in Unterprojekt-Pfad '$sm_path' nicht finden" -#: git-submodule.sh:622 +#: git-submodule.sh:646 #, sh-format msgid "Unable to fetch in submodule path '$sm_path'" msgstr "Konnte in Unterprojekt-Pfad '$sm_path' nicht anfordern" -#: git-submodule.sh:636 +#: git-submodule.sh:660 #, sh-format msgid "Unable to rebase '$sha1' in submodule path '$sm_path'" msgstr "Neuaufbau von '$sha1' in Unterprojekt-Pfad '$sm_path' nicht möglich" -#: git-submodule.sh:637 +#: git-submodule.sh:661 #, sh-format msgid "Submodule path '$sm_path': rebased into '$sha1'" msgstr "Unterprojekt-Pfad '$sm_path': neu aufgebaut in '$sha1'" -#: git-submodule.sh:642 +#: git-submodule.sh:666 #, sh-format msgid "Unable to merge '$sha1' in submodule path '$sm_path'" msgstr "" "Zusammenführung von '$sha1' in Unterprojekt-Pfad '$sm_path' fehlgeschlagen" -#: git-submodule.sh:643 +#: git-submodule.sh:667 #, sh-format msgid "Submodule path '$sm_path': merged in '$sha1'" msgstr "Unterprojekt-Pfad '$sm_path': zusammengeführt in '$sha1'" -#: git-submodule.sh:648 +#: git-submodule.sh:672 #, sh-format msgid "Unable to checkout '$sha1' in submodule path '$sm_path'" msgstr "Konnte '$sha1' in Unterprojekt-Pfad '$sm_path' nicht auschecken." -#: git-submodule.sh:649 +#: git-submodule.sh:673 #, sh-format msgid "Submodule path '$sm_path': checked out '$sha1'" msgstr "Unterprojekt-Pfad: '$sm_path': '$sha1' ausgecheckt" -#: git-submodule.sh:671 git-submodule.sh:995 +#: git-submodule.sh:695 git-submodule.sh:1017 #, sh-format msgid "Failed to recurse into submodule path '$sm_path'" msgstr "Fehler bei Rekursion in Unterprojekt-Pfad '$sm_path'" -#: git-submodule.sh:779 +#: git-submodule.sh:803 msgid "The --cached option cannot be used with the --files option" msgstr "Die --cached Option kann nicht mit der --files Option benutzt werden" #. unexpected type -#: git-submodule.sh:819 +#: git-submodule.sh:843 #, sh-format msgid "unexpected mode $mod_dst" msgstr "unerwarteter Modus $mod_dst" -#: git-submodule.sh:837 +#: git-submodule.sh:861 #, sh-format msgid " Warn: $name doesn't contain commit $sha1_src" msgstr " Warnung: $name beinhaltet nicht Version $sha1_src" -#: git-submodule.sh:840 +#: git-submodule.sh:864 #, sh-format msgid " Warn: $name doesn't contain commit $sha1_dst" msgstr " Warnung: $name beinhaltet nicht Version $sha1_dst" -#: git-submodule.sh:843 +#: git-submodule.sh:867 #, 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:868 +#: git-submodule.sh:892 msgid "blob" msgstr "Blob" -#: git-submodule.sh:906 +#: git-submodule.sh:930 msgid "# Submodules changed but not updated:" msgstr "# Unterprojekte geändert, aber nicht aktualisiert:" -#: git-submodule.sh:908 +#: git-submodule.sh:932 msgid "# Submodule changes to be committed:" msgstr "# Änderungen in Unterprojekt zum Eintragen:" -#: git-submodule.sh:1054 +#: git-submodule.sh:1080 #, sh-format -msgid "Synchronizing submodule url for '$name'" -msgstr "Synchronisiere Unterprojekt-URL für '$name'" +msgid "Synchronizing submodule url for '$prefix$sm_path'" +msgstr "Synchronisiere Unterprojekt-URL für '$prefix$sm_path'" + +#~ msgid " 0 files changed" +#~ msgstr " 0 Dateien geändert" + +#~ msgid " %d file changed" +#~ msgid_plural " %d files changed" +#~ msgstr[0] " %d Datei geändert" +#~ msgstr[1] " %d Dateien geändert" + +#~ msgid ", %d insertion(+)" +#~ msgid_plural ", %d insertions(+)" +#~ msgstr[0] ", %d Zeile hinzugefügt(+)" +#~ msgstr[1] ", %d Zeilen hinzugefügt(+)" + +#~ msgid ", %d deletion(-)" +#~ msgid_plural ", %d deletions(-)" +#~ msgstr[0] ", %d Zeile entfernt(-)" +#~ msgstr[1] ", %d Zeilen entfernt(-)" + +#~ msgid "Auto packing the repository for optimum performance.\n" +#~ msgstr "" +#~ "Die Datenbank des Projektarchivs wird für eine optimale Performance " +#~ "komprimiert.\n" + +#~ msgid "git remote set-head <name> (-a | -d | <branch>])" +#~ msgstr "git remote set-head <Name> (-a | -d | <Zweig>])" + +#~ msgid " (use \"git add\" to track)" +#~ msgstr " (benutze \"git add\" zum Beobachten)" + +#~ msgid "-B cannot be used with -b" +#~ msgstr "-B kann nicht mit -b benutzt werden" + +#~ msgid "--patch is incompatible with all other options" +#~ msgstr "--patch ist inkompatibel mit allen anderen Optionen" + +#~ msgid "--detach cannot be used with -b/-B/--orphan" +#~ msgstr "--detach kann nicht mit -b/-B/--orphan benutzt werden" + +#~ msgid "--detach cannot be used with -t" +#~ msgstr "--detach kann nicht mit -t benutzt werden" + +#~ msgid "--orphan and -b|-B are mutually exclusive" +#~ msgstr "--orphan und -b|-B sind gegenseitig exklusiv" + +#~ msgid "--orphan cannot be used with -t" +#~ msgstr "--orphan kann nicht mit -t benutzt werden" + +#~ msgid "git checkout: -f and -m are incompatible" +#~ msgstr "git checkout: -f und -m sind inkompatibel" + +#~ msgid "" +#~ "git checkout: updating paths is incompatible with switching branches." +#~ msgstr "" +#~ "git checkout: Die Aktualisierung von Pfaden ist inkompatibel mit dem " +#~ "Wechsel von Zweigen." #~ msgid "diff setup failed" #~ msgstr "diff_setup_done fehlgeschlagen" @@ -6199,9 +9753,6 @@ msgstr "Synchronisiere Unterprojekt-URL für '$name'" #~ msgid "Please enter the commit message for your changes." #~ msgstr "Bitte gebe die Versionsbeschreibung für deine Änderungen ein." -#~ msgid "Too many options specified" -#~ msgstr "Zu viele Optionen angegeben" - #~ msgid "" #~ "To prevent you from losing history, non-fast-forward updates were " #~ "rejected\n" @@ -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: 2012-10-16 08:38+0800\n" +"POT-Creation-Date: 2012-11-30 12:40+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" @@ -60,7 +60,7 @@ msgstr "" msgid "archive format" msgstr "" -#: archive.c:323 builtin/log.c:1079 +#: archive.c:323 builtin/log.c:1084 msgid "prefix" msgstr "" @@ -68,9 +68,9 @@ msgstr "" msgid "prepend prefix to each pathname in the archive" msgstr "" -#: archive.c:325 builtin/archive.c:91 builtin/blame.c:2389 -#: builtin/blame.c:2390 builtin/config.c:56 builtin/fast-export.c:642 -#: builtin/fast-export.c:644 builtin/grep.c:801 builtin/hash-object.c:77 +#: archive.c:325 builtin/archive.c:91 builtin/blame.c:2390 +#: builtin/blame.c:2391 builtin/config.c:55 builtin/fast-export.c:642 +#: builtin/fast-export.c:644 builtin/grep.c:715 builtin/hash-object.c:77 #: builtin/ls-files.c:494 builtin/ls-files.c:497 builtin/notes.c:540 #: builtin/notes.c:697 builtin/read-tree.c:107 parse-options.h:149 msgid "file" @@ -120,6 +120,12 @@ msgstr "" msgid "path to the remote git-upload-archive command" msgstr "" +#: attr.c:259 +msgid "" +"Negative patterns are forbidden in git attributes\n" +"Use '\\!' for literal leading exclamation." +msgstr "" + #: bundle.c:36 #, c-format msgid "'%s' does not look like a v2 bundle file" @@ -130,7 +136,7 @@ msgstr "" msgid "unrecognized header: %s%s (%d)" msgstr "" -#: bundle.c:89 builtin/commit.c:672 +#: bundle.c:89 builtin/commit.c:674 #, c-format msgid "could not open '%s'" msgstr "" @@ -140,7 +146,7 @@ msgid "Repository lacks these prerequisite commits:" msgstr "" #: bundle.c:164 sequencer.c:562 sequencer.c:994 builtin/log.c:290 -#: builtin/log.c:727 builtin/log.c:1313 builtin/log.c:1529 builtin/merge.c:347 +#: builtin/log.c:732 builtin/log.c:1319 builtin/log.c:1535 builtin/merge.c:347 #: builtin/shortlog.c:181 msgid "revision walk setup failed" msgstr "" @@ -167,7 +173,7 @@ msgstr[1] "" msgid "rev-list died" msgstr "" -#: bundle.c:300 builtin/log.c:1209 builtin/shortlog.c:284 +#: bundle.c:300 builtin/log.c:1215 builtin/shortlog.c:284 #, c-format msgid "unrecognized argument: %s" msgstr "" @@ -293,30 +299,40 @@ msgid_plural "%lu years ago" msgstr[0] "" msgstr[1] "" -#: diff.c:105 +#: diff.c:111 +#, c-format +msgid " Failed to parse dirstat cut-off percentage '%s'\n" +msgstr "" + +#: diff.c:116 #, c-format -msgid " Failed to parse dirstat cut-off percentage '%.*s'\n" +msgid " Unknown dirstat parameter '%s'\n" msgstr "" -#: diff.c:110 +#: diff.c:194 #, c-format -msgid " Unknown dirstat parameter '%.*s'\n" +msgid "Unknown value for 'diff.submodule' config variable: '%s'" msgstr "" -#: diff.c:210 +#: diff.c:237 #, c-format msgid "" "Found errors in 'diff.dirstat' config variable:\n" "%s" msgstr "" -#: diff.c:3458 +#: diff.c:3494 #, c-format msgid "" "Failed to parse --dirstat/-X option parameter:\n" "%s" msgstr "" +#: diff.c:3508 +#, c-format +msgid "Failed to parse --submodule option parameter: '%s'" +msgstr "" + #: gpg-interface.c:59 msgid "could not run gpg." msgstr "" @@ -329,17 +345,17 @@ msgstr "" msgid "gpg failed to sign the data" msgstr "" -#: grep.c:1441 +#: grep.c:1622 #, c-format msgid "'%s': unable to read %s" msgstr "" -#: grep.c:1458 +#: grep.c:1639 #, c-format msgid "'%s': %s" msgstr "" -#: grep.c:1469 +#: grep.c:1650 #, c-format msgid "'%s': short read %s" msgstr "" @@ -391,6 +407,15 @@ msgid_plural "" msgstr[0] "" msgstr[1] "" +#: merge.c:56 +msgid "failed to read the cache" +msgstr "" + +#: merge.c:110 builtin/checkout.c:333 builtin/checkout.c:534 +#: builtin/clone.c:586 +msgid "unable to write new index file" +msgstr "" + #: merge-recursive.c:190 #, c-format msgid "(bad commit)\n" @@ -563,7 +588,7 @@ msgstr "" msgid "Auto-merging %s" msgstr "" -#: merge-recursive.c:1633 git-submodule.sh:869 +#: merge-recursive.c:1633 git-submodule.sh:893 msgid "submodule" msgstr "" @@ -633,7 +658,7 @@ msgstr "" msgid "Could not parse object '%s'" msgstr "" -#: merge-recursive.c:2009 builtin/merge.c:696 +#: merge-recursive.c:2009 builtin/merge.c:643 msgid "Unable to write index." msgstr "" @@ -665,7 +690,11 @@ msgid_plural "Your branch is ahead of '%s' by %d commits.\n" msgstr[0] "" msgstr[1] "" -#: remote.c:1638 +#: remote.c:1637 +msgid " (use \"git push\" to publish your local commits)\n" +msgstr "" + +#: remote.c:1640 #, c-format msgid "Your branch is behind '%s' by %d commit, and can be fast-forwarded.\n" msgid_plural "" @@ -673,7 +702,11 @@ msgid_plural "" msgstr[0] "" msgstr[1] "" -#: remote.c:1646 +#: remote.c:1647 +msgid " (use \"git pull\" to update your local branch)\n" +msgstr "" + +#: remote.c:1650 #, c-format msgid "" "Your branch and '%s' have diverged,\n" @@ -684,14 +717,18 @@ msgid_plural "" msgstr[0] "" msgstr[1] "" -#: sequencer.c:123 builtin/merge.c:864 builtin/merge.c:977 -#: builtin/merge.c:1087 builtin/merge.c:1097 +#: remote.c:1659 +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 #, c-format msgid "Could not open '%s' for writing" msgstr "" -#: sequencer.c:125 builtin/merge.c:333 builtin/merge.c:867 -#: builtin/merge.c:1089 builtin/merge.c:1102 +#: sequencer.c:125 builtin/merge.c:333 builtin/merge.c:764 builtin/merge.c:986 +#: builtin/merge.c:999 #, c-format msgid "Could not write to '%s'" msgstr "" @@ -1299,7 +1336,7 @@ msgstr "" msgid "unexpected diff status %c" msgstr "" -#: builtin/add.c:67 builtin/commit.c:230 +#: builtin/add.c:67 builtin/commit.c:231 msgid "updating files failed" msgstr "" @@ -1317,7 +1354,7 @@ msgstr "" msgid "Unstaged changes after refreshing the index:" msgstr "" -#: builtin/add.c:195 builtin/add.c:460 builtin/rm.c:186 +#: builtin/add.c:195 builtin/add.c:460 builtin/rm.c:275 #, c-format msgid "pathspec '%s' did not match any files" msgstr "" @@ -1360,12 +1397,12 @@ msgstr "" #: builtin/add.c:319 builtin/clean.c:52 builtin/fetch.c:78 builtin/mv.c:63 #: builtin/prune-packed.c:76 builtin/push.c:388 builtin/remote.c:1253 -#: builtin/rm.c:133 +#: builtin/rm.c:206 msgid "dry run" msgstr "" -#: builtin/add.c:320 builtin/apply.c:4354 builtin/commit.c:1154 -#: builtin/count-objects.c:82 builtin/fsck.c:613 builtin/log.c:1477 +#: builtin/add.c:320 builtin/apply.c:4354 builtin/commit.c:1160 +#: builtin/count-objects.c:82 builtin/fsck.c:613 builtin/log.c:1483 #: builtin/mv.c:62 builtin/read-tree.c:112 msgid "be verbose" msgstr "" @@ -1374,7 +1411,7 @@ msgstr "" msgid "interactive picking" msgstr "" -#: builtin/add.c:323 builtin/checkout.c:1028 builtin/reset.c:248 +#: builtin/add.c:323 builtin/checkout.c:1031 builtin/reset.c:248 msgid "select hunks interactively" msgstr "" @@ -1441,12 +1478,12 @@ msgstr "" msgid "Maybe you wanted to say 'git add .'?\n" msgstr "" -#: builtin/add.c:421 builtin/clean.c:95 builtin/commit.c:290 builtin/mv.c:82 -#: builtin/rm.c:162 +#: builtin/add.c:421 builtin/clean.c:95 builtin/commit.c:291 builtin/mv.c:82 +#: builtin/rm.c:235 msgid "index file corrupt" msgstr "" -#: builtin/add.c:481 builtin/apply.c:4450 builtin/mv.c:229 builtin/rm.c:260 +#: builtin/add.c:481 builtin/apply.c:4450 builtin/mv.c:229 builtin/rm.c:370 msgid "Unable to write new index file" msgstr "" @@ -1975,95 +2012,95 @@ msgstr "" msgid "[rev-opts] are documented in git-rev-list(1)" msgstr "" -#: builtin/blame.c:2373 +#: builtin/blame.c:2374 msgid "Show blame entries as we find them, incrementally" msgstr "" -#: builtin/blame.c:2374 +#: builtin/blame.c:2375 msgid "Show blank SHA-1 for boundary commits (Default: off)" msgstr "" -#: builtin/blame.c:2375 +#: builtin/blame.c:2376 msgid "Do not treat root commits as boundaries (Default: off)" msgstr "" -#: builtin/blame.c:2376 +#: builtin/blame.c:2377 msgid "Show work cost statistics" msgstr "" -#: builtin/blame.c:2377 +#: builtin/blame.c:2378 msgid "Show output score for blame entries" msgstr "" -#: builtin/blame.c:2378 +#: builtin/blame.c:2379 msgid "Show original filename (Default: auto)" msgstr "" -#: builtin/blame.c:2379 +#: builtin/blame.c:2380 msgid "Show original linenumber (Default: off)" msgstr "" -#: builtin/blame.c:2380 +#: builtin/blame.c:2381 msgid "Show in a format designed for machine consumption" msgstr "" -#: builtin/blame.c:2381 +#: builtin/blame.c:2382 msgid "Show porcelain format with per-line commit information" msgstr "" -#: builtin/blame.c:2382 +#: builtin/blame.c:2383 msgid "Use the same output mode as git-annotate (Default: off)" msgstr "" -#: builtin/blame.c:2383 +#: builtin/blame.c:2384 msgid "Show raw timestamp (Default: off)" msgstr "" -#: builtin/blame.c:2384 +#: builtin/blame.c:2385 msgid "Show long commit SHA1 (Default: off)" msgstr "" -#: builtin/blame.c:2385 +#: builtin/blame.c:2386 msgid "Suppress author name and timestamp (Default: off)" msgstr "" -#: builtin/blame.c:2386 +#: builtin/blame.c:2387 msgid "Show author email instead of name (Default: off)" msgstr "" -#: builtin/blame.c:2387 +#: builtin/blame.c:2388 msgid "Ignore whitespace differences" msgstr "" -#: builtin/blame.c:2388 +#: builtin/blame.c:2389 msgid "Spend extra cycles to find better match" msgstr "" -#: builtin/blame.c:2389 +#: builtin/blame.c:2390 msgid "Use revisions from <file> instead of calling git-rev-list" msgstr "" -#: builtin/blame.c:2390 +#: builtin/blame.c:2391 msgid "Use <file>'s contents as the final image" msgstr "" -#: builtin/blame.c:2391 builtin/blame.c:2392 +#: builtin/blame.c:2392 builtin/blame.c:2393 msgid "score" msgstr "" -#: builtin/blame.c:2391 +#: builtin/blame.c:2392 msgid "Find line copies within and across files" msgstr "" -#: builtin/blame.c:2392 +#: builtin/blame.c:2393 msgid "Find line movements within and across files" msgstr "" -#: builtin/blame.c:2393 +#: builtin/blame.c:2394 msgid "n,m" msgstr "" -#: builtin/blame.c:2393 +#: builtin/blame.c:2394 msgid "Process only line range n,m, counting from 1" msgstr "" @@ -2097,269 +2134,269 @@ msgid "" " '%s', even though it is merged to HEAD." msgstr "" -#: builtin/branch.c:181 +#: builtin/branch.c:163 +#, c-format +msgid "Couldn't look up commit object for '%s'" +msgstr "" + +#: builtin/branch.c:167 +#, 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 +msgid "Update of config-file failed" +msgstr "" + +#: builtin/branch.c:208 msgid "cannot use -a with -d" msgstr "" -#: builtin/branch.c:187 +#: builtin/branch.c:214 msgid "Couldn't look up commit object for HEAD" msgstr "" -#: builtin/branch.c:192 +#: builtin/branch.c:222 #, c-format msgid "Cannot delete the branch '%s' which you are currently on." msgstr "" -#: builtin/branch.c:203 +#: builtin/branch.c:235 #, c-format msgid "remote branch '%s' not found." msgstr "" -#: builtin/branch.c:204 +#: builtin/branch.c:236 #, c-format msgid "branch '%s' not found." msgstr "" -#: builtin/branch.c:211 -#, c-format -msgid "Couldn't look up commit object for '%s'" -msgstr "" - -#: builtin/branch.c:217 -#, 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:226 +#: builtin/branch.c:250 #, c-format msgid "Error deleting remote branch '%s'" msgstr "" -#: builtin/branch.c:227 +#: builtin/branch.c:251 #, c-format msgid "Error deleting branch '%s'" msgstr "" -#: builtin/branch.c:234 +#: builtin/branch.c:258 #, c-format msgid "Deleted remote branch %s (was %s).\n" msgstr "" -#: builtin/branch.c:235 +#: builtin/branch.c:259 #, c-format msgid "Deleted branch %s (was %s).\n" msgstr "" -#: builtin/branch.c:240 -msgid "Update of config-file failed" -msgstr "" - -#: builtin/branch.c:338 +#: builtin/branch.c:361 #, c-format msgid "branch '%s' does not point at a commit" msgstr "" -#: builtin/branch.c:410 +#: builtin/branch.c:433 #, c-format msgid "[%s: behind %d]" msgstr "" -#: builtin/branch.c:412 +#: builtin/branch.c:435 #, c-format msgid "[behind %d]" msgstr "" -#: builtin/branch.c:416 +#: builtin/branch.c:439 #, c-format msgid "[%s: ahead %d]" msgstr "" -#: builtin/branch.c:418 +#: builtin/branch.c:441 #, c-format msgid "[ahead %d]" msgstr "" -#: builtin/branch.c:421 +#: builtin/branch.c:444 #, c-format msgid "[%s: ahead %d, behind %d]" msgstr "" -#: builtin/branch.c:424 +#: builtin/branch.c:447 #, c-format msgid "[ahead %d, behind %d]" msgstr "" -#: builtin/branch.c:537 +#: builtin/branch.c:560 msgid "(no branch)" msgstr "" -#: builtin/branch.c:602 +#: builtin/branch.c:625 msgid "some refs could not be read" msgstr "" -#: builtin/branch.c:615 +#: builtin/branch.c:638 msgid "cannot rename the current branch while not on any." msgstr "" -#: builtin/branch.c:625 +#: builtin/branch.c:648 #, c-format msgid "Invalid branch name: '%s'" msgstr "" -#: builtin/branch.c:640 +#: builtin/branch.c:663 msgid "Branch rename failed" msgstr "" -#: builtin/branch.c:644 +#: builtin/branch.c:667 #, c-format msgid "Renamed a misnamed branch '%s' away" msgstr "" -#: builtin/branch.c:648 +#: builtin/branch.c:671 #, c-format msgid "Branch renamed to %s, but HEAD is not updated!" msgstr "" -#: builtin/branch.c:655 +#: builtin/branch.c:678 msgid "Branch is renamed, but update of config-file failed" msgstr "" -#: builtin/branch.c:670 +#: builtin/branch.c:693 #, c-format msgid "malformed object name %s" msgstr "" -#: builtin/branch.c:694 +#: builtin/branch.c:717 #, c-format msgid "could not write branch description template: %s" msgstr "" -#: builtin/branch.c:724 +#: builtin/branch.c:747 msgid "Generic options" msgstr "" -#: builtin/branch.c:726 +#: builtin/branch.c:749 msgid "show hash and subject, give twice for upstream branch" msgstr "" -#: builtin/branch.c:727 +#: builtin/branch.c:750 msgid "suppress informational messages" msgstr "" -#: builtin/branch.c:728 +#: builtin/branch.c:751 msgid "set up tracking mode (see git-pull(1))" msgstr "" -#: builtin/branch.c:730 +#: builtin/branch.c:753 msgid "change upstream info" msgstr "" -#: builtin/branch.c:734 +#: builtin/branch.c:757 msgid "use colored output" msgstr "" -#: builtin/branch.c:735 +#: builtin/branch.c:758 msgid "act on remote-tracking branches" msgstr "" -#: builtin/branch.c:738 builtin/branch.c:744 builtin/branch.c:765 -#: builtin/branch.c:771 builtin/commit.c:1362 builtin/commit.c:1363 -#: builtin/commit.c:1364 builtin/commit.c:1365 builtin/tag.c:470 +#: builtin/branch.c:761 builtin/branch.c:767 builtin/branch.c:788 +#: builtin/branch.c:794 builtin/commit.c:1376 builtin/commit.c:1377 +#: builtin/commit.c:1378 builtin/commit.c:1379 builtin/tag.c:470 msgid "commit" msgstr "" -#: builtin/branch.c:739 builtin/branch.c:745 +#: builtin/branch.c:762 builtin/branch.c:768 msgid "print only branches that contain the commit" msgstr "" -#: builtin/branch.c:751 +#: builtin/branch.c:774 msgid "Specific git-branch actions:" msgstr "" -#: builtin/branch.c:752 +#: builtin/branch.c:775 msgid "list both remote-tracking and local branches" msgstr "" -#: builtin/branch.c:754 +#: builtin/branch.c:777 msgid "delete fully merged branch" msgstr "" -#: builtin/branch.c:755 +#: builtin/branch.c:778 msgid "delete branch (even if not merged)" msgstr "" -#: builtin/branch.c:756 +#: builtin/branch.c:779 msgid "move/rename a branch and its reflog" msgstr "" -#: builtin/branch.c:757 +#: builtin/branch.c:780 msgid "move/rename a branch, even if target exists" msgstr "" -#: builtin/branch.c:758 +#: builtin/branch.c:781 msgid "list branch names" msgstr "" -#: builtin/branch.c:759 +#: builtin/branch.c:782 msgid "create the branch's reflog" msgstr "" -#: builtin/branch.c:761 +#: builtin/branch.c:784 msgid "edit the description for the branch" msgstr "" -#: builtin/branch.c:762 +#: builtin/branch.c:785 msgid "force creation (when already exists)" msgstr "" -#: builtin/branch.c:765 +#: builtin/branch.c:788 msgid "print only not merged branches" msgstr "" -#: builtin/branch.c:771 +#: builtin/branch.c:794 msgid "print only merged branches" msgstr "" -#: builtin/branch.c:775 +#: builtin/branch.c:798 msgid "list branches in columns" msgstr "" -#: builtin/branch.c:788 +#: builtin/branch.c:811 msgid "Failed to resolve HEAD as a valid ref." msgstr "" -#: builtin/branch.c:793 builtin/clone.c:561 +#: builtin/branch.c:816 builtin/clone.c:561 msgid "HEAD not found below refs/heads!" msgstr "" -#: builtin/branch.c:813 +#: builtin/branch.c:836 msgid "--column and --verbose are incompatible" msgstr "" -#: builtin/branch.c:864 +#: builtin/branch.c:887 #, c-format msgid "branch '%s' does not exist" msgstr "" -#: builtin/branch.c:876 +#: builtin/branch.c:899 #, c-format msgid "Branch '%s' has no upstream information" msgstr "" -#: builtin/branch.c:891 +#: builtin/branch.c:914 msgid "-a and -r options to 'git branch' do not make sense with a branch name" msgstr "" -#: builtin/branch.c:894 +#: builtin/branch.c:917 #, 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:911 +#: builtin/branch.c:934 #, c-format msgid "" "\n" @@ -2367,12 +2404,12 @@ msgid "" "\n" msgstr "" -#: builtin/branch.c:912 +#: builtin/branch.c:935 #, c-format msgid " git branch -d %s\n" msgstr "" -#: builtin/branch.c:913 +#: builtin/branch.c:936 #, c-format msgid " git branch --set-upstream-to %s\n" msgstr "" @@ -2561,11 +2598,6 @@ msgstr "" msgid "path '%s' is unmerged" msgstr "" -#: builtin/checkout.c:333 builtin/checkout.c:534 builtin/clone.c:586 -#: builtin/merge.c:811 -msgid "unable to write new index file" -msgstr "" - #: builtin/checkout.c:448 msgid "you need to resolve your current index first" msgstr "" @@ -2594,7 +2626,7 @@ msgstr "" msgid "Switched to and reset branch '%s'\n" msgstr "" -#: builtin/checkout.c:618 +#: builtin/checkout.c:618 builtin/checkout.c:955 #, c-format msgid "Switched to a new branch '%s'\n" msgstr "" @@ -2659,124 +2691,124 @@ msgstr "" msgid "reference is not a tree: %s" msgstr "" -#: builtin/checkout.c:961 +#: builtin/checkout.c:964 msgid "paths cannot be used with switching branches" msgstr "" -#: builtin/checkout.c:964 builtin/checkout.c:968 +#: builtin/checkout.c:967 builtin/checkout.c:971 #, c-format msgid "'%s' cannot be used with switching branches" msgstr "" -#: builtin/checkout.c:972 builtin/checkout.c:975 builtin/checkout.c:980 -#: builtin/checkout.c:983 +#: builtin/checkout.c:975 builtin/checkout.c:978 builtin/checkout.c:983 +#: builtin/checkout.c:986 #, c-format msgid "'%s' cannot be used with '%s'" msgstr "" -#: builtin/checkout.c:988 +#: builtin/checkout.c:991 #, c-format msgid "Cannot switch branch to a non-commit '%s'" msgstr "" -#: builtin/checkout.c:1009 builtin/gc.c:177 +#: builtin/checkout.c:1012 builtin/gc.c:177 msgid "suppress progress reporting" msgstr "" -#: builtin/checkout.c:1010 builtin/checkout.c:1012 builtin/clone.c:89 +#: builtin/checkout.c:1013 builtin/checkout.c:1015 builtin/clone.c:89 #: builtin/remote.c:169 builtin/remote.c:171 msgid "branch" msgstr "" -#: builtin/checkout.c:1011 +#: builtin/checkout.c:1014 msgid "create and checkout a new branch" msgstr "" -#: builtin/checkout.c:1013 +#: builtin/checkout.c:1016 msgid "create/reset and checkout a branch" msgstr "" -#: builtin/checkout.c:1014 +#: builtin/checkout.c:1017 msgid "create reflog for new branch" msgstr "" -#: builtin/checkout.c:1015 +#: builtin/checkout.c:1018 msgid "detach the HEAD at named commit" msgstr "" -#: builtin/checkout.c:1016 +#: builtin/checkout.c:1019 msgid "set upstream info for new branch" msgstr "" -#: builtin/checkout.c:1018 +#: builtin/checkout.c:1021 msgid "new branch" msgstr "" -#: builtin/checkout.c:1018 +#: builtin/checkout.c:1021 msgid "new unparented branch" msgstr "" -#: builtin/checkout.c:1019 +#: builtin/checkout.c:1022 msgid "checkout our version for unmerged files" msgstr "" -#: builtin/checkout.c:1021 +#: builtin/checkout.c:1024 msgid "checkout their version for unmerged files" msgstr "" -#: builtin/checkout.c:1023 +#: builtin/checkout.c:1026 msgid "force checkout (throw away local modifications)" msgstr "" -#: builtin/checkout.c:1024 +#: builtin/checkout.c:1027 msgid "perform a 3-way merge with the new branch" msgstr "" -#: builtin/checkout.c:1025 builtin/merge.c:215 +#: builtin/checkout.c:1028 builtin/merge.c:215 msgid "update ignored files (default)" msgstr "" -#: builtin/checkout.c:1026 builtin/log.c:1111 parse-options.h:241 +#: builtin/checkout.c:1029 builtin/log.c:1116 parse-options.h:241 msgid "style" msgstr "" -#: builtin/checkout.c:1027 +#: builtin/checkout.c:1030 msgid "conflict style (merge or diff3)" msgstr "" -#: builtin/checkout.c:1030 +#: builtin/checkout.c:1033 msgid "second guess 'git checkout no-such-branch'" msgstr "" -#: builtin/checkout.c:1054 +#: builtin/checkout.c:1057 msgid "-b, -B and --orphan are mutually exclusive" msgstr "" -#: builtin/checkout.c:1071 +#: builtin/checkout.c:1074 msgid "--track needs a branch name" msgstr "" -#: builtin/checkout.c:1078 +#: builtin/checkout.c:1081 msgid "Missing branch name; try -b" msgstr "" -#: builtin/checkout.c:1113 +#: builtin/checkout.c:1116 msgid "invalid path specification" msgstr "" -#: builtin/checkout.c:1120 +#: builtin/checkout.c:1123 #, 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:1125 +#: builtin/checkout.c:1128 #, c-format msgid "git checkout: --detach does not take a path argument '%s'" msgstr "" -#: builtin/checkout.c:1129 +#: builtin/checkout.c:1132 msgid "" "git checkout: --ours/--theirs, --force and --merge are incompatible when\n" "checking out of the index." @@ -2798,8 +2830,8 @@ msgstr "" msgid "remove whole directories" msgstr "" -#: builtin/clean.c:56 builtin/describe.c:413 builtin/grep.c:803 -#: builtin/ls-files.c:491 builtin/name-rev.c:231 builtin/show-ref.c:199 +#: builtin/clean.c:56 builtin/describe.c:413 builtin/grep.c:717 +#: builtin/ls-files.c:491 builtin/name-rev.c:231 builtin/show-ref.c:182 msgid "pattern" msgstr "" @@ -2920,7 +2952,7 @@ msgstr "" msgid "path to git-upload-pack on the remote" msgstr "" -#: builtin/clone.c:93 builtin/fetch.c:83 builtin/grep.c:748 +#: builtin/clone.c:93 builtin/fetch.c:83 builtin/grep.c:662 msgid "depth" msgstr "" @@ -3134,93 +3166,93 @@ msgid "" "Otherwise, please use 'git reset'\n" msgstr "" -#: builtin/commit.c:257 +#: builtin/commit.c:258 msgid "failed to unpack HEAD tree object" msgstr "" -#: builtin/commit.c:299 +#: builtin/commit.c:300 msgid "unable to create temporary index" msgstr "" -#: builtin/commit.c:305 +#: builtin/commit.c:306 msgid "interactive add failed" msgstr "" -#: builtin/commit.c:338 builtin/commit.c:359 builtin/commit.c:409 +#: builtin/commit.c:339 builtin/commit.c:360 builtin/commit.c:410 msgid "unable to write new_index file" msgstr "" -#: builtin/commit.c:390 +#: builtin/commit.c:391 msgid "cannot do a partial commit during a merge." msgstr "" -#: builtin/commit.c:392 +#: builtin/commit.c:393 msgid "cannot do a partial commit during a cherry-pick." msgstr "" -#: builtin/commit.c:402 +#: builtin/commit.c:403 msgid "cannot read the index" msgstr "" -#: builtin/commit.c:422 +#: builtin/commit.c:423 msgid "unable to write temporary index file" msgstr "" -#: builtin/commit.c:509 builtin/commit.c:515 +#: builtin/commit.c:511 builtin/commit.c:517 #, c-format msgid "invalid commit: %s" msgstr "" -#: builtin/commit.c:538 +#: builtin/commit.c:540 msgid "malformed --author parameter" msgstr "" -#: builtin/commit.c:558 +#: builtin/commit.c:560 #, c-format msgid "Malformed ident string: '%s'" msgstr "" -#: builtin/commit.c:596 builtin/commit.c:629 builtin/commit.c:952 +#: builtin/commit.c:598 builtin/commit.c:631 builtin/commit.c:954 #, c-format msgid "could not lookup commit %s" msgstr "" -#: builtin/commit.c:608 builtin/shortlog.c:296 +#: builtin/commit.c:610 builtin/shortlog.c:296 #, c-format msgid "(reading log message from standard input)\n" msgstr "" -#: builtin/commit.c:610 +#: builtin/commit.c:612 msgid "could not read log from standard input" msgstr "" -#: builtin/commit.c:614 +#: builtin/commit.c:616 #, c-format msgid "could not read log file '%s'" msgstr "" -#: builtin/commit.c:620 +#: builtin/commit.c:622 msgid "commit has empty message" msgstr "" -#: builtin/commit.c:636 +#: builtin/commit.c:638 msgid "could not read MERGE_MSG" msgstr "" -#: builtin/commit.c:640 +#: builtin/commit.c:642 msgid "could not read SQUASH_MSG" msgstr "" -#: builtin/commit.c:644 +#: builtin/commit.c:646 #, c-format msgid "could not read '%s'" msgstr "" -#: builtin/commit.c:705 +#: builtin/commit.c:707 msgid "could not write commit template" msgstr "" -#: builtin/commit.c:716 +#: builtin/commit.c:718 #, c-format msgid "" "\n" @@ -3230,7 +3262,7 @@ msgid "" "and try again.\n" msgstr "" -#: builtin/commit.c:721 +#: builtin/commit.c:723 #, c-format msgid "" "\n" @@ -3240,356 +3272,364 @@ msgid "" "and try again.\n" msgstr "" -#: builtin/commit.c:733 +#: builtin/commit.c:735 msgid "" "Please enter the commit message for your changes. Lines starting\n" "with '#' will be ignored, and an empty message aborts the commit.\n" msgstr "" -#: builtin/commit.c:738 +#: builtin/commit.c:740 msgid "" "Please enter the commit message for your changes. Lines starting\n" "with '#' will be kept; you may remove them yourself if you want to.\n" "An empty message aborts the commit.\n" msgstr "" -#: builtin/commit.c:751 +#: builtin/commit.c:753 #, c-format msgid "%sAuthor: %s" msgstr "" -#: builtin/commit.c:758 +#: builtin/commit.c:760 #, c-format msgid "%sCommitter: %s" msgstr "" -#: builtin/commit.c:778 +#: builtin/commit.c:780 msgid "Cannot read index" msgstr "" -#: builtin/commit.c:815 +#: builtin/commit.c:817 msgid "Error building trees" msgstr "" -#: builtin/commit.c:830 builtin/tag.c:361 +#: builtin/commit.c:832 builtin/tag.c:361 #, c-format msgid "Please supply the message using either -m or -F option.\n" msgstr "" -#: builtin/commit.c:927 +#: builtin/commit.c:929 #, c-format msgid "No existing author found with '%s'" msgstr "" -#: builtin/commit.c:942 builtin/commit.c:1142 +#: builtin/commit.c:944 builtin/commit.c:1148 #, c-format msgid "Invalid untracked files mode '%s'" msgstr "" -#: builtin/commit.c:982 +#: builtin/commit.c:984 msgid "Using both --reset-author and --author does not make sense" msgstr "" -#: builtin/commit.c:993 +#: builtin/commit.c:995 msgid "You have nothing to amend." msgstr "" -#: builtin/commit.c:996 +#: builtin/commit.c:998 msgid "You are in the middle of a merge -- cannot amend." msgstr "" -#: builtin/commit.c:998 +#: builtin/commit.c:1000 msgid "You are in the middle of a cherry-pick -- cannot amend." msgstr "" -#: builtin/commit.c:1001 +#: builtin/commit.c:1003 msgid "Options --squash and --fixup cannot be used together" msgstr "" -#: builtin/commit.c:1011 +#: builtin/commit.c:1013 msgid "Only one of -c/-C/-F/--fixup can be used." msgstr "" -#: builtin/commit.c:1013 +#: builtin/commit.c:1015 msgid "Option -m cannot be combined with -c/-C/-F/--fixup." msgstr "" -#: builtin/commit.c:1021 +#: builtin/commit.c:1023 msgid "--reset-author can be used only with -C, -c or --amend." msgstr "" -#: builtin/commit.c:1038 +#: builtin/commit.c:1040 msgid "Only one of --include/--only/--all/--interactive/--patch can be used." msgstr "" -#: builtin/commit.c:1040 +#: builtin/commit.c:1042 msgid "No paths with --include/--only does not make sense." msgstr "" -#: builtin/commit.c:1042 +#: builtin/commit.c:1044 msgid "Clever... amending the last one with dirty index." msgstr "" -#: builtin/commit.c:1044 +#: builtin/commit.c:1046 msgid "Explicit paths specified without -i nor -o; assuming --only paths..." msgstr "" -#: builtin/commit.c:1054 builtin/tag.c:577 +#: builtin/commit.c:1056 builtin/tag.c:577 #, c-format msgid "Invalid cleanup mode %s" msgstr "" -#: builtin/commit.c:1059 +#: builtin/commit.c:1061 msgid "Paths with -a does not make sense." msgstr "" -#: builtin/commit.c:1156 builtin/commit.c:1384 +#: builtin/commit.c:1067 builtin/commit.c:1202 +msgid "--long and -z are incompatible" +msgstr "" + +#: builtin/commit.c:1162 builtin/commit.c:1398 msgid "show status concisely" msgstr "" -#: builtin/commit.c:1158 builtin/commit.c:1386 +#: builtin/commit.c:1164 builtin/commit.c:1400 msgid "show branch information" msgstr "" -#: builtin/commit.c:1160 builtin/commit.c:1388 builtin/push.c:389 +#: builtin/commit.c:1166 builtin/commit.c:1402 builtin/push.c:389 msgid "machine-readable output" msgstr "" -#: builtin/commit.c:1163 builtin/commit.c:1390 +#: builtin/commit.c:1169 builtin/commit.c:1404 +msgid "show status in long format (default)" +msgstr "" + +#: builtin/commit.c:1172 builtin/commit.c:1407 msgid "terminate entries with NUL" msgstr "" -#: builtin/commit.c:1165 builtin/commit.c:1393 builtin/fast-export.c:636 +#: builtin/commit.c:1174 builtin/commit.c:1410 builtin/fast-export.c:636 #: builtin/fast-export.c:639 builtin/tag.c:461 msgid "mode" msgstr "" -#: builtin/commit.c:1166 builtin/commit.c:1393 +#: builtin/commit.c:1175 builtin/commit.c:1410 msgid "show untracked files, optional modes: all, normal, no. (Default: all)" msgstr "" -#: builtin/commit.c:1169 +#: builtin/commit.c:1178 msgid "show ignored files" msgstr "" -#: builtin/commit.c:1170 parse-options.h:151 +#: builtin/commit.c:1179 parse-options.h:151 msgid "when" msgstr "" -#: builtin/commit.c:1171 +#: builtin/commit.c:1180 msgid "" "ignore changes to submodules, optional when: all, dirty, untracked. " "(Default: all)" msgstr "" -#: builtin/commit.c:1173 +#: builtin/commit.c:1182 msgid "list untracked files in columns" msgstr "" -#: builtin/commit.c:1242 +#: builtin/commit.c:1256 msgid "couldn't look up newly created commit" msgstr "" -#: builtin/commit.c:1244 +#: builtin/commit.c:1258 msgid "could not parse newly created commit" msgstr "" -#: builtin/commit.c:1285 +#: builtin/commit.c:1299 msgid "detached HEAD" msgstr "" -#: builtin/commit.c:1287 +#: builtin/commit.c:1301 msgid " (root-commit)" msgstr "" -#: builtin/commit.c:1354 +#: builtin/commit.c:1368 msgid "suppress summary after successful commit" msgstr "" -#: builtin/commit.c:1355 +#: builtin/commit.c:1369 msgid "show diff in commit message template" msgstr "" -#: builtin/commit.c:1357 +#: builtin/commit.c:1371 msgid "Commit message options" msgstr "" -#: builtin/commit.c:1358 builtin/tag.c:459 +#: builtin/commit.c:1372 builtin/tag.c:459 msgid "read message from file" msgstr "" -#: builtin/commit.c:1359 +#: builtin/commit.c:1373 msgid "author" msgstr "" -#: builtin/commit.c:1359 +#: builtin/commit.c:1373 msgid "override author for commit" msgstr "" -#: builtin/commit.c:1360 builtin/gc.c:178 +#: builtin/commit.c:1374 builtin/gc.c:178 msgid "date" msgstr "" -#: builtin/commit.c:1360 +#: builtin/commit.c:1374 msgid "override date for commit" msgstr "" -#: builtin/commit.c:1361 builtin/merge.c:206 builtin/notes.c:537 +#: builtin/commit.c:1375 builtin/merge.c:206 builtin/notes.c:537 #: builtin/notes.c:694 builtin/tag.c:457 msgid "message" msgstr "" -#: builtin/commit.c:1361 +#: builtin/commit.c:1375 msgid "commit message" msgstr "" -#: builtin/commit.c:1362 +#: builtin/commit.c:1376 msgid "reuse and edit message from specified commit" msgstr "" -#: builtin/commit.c:1363 +#: builtin/commit.c:1377 msgid "reuse message from specified commit" msgstr "" -#: builtin/commit.c:1364 +#: builtin/commit.c:1378 msgid "use autosquash formatted message to fixup specified commit" msgstr "" -#: builtin/commit.c:1365 +#: builtin/commit.c:1379 msgid "use autosquash formatted message to squash specified commit" msgstr "" -#: builtin/commit.c:1366 +#: builtin/commit.c:1380 msgid "the commit is authored by me now (used with -C/-c/--amend)" msgstr "" -#: builtin/commit.c:1367 builtin/log.c:1068 builtin/revert.c:109 +#: builtin/commit.c:1381 builtin/log.c:1073 builtin/revert.c:109 msgid "add Signed-off-by:" msgstr "" -#: builtin/commit.c:1368 +#: builtin/commit.c:1382 msgid "use specified template file" msgstr "" -#: builtin/commit.c:1369 +#: builtin/commit.c:1383 msgid "force edit of commit" msgstr "" -#: builtin/commit.c:1370 +#: builtin/commit.c:1384 msgid "default" msgstr "" -#: builtin/commit.c:1370 builtin/tag.c:462 +#: builtin/commit.c:1384 builtin/tag.c:462 msgid "how to strip spaces and #comments from message" msgstr "" -#: builtin/commit.c:1371 +#: builtin/commit.c:1385 msgid "include status in commit message template" msgstr "" -#: builtin/commit.c:1372 builtin/merge.c:213 builtin/tag.c:463 +#: builtin/commit.c:1386 builtin/merge.c:213 builtin/tag.c:463 msgid "key id" msgstr "" -#: builtin/commit.c:1373 builtin/merge.c:214 +#: builtin/commit.c:1387 builtin/merge.c:214 msgid "GPG sign commit" msgstr "" #. end commit message options -#: builtin/commit.c:1376 +#: builtin/commit.c:1390 msgid "Commit contents options" msgstr "" -#: builtin/commit.c:1377 +#: builtin/commit.c:1391 msgid "commit all changed files" msgstr "" -#: builtin/commit.c:1378 +#: builtin/commit.c:1392 msgid "add specified files to index for commit" msgstr "" -#: builtin/commit.c:1379 +#: builtin/commit.c:1393 msgid "interactively add files" msgstr "" -#: builtin/commit.c:1380 +#: builtin/commit.c:1394 msgid "interactively add changes" msgstr "" -#: builtin/commit.c:1381 +#: builtin/commit.c:1395 msgid "commit only specified files" msgstr "" -#: builtin/commit.c:1382 +#: builtin/commit.c:1396 msgid "bypass pre-commit hook" msgstr "" -#: builtin/commit.c:1383 +#: builtin/commit.c:1397 msgid "show what would be committed" msgstr "" -#: builtin/commit.c:1391 +#: builtin/commit.c:1408 msgid "amend previous commit" msgstr "" -#: builtin/commit.c:1392 +#: builtin/commit.c:1409 msgid "bypass post-rewrite hook" msgstr "" -#: builtin/commit.c:1397 +#: builtin/commit.c:1414 msgid "ok to record an empty change" msgstr "" -#: builtin/commit.c:1400 +#: builtin/commit.c:1417 msgid "ok to record a change with an empty message" msgstr "" -#: builtin/commit.c:1432 +#: builtin/commit.c:1449 msgid "could not parse HEAD commit" msgstr "" -#: builtin/commit.c:1470 builtin/merge.c:508 +#: builtin/commit.c:1487 builtin/merge.c:508 #, c-format msgid "could not open '%s' for reading" msgstr "" -#: builtin/commit.c:1477 +#: builtin/commit.c:1494 #, c-format msgid "Corrupt MERGE_HEAD file (%s)" msgstr "" -#: builtin/commit.c:1484 +#: builtin/commit.c:1501 msgid "could not read MERGE_MODE" msgstr "" -#: builtin/commit.c:1503 +#: builtin/commit.c:1520 #, c-format msgid "could not read commit message: %s" msgstr "" -#: builtin/commit.c:1517 +#: builtin/commit.c:1534 #, c-format msgid "Aborting commit; you did not edit the message.\n" msgstr "" -#: builtin/commit.c:1522 +#: builtin/commit.c:1539 #, c-format msgid "Aborting commit due to empty commit message.\n" msgstr "" -#: builtin/commit.c:1537 builtin/merge.c:935 builtin/merge.c:960 +#: builtin/commit.c:1554 builtin/merge.c:832 builtin/merge.c:857 msgid "failed to write commit object" msgstr "" -#: builtin/commit.c:1558 +#: builtin/commit.c:1575 msgid "cannot lock HEAD ref" msgstr "" -#: builtin/commit.c:1562 +#: builtin/commit.c:1579 msgid "cannot update HEAD ref" msgstr "" -#: builtin/commit.c:1573 +#: builtin/commit.c:1590 msgid "" "Repository has been updated, but unable to write\n" "new_index file. Check that disk is not full or quota is\n" @@ -3600,115 +3640,115 @@ msgstr "" msgid "git config [options]" msgstr "" -#: builtin/config.c:52 +#: builtin/config.c:51 msgid "Config file location" msgstr "" -#: builtin/config.c:53 +#: builtin/config.c:52 msgid "use global config file" msgstr "" -#: builtin/config.c:54 +#: builtin/config.c:53 msgid "use system config file" msgstr "" -#: builtin/config.c:55 +#: builtin/config.c:54 msgid "use repository config file" msgstr "" -#: builtin/config.c:56 +#: builtin/config.c:55 msgid "use given config file" msgstr "" -#: builtin/config.c:57 +#: builtin/config.c:56 msgid "Action" msgstr "" -#: builtin/config.c:58 +#: builtin/config.c:57 msgid "get value: name [value-regex]" msgstr "" -#: builtin/config.c:59 +#: builtin/config.c:58 msgid "get all values: key [value-regex]" msgstr "" -#: builtin/config.c:60 +#: builtin/config.c:59 msgid "get values for regexp: name-regex [value-regex]" msgstr "" -#: builtin/config.c:61 +#: builtin/config.c:60 msgid "replace all matching variables: name value [value_regex]" msgstr "" -#: builtin/config.c:62 +#: builtin/config.c:61 msgid "add a new variable: name value" msgstr "" -#: builtin/config.c:63 +#: builtin/config.c:62 msgid "remove a variable: name [value-regex]" msgstr "" -#: builtin/config.c:64 +#: builtin/config.c:63 msgid "remove all matches: name [value-regex]" msgstr "" -#: builtin/config.c:65 +#: builtin/config.c:64 msgid "rename section: old-name new-name" msgstr "" -#: builtin/config.c:66 +#: builtin/config.c:65 msgid "remove a section: name" msgstr "" -#: builtin/config.c:67 +#: builtin/config.c:66 msgid "list all" msgstr "" -#: builtin/config.c:68 +#: builtin/config.c:67 msgid "open an editor" msgstr "" -#: builtin/config.c:69 builtin/config.c:70 +#: builtin/config.c:68 builtin/config.c:69 msgid "slot" msgstr "" -#: builtin/config.c:69 +#: builtin/config.c:68 msgid "find the color configured: [default]" msgstr "" -#: builtin/config.c:70 +#: builtin/config.c:69 msgid "find the color setting: [stdout-is-tty]" msgstr "" -#: builtin/config.c:71 +#: builtin/config.c:70 msgid "Type" msgstr "" -#: builtin/config.c:72 +#: builtin/config.c:71 msgid "value is \"true\" or \"false\"" msgstr "" -#: builtin/config.c:73 +#: builtin/config.c:72 msgid "value is decimal number" msgstr "" -#: builtin/config.c:74 +#: builtin/config.c:73 msgid "value is --bool or --int" msgstr "" -#: builtin/config.c:75 +#: builtin/config.c:74 msgid "value is a path (file or directory name)" msgstr "" -#: builtin/config.c:76 +#: builtin/config.c:75 msgid "Other" msgstr "" -#: builtin/config.c:77 +#: builtin/config.c:76 msgid "terminate values with NUL byte" msgstr "" -#: builtin/config.c:78 +#: builtin/config.c:77 msgid "respect include directives on lookup" msgstr "" @@ -3851,31 +3891,31 @@ msgstr "" msgid "'%s': not a regular file or symlink" msgstr "" -#: builtin/diff.c:224 +#: builtin/diff.c:228 #, c-format msgid "invalid option: %s" msgstr "" -#: builtin/diff.c:301 +#: builtin/diff.c:305 msgid "Not a git repository" msgstr "" -#: builtin/diff.c:344 +#: builtin/diff.c:348 #, c-format msgid "invalid object '%s' given." msgstr "" -#: builtin/diff.c:349 +#: builtin/diff.c:353 #, c-format msgid "more than %d trees given: '%s'" msgstr "" -#: builtin/diff.c:359 +#: builtin/diff.c:363 #, c-format msgid "more than two blobs given: '%s'" msgstr "" -#: builtin/diff.c:367 +#: builtin/diff.c:371 #, c-format msgid "unhandled object '%s' given." msgstr "" @@ -3988,7 +4028,7 @@ msgstr "" msgid "deepen history of shallow clone" msgstr "" -#: builtin/fetch.c:85 builtin/log.c:1083 +#: builtin/fetch.c:85 builtin/log.c:1088 msgid "dir" msgstr "" @@ -4155,8 +4195,8 @@ msgstr "" msgid "git fmt-merge-msg [-m <message>] [--log[=<n>]|--no-log] [--file <file>]" msgstr "" -#: builtin/fmt-merge-msg.c:653 builtin/fmt-merge-msg.c:656 builtin/grep.c:787 -#: builtin/merge.c:188 builtin/show-branch.c:656 builtin/show-ref.c:192 +#: builtin/fmt-merge-msg.c:653 builtin/fmt-merge-msg.c:656 builtin/grep.c:701 +#: builtin/merge.c:188 builtin/show-branch.c:656 builtin/show-ref.c:175 #: builtin/tag.c:448 parse-options.h:133 parse-options.h:235 msgid "n" msgstr "" @@ -4312,225 +4352,225 @@ msgstr "" msgid "grep: failed to create thread: %s" msgstr "" -#: builtin/grep.c:455 +#: builtin/grep.c:365 #, c-format msgid "Failed to chdir: %s" msgstr "" -#: builtin/grep.c:531 builtin/grep.c:565 +#: builtin/grep.c:443 builtin/grep.c:478 #, c-format msgid "unable to read tree (%s)" msgstr "" -#: builtin/grep.c:579 +#: builtin/grep.c:493 #, c-format msgid "unable to grep from object of type %s" msgstr "" -#: builtin/grep.c:637 +#: builtin/grep.c:551 #, c-format msgid "switch `%c' expects a numerical value" msgstr "" -#: builtin/grep.c:654 +#: builtin/grep.c:568 #, c-format msgid "cannot open '%s'" msgstr "" -#: builtin/grep.c:729 +#: builtin/grep.c:643 msgid "search in index instead of in the work tree" msgstr "" -#: builtin/grep.c:731 +#: builtin/grep.c:645 msgid "find in contents not managed by git" msgstr "" -#: builtin/grep.c:733 +#: builtin/grep.c:647 msgid "search in both tracked and untracked files" msgstr "" -#: builtin/grep.c:735 +#: builtin/grep.c:649 msgid "search also in ignored files" msgstr "" -#: builtin/grep.c:738 +#: builtin/grep.c:652 msgid "show non-matching lines" msgstr "" -#: builtin/grep.c:740 +#: builtin/grep.c:654 msgid "case insensitive matching" msgstr "" -#: builtin/grep.c:742 +#: builtin/grep.c:656 msgid "match patterns only at word boundaries" msgstr "" -#: builtin/grep.c:744 +#: builtin/grep.c:658 msgid "process binary files as text" msgstr "" -#: builtin/grep.c:746 +#: builtin/grep.c:660 msgid "don't match patterns in binary files" msgstr "" -#: builtin/grep.c:749 +#: builtin/grep.c:663 msgid "descend at most <depth> levels" msgstr "" -#: builtin/grep.c:753 +#: builtin/grep.c:667 msgid "use extended POSIX regular expressions" msgstr "" -#: builtin/grep.c:756 +#: builtin/grep.c:670 msgid "use basic POSIX regular expressions (default)" msgstr "" -#: builtin/grep.c:759 +#: builtin/grep.c:673 msgid "interpret patterns as fixed strings" msgstr "" -#: builtin/grep.c:762 +#: builtin/grep.c:676 msgid "use Perl-compatible regular expressions" msgstr "" -#: builtin/grep.c:765 +#: builtin/grep.c:679 msgid "show line numbers" msgstr "" -#: builtin/grep.c:766 +#: builtin/grep.c:680 msgid "don't show filenames" msgstr "" -#: builtin/grep.c:767 +#: builtin/grep.c:681 msgid "show filenames" msgstr "" -#: builtin/grep.c:769 +#: builtin/grep.c:683 msgid "show filenames relative to top directory" msgstr "" -#: builtin/grep.c:771 +#: builtin/grep.c:685 msgid "show only filenames instead of matching lines" msgstr "" -#: builtin/grep.c:773 +#: builtin/grep.c:687 msgid "synonym for --files-with-matches" msgstr "" -#: builtin/grep.c:776 +#: builtin/grep.c:690 msgid "show only the names of files without match" msgstr "" -#: builtin/grep.c:778 +#: builtin/grep.c:692 msgid "print NUL after filenames" msgstr "" -#: builtin/grep.c:780 +#: builtin/grep.c:694 msgid "show the number of matches instead of matching lines" msgstr "" -#: builtin/grep.c:781 +#: builtin/grep.c:695 msgid "highlight matches" msgstr "" -#: builtin/grep.c:783 +#: builtin/grep.c:697 msgid "print empty line between matches from different files" msgstr "" -#: builtin/grep.c:785 +#: builtin/grep.c:699 msgid "show filename only once above matches from same file" msgstr "" -#: builtin/grep.c:788 +#: builtin/grep.c:702 msgid "show <n> context lines before and after matches" msgstr "" -#: builtin/grep.c:791 +#: builtin/grep.c:705 msgid "show <n> context lines before matches" msgstr "" -#: builtin/grep.c:793 +#: builtin/grep.c:707 msgid "show <n> context lines after matches" msgstr "" -#: builtin/grep.c:794 +#: builtin/grep.c:708 msgid "shortcut for -C NUM" msgstr "" -#: builtin/grep.c:797 +#: builtin/grep.c:711 msgid "show a line with the function name before matches" msgstr "" -#: builtin/grep.c:799 +#: builtin/grep.c:713 msgid "show the surrounding function" msgstr "" -#: builtin/grep.c:802 +#: builtin/grep.c:716 msgid "read patterns from file" msgstr "" -#: builtin/grep.c:804 +#: builtin/grep.c:718 msgid "match <pattern>" msgstr "" -#: builtin/grep.c:806 +#: builtin/grep.c:720 msgid "combine patterns specified with -e" msgstr "" -#: builtin/grep.c:818 +#: builtin/grep.c:732 msgid "indicate hit with exit status without output" msgstr "" -#: builtin/grep.c:820 +#: builtin/grep.c:734 msgid "show only matches from files that match all patterns" msgstr "" -#: builtin/grep.c:822 +#: builtin/grep.c:736 msgid "show parse tree for grep expression" msgstr "" -#: builtin/grep.c:826 +#: builtin/grep.c:740 msgid "pager" msgstr "" -#: builtin/grep.c:826 +#: builtin/grep.c:740 msgid "show matching files in the pager" msgstr "" -#: builtin/grep.c:829 +#: builtin/grep.c:743 msgid "allow calling of grep(1) (ignored by this build)" msgstr "" -#: builtin/grep.c:830 builtin/show-ref.c:201 +#: builtin/grep.c:744 builtin/show-ref.c:184 msgid "show usage" msgstr "" -#: builtin/grep.c:921 +#: builtin/grep.c:811 msgid "no pattern given." msgstr "" -#: builtin/grep.c:935 +#: builtin/grep.c:825 #, c-format msgid "bad object %s" msgstr "" -#: builtin/grep.c:976 +#: builtin/grep.c:866 msgid "--open-files-in-pager only works on the worktree" msgstr "" -#: builtin/grep.c:999 +#: builtin/grep.c:889 msgid "--cached or --untracked cannot be used with --no-index." msgstr "" -#: builtin/grep.c:1004 +#: builtin/grep.c:894 msgid "--no-index or --untracked cannot be used with revs." msgstr "" -#: builtin/grep.c:1007 +#: builtin/grep.c:897 msgid "--[no-]exclude-standard cannot be used for tracked contents." msgstr "" -#: builtin/grep.c:1015 +#: builtin/grep.c:905 msgid "both --cached and trees are given." msgstr "" @@ -5114,219 +5154,219 @@ msgstr "" msgid "Final output: %d %s\n" msgstr "" -#: builtin/log.c:403 builtin/log.c:494 +#: builtin/log.c:405 builtin/log.c:497 #, c-format msgid "Could not read object %s" msgstr "" -#: builtin/log.c:518 +#: builtin/log.c:521 #, c-format msgid "Unknown type: %d" msgstr "" -#: builtin/log.c:608 +#: builtin/log.c:613 msgid "format.headers without value" msgstr "" -#: builtin/log.c:682 +#: builtin/log.c:687 msgid "name of output directory is too long" msgstr "" -#: builtin/log.c:693 +#: builtin/log.c:698 #, c-format msgid "Cannot open patch file %s" msgstr "" -#: builtin/log.c:707 +#: builtin/log.c:712 msgid "Need exactly one range." msgstr "" -#: builtin/log.c:715 +#: builtin/log.c:720 msgid "Not a range." msgstr "" -#: builtin/log.c:789 +#: builtin/log.c:794 msgid "Cover letter needs email format" msgstr "" -#: builtin/log.c:862 +#: builtin/log.c:867 #, c-format msgid "insane in-reply-to: %s" msgstr "" -#: builtin/log.c:890 +#: builtin/log.c:895 msgid "git format-patch [options] [<since> | <revision range>]" msgstr "" -#: builtin/log.c:935 +#: builtin/log.c:940 msgid "Two output directories?" msgstr "" -#: builtin/log.c:1063 +#: builtin/log.c:1068 msgid "use [PATCH n/m] even with a single patch" msgstr "" -#: builtin/log.c:1066 +#: builtin/log.c:1071 msgid "use [PATCH] even with multiple patches" msgstr "" -#: builtin/log.c:1070 +#: builtin/log.c:1075 msgid "print patches to standard out" msgstr "" -#: builtin/log.c:1072 +#: builtin/log.c:1077 msgid "generate a cover letter" msgstr "" -#: builtin/log.c:1074 +#: builtin/log.c:1079 msgid "use simple number sequence for output file names" msgstr "" -#: builtin/log.c:1075 +#: builtin/log.c:1080 msgid "sfx" msgstr "" -#: builtin/log.c:1076 +#: builtin/log.c:1081 msgid "use <sfx> instead of '.patch'" msgstr "" -#: builtin/log.c:1078 +#: builtin/log.c:1083 msgid "start numbering patches at <n> instead of 1" msgstr "" -#: builtin/log.c:1080 +#: builtin/log.c:1085 msgid "Use [<prefix>] instead of [PATCH]" msgstr "" -#: builtin/log.c:1083 +#: builtin/log.c:1088 msgid "store resulting files in <dir>" msgstr "" -#: builtin/log.c:1086 +#: builtin/log.c:1091 msgid "don't strip/add [PATCH]" msgstr "" -#: builtin/log.c:1089 +#: builtin/log.c:1094 msgid "don't output binary diffs" msgstr "" -#: builtin/log.c:1091 +#: builtin/log.c:1096 msgid "don't include a patch matching a commit upstream" msgstr "" -#: builtin/log.c:1093 +#: builtin/log.c:1098 msgid "show patch format instead of default (patch + stat)" msgstr "" -#: builtin/log.c:1095 +#: builtin/log.c:1100 msgid "Messaging" msgstr "" -#: builtin/log.c:1096 +#: builtin/log.c:1101 msgid "header" msgstr "" -#: builtin/log.c:1097 +#: builtin/log.c:1102 msgid "add email header" msgstr "" -#: builtin/log.c:1098 builtin/log.c:1100 +#: builtin/log.c:1103 builtin/log.c:1105 msgid "email" msgstr "" -#: builtin/log.c:1098 +#: builtin/log.c:1103 msgid "add To: header" msgstr "" -#: builtin/log.c:1100 +#: builtin/log.c:1105 msgid "add Cc: header" msgstr "" -#: builtin/log.c:1102 +#: builtin/log.c:1107 msgid "message-id" msgstr "" -#: builtin/log.c:1103 +#: builtin/log.c:1108 msgid "make first mail a reply to <message-id>" msgstr "" -#: builtin/log.c:1104 builtin/log.c:1107 +#: builtin/log.c:1109 builtin/log.c:1112 msgid "boundary" msgstr "" -#: builtin/log.c:1105 +#: builtin/log.c:1110 msgid "attach the patch" msgstr "" -#: builtin/log.c:1108 +#: builtin/log.c:1113 msgid "inline the patch" msgstr "" -#: builtin/log.c:1112 +#: builtin/log.c:1117 msgid "enable message threading, styles: shallow, deep" msgstr "" -#: builtin/log.c:1114 +#: builtin/log.c:1119 msgid "signature" msgstr "" -#: builtin/log.c:1115 +#: builtin/log.c:1120 msgid "add a signature" msgstr "" -#: builtin/log.c:1117 +#: builtin/log.c:1122 msgid "don't print the patch filenames" msgstr "" -#: builtin/log.c:1157 +#: builtin/log.c:1163 #, c-format msgid "bogus committer info %s" msgstr "" -#: builtin/log.c:1202 +#: builtin/log.c:1208 msgid "-n and -k are mutually exclusive." msgstr "" -#: builtin/log.c:1204 +#: builtin/log.c:1210 msgid "--subject-prefix and -k are mutually exclusive." msgstr "" -#: builtin/log.c:1212 +#: builtin/log.c:1218 msgid "--name-only does not make sense" msgstr "" -#: builtin/log.c:1214 +#: builtin/log.c:1220 msgid "--name-status does not make sense" msgstr "" -#: builtin/log.c:1216 +#: builtin/log.c:1222 msgid "--check does not make sense" msgstr "" -#: builtin/log.c:1239 +#: builtin/log.c:1245 msgid "standard output, or directory, which one?" msgstr "" -#: builtin/log.c:1241 +#: builtin/log.c:1247 #, c-format msgid "Could not create directory '%s'" msgstr "" -#: builtin/log.c:1394 +#: builtin/log.c:1400 msgid "Failed to create output files" msgstr "" -#: builtin/log.c:1443 +#: builtin/log.c:1449 msgid "git cherry [-v] [<upstream> [<head> [<limit>]]]" msgstr "" -#: builtin/log.c:1498 +#: builtin/log.c:1504 #, c-format msgid "" "Could not find a tracked remote branch, please specify <upstream> manually.\n" msgstr "" -#: builtin/log.c:1511 builtin/log.c:1513 builtin/log.c:1525 +#: builtin/log.c:1517 builtin/log.c:1519 builtin/log.c:1531 #, c-format msgid "Unknown commit %s" msgstr "" @@ -5603,35 +5643,31 @@ msgstr "" msgid "git write-tree failed to write a tree" msgstr "" -#: builtin/merge.c:678 -msgid "failed to read the cache" -msgstr "" - -#: builtin/merge.c:709 +#: builtin/merge.c:656 msgid "Not handling anything other than two heads merge." msgstr "" -#: builtin/merge.c:723 +#: builtin/merge.c:670 #, c-format msgid "Unknown option for merge-recursive: -X%s" msgstr "" -#: builtin/merge.c:737 +#: builtin/merge.c:684 #, c-format msgid "unable to write %s" msgstr "" -#: builtin/merge.c:876 +#: builtin/merge.c:773 #, c-format msgid "Could not read from '%s'" msgstr "" -#: builtin/merge.c:885 +#: builtin/merge.c:782 #, c-format msgid "Not committing merge; use 'git commit' to complete the merge.\n" msgstr "" -#: builtin/merge.c:891 +#: builtin/merge.c:788 msgid "" "Please enter a commit message to explain why this merge is necessary,\n" "especially if it merges an updated upstream into a topic branch.\n" @@ -5640,140 +5676,140 @@ msgid "" "the commit.\n" msgstr "" -#: builtin/merge.c:915 +#: builtin/merge.c:812 msgid "Empty commit message." msgstr "" -#: builtin/merge.c:927 +#: builtin/merge.c:824 #, c-format msgid "Wonderful.\n" msgstr "" -#: builtin/merge.c:992 +#: builtin/merge.c:889 #, c-format msgid "Automatic merge failed; fix conflicts and then commit the result.\n" msgstr "" -#: builtin/merge.c:1008 +#: builtin/merge.c:905 #, c-format msgid "'%s' is not a commit" msgstr "" -#: builtin/merge.c:1049 +#: builtin/merge.c:946 msgid "No current branch." msgstr "" -#: builtin/merge.c:1051 +#: builtin/merge.c:948 msgid "No remote for the current branch." msgstr "" -#: builtin/merge.c:1053 +#: builtin/merge.c:950 msgid "No default upstream defined for the current branch." msgstr "" -#: builtin/merge.c:1058 +#: builtin/merge.c:955 #, c-format msgid "No remote tracking branch for %s from %s" msgstr "" -#: builtin/merge.c:1145 builtin/merge.c:1302 +#: builtin/merge.c:1042 builtin/merge.c:1199 #, c-format msgid "%s - not something we can merge" msgstr "" -#: builtin/merge.c:1213 +#: builtin/merge.c:1110 msgid "There is no merge to abort (MERGE_HEAD missing)." msgstr "" -#: builtin/merge.c:1229 git-pull.sh:31 +#: builtin/merge.c:1126 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:1232 git-pull.sh:34 +#: builtin/merge.c:1129 git-pull.sh:34 msgid "You have not concluded your merge (MERGE_HEAD exists)." msgstr "" -#: builtin/merge.c:1236 +#: builtin/merge.c:1133 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:1239 +#: builtin/merge.c:1136 msgid "You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists)." msgstr "" -#: builtin/merge.c:1248 +#: builtin/merge.c:1145 msgid "You cannot combine --squash with --no-ff." msgstr "" -#: builtin/merge.c:1253 +#: builtin/merge.c:1150 msgid "You cannot combine --no-ff with --ff-only." msgstr "" -#: builtin/merge.c:1260 +#: builtin/merge.c:1157 msgid "No commit specified and merge.defaultToUpstream not set." msgstr "" -#: builtin/merge.c:1292 +#: builtin/merge.c:1189 msgid "Can merge only exactly one commit into empty head" msgstr "" -#: builtin/merge.c:1295 +#: builtin/merge.c:1192 msgid "Squash commit into empty head not supported yet" msgstr "" -#: builtin/merge.c:1297 +#: builtin/merge.c:1194 msgid "Non-fast-forward commit does not make sense into an empty head" msgstr "" -#: builtin/merge.c:1412 +#: builtin/merge.c:1309 #, c-format msgid "Updating %s..%s\n" msgstr "" -#: builtin/merge.c:1450 +#: builtin/merge.c:1348 #, c-format msgid "Trying really trivial in-index merge...\n" msgstr "" -#: builtin/merge.c:1457 +#: builtin/merge.c:1355 #, c-format msgid "Nope.\n" msgstr "" -#: builtin/merge.c:1489 +#: builtin/merge.c:1387 msgid "Not possible to fast-forward, aborting." msgstr "" -#: builtin/merge.c:1512 builtin/merge.c:1591 +#: builtin/merge.c:1410 builtin/merge.c:1489 #, c-format msgid "Rewinding the tree to pristine...\n" msgstr "" -#: builtin/merge.c:1516 +#: builtin/merge.c:1414 #, c-format msgid "Trying merge strategy %s...\n" msgstr "" -#: builtin/merge.c:1582 +#: builtin/merge.c:1480 #, c-format msgid "No merge strategy handled the merge.\n" msgstr "" -#: builtin/merge.c:1584 +#: builtin/merge.c:1482 #, c-format msgid "Merge with strategy %s failed.\n" msgstr "" -#: builtin/merge.c:1593 +#: builtin/merge.c:1491 #, c-format msgid "Using the %s to prepare resolving by hand.\n" msgstr "" -#: builtin/merge.c:1605 +#: builtin/merge.c:1503 #, c-format msgid "Automatic merge went well; stopped before committing as requested\n" msgstr "" @@ -6323,143 +6359,143 @@ msgstr "" msgid "deflate error (%d)" msgstr "" -#: builtin/pack-objects.c:2398 +#: builtin/pack-objects.c:2397 #, c-format msgid "unsupported index version %s" msgstr "" -#: builtin/pack-objects.c:2402 +#: builtin/pack-objects.c:2401 #, c-format msgid "bad index version '%s'" msgstr "" -#: builtin/pack-objects.c:2425 +#: builtin/pack-objects.c:2424 #, c-format msgid "option %s does not accept negative form" msgstr "" -#: builtin/pack-objects.c:2429 +#: builtin/pack-objects.c:2428 #, c-format msgid "unable to parse value '%s' for option %s" msgstr "" -#: builtin/pack-objects.c:2448 +#: builtin/pack-objects.c:2447 msgid "do not show progress meter" msgstr "" -#: builtin/pack-objects.c:2450 +#: builtin/pack-objects.c:2449 msgid "show progress meter" msgstr "" -#: builtin/pack-objects.c:2452 +#: builtin/pack-objects.c:2451 msgid "show progress meter during object writing phase" msgstr "" -#: builtin/pack-objects.c:2455 +#: builtin/pack-objects.c:2454 msgid "similar to --all-progress when progress meter is shown" msgstr "" -#: builtin/pack-objects.c:2456 +#: builtin/pack-objects.c:2455 msgid "version[,offset]" msgstr "" -#: builtin/pack-objects.c:2457 +#: builtin/pack-objects.c:2456 msgid "write the pack index file in the specified idx format version" msgstr "" -#: builtin/pack-objects.c:2460 +#: builtin/pack-objects.c:2459 msgid "maximum size of each output pack file" msgstr "" -#: builtin/pack-objects.c:2462 +#: builtin/pack-objects.c:2461 msgid "ignore borrowed objects from alternate object store" msgstr "" -#: builtin/pack-objects.c:2464 +#: builtin/pack-objects.c:2463 msgid "ignore packed objects" msgstr "" -#: builtin/pack-objects.c:2466 +#: builtin/pack-objects.c:2465 msgid "limit pack window by objects" msgstr "" -#: builtin/pack-objects.c:2468 +#: builtin/pack-objects.c:2467 msgid "limit pack window by memory in addition to object limit" msgstr "" -#: builtin/pack-objects.c:2470 +#: builtin/pack-objects.c:2469 msgid "maximum length of delta chain allowed in the resulting pack" msgstr "" -#: builtin/pack-objects.c:2472 +#: builtin/pack-objects.c:2471 msgid "reuse existing deltas" msgstr "" -#: builtin/pack-objects.c:2474 +#: builtin/pack-objects.c:2473 msgid "reuse existing objects" msgstr "" -#: builtin/pack-objects.c:2476 +#: builtin/pack-objects.c:2475 msgid "use OFS_DELTA objects" msgstr "" -#: builtin/pack-objects.c:2478 +#: builtin/pack-objects.c:2477 msgid "use threads when searching for best delta matches" msgstr "" -#: builtin/pack-objects.c:2480 +#: builtin/pack-objects.c:2479 msgid "do not create an empty pack output" msgstr "" -#: builtin/pack-objects.c:2482 +#: builtin/pack-objects.c:2481 msgid "read revision arguments from standard input" msgstr "" -#: builtin/pack-objects.c:2484 +#: builtin/pack-objects.c:2483 msgid "limit the objects to those that are not yet packed" msgstr "" -#: builtin/pack-objects.c:2487 +#: builtin/pack-objects.c:2486 msgid "include objects reachable from any reference" msgstr "" -#: builtin/pack-objects.c:2490 +#: builtin/pack-objects.c:2489 msgid "include objects referred by reflog entries" msgstr "" -#: builtin/pack-objects.c:2493 +#: builtin/pack-objects.c:2492 msgid "output pack to stdout" msgstr "" -#: builtin/pack-objects.c:2495 +#: builtin/pack-objects.c:2494 msgid "include tag objects that refer to objects to be packed" msgstr "" -#: builtin/pack-objects.c:2497 +#: builtin/pack-objects.c:2496 msgid "keep unreachable objects" msgstr "" -#: builtin/pack-objects.c:2498 parse-options.h:141 +#: builtin/pack-objects.c:2497 parse-options.h:141 msgid "time" msgstr "" -#: builtin/pack-objects.c:2499 +#: builtin/pack-objects.c:2498 msgid "unpack unreachable objects newer than <time>" msgstr "" -#: builtin/pack-objects.c:2502 +#: builtin/pack-objects.c:2501 msgid "create thin packs" msgstr "" -#: builtin/pack-objects.c:2504 +#: builtin/pack-objects.c:2503 msgid "ignore packs that have companion .keep file" msgstr "" -#: builtin/pack-objects.c:2506 +#: builtin/pack-objects.c:2505 msgid "pack compression level" msgstr "" -#: builtin/pack-objects.c:2508 +#: builtin/pack-objects.c:2507 msgid "do not hide commits by grafts" msgstr "" @@ -6800,7 +6836,7 @@ msgstr "" msgid "git remote remove <name>" msgstr "" -#: builtin/remote.c:15 +#: builtin/remote.c:15 builtin/remote.c:42 msgid "git remote set-head <name> (-a | -d | <branch>)" msgstr "" @@ -6837,10 +6873,6 @@ msgstr "" msgid "git remote add [<options>] <name> <url>" msgstr "" -#: builtin/remote.c:42 -msgid "git remote set-head <name> (-a | -d | <branch>])" -msgstr "" - #: builtin/remote.c:47 msgid "git remote set-branches <name> <branch>..." msgstr "" @@ -7280,15 +7312,15 @@ msgstr "" msgid "git replace -l [<pattern>]" msgstr "" -#: builtin/replace.c:118 +#: builtin/replace.c:121 msgid "list replace refs" msgstr "" -#: builtin/replace.c:119 +#: builtin/replace.c:122 msgid "delete replace refs" msgstr "" -#: builtin/replace.c:120 +#: builtin/replace.c:123 msgid "replace the ref if it exists" msgstr "" @@ -7526,57 +7558,64 @@ msgstr "" msgid "cherry-pick failed" msgstr "" -#: builtin/rm.c:14 +#: builtin/rm.c:15 msgid "git rm [options] [--] <file>..." msgstr "" -#: builtin/rm.c:109 +#: builtin/rm.c:64 builtin/rm.c:186 +#, c-format +msgid "" +"submodule '%s' (or one of its nested submodules) uses a .git directory\n" +"(use 'rm -rf' if you really want to remove it including all of its history)" +msgstr "" + +#: builtin/rm.c:174 #, c-format msgid "" "'%s' has staged content different from both the file and the HEAD\n" "(use -f to force removal)" msgstr "" -#: builtin/rm.c:115 +#: builtin/rm.c:180 #, c-format msgid "" "'%s' has changes staged in the index\n" "(use --cached to keep the file, or -f to force removal)" msgstr "" -#: builtin/rm.c:119 +#: builtin/rm.c:191 #, c-format msgid "" "'%s' has local modifications\n" "(use --cached to keep the file, or -f to force removal)" msgstr "" -#: builtin/rm.c:134 +#: builtin/rm.c:207 msgid "do not list removed files" msgstr "" -#: builtin/rm.c:135 +#: builtin/rm.c:208 msgid "only remove from the index" msgstr "" -#: builtin/rm.c:136 +#: builtin/rm.c:209 msgid "override the up-to-date check" msgstr "" -#: builtin/rm.c:137 +#: builtin/rm.c:210 msgid "allow recursive removal" msgstr "" -#: builtin/rm.c:139 +#: builtin/rm.c:212 msgid "exit with a zero status even if nothing matched" msgstr "" -#: builtin/rm.c:194 +#: builtin/rm.c:283 #, c-format msgid "not removing '%s' recursively without -r" msgstr "" -#: builtin/rm.c:230 +#: builtin/rm.c:322 #, c-format msgid "git rm: unable to remove %s" msgstr "" @@ -7696,35 +7735,35 @@ msgstr "" msgid "git show-ref --exclude-existing[=pattern] < ref-list" msgstr "" -#: builtin/show-ref.c:182 +#: builtin/show-ref.c:165 msgid "only show tags (can be combined with heads)" msgstr "" -#: builtin/show-ref.c:183 +#: builtin/show-ref.c:166 msgid "only show heads (can be combined with tags)" msgstr "" -#: builtin/show-ref.c:184 +#: builtin/show-ref.c:167 msgid "stricter reference checking, requires exact ref path" msgstr "" -#: builtin/show-ref.c:187 builtin/show-ref.c:189 +#: builtin/show-ref.c:170 builtin/show-ref.c:172 msgid "show the HEAD reference" msgstr "" -#: builtin/show-ref.c:191 +#: builtin/show-ref.c:174 msgid "dereference tags into object IDs" msgstr "" -#: builtin/show-ref.c:193 +#: builtin/show-ref.c:176 msgid "only show SHA1 hash using <n> digits" msgstr "" -#: builtin/show-ref.c:197 +#: builtin/show-ref.c:180 msgid "do not print results to stdout (useful with --verify)" msgstr "" -#: builtin/show-ref.c:199 +#: builtin/show-ref.c:182 msgid "show refs from stdin that aren't in local repository" msgstr "" @@ -7732,19 +7771,27 @@ msgstr "" msgid "git symbolic-ref [options] name [ref]" msgstr "" -#: builtin/symbolic-ref.c:38 +#: builtin/symbolic-ref.c:8 +msgid "git symbolic-ref -d [-q] name" +msgstr "" + +#: builtin/symbolic-ref.c:40 msgid "suppress error message for non-symbolic (detached) refs" msgstr "" -#: builtin/symbolic-ref.c:39 +#: builtin/symbolic-ref.c:41 +msgid "delete symbolic ref" +msgstr "" + +#: builtin/symbolic-ref.c:42 msgid "shorten ref output" msgstr "" -#: builtin/symbolic-ref.c:40 builtin/update-ref.c:18 +#: builtin/symbolic-ref.c:43 builtin/update-ref.c:18 msgid "reason" msgstr "" -#: builtin/symbolic-ref.c:40 builtin/update-ref.c:18 +#: builtin/symbolic-ref.c:43 builtin/update-ref.c:18 msgid "reason of the update" msgstr "" @@ -7954,111 +8001,111 @@ msgstr "" msgid "git update-index [options] [--] [<file>...]" msgstr "" -#: builtin/update-index.c:717 +#: builtin/update-index.c:718 msgid "continue refresh even when index needs update" msgstr "" -#: builtin/update-index.c:720 +#: builtin/update-index.c:721 msgid "refresh: ignore submodules" msgstr "" -#: builtin/update-index.c:723 +#: builtin/update-index.c:724 msgid "do not ignore new files" msgstr "" -#: builtin/update-index.c:725 +#: builtin/update-index.c:726 msgid "let files replace directories and vice-versa" msgstr "" -#: builtin/update-index.c:727 +#: builtin/update-index.c:728 msgid "notice files missing from worktree" msgstr "" -#: builtin/update-index.c:729 +#: builtin/update-index.c:730 msgid "refresh even if index contains unmerged entries" msgstr "" -#: builtin/update-index.c:732 +#: builtin/update-index.c:733 msgid "refresh stat information" msgstr "" -#: builtin/update-index.c:736 +#: builtin/update-index.c:737 msgid "like --refresh, but ignore assume-unchanged setting" msgstr "" -#: builtin/update-index.c:740 +#: builtin/update-index.c:741 msgid "<mode> <object> <path>" msgstr "" -#: builtin/update-index.c:741 +#: builtin/update-index.c:742 msgid "add the specified entry to the index" msgstr "" -#: builtin/update-index.c:745 +#: builtin/update-index.c:746 msgid "(+/-)x" msgstr "" -#: builtin/update-index.c:746 +#: builtin/update-index.c:747 msgid "override the executable bit of the listed files" msgstr "" -#: builtin/update-index.c:750 +#: builtin/update-index.c:751 msgid "mark files as \"not changing\"" msgstr "" -#: builtin/update-index.c:753 +#: builtin/update-index.c:754 msgid "clear assumed-unchanged bit" msgstr "" -#: builtin/update-index.c:756 +#: builtin/update-index.c:757 msgid "mark files as \"index-only\"" msgstr "" -#: builtin/update-index.c:759 +#: builtin/update-index.c:760 msgid "clear skip-worktree bit" msgstr "" -#: builtin/update-index.c:762 +#: builtin/update-index.c:763 msgid "add to index only; do not add content to object database" msgstr "" -#: builtin/update-index.c:764 +#: builtin/update-index.c:765 msgid "remove named paths even if present in worktree" msgstr "" -#: builtin/update-index.c:766 +#: builtin/update-index.c:767 msgid "with --stdin: input lines are terminated by null bytes" msgstr "" -#: builtin/update-index.c:768 +#: builtin/update-index.c:769 msgid "read list of paths to be updated from standard input" msgstr "" -#: builtin/update-index.c:772 +#: builtin/update-index.c:773 msgid "add entries from standard input to the index" msgstr "" -#: builtin/update-index.c:776 +#: builtin/update-index.c:777 msgid "repopulate stages #2 and #3 for the listed paths" msgstr "" -#: builtin/update-index.c:780 +#: builtin/update-index.c:781 msgid "only update entries that differ from HEAD" msgstr "" -#: builtin/update-index.c:784 +#: builtin/update-index.c:785 msgid "ignore files missing from worktree" msgstr "" -#: builtin/update-index.c:787 +#: builtin/update-index.c:788 msgid "report actions to standard output" msgstr "" -#: builtin/update-index.c:789 +#: builtin/update-index.c:790 msgid "(for porcelains) forget saved unresolved conflicts" msgstr "" -#: builtin/update-index.c:793 +#: builtin/update-index.c:794 msgid "write index in this format" msgstr "" @@ -8535,7 +8582,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:228 +#: git-pull.sh:229 #, sh-format msgid "" "Warning: fetch updated the current branch head.\n" @@ -8543,11 +8590,11 @@ msgid "" "Warning: commit $orig_head." msgstr "" -#: git-pull.sh:253 +#: git-pull.sh:254 msgid "Cannot merge multiple branches into empty head" msgstr "" -#: git-pull.sh:257 +#: git-pull.sh:258 msgid "Cannot rebase onto multiple branches" msgstr "" @@ -8788,12 +8835,12 @@ msgstr "" msgid "(To restore them type \"git stash apply\")" msgstr "" -#: git-submodule.sh:88 +#: git-submodule.sh:89 #, sh-format msgid "cannot strip one component off url '$remoteurl'" msgstr "" -#: git-submodule.sh:167 +#: git-submodule.sh:168 #, sh-format msgid "No submodule mapping found in .gitmodules for path '$sm_path'" msgstr "" @@ -8808,17 +8855,17 @@ msgstr "" msgid "Gitdir '$a' is part of the submodule path '$b' or vice versa" msgstr "" -#: git-submodule.sh:312 +#: git-submodule.sh:316 #, sh-format msgid "repo URL: '$repo' must be absolute or begin with ./|../" msgstr "" -#: git-submodule.sh:329 +#: git-submodule.sh:333 #, sh-format msgid "'$sm_path' already exists in the index" msgstr "" -#: git-submodule.sh:333 +#: git-submodule.sh:337 #, sh-format msgid "" "The following path is ignored by one of your .gitignore files:\n" @@ -8826,151 +8873,180 @@ msgid "" "Use -f if you really want to add it." msgstr "" -#: git-submodule.sh:344 +#: git-submodule.sh:355 #, sh-format msgid "Adding existing repo at '$sm_path' to the index" msgstr "" -#: git-submodule.sh:346 +#: git-submodule.sh:357 #, sh-format msgid "'$sm_path' already exists and is not a valid git repo" msgstr "" -#: git-submodule.sh:360 +#: git-submodule.sh:365 +#, sh-format +msgid "A git directory for '$sm_name' is found locally with remote(s):" +msgstr "" + +#: git-submodule.sh:367 +#, sh-format +msgid "" +"If you want to reuse this local git directory instead of cloning again from" +msgstr "" + +#: git-submodule.sh:369 +#, sh-format +msgid "" +"use the '--force' option. If the local git directory is not the correct repo" +msgstr "" + +#: git-submodule.sh:370 +#, sh-format +msgid "" +"or you are unsure what this means choose another name with the '--name' " +"option." +msgstr "" + +#: git-submodule.sh:372 +#, sh-format +msgid "Reactivating local git directory for submodule '$sm_name'." +msgstr "" + +#: git-submodule.sh:384 #, sh-format msgid "Unable to checkout submodule '$sm_path'" msgstr "" -#: git-submodule.sh:365 +#: git-submodule.sh:389 #, sh-format msgid "Failed to add submodule '$sm_path'" msgstr "" -#: git-submodule.sh:370 +#: git-submodule.sh:394 #, sh-format msgid "Failed to register submodule '$sm_path'" msgstr "" -#: git-submodule.sh:413 +#: git-submodule.sh:437 #, sh-format msgid "Entering '$prefix$sm_path'" msgstr "" -#: git-submodule.sh:427 +#: git-submodule.sh:451 #, sh-format msgid "Stopping at '$sm_path'; script returned non-zero status." msgstr "" -#: git-submodule.sh:471 +#: git-submodule.sh:495 #, sh-format msgid "No url found for submodule path '$sm_path' in .gitmodules" msgstr "" -#: git-submodule.sh:480 +#: git-submodule.sh:504 #, sh-format msgid "Failed to register url for submodule path '$sm_path'" msgstr "" -#: git-submodule.sh:482 +#: git-submodule.sh:506 #, sh-format msgid "Submodule '$name' ($url) registered for path '$sm_path'" msgstr "" -#: git-submodule.sh:490 +#: git-submodule.sh:514 #, sh-format msgid "Failed to register update mode for submodule path '$sm_path'" msgstr "" -#: git-submodule.sh:590 +#: git-submodule.sh:614 #, sh-format msgid "" "Submodule path '$sm_path' not initialized\n" "Maybe you want to use 'update --init'?" msgstr "" -#: git-submodule.sh:603 +#: git-submodule.sh:627 #, sh-format msgid "Unable to find current revision in submodule path '$sm_path'" msgstr "" -#: git-submodule.sh:622 +#: git-submodule.sh:646 #, sh-format msgid "Unable to fetch in submodule path '$sm_path'" msgstr "" -#: git-submodule.sh:636 +#: git-submodule.sh:660 #, sh-format msgid "Unable to rebase '$sha1' in submodule path '$sm_path'" msgstr "" -#: git-submodule.sh:637 +#: git-submodule.sh:661 #, sh-format msgid "Submodule path '$sm_path': rebased into '$sha1'" msgstr "" -#: git-submodule.sh:642 +#: git-submodule.sh:666 #, sh-format msgid "Unable to merge '$sha1' in submodule path '$sm_path'" msgstr "" -#: git-submodule.sh:643 +#: git-submodule.sh:667 #, sh-format msgid "Submodule path '$sm_path': merged in '$sha1'" msgstr "" -#: git-submodule.sh:648 +#: git-submodule.sh:672 #, sh-format msgid "Unable to checkout '$sha1' in submodule path '$sm_path'" msgstr "" -#: git-submodule.sh:649 +#: git-submodule.sh:673 #, sh-format msgid "Submodule path '$sm_path': checked out '$sha1'" msgstr "" -#: git-submodule.sh:671 git-submodule.sh:995 +#: git-submodule.sh:695 git-submodule.sh:1017 #, sh-format msgid "Failed to recurse into submodule path '$sm_path'" msgstr "" -#: git-submodule.sh:779 +#: git-submodule.sh:803 msgid "The --cached option cannot be used with the --files option" msgstr "" #. unexpected type -#: git-submodule.sh:819 +#: git-submodule.sh:843 #, sh-format msgid "unexpected mode $mod_dst" msgstr "" -#: git-submodule.sh:837 +#: git-submodule.sh:861 #, sh-format msgid " Warn: $name doesn't contain commit $sha1_src" msgstr "" -#: git-submodule.sh:840 +#: git-submodule.sh:864 #, sh-format msgid " Warn: $name doesn't contain commit $sha1_dst" msgstr "" -#: git-submodule.sh:843 +#: git-submodule.sh:867 #, sh-format msgid " Warn: $name doesn't contain commits $sha1_src and $sha1_dst" msgstr "" -#: git-submodule.sh:868 +#: git-submodule.sh:892 msgid "blob" msgstr "" -#: git-submodule.sh:906 +#: git-submodule.sh:930 msgid "# Submodules changed but not updated:" msgstr "" -#: git-submodule.sh:908 +#: git-submodule.sh:932 msgid "# Submodule changes to be committed:" msgstr "" -#: git-submodule.sh:1054 +#: git-submodule.sh:1080 #, sh-format -msgid "Synchronizing submodule url for '$name'" +msgid "Synchronizing submodule url for '$prefix$sm_path'" msgstr "" @@ -5,10 +5,10 @@ # msgid "" msgstr "" -"Project-Id-Version: git 1.7.12\n" +"Project-Id-Version: git 1.8.1\n" "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n" -"POT-Creation-Date: 2012-10-16 08:38+0800\n" -"PO-Revision-Date: 2012-10-16 08:36+0100\n" +"POT-Creation-Date: 2012-11-30 12:40+0800\n" +"PO-Revision-Date: 2012-11-30 10:49+0100\n" "Last-Translator: Peter Krefting <peter@softwolves.pp.se>\n" "Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n" "Language: sv\n" @@ -65,7 +65,7 @@ msgstr "fmt" msgid "archive format" msgstr "arkivformat" -#: archive.c:323 builtin/log.c:1079 +#: archive.c:323 builtin/log.c:1084 msgid "prefix" msgstr "prefix" @@ -73,9 +73,9 @@ 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:325 builtin/archive.c:91 builtin/blame.c:2389 -#: builtin/blame.c:2390 builtin/config.c:56 builtin/fast-export.c:642 -#: builtin/fast-export.c:644 builtin/grep.c:801 builtin/hash-object.c:77 +#: archive.c:325 builtin/archive.c:91 builtin/blame.c:2390 +#: builtin/blame.c:2391 builtin/config.c:55 builtin/fast-export.c:642 +#: builtin/fast-export.c:644 builtin/grep.c:715 builtin/hash-object.c:77 #: builtin/ls-files.c:494 builtin/ls-files.c:497 builtin/notes.c:540 #: builtin/notes.c:697 builtin/read-tree.c:107 parse-options.h:149 msgid "file" @@ -125,6 +125,14 @@ msgstr "kommando" msgid "path to the remote git-upload-archive command" msgstr "sökväg till kommandot git-upload-archive pÃ¥ fjärren" +#: attr.c:259 +msgid "" +"Negative patterns are forbidden in git attributes\n" +"Use '\\!' for literal leading exclamation." +msgstr "" +"Negativa mönster är förbjudna i git-attribut\n" +"Använd '\\!' för att inleda med ett utropstecken." + #: bundle.c:36 #, c-format msgid "'%s' does not look like a v2 bundle file" @@ -135,7 +143,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:672 +#: bundle.c:89 builtin/commit.c:674 #, c-format msgid "could not open '%s'" msgstr "kunde inte öppna \"%s\"" @@ -145,7 +153,7 @@ msgid "Repository lacks these prerequisite commits:" msgstr "Arkivet saknar dessa nödvändiga incheckningar:" #: bundle.c:164 sequencer.c:562 sequencer.c:994 builtin/log.c:290 -#: builtin/log.c:727 builtin/log.c:1313 builtin/log.c:1529 builtin/merge.c:347 +#: builtin/log.c:732 builtin/log.c:1319 builtin/log.c:1535 builtin/merge.c:347 #: builtin/shortlog.c:181 msgid "revision walk setup failed" msgstr "misslyckades skapa revisionstraversering" @@ -172,7 +180,7 @@ msgstr[1] "Paketet (bundlen) kräver dessa %d referenser" msgid "rev-list died" msgstr "rev-list dog" -#: bundle.c:300 builtin/log.c:1209 builtin/shortlog.c:284 +#: bundle.c:300 builtin/log.c:1215 builtin/shortlog.c:284 #, c-format msgid "unrecognized argument: %s" msgstr "okänt argument: %s" @@ -298,17 +306,22 @@ msgid_plural "%lu years ago" msgstr[0] "%lu Ã¥r sedan" msgstr[1] "%lu Ã¥r sedan" -#: diff.c:105 +#: diff.c:111 +#, c-format +msgid " Failed to parse dirstat cut-off percentage '%s'\n" +msgstr " Misslyckades tolka dirstat-avskärningsprocentandel \"%s\"\n" + +#: diff.c:116 #, c-format -msgid " Failed to parse dirstat cut-off percentage '%.*s'\n" -msgstr " Misslyckades tolka dirstat-avskärningsprocentandel \"%.*s\"\n" +msgid " Unknown dirstat parameter '%s'\n" +msgstr " Okänd dirstat-parameter \"%s\"\n" -#: diff.c:110 +#: diff.c:194 #, c-format -msgid " Unknown dirstat parameter '%.*s'\n" -msgstr " Okänd dirstat-parameter \"%.*s\"\n" +msgid "Unknown value for 'diff.submodule' config variable: '%s'" +msgstr "Okänt värde för konfigurationsvariabeln \"diff.submodule\": \"%s\"" -#: diff.c:210 +#: diff.c:237 #, c-format msgid "" "Found errors in 'diff.dirstat' config variable:\n" @@ -317,7 +330,7 @@ msgstr "" "Hittade fel i konfigurationsvariabeln \"diff.dirstat\":\n" "%s" -#: diff.c:3458 +#: diff.c:3494 #, c-format msgid "" "Failed to parse --dirstat/-X option parameter:\n" @@ -326,6 +339,11 @@ msgstr "" "Misslyckades tolka argument till flaggan --dirstat/-X;\n" "%s" +#: diff.c:3508 +#, c-format +msgid "Failed to parse --submodule option parameter: '%s'" +msgstr "Misslyckades tolka argument till flaggan --submodule: \"%s\"" + #: gpg-interface.c:59 msgid "could not run gpg." msgstr "kunde inte köra gpg." @@ -338,17 +356,17 @@ msgstr "gpg godtog inte data" msgid "gpg failed to sign the data" msgstr "gpg misslyckades signera data" -#: grep.c:1441 +#: grep.c:1622 #, c-format msgid "'%s': unable to read %s" msgstr "\"%s\" kunde inte läsa %s" -#: grep.c:1458 +#: grep.c:1639 #, c-format msgid "'%s': %s" msgstr "\"%s\": %s" -#: grep.c:1469 +#: grep.c:1650 #, c-format msgid "'%s': short read %s" msgstr "\"%s\": kort läsning %s" @@ -408,6 +426,15 @@ msgstr[1] "" "\n" "Menade du ett av dessa?" +#: merge.c:56 +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 +msgid "unable to write new index file" +msgstr "kunde inte skriva ny indexfil" + #: merge-recursive.c:190 #, c-format msgid "(bad commit)\n" @@ -587,7 +614,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:869 +#: merge-recursive.c:1633 git-submodule.sh:893 msgid "submodule" msgstr "undermodul" @@ -658,7 +685,7 @@ msgstr "sammanslagningen returnerade ingen incheckning" msgid "Could not parse object '%s'" msgstr "Kunde inte tolka objektet \"%s\"" -#: merge-recursive.c:2009 builtin/merge.c:696 +#: merge-recursive.c:2009 builtin/merge.c:643 msgid "Unable to write index." msgstr "Kunde inte skriva indexet." @@ -690,7 +717,11 @@ 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:1638 +#: remote.c:1637 +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:1640 #, c-format msgid "Your branch is behind '%s' by %d commit, and can be fast-forwarded.\n" msgid_plural "" @@ -700,7 +731,11 @@ msgstr[0] "" msgstr[1] "" "Din gren ligger efter \"%s\" med %d incheckningar, och kan snabbspolas.\n" -#: remote.c:1646 +#: remote.c:1647 +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:1650 #, c-format msgid "" "Your branch and '%s' have diverged,\n" @@ -715,14 +750,18 @@ msgstr[1] "" "Din gren och \"%s\" har divergerat,\n" "och har %d respektive %d olika incheckningar.\n" -#: sequencer.c:123 builtin/merge.c:864 builtin/merge.c:977 -#: builtin/merge.c:1087 builtin/merge.c:1097 +#: remote.c:1659 +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 #, 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:867 -#: builtin/merge.c:1089 builtin/merge.c:1102 +#: sequencer.c:125 builtin/merge.c:333 builtin/merge.c:764 builtin/merge.c:986 +#: builtin/merge.c:999 #, c-format msgid "Could not write to '%s'" msgstr "Kunde inte skriva till \"%s\"" @@ -1348,7 +1387,7 @@ msgstr "git add [flaggor] [--] <filmönster>..." msgid "unexpected diff status %c" msgstr "diff-status %c förväntades inte" -#: builtin/add.c:67 builtin/commit.c:230 +#: builtin/add.c:67 builtin/commit.c:231 msgid "updating files failed" msgstr "misslyckades uppdatera filer" @@ -1366,7 +1405,7 @@ msgstr "Sökvägen \"%s\" är i undermodulen \"%.*s\"" msgid "Unstaged changes after refreshing the index:" msgstr "OspÃ¥rade ändringar efter att ha uppdaterat indexet:" -#: builtin/add.c:195 builtin/add.c:460 builtin/rm.c:186 +#: builtin/add.c:195 builtin/add.c:460 builtin/rm.c:275 #, c-format msgid "pathspec '%s' did not match any files" msgstr "sökvägsangivelsen \"%s\" motsvarade inte nÃ¥gra filer" @@ -1409,12 +1448,12 @@ msgstr "Följande sökvägar ignoreras av en av dina .gitignore-filer:\n" #: builtin/add.c:319 builtin/clean.c:52 builtin/fetch.c:78 builtin/mv.c:63 #: builtin/prune-packed.c:76 builtin/push.c:388 builtin/remote.c:1253 -#: builtin/rm.c:133 +#: builtin/rm.c:206 msgid "dry run" msgstr "testkörning" -#: builtin/add.c:320 builtin/apply.c:4354 builtin/commit.c:1154 -#: builtin/count-objects.c:82 builtin/fsck.c:613 builtin/log.c:1477 +#: builtin/add.c:320 builtin/apply.c:4354 builtin/commit.c:1160 +#: builtin/count-objects.c:82 builtin/fsck.c:613 builtin/log.c:1483 #: builtin/mv.c:62 builtin/read-tree.c:112 msgid "be verbose" msgstr "var pratsam" @@ -1423,7 +1462,7 @@ msgstr "var pratsam" msgid "interactive picking" msgstr "plocka interaktivt" -#: builtin/add.c:323 builtin/checkout.c:1028 builtin/reset.c:248 +#: builtin/add.c:323 builtin/checkout.c:1031 builtin/reset.c:248 msgid "select hunks interactively" msgstr "välj stycken interaktivt" @@ -1490,12 +1529,12 @@ msgstr "Inget angivet, inget tillagt.\n" msgid "Maybe you wanted to say 'git add .'?\n" msgstr "Kanske menade du att skriva \"git add .\"?\n" -#: builtin/add.c:421 builtin/clean.c:95 builtin/commit.c:290 builtin/mv.c:82 -#: builtin/rm.c:162 +#: builtin/add.c:421 builtin/clean.c:95 builtin/commit.c:291 builtin/mv.c:82 +#: builtin/rm.c:235 msgid "index file corrupt" msgstr "indexfilen trasig" -#: builtin/add.c:481 builtin/apply.c:4450 builtin/mv.c:229 builtin/rm.c:260 +#: builtin/add.c:481 builtin/apply.c:4450 builtin/mv.c:229 builtin/rm.c:370 msgid "Unable to write new index file" msgstr "Kunde inte skriva ny indexfil" @@ -2031,95 +2070,95 @@ msgstr "git blame [flaggor] [rev-flaggor] [rev] [--] fil" msgid "[rev-opts] are documented in git-rev-list(1)" msgstr "[rev-flaggor] dokumenteras i git-rev-list(1)" -#: builtin/blame.c:2373 +#: builtin/blame.c:2374 msgid "Show blame entries as we find them, incrementally" msgstr "Visa klandringsposter när vi hittar dem, interaktivt" -#: builtin/blame.c:2374 +#: builtin/blame.c:2375 msgid "Show blank SHA-1 for boundary commits (Default: off)" msgstr "Visa blank SHA-1 för gränsincheckningar (Standard: av)" -#: builtin/blame.c:2375 +#: builtin/blame.c:2376 msgid "Do not treat root commits as boundaries (Default: off)" msgstr "Behandla inte rotincheckningar som gränser (Standard: av)" -#: builtin/blame.c:2376 +#: builtin/blame.c:2377 msgid "Show work cost statistics" msgstr "Visa statistik över arbetskostnad" -#: builtin/blame.c:2377 +#: builtin/blame.c:2378 msgid "Show output score for blame entries" msgstr "Visa utdatapoäng för klandringsposter" -#: builtin/blame.c:2378 +#: builtin/blame.c:2379 msgid "Show original filename (Default: auto)" msgstr "Visa originalfilnamn (Standard: auto)" -#: builtin/blame.c:2379 +#: builtin/blame.c:2380 msgid "Show original linenumber (Default: off)" msgstr "Visa ursprungligt radnummer (Standard: av)" -#: builtin/blame.c:2380 +#: builtin/blame.c:2381 msgid "Show in a format designed for machine consumption" msgstr "Visa i ett format avsett för maskinkonsumtion" -#: builtin/blame.c:2381 +#: builtin/blame.c:2382 msgid "Show porcelain format with per-line commit information" msgstr "Visa porslinsformat med per-rad-incheckningsinformation" -#: builtin/blame.c:2382 +#: builtin/blame.c:2383 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:2383 +#: builtin/blame.c:2384 msgid "Show raw timestamp (Default: off)" msgstr "Visa rÃ¥ tidsstämpel (Standard: av)" -#: builtin/blame.c:2384 +#: builtin/blame.c:2385 msgid "Show long commit SHA1 (Default: off)" msgstr "Visa lÃ¥ng inchecknings-SHA1 (Standard: av)" -#: builtin/blame.c:2385 +#: builtin/blame.c:2386 msgid "Suppress author name and timestamp (Default: off)" msgstr "Undertryck författarnamn och tidsstämpel (Standard: av)" -#: builtin/blame.c:2386 +#: builtin/blame.c:2387 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:2387 +#: builtin/blame.c:2388 msgid "Ignore whitespace differences" msgstr "Ignorera ändringar i blanksteg" -#: builtin/blame.c:2388 +#: builtin/blame.c:2389 msgid "Spend extra cycles to find better match" msgstr "Slösa extra cykler med att hitta bättre träff" -#: builtin/blame.c:2389 +#: builtin/blame.c:2390 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:2390 +#: builtin/blame.c:2391 msgid "Use <file>'s contents as the final image" msgstr "Använd <fil>s innehÃ¥ll som slutgiltig bild" -#: builtin/blame.c:2391 builtin/blame.c:2392 +#: builtin/blame.c:2392 builtin/blame.c:2393 msgid "score" msgstr "poäng" -#: builtin/blame.c:2391 +#: builtin/blame.c:2392 msgid "Find line copies within and across files" msgstr "Hitta kopierade rader inuti och mellan filer" -#: builtin/blame.c:2392 +#: builtin/blame.c:2393 msgid "Find line movements within and across files" msgstr "Hitta flyttade rader inuti och mellan filer" -#: builtin/blame.c:2393 +#: builtin/blame.c:2394 msgid "n,m" msgstr "n,m" -#: builtin/blame.c:2393 +#: builtin/blame.c:2394 msgid "Process only line range n,m, counting from 1" msgstr "Behandla endast radintervallet n,m, med början pÃ¥ 1" @@ -2157,267 +2196,267 @@ 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:181 +#: builtin/branch.c:163 +#, c-format +msgid "Couldn't look up commit object for '%s'" +msgstr "Kunde inte slÃ¥ upp incheckningsobjekt för \"%s\"" + +#: builtin/branch.c:167 +#, 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 "" +"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 +msgid "Update of config-file failed" +msgstr "Misslyckades uppdatera konfigurationsfil" + +#: builtin/branch.c:208 msgid "cannot use -a with -d" msgstr "kan inte ange -a med -d" -#: builtin/branch.c:187 +#: builtin/branch.c:214 msgid "Couldn't look up commit object for HEAD" msgstr "Kunde inte slÃ¥ upp incheckningsobjekt för HEAD" -#: builtin/branch.c:192 +#: builtin/branch.c:222 #, 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:203 +#: builtin/branch.c:235 #, c-format msgid "remote branch '%s' not found." msgstr "fjärrgrenen \"%s\" hittades inte." -#: builtin/branch.c:204 +#: builtin/branch.c:236 #, c-format msgid "branch '%s' not found." msgstr "grenen \"%s\" hittades inte." -#: builtin/branch.c:211 -#, c-format -msgid "Couldn't look up commit object for '%s'" -msgstr "Kunde inte slÃ¥ upp incheckningsobjekt för \"%s\"" - -#: builtin/branch.c:217 -#, 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 "" -"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:226 +#: builtin/branch.c:250 #, c-format msgid "Error deleting remote branch '%s'" msgstr "Fel vid borttagning av fjärrgrenen \"%s\"" -#: builtin/branch.c:227 +#: builtin/branch.c:251 #, c-format msgid "Error deleting branch '%s'" msgstr "Fel vid borttagning av grenen \"%s\"" -#: builtin/branch.c:234 +#: builtin/branch.c:258 #, c-format msgid "Deleted remote branch %s (was %s).\n" msgstr "Tog bort fjärrgrenen %s (var %s).\n" -#: builtin/branch.c:235 +#: builtin/branch.c:259 #, c-format msgid "Deleted branch %s (was %s).\n" msgstr "Tog bort grenen %s (var %s).\n" -#: builtin/branch.c:240 -msgid "Update of config-file failed" -msgstr "Misslyckades uppdatera konfigurationsfil" - -#: builtin/branch.c:338 +#: builtin/branch.c:361 #, c-format msgid "branch '%s' does not point at a commit" msgstr "grenen \"%s\" pekar inte pÃ¥ en incheckning" -#: builtin/branch.c:410 +#: builtin/branch.c:433 #, c-format msgid "[%s: behind %d]" msgstr "[%s: bakom %d] " -#: builtin/branch.c:412 +#: builtin/branch.c:435 #, c-format msgid "[behind %d]" msgstr "[bakom %d] " -#: builtin/branch.c:416 +#: builtin/branch.c:439 #, c-format msgid "[%s: ahead %d]" msgstr "[%s: före %d] " -#: builtin/branch.c:418 +#: builtin/branch.c:441 #, c-format msgid "[ahead %d]" msgstr "[före %d] " -#: builtin/branch.c:421 +#: builtin/branch.c:444 #, c-format msgid "[%s: ahead %d, behind %d]" msgstr "[%s: före %d, bakom %d] " -#: builtin/branch.c:424 +#: builtin/branch.c:447 #, c-format msgid "[ahead %d, behind %d]" msgstr "[före %d, bakom %d] " -#: builtin/branch.c:537 +#: builtin/branch.c:560 msgid "(no branch)" msgstr "(ingen gren)" -#: builtin/branch.c:602 +#: builtin/branch.c:625 msgid "some refs could not be read" msgstr "vissa referenser kunde inte läsas" -#: builtin/branch.c:615 +#: builtin/branch.c:638 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:625 +#: builtin/branch.c:648 #, c-format msgid "Invalid branch name: '%s'" msgstr "Felaktigt namn pÃ¥ gren: \"%s\"" -#: builtin/branch.c:640 +#: builtin/branch.c:663 msgid "Branch rename failed" msgstr "Misslyckades byta namn pÃ¥ gren" -#: builtin/branch.c:644 +#: builtin/branch.c:667 #, c-format msgid "Renamed a misnamed branch '%s' away" msgstr "Bytte bort namn pÃ¥ en felaktigt namngiven gren \"%s\"" -#: builtin/branch.c:648 +#: builtin/branch.c:671 #, 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:655 +#: builtin/branch.c:678 msgid "Branch is renamed, but update of config-file failed" msgstr "Grenen namnbytt, men misslyckades uppdatera konfigurationsfilen" -#: builtin/branch.c:670 +#: builtin/branch.c:693 #, c-format msgid "malformed object name %s" msgstr "felformat objektnamn %s" -#: builtin/branch.c:694 +#: builtin/branch.c:717 #, c-format msgid "could not write branch description template: %s" msgstr "kunde inte skriva grenbeskrivningsmall: %s" -#: builtin/branch.c:724 +#: builtin/branch.c:747 msgid "Generic options" msgstr "Allmänna flaggor" -#: builtin/branch.c:726 +#: builtin/branch.c:749 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:727 +#: builtin/branch.c:750 msgid "suppress informational messages" msgstr "undertryck informationsmeddelanden" -#: builtin/branch.c:728 +#: builtin/branch.c:751 msgid "set up tracking mode (see git-pull(1))" msgstr "ställ in spÃ¥rningsläge (se git-pull(1))" -#: builtin/branch.c:730 +#: builtin/branch.c:753 msgid "change upstream info" msgstr "ändra uppströmsinformation" -#: builtin/branch.c:734 +#: builtin/branch.c:757 msgid "use colored output" msgstr "använd färgad utdata" -#: builtin/branch.c:735 +#: builtin/branch.c:758 msgid "act on remote-tracking branches" msgstr "arbeta pÃ¥ fjärrspÃ¥rande grenar" -#: builtin/branch.c:738 builtin/branch.c:744 builtin/branch.c:765 -#: builtin/branch.c:771 builtin/commit.c:1362 builtin/commit.c:1363 -#: builtin/commit.c:1364 builtin/commit.c:1365 builtin/tag.c:470 +#: builtin/branch.c:761 builtin/branch.c:767 builtin/branch.c:788 +#: builtin/branch.c:794 builtin/commit.c:1376 builtin/commit.c:1377 +#: builtin/commit.c:1378 builtin/commit.c:1379 builtin/tag.c:470 msgid "commit" msgstr "incheckning" -#: builtin/branch.c:739 builtin/branch.c:745 +#: builtin/branch.c:762 builtin/branch.c:768 msgid "print only branches that contain the commit" msgstr "visa endast grenar som innehÃ¥ller incheckningen" -#: builtin/branch.c:751 +#: builtin/branch.c:774 msgid "Specific git-branch actions:" msgstr "Specifika git-branch-Ã¥tgärder:" -#: builtin/branch.c:752 +#: builtin/branch.c:775 msgid "list both remote-tracking and local branches" msgstr "visa bÃ¥de fjärrspÃ¥rande och lokala grenar" -#: builtin/branch.c:754 +#: builtin/branch.c:777 msgid "delete fully merged branch" msgstr "ta bort helt sammanslagen gren" -#: builtin/branch.c:755 +#: builtin/branch.c:778 msgid "delete branch (even if not merged)" msgstr "ta bort gren (även om inte helt sammanslagen)" -#: builtin/branch.c:756 +#: builtin/branch.c:779 msgid "move/rename a branch and its reflog" msgstr "flytta/ta bort en gren och dess reflogg" -#: builtin/branch.c:757 +#: builtin/branch.c:780 msgid "move/rename a branch, even if target exists" msgstr "flytta/ta bort en gren, även om mÃ¥let finns" -#: builtin/branch.c:758 +#: builtin/branch.c:781 msgid "list branch names" msgstr "lista namn pÃ¥ grenar" -#: builtin/branch.c:759 +#: builtin/branch.c:782 msgid "create the branch's reflog" msgstr "skapa grenens reflogg" -#: builtin/branch.c:761 +#: builtin/branch.c:784 msgid "edit the description for the branch" msgstr "redigera beskrivning för grenen" -#: builtin/branch.c:762 +#: builtin/branch.c:785 msgid "force creation (when already exists)" msgstr "tvinga skapande (när den redan finns)" -#: builtin/branch.c:765 +#: builtin/branch.c:788 msgid "print only not merged branches" msgstr "visa endast ej sammanslagna grenar" -#: builtin/branch.c:771 +#: builtin/branch.c:794 msgid "print only merged branches" msgstr "visa endast sammanslagna grenar" -#: builtin/branch.c:775 +#: builtin/branch.c:798 msgid "list branches in columns" msgstr "visa grenar i spalter" -#: builtin/branch.c:788 +#: builtin/branch.c:811 msgid "Failed to resolve HEAD as a valid ref." msgstr "Misslyckades slÃ¥ upp HEAD som giltig referens" -#: builtin/branch.c:793 builtin/clone.c:561 +#: builtin/branch.c:816 builtin/clone.c:561 msgid "HEAD not found below refs/heads!" msgstr "HEAD hittades inte under refs/heads!" -#: builtin/branch.c:813 +#: builtin/branch.c:836 msgid "--column and --verbose are incompatible" msgstr "--column och --verbose är inkompatibla" -#: builtin/branch.c:864 +#: builtin/branch.c:887 #, c-format msgid "branch '%s' does not exist" msgstr "grenen \"%s\" finns inte" -#: builtin/branch.c:876 +#: builtin/branch.c:899 #, c-format msgid "Branch '%s' has no upstream information" msgstr "Grenen \"%s\" har ingen uppströmsinformation" -#: builtin/branch.c:891 +#: builtin/branch.c:914 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:894 +#: builtin/branch.c:917 #, c-format msgid "" "The --set-upstream flag is deprecated and will be removed. Consider using --" @@ -2426,7 +2465,7 @@ msgstr "" "Flaggan --set-upstream rekommenderas ej och kommer tas bort. Använd --track " "eller --set-upstream-to\n" -#: builtin/branch.c:911 +#: builtin/branch.c:934 #, c-format msgid "" "\n" @@ -2437,12 +2476,12 @@ msgstr "" "Om du vill göra sÃ¥ att \"%s\" spÃ¥rar \"%s\" gör du sÃ¥ här:\n" "\n" -#: builtin/branch.c:912 +#: builtin/branch.c:935 #, c-format msgid " git branch -d %s\n" msgstr " git branch -d %s\n" -#: builtin/branch.c:913 +#: builtin/branch.c:936 #, c-format msgid " git branch --set-upstream-to %s\n" msgstr " git branch --set-upstream-to %s\n" @@ -2631,11 +2670,6 @@ msgstr "indexfilen är trasig" msgid "path '%s' is unmerged" msgstr "sökvägen \"%s\" har inte slagits ihop" -#: builtin/checkout.c:333 builtin/checkout.c:534 builtin/clone.c:586 -#: builtin/merge.c:811 -msgid "unable to write new index file" -msgstr "kunde inte skriva ny indexfil" - #: builtin/checkout.c:448 msgid "you need to resolve your current index first" msgstr "du mÃ¥ste lösa ditt befintliga index först" @@ -2664,7 +2698,7 @@ msgstr "Redan pÃ¥ \"%s\"\n" 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:618 builtin/checkout.c:955 #, c-format msgid "Switched to a new branch '%s'\n" msgstr "Växlade till en ny gren \"%s\"\n" @@ -2742,112 +2776,112 @@ msgstr "felaktig referens: %s" msgid "reference is not a tree: %s" msgstr "referensen är inte ett träd: %s" -#: builtin/checkout.c:961 +#: builtin/checkout.c:964 msgid "paths cannot be used with switching branches" msgstr "sökvägar kan inte användas vid byte av gren" -#: builtin/checkout.c:964 builtin/checkout.c:968 +#: builtin/checkout.c:967 builtin/checkout.c:971 #, c-format msgid "'%s' cannot be used with switching branches" msgstr "\"%s\" kan inte användas vid byte av gren" -#: builtin/checkout.c:972 builtin/checkout.c:975 builtin/checkout.c:980 -#: builtin/checkout.c:983 +#: builtin/checkout.c:975 builtin/checkout.c:978 builtin/checkout.c:983 +#: builtin/checkout.c:986 #, c-format msgid "'%s' cannot be used with '%s'" msgstr "\"%s\" kan inte användas med \"%s\"" -#: builtin/checkout.c:988 +#: builtin/checkout.c:991 #, c-format msgid "Cannot switch branch to a non-commit '%s'" msgstr "Kan inte växla gren till icke-incheckningen \"%s\"" -#: builtin/checkout.c:1009 builtin/gc.c:177 +#: builtin/checkout.c:1012 builtin/gc.c:177 msgid "suppress progress reporting" msgstr "undertryck förloppsrapportering" -#: builtin/checkout.c:1010 builtin/checkout.c:1012 builtin/clone.c:89 +#: builtin/checkout.c:1013 builtin/checkout.c:1015 builtin/clone.c:89 #: builtin/remote.c:169 builtin/remote.c:171 msgid "branch" msgstr "gren" -#: builtin/checkout.c:1011 +#: builtin/checkout.c:1014 msgid "create and checkout a new branch" msgstr "skapa och checka ut en ny gren" -#: builtin/checkout.c:1013 +#: builtin/checkout.c:1016 msgid "create/reset and checkout a branch" msgstr "skapa/nollställ och checka ut en gren" -#: builtin/checkout.c:1014 +#: builtin/checkout.c:1017 msgid "create reflog for new branch" msgstr "skapa reflogg för ny gren" -#: builtin/checkout.c:1015 +#: builtin/checkout.c:1018 msgid "detach the HEAD at named commit" msgstr "koppla frÃ¥n HEAD vid namngiven incheckning" -#: builtin/checkout.c:1016 +#: builtin/checkout.c:1019 msgid "set upstream info for new branch" msgstr "sätt uppströmsinformation för ny gren" -#: builtin/checkout.c:1018 +#: builtin/checkout.c:1021 msgid "new branch" msgstr "ny gren" -#: builtin/checkout.c:1018 +#: builtin/checkout.c:1021 msgid "new unparented branch" msgstr "ny gren utan förälder" -#: builtin/checkout.c:1019 +#: builtin/checkout.c:1022 msgid "checkout our version for unmerged files" msgstr "checka ut vÃ¥r version för ej sammanslagna filer" -#: builtin/checkout.c:1021 +#: builtin/checkout.c:1024 msgid "checkout their version for unmerged files" msgstr "checka ut deras version för ej sammanslagna filer" -#: builtin/checkout.c:1023 +#: builtin/checkout.c:1026 msgid "force checkout (throw away local modifications)" msgstr "tvinga utcheckning (kasta bort lokala ändringar)" -#: builtin/checkout.c:1024 +#: builtin/checkout.c:1027 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:1025 builtin/merge.c:215 +#: builtin/checkout.c:1028 builtin/merge.c:215 msgid "update ignored files (default)" msgstr "uppdatera ignorerade filer (standard)" -#: builtin/checkout.c:1026 builtin/log.c:1111 parse-options.h:241 +#: builtin/checkout.c:1029 builtin/log.c:1116 parse-options.h:241 msgid "style" msgstr "stil" -#: builtin/checkout.c:1027 +#: builtin/checkout.c:1030 msgid "conflict style (merge or diff3)" msgstr "konfliktstil (merge eller diff3)" -#: builtin/checkout.c:1030 +#: builtin/checkout.c:1033 msgid "second guess 'git checkout no-such-branch'" msgstr "förutspÃ¥ \"git checkout gren-saknas\"" -#: builtin/checkout.c:1054 +#: builtin/checkout.c:1057 msgid "-b, -B and --orphan are mutually exclusive" msgstr "-b, -B och --orphan är ömsesidigt uteslutande" -#: builtin/checkout.c:1071 +#: builtin/checkout.c:1074 msgid "--track needs a branch name" msgstr "--track behöver ett namn pÃ¥ en gren" -#: builtin/checkout.c:1078 +#: builtin/checkout.c:1081 msgid "Missing branch name; try -b" msgstr "Grennamn saknas; försök med -b" -#: builtin/checkout.c:1113 +#: builtin/checkout.c:1116 msgid "invalid path specification" msgstr "felaktig sökvägsangivelse" -#: builtin/checkout.c:1120 +#: builtin/checkout.c:1123 #, c-format msgid "" "Cannot update paths and switch to branch '%s' at the same time.\n" @@ -2856,12 +2890,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:1125 +#: builtin/checkout.c:1128 #, 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:1129 +#: builtin/checkout.c:1132 msgid "" "git checkout: --ours/--theirs, --force and --merge are incompatible when\n" "checking out of the index." @@ -2886,8 +2920,8 @@ msgstr "tvinga" msgid "remove whole directories" msgstr "ta bort hela kataloger" -#: builtin/clean.c:56 builtin/describe.c:413 builtin/grep.c:803 -#: builtin/ls-files.c:491 builtin/name-rev.c:231 builtin/show-ref.c:199 +#: builtin/clean.c:56 builtin/describe.c:413 builtin/grep.c:717 +#: builtin/ls-files.c:491 builtin/name-rev.c:231 builtin/show-ref.c:182 msgid "pattern" msgstr "mönster" @@ -3012,7 +3046,7 @@ msgstr "checka ut <gren> istället för fjärrens HEAD" 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:748 +#: builtin/clone.c:93 builtin/fetch.c:83 builtin/grep.c:662 msgid "depth" msgstr "djup" @@ -3247,93 +3281,93 @@ msgstr "" "\n" "Annars använder du \"git reset\"\n" -#: builtin/commit.c:257 +#: builtin/commit.c:258 msgid "failed to unpack HEAD tree object" msgstr "misslyckades packa upp HEAD:s trädobjekt" -#: builtin/commit.c:299 +#: builtin/commit.c:300 msgid "unable to create temporary index" msgstr "kunde inte skapa temporär indexfil" -#: builtin/commit.c:305 +#: builtin/commit.c:306 msgid "interactive add failed" msgstr "interaktiv tilläggning misslyckades" -#: builtin/commit.c:338 builtin/commit.c:359 builtin/commit.c:409 +#: builtin/commit.c:339 builtin/commit.c:360 builtin/commit.c:410 msgid "unable to write new_index file" msgstr "kunde inte skriva filen new_index" -#: builtin/commit.c:390 +#: builtin/commit.c:391 msgid "cannot do a partial commit during a merge." msgstr "kan inte utföra en delvis incheckning under en sammanslagning." -#: builtin/commit.c:392 +#: builtin/commit.c:393 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:402 +#: builtin/commit.c:403 msgid "cannot read the index" msgstr "kan inte läsa indexet" -#: builtin/commit.c:422 +#: builtin/commit.c:423 msgid "unable to write temporary index file" msgstr "kunde inte skriva temporär indexfil" -#: builtin/commit.c:509 builtin/commit.c:515 +#: builtin/commit.c:511 builtin/commit.c:517 #, c-format msgid "invalid commit: %s" msgstr "felaktig incheckning: %s" -#: builtin/commit.c:538 +#: builtin/commit.c:540 msgid "malformed --author parameter" msgstr "felformad \"--author\"-flagga" -#: builtin/commit.c:558 +#: builtin/commit.c:560 #, c-format msgid "Malformed ident string: '%s'" msgstr "Felaktig indragningssträng: \"%s\"" -#: builtin/commit.c:596 builtin/commit.c:629 builtin/commit.c:952 +#: builtin/commit.c:598 builtin/commit.c:631 builtin/commit.c:954 #, c-format msgid "could not lookup commit %s" msgstr "kunde inte slÃ¥ upp incheckningen %s" -#: builtin/commit.c:608 builtin/shortlog.c:296 +#: builtin/commit.c:610 builtin/shortlog.c:296 #, c-format msgid "(reading log message from standard input)\n" msgstr "(läser loggmeddelande frÃ¥n standard in)\n" -#: builtin/commit.c:610 +#: builtin/commit.c:612 msgid "could not read log from standard input" msgstr "kunde inte läsa logg frÃ¥n standard in" -#: builtin/commit.c:614 +#: builtin/commit.c:616 #, c-format msgid "could not read log file '%s'" msgstr "kunde inte läsa loggfilen \"%s\"" -#: builtin/commit.c:620 +#: builtin/commit.c:622 msgid "commit has empty message" msgstr "incheckningen har ett tomt meddelande" -#: builtin/commit.c:636 +#: builtin/commit.c:638 msgid "could not read MERGE_MSG" msgstr "kunde inte läsa MERGE_MSG" -#: builtin/commit.c:640 +#: builtin/commit.c:642 msgid "could not read SQUASH_MSG" msgstr "kunde inte läsa SQUASH_MSG" -#: builtin/commit.c:644 +#: builtin/commit.c:646 #, c-format msgid "could not read '%s'" msgstr "kunde inte läsa \"%s\"" -#: builtin/commit.c:705 +#: builtin/commit.c:707 msgid "could not write commit template" msgstr "kunde inte skriva incheckningsmall" -#: builtin/commit.c:716 +#: builtin/commit.c:718 #, c-format msgid "" "\n" @@ -3348,7 +3382,7 @@ msgstr "" "\t%s\n" "och försöker igen.\n" -#: builtin/commit.c:721 +#: builtin/commit.c:723 #, c-format msgid "" "\n" @@ -3363,7 +3397,7 @@ msgstr "" "\t%s\n" "och försöker igen.\n" -#: builtin/commit.c:733 +#: builtin/commit.c:735 msgid "" "Please enter the commit message for your changes. Lines starting\n" "with '#' will be ignored, and an empty message aborts the commit.\n" @@ -3371,7 +3405,7 @@ msgstr "" "Ange incheckningsmeddelandet för dina ändringar. Rader som inleds\n" "med \"#\" kommer ignoreras, och ett tomt meddelande avbryter incheckningen.\n" -#: builtin/commit.c:738 +#: builtin/commit.c:740 msgid "" "Please enter the commit message for your changes. Lines starting\n" "with '#' will be kept; you may remove them yourself if you want to.\n" @@ -3381,131 +3415,139 @@ msgstr "" "med \"#\" kommer behÃ¥llas; du kan själv ta bort dem om du vill.\n" "Ett tomt meddelande avbryter incheckningen.\n" -#: builtin/commit.c:751 +#: builtin/commit.c:753 #, c-format msgid "%sAuthor: %s" msgstr "%sFörfattare: %s" -#: builtin/commit.c:758 +#: builtin/commit.c:760 #, c-format msgid "%sCommitter: %s" msgstr "%sIncheckare: %s" -#: builtin/commit.c:778 +#: builtin/commit.c:780 msgid "Cannot read index" msgstr "Kan inte läsa indexet" -#: builtin/commit.c:815 +#: builtin/commit.c:817 msgid "Error building trees" msgstr "Fel vid byggande av träd" -#: builtin/commit.c:830 builtin/tag.c:361 +#: builtin/commit.c:832 builtin/tag.c:361 #, 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:927 +#: builtin/commit.c:929 #, c-format msgid "No existing author found with '%s'" msgstr "Hittade ingen befintlig författare med \"%s\"" -#: builtin/commit.c:942 builtin/commit.c:1142 +#: builtin/commit.c:944 builtin/commit.c:1148 #, c-format msgid "Invalid untracked files mode '%s'" msgstr "Ogiltigt läge för ospÃ¥rade filer: \"%s\"" -#: builtin/commit.c:982 +#: builtin/commit.c:984 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:993 +#: builtin/commit.c:995 msgid "You have nothing to amend." msgstr "Du har inget att utöka." -#: builtin/commit.c:996 +#: builtin/commit.c:998 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:998 +#: builtin/commit.c:1000 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:1001 +#: builtin/commit.c:1003 msgid "Options --squash and --fixup cannot be used together" msgstr "Flaggorna --squash och --fixup kan inte användas samtidigt" -#: builtin/commit.c:1011 +#: builtin/commit.c:1013 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:1013 +#: builtin/commit.c:1015 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:1021 +#: builtin/commit.c:1023 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:1038 +#: builtin/commit.c:1040 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:1040 +#: builtin/commit.c:1042 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:1042 +#: builtin/commit.c:1044 msgid "Clever... amending the last one with dirty index." msgstr "Smart... utöka den senaste med smutsigt index." -#: builtin/commit.c:1044 +#: builtin/commit.c:1046 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:1054 builtin/tag.c:577 +#: builtin/commit.c:1056 builtin/tag.c:577 #, c-format msgid "Invalid cleanup mode %s" msgstr "Felaktigt städningsläge %s" -#: builtin/commit.c:1059 +#: builtin/commit.c:1061 msgid "Paths with -a does not make sense." msgstr "Kan inte ange sökvägar med -a." -#: builtin/commit.c:1156 builtin/commit.c:1384 +#: builtin/commit.c:1067 builtin/commit.c:1202 +msgid "--long and -z are incompatible" +msgstr "--long och -z är inkompatibla" + +#: builtin/commit.c:1162 builtin/commit.c:1398 msgid "show status concisely" msgstr "vis koncis status" -#: builtin/commit.c:1158 builtin/commit.c:1386 +#: builtin/commit.c:1164 builtin/commit.c:1400 msgid "show branch information" msgstr "visa information om gren" -#: builtin/commit.c:1160 builtin/commit.c:1388 builtin/push.c:389 +#: builtin/commit.c:1166 builtin/commit.c:1402 builtin/push.c:389 msgid "machine-readable output" msgstr "maskinläsbar utdata" -#: builtin/commit.c:1163 builtin/commit.c:1390 +#: builtin/commit.c:1169 builtin/commit.c:1404 +msgid "show status in long format (default)" +msgstr "visa status i lÃ¥ngt format (standard)" + +#: builtin/commit.c:1172 builtin/commit.c:1407 msgid "terminate entries with NUL" msgstr "terminera poster med NUL" -#: builtin/commit.c:1165 builtin/commit.c:1393 builtin/fast-export.c:636 +#: builtin/commit.c:1174 builtin/commit.c:1410 builtin/fast-export.c:636 #: builtin/fast-export.c:639 builtin/tag.c:461 msgid "mode" msgstr "läge" -#: builtin/commit.c:1166 builtin/commit.c:1393 +#: builtin/commit.c:1175 builtin/commit.c:1410 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:1169 +#: builtin/commit.c:1178 msgid "show ignored files" msgstr "visa ignorerade filer" -#: builtin/commit.c:1170 parse-options.h:151 +#: builtin/commit.c:1179 parse-options.h:151 msgid "when" msgstr "när" -#: builtin/commit.c:1171 +#: builtin/commit.c:1180 msgid "" "ignore changes to submodules, optional when: all, dirty, untracked. " "(Default: all)" @@ -3513,217 +3555,217 @@ msgstr "" "ignorera ändringar i undermoduler, valfritt när: all, dirty, untracked. " "(Default: all)" -#: builtin/commit.c:1173 +#: builtin/commit.c:1182 msgid "list untracked files in columns" msgstr "visa ospÃ¥rade filer i spalter" -#: builtin/commit.c:1242 +#: builtin/commit.c:1256 msgid "couldn't look up newly created commit" msgstr "kunde inte slÃ¥ upp en precis skapad incheckning" -#: builtin/commit.c:1244 +#: builtin/commit.c:1258 msgid "could not parse newly created commit" msgstr "kunde inte tolka en precis skapad incheckning" -#: builtin/commit.c:1285 +#: builtin/commit.c:1299 msgid "detached HEAD" msgstr "frÃ¥nkopplad HEAD" -#: builtin/commit.c:1287 +#: builtin/commit.c:1301 msgid " (root-commit)" msgstr " (rotincheckning)" -#: builtin/commit.c:1354 +#: builtin/commit.c:1368 msgid "suppress summary after successful commit" msgstr "undertryck sammanfattning efter framgÃ¥ngsrik incheckning" -#: builtin/commit.c:1355 +#: builtin/commit.c:1369 msgid "show diff in commit message template" msgstr "visa diff i mallen för incheckningsmeddelandet" -#: builtin/commit.c:1357 +#: builtin/commit.c:1371 msgid "Commit message options" msgstr "Alternativ för incheckningsmeddelande" -#: builtin/commit.c:1358 builtin/tag.c:459 +#: builtin/commit.c:1372 builtin/tag.c:459 msgid "read message from file" msgstr "läs meddelande frÃ¥n fil" -#: builtin/commit.c:1359 +#: builtin/commit.c:1373 msgid "author" msgstr "författare" -#: builtin/commit.c:1359 +#: builtin/commit.c:1373 msgid "override author for commit" msgstr "överstyr författare för incheckningen" -#: builtin/commit.c:1360 builtin/gc.c:178 +#: builtin/commit.c:1374 builtin/gc.c:178 msgid "date" msgstr "datum" -#: builtin/commit.c:1360 +#: builtin/commit.c:1374 msgid "override date for commit" msgstr "överstyr datum för inchecknignen" -#: builtin/commit.c:1361 builtin/merge.c:206 builtin/notes.c:537 +#: builtin/commit.c:1375 builtin/merge.c:206 builtin/notes.c:537 #: builtin/notes.c:694 builtin/tag.c:457 msgid "message" msgstr "meddelande" -#: builtin/commit.c:1361 +#: builtin/commit.c:1375 msgid "commit message" msgstr "incheckningsmeddelande" -#: builtin/commit.c:1362 +#: builtin/commit.c:1376 msgid "reuse and edit message from specified commit" msgstr "Ã¥teranvänd och redigera meddelande frÃ¥n angiven incheckning" -#: builtin/commit.c:1363 +#: builtin/commit.c:1377 msgid "reuse message from specified commit" msgstr "Ã¥teranvänd meddelande frÃ¥n angiven incheckning" -#: builtin/commit.c:1364 +#: builtin/commit.c:1378 msgid "use autosquash formatted message to fixup specified commit" msgstr "" "använd autosquash-formaterat meddelande för att fixa angiven incheckning" -#: builtin/commit.c:1365 +#: builtin/commit.c:1379 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:1366 +#: builtin/commit.c:1380 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:1367 builtin/log.c:1068 builtin/revert.c:109 +#: builtin/commit.c:1381 builtin/log.c:1073 builtin/revert.c:109 msgid "add Signed-off-by:" msgstr "lägg till Signed-off-by:" -#: builtin/commit.c:1368 +#: builtin/commit.c:1382 msgid "use specified template file" msgstr "använd angiven mallfil" -#: builtin/commit.c:1369 +#: builtin/commit.c:1383 msgid "force edit of commit" msgstr "tvinga redigering av incheckning" -#: builtin/commit.c:1370 +#: builtin/commit.c:1384 msgid "default" msgstr "standard" -#: builtin/commit.c:1370 builtin/tag.c:462 +#: builtin/commit.c:1384 builtin/tag.c:462 msgid "how to strip spaces and #comments from message" msgstr "hur blanksteg och #kommentarer skall tas bort frÃ¥n meddelande" -#: builtin/commit.c:1371 +#: builtin/commit.c:1385 msgid "include status in commit message template" msgstr "inkludera status i mallen för incheckningsmeddelandet" -#: builtin/commit.c:1372 builtin/merge.c:213 builtin/tag.c:463 +#: builtin/commit.c:1386 builtin/merge.c:213 builtin/tag.c:463 msgid "key id" msgstr "nyckel-id" -#: builtin/commit.c:1373 builtin/merge.c:214 +#: builtin/commit.c:1387 builtin/merge.c:214 msgid "GPG sign commit" msgstr "GPG-signera incheckning" #. end commit message options -#: builtin/commit.c:1376 +#: builtin/commit.c:1390 msgid "Commit contents options" msgstr "Alternativ för incheckningens innehÃ¥ll" -#: builtin/commit.c:1377 +#: builtin/commit.c:1391 msgid "commit all changed files" msgstr "checka in alla ändrade filer" -#: builtin/commit.c:1378 +#: builtin/commit.c:1392 msgid "add specified files to index for commit" msgstr "lägg till angivna filer till indexet för incheckning" -#: builtin/commit.c:1379 +#: builtin/commit.c:1393 msgid "interactively add files" msgstr "lägg till filer interaktivt" -#: builtin/commit.c:1380 +#: builtin/commit.c:1394 msgid "interactively add changes" msgstr "lägg till ändringar interaktivt" -#: builtin/commit.c:1381 +#: builtin/commit.c:1395 msgid "commit only specified files" msgstr "checka endast in angivna filer" -#: builtin/commit.c:1382 +#: builtin/commit.c:1396 msgid "bypass pre-commit hook" msgstr "förbigÃ¥ pre-commit-krok" -#: builtin/commit.c:1383 +#: builtin/commit.c:1397 msgid "show what would be committed" msgstr "visa vad som skulle checkas in" -#: builtin/commit.c:1391 +#: builtin/commit.c:1408 msgid "amend previous commit" msgstr "lägg till föregÃ¥ende incheckning" -#: builtin/commit.c:1392 +#: builtin/commit.c:1409 msgid "bypass post-rewrite hook" msgstr "förbigÃ¥ post-rewrite-krok" -#: builtin/commit.c:1397 +#: builtin/commit.c:1414 msgid "ok to record an empty change" msgstr "ok att registrera en tom ändring" -#: builtin/commit.c:1400 +#: builtin/commit.c:1417 msgid "ok to record a change with an empty message" msgstr "ok att registrera en ändring med tomt meddelande" -#: builtin/commit.c:1432 +#: builtin/commit.c:1449 msgid "could not parse HEAD commit" msgstr "kunde inte tolka HEAD:s incheckning" -#: builtin/commit.c:1470 builtin/merge.c:508 +#: builtin/commit.c:1487 builtin/merge.c:508 #, c-format msgid "could not open '%s' for reading" msgstr "kunde inte öppna \"%s\" för läsning" -#: builtin/commit.c:1477 +#: builtin/commit.c:1494 #, c-format msgid "Corrupt MERGE_HEAD file (%s)" msgstr "Trasig MERGE_HEAD-fil (%s)" -#: builtin/commit.c:1484 +#: builtin/commit.c:1501 msgid "could not read MERGE_MODE" msgstr "kunde inte läsa MERGE_MODE" -#: builtin/commit.c:1503 +#: builtin/commit.c:1520 #, c-format msgid "could not read commit message: %s" msgstr "kunde inte läsa incheckningsmeddelande: %s" -#: builtin/commit.c:1517 +#: builtin/commit.c:1534 #, c-format msgid "Aborting commit; you did not edit the message.\n" msgstr "Avbryter incheckning; meddelandet inte redigerat.\n" -#: builtin/commit.c:1522 +#: builtin/commit.c:1539 #, c-format msgid "Aborting commit due to empty commit message.\n" msgstr "Avbryter pÃ¥ grund av tomt incheckningsmeddelande.\n" -#: builtin/commit.c:1537 builtin/merge.c:935 builtin/merge.c:960 +#: builtin/commit.c:1554 builtin/merge.c:832 builtin/merge.c:857 msgid "failed to write commit object" msgstr "kunde inte skriva incheckningsobjekt" -#: builtin/commit.c:1558 +#: builtin/commit.c:1575 msgid "cannot lock HEAD ref" msgstr "kunde inte lÃ¥sa HEAD-referens" -#: builtin/commit.c:1562 +#: builtin/commit.c:1579 msgid "cannot update HEAD ref" msgstr "kunde inte uppdatera HEAD-referens" -#: builtin/commit.c:1573 +#: builtin/commit.c:1590 msgid "" "Repository has been updated, but unable to write\n" "new_index file. Check that disk is not full or quota is\n" @@ -3738,115 +3780,115 @@ msgstr "" msgid "git config [options]" msgstr "git config [flaggor]" -#: builtin/config.c:52 +#: builtin/config.c:51 msgid "Config file location" msgstr "Konfigurationsfilens plats" -#: builtin/config.c:53 +#: builtin/config.c:52 msgid "use global config file" msgstr "använd global konfigurationsfil" -#: builtin/config.c:54 +#: builtin/config.c:53 msgid "use system config file" msgstr "använd systemets konfigurationsfil" -#: builtin/config.c:55 +#: builtin/config.c:54 msgid "use repository config file" msgstr "använd arkivets konfigurationsfil" -#: builtin/config.c:56 +#: builtin/config.c:55 msgid "use given config file" msgstr "använd angiven konfigurationsil" -#: builtin/config.c:57 +#: builtin/config.c:56 msgid "Action" msgstr "Ã…tgärd" -#: builtin/config.c:58 +#: builtin/config.c:57 msgid "get value: name [value-regex]" msgstr "hämta värde: namn [värde-reguttr]" -#: builtin/config.c:59 +#: builtin/config.c:58 msgid "get all values: key [value-regex]" msgstr "hämta alla värden: nyckel [värde-reguttr]" -#: builtin/config.c:60 +#: builtin/config.c:59 msgid "get values for regexp: name-regex [value-regex]" msgstr "hämta värden för reguttr: namn-reguttr [värde-reguttr]" -#: builtin/config.c:61 +#: builtin/config.c:60 msgid "replace all matching variables: name value [value_regex]" msgstr "ersätt alla motsvarande variabler: namn värde [värde-reguttr]" -#: builtin/config.c:62 +#: builtin/config.c:61 msgid "add a new variable: name value" msgstr "lägg till en ny variabel: namn värde" -#: builtin/config.c:63 +#: builtin/config.c:62 msgid "remove a variable: name [value-regex]" msgstr "ta bort en variabel: namn [värde-reguttr]" -#: builtin/config.c:64 +#: builtin/config.c:63 msgid "remove all matches: name [value-regex]" msgstr "ta bort alla träffar: namn [värde-reguttr]" -#: builtin/config.c:65 +#: builtin/config.c:64 msgid "rename section: old-name new-name" msgstr "byt namn pÃ¥ sektion: gammalt-namn nytt-namn" -#: builtin/config.c:66 +#: builtin/config.c:65 msgid "remove a section: name" msgstr "ta bort en sektion: namn" -#: builtin/config.c:67 +#: builtin/config.c:66 msgid "list all" msgstr "visa alla" -#: builtin/config.c:68 +#: builtin/config.c:67 msgid "open an editor" msgstr "öppna textredigeringsprogram" -#: builtin/config.c:69 builtin/config.c:70 +#: builtin/config.c:68 builtin/config.c:69 msgid "slot" msgstr "plats" -#: builtin/config.c:69 +#: builtin/config.c:68 msgid "find the color configured: [default]" msgstr "hitta den inställda färgen: [default]" -#: builtin/config.c:70 +#: builtin/config.c:69 msgid "find the color setting: [stdout-is-tty]" msgstr "hitta färginställningen: [stdout-is-tty]" -#: builtin/config.c:71 +#: builtin/config.c:70 msgid "Type" msgstr "Typ" -#: builtin/config.c:72 +#: builtin/config.c:71 msgid "value is \"true\" or \"false\"" msgstr "värdet är \"true\" eller \"false\"" -#: builtin/config.c:73 +#: builtin/config.c:72 msgid "value is decimal number" msgstr "värdet är ett decimalt tal" -#: builtin/config.c:74 +#: builtin/config.c:73 msgid "value is --bool or --int" msgstr "värdet är --bool eller --int" -#: builtin/config.c:75 +#: builtin/config.c:74 msgid "value is a path (file or directory name)" msgstr "värdet är en sökväg (fil- eller katalognamn)" -#: builtin/config.c:76 +#: builtin/config.c:75 msgid "Other" msgstr "Andra" -#: builtin/config.c:77 +#: builtin/config.c:76 msgid "terminate values with NUL byte" msgstr "terminera värden med NUL-byte" -#: builtin/config.c:78 +#: builtin/config.c:77 msgid "respect include directives on lookup" msgstr "respektera inkluderingsdirektiv vid uppslag" @@ -3995,31 +4037,31 @@ msgstr "--dirty är inkompatibelt med \"committish\"-värden" msgid "'%s': not a regular file or symlink" msgstr "\"%s\": inte en normal fil eller symbolisk länk" -#: builtin/diff.c:224 +#: builtin/diff.c:228 #, c-format msgid "invalid option: %s" msgstr "ogiltig flagga: %s" -#: builtin/diff.c:301 +#: builtin/diff.c:305 msgid "Not a git repository" msgstr "Inte ett git-arkiv" -#: builtin/diff.c:344 +#: builtin/diff.c:348 #, c-format msgid "invalid object '%s' given." msgstr "objektet \"%s\" som angavs är felaktigt." -#: builtin/diff.c:349 +#: builtin/diff.c:353 #, c-format msgid "more than %d trees given: '%s'" msgstr "mer än %d träd angavs: \"%s\"" -#: builtin/diff.c:359 +#: builtin/diff.c:363 #, c-format msgid "more than two blobs given: '%s'" msgstr "mer än tvÃ¥ blobbar angavs: \"%s\"" -#: builtin/diff.c:367 +#: builtin/diff.c:371 #, c-format msgid "unhandled object '%s' given." msgstr "ej hanterat objekt \"%s\" angavs." @@ -4132,7 +4174,7 @@ msgstr "tillÃ¥t uppdatering av HEAD-referens" msgid "deepen history of shallow clone" msgstr "fördjupa historik för grund klon" -#: builtin/fetch.c:85 builtin/log.c:1083 +#: builtin/fetch.c:85 builtin/log.c:1088 msgid "dir" msgstr "kat" @@ -4304,8 +4346,8 @@ 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:653 builtin/fmt-merge-msg.c:656 builtin/grep.c:787 -#: builtin/merge.c:188 builtin/show-branch.c:656 builtin/show-ref.c:192 +#: builtin/fmt-merge-msg.c:653 builtin/fmt-merge-msg.c:656 builtin/grep.c:701 +#: builtin/merge.c:188 builtin/show-branch.c:656 builtin/show-ref.c:175 #: builtin/tag.c:448 parse-options.h:133 parse-options.h:235 msgid "n" msgstr "n" @@ -4465,225 +4507,225 @@ msgstr "git grep [flaggor] [-e] <mönster> [<rev>...] [[--] <sökväg>...]" msgid "grep: failed to create thread: %s" msgstr "grep: misslyckades skapa trÃ¥d. %s" -#: builtin/grep.c:455 +#: builtin/grep.c:365 #, c-format msgid "Failed to chdir: %s" msgstr "Kunde inte byta katalog (chdir): %s" -#: builtin/grep.c:531 builtin/grep.c:565 +#: builtin/grep.c:443 builtin/grep.c:478 #, c-format msgid "unable to read tree (%s)" msgstr "kunde inte läsa träd (%s)" -#: builtin/grep.c:579 +#: builtin/grep.c:493 #, c-format msgid "unable to grep from object of type %s" msgstr "Kunde inte \"grep\" frÃ¥n objekt av typen %s" -#: builtin/grep.c:637 +#: builtin/grep.c:551 #, c-format msgid "switch `%c' expects a numerical value" msgstr "flaggan \"%c\" antar ett numeriskt värde" -#: builtin/grep.c:654 +#: builtin/grep.c:568 #, c-format msgid "cannot open '%s'" msgstr "kan inte öppna \"%s\"" -#: builtin/grep.c:729 +#: builtin/grep.c:643 msgid "search in index instead of in the work tree" msgstr "sök i indexet istället för i arbetskatalogen" -#: builtin/grep.c:731 +#: builtin/grep.c:645 msgid "find in contents not managed by git" msgstr "sök i innehÃ¥l som inte hanteras av git" -#: builtin/grep.c:733 +#: builtin/grep.c:647 msgid "search in both tracked and untracked files" msgstr "sök i bÃ¥de spÃ¥rade och ospÃ¥rade filer" -#: builtin/grep.c:735 +#: builtin/grep.c:649 msgid "search also in ignored files" msgstr "sök även i ignorerade filer" -#: builtin/grep.c:738 +#: builtin/grep.c:652 msgid "show non-matching lines" msgstr "vis rader som inte träffas" -#: builtin/grep.c:740 +#: builtin/grep.c:654 msgid "case insensitive matching" msgstr "skiftlägesokänslig sökning" -#: builtin/grep.c:742 +#: builtin/grep.c:656 msgid "match patterns only at word boundaries" msgstr "matcha endast mönster vid ordgränser" -#: builtin/grep.c:744 +#: builtin/grep.c:658 msgid "process binary files as text" msgstr "hantera binärfiler som text" -#: builtin/grep.c:746 +#: builtin/grep.c:660 msgid "don't match patterns in binary files" msgstr "träffa inte mönster i binärfiler" -#: builtin/grep.c:749 +#: builtin/grep.c:663 msgid "descend at most <depth> levels" msgstr "gÃ¥ som mest ned <djup> nivÃ¥er" -#: builtin/grep.c:753 +#: builtin/grep.c:667 msgid "use extended POSIX regular expressions" msgstr "använd utökade POSIX-reguljära uttryck" -#: builtin/grep.c:756 +#: builtin/grep.c:670 msgid "use basic POSIX regular expressions (default)" msgstr "använd grundläggande POSIX-reguljära uttryck (standard)" -#: builtin/grep.c:759 +#: builtin/grep.c:673 msgid "interpret patterns as fixed strings" msgstr "tolka mönster som fixerade strängar" -#: builtin/grep.c:762 +#: builtin/grep.c:676 msgid "use Perl-compatible regular expressions" msgstr "använd Perlkompatibla reguljära uttryck" -#: builtin/grep.c:765 +#: builtin/grep.c:679 msgid "show line numbers" msgstr "visa radnummer" -#: builtin/grep.c:766 +#: builtin/grep.c:680 msgid "don't show filenames" msgstr "visa inte filnamn" -#: builtin/grep.c:767 +#: builtin/grep.c:681 msgid "show filenames" msgstr "visa filnamn" -#: builtin/grep.c:769 +#: builtin/grep.c:683 msgid "show filenames relative to top directory" msgstr "visa filnamn relativa till toppkatalogen" -#: builtin/grep.c:771 +#: builtin/grep.c:685 msgid "show only filenames instead of matching lines" msgstr "visa endast filnamn istället för träffade rader" -#: builtin/grep.c:773 +#: builtin/grep.c:687 msgid "synonym for --files-with-matches" msgstr "synonym för --files-with-matches" -#: builtin/grep.c:776 +#: builtin/grep.c:690 msgid "show only the names of files without match" msgstr "visa endast namn pÃ¥ filer utan träffar" -#: builtin/grep.c:778 +#: builtin/grep.c:692 msgid "print NUL after filenames" msgstr "skriv NUL efter filnamn" -#: builtin/grep.c:780 +#: builtin/grep.c:694 msgid "show the number of matches instead of matching lines" msgstr "visa antal träffar istället för träffade rader" -#: builtin/grep.c:781 +#: builtin/grep.c:695 msgid "highlight matches" msgstr "ljusmarkera träffar" -#: builtin/grep.c:783 +#: builtin/grep.c:697 msgid "print empty line between matches from different files" msgstr "skriv tomma rader mellan träffar frÃ¥n olika filer" -#: builtin/grep.c:785 +#: builtin/grep.c:699 msgid "show filename only once above matches from same file" msgstr "visa filnamn endast en gÃ¥ng ovanför träffar frÃ¥n samma fil" -#: builtin/grep.c:788 +#: builtin/grep.c:702 msgid "show <n> context lines before and after matches" msgstr "visa <n> rader sammanhang före och efter träffar" -#: builtin/grep.c:791 +#: builtin/grep.c:705 msgid "show <n> context lines before matches" msgstr "visa <n> rader sammanhang före träffar" -#: builtin/grep.c:793 +#: builtin/grep.c:707 msgid "show <n> context lines after matches" msgstr "visa <n> rader sammanhang efter träffar" -#: builtin/grep.c:794 +#: builtin/grep.c:708 msgid "shortcut for -C NUM" msgstr "genväg för -C NUM" -#: builtin/grep.c:797 +#: builtin/grep.c:711 msgid "show a line with the function name before matches" msgstr "visa en rad med funktionsnamnet före träffen" -#: builtin/grep.c:799 +#: builtin/grep.c:713 msgid "show the surrounding function" msgstr "visa den omkringliggande funktionen" -#: builtin/grep.c:802 +#: builtin/grep.c:716 msgid "read patterns from file" msgstr "läs mönster frÃ¥n fil" -#: builtin/grep.c:804 +#: builtin/grep.c:718 msgid "match <pattern>" msgstr "träffa <mönster>" -#: builtin/grep.c:806 +#: builtin/grep.c:720 msgid "combine patterns specified with -e" msgstr "kombinera mönster som anges med -e" -#: builtin/grep.c:818 +#: builtin/grep.c:732 msgid "indicate hit with exit status without output" msgstr "ange träff med slutstatuskod utan utdata" -#: builtin/grep.c:820 +#: builtin/grep.c:734 msgid "show only matches from files that match all patterns" msgstr "visa endast träffar frÃ¥n filer som träffar alla mönster" -#: builtin/grep.c:822 +#: builtin/grep.c:736 msgid "show parse tree for grep expression" msgstr "visa analysträd för grep-uttryck" -#: builtin/grep.c:826 +#: builtin/grep.c:740 msgid "pager" msgstr "bläddrare" -#: builtin/grep.c:826 +#: builtin/grep.c:740 msgid "show matching files in the pager" msgstr "visa träffade filer i filbläddraren" -#: builtin/grep.c:829 +#: builtin/grep.c:743 msgid "allow calling of grep(1) (ignored by this build)" msgstr "tillÃ¥t anropa grep(1) (ignoreras av detta bygge)" -#: builtin/grep.c:830 builtin/show-ref.c:201 +#: builtin/grep.c:744 builtin/show-ref.c:184 msgid "show usage" msgstr "visa användning" -#: builtin/grep.c:921 +#: builtin/grep.c:811 msgid "no pattern given." msgstr "inget mönster angavs." -#: builtin/grep.c:935 +#: builtin/grep.c:825 #, c-format msgid "bad object %s" msgstr "felaktigt objekt %s" -#: builtin/grep.c:976 +#: 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:999 +#: 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:1004 +#: 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:1007 +#: 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:1015 +#: builtin/grep.c:905 msgid "both --cached and trees are given." msgstr "bÃ¥de --cached och träd angavs." @@ -5277,219 +5319,219 @@ msgstr "dekoreringsflaggor" msgid "Final output: %d %s\n" msgstr "Slututdata: %d %s\n" -#: builtin/log.c:403 builtin/log.c:494 +#: builtin/log.c:405 builtin/log.c:497 #, c-format msgid "Could not read object %s" msgstr "Kunde inte läsa objektet %s" -#: builtin/log.c:518 +#: builtin/log.c:521 #, c-format msgid "Unknown type: %d" msgstr "Okänd typ: %d" -#: builtin/log.c:608 +#: builtin/log.c:613 msgid "format.headers without value" msgstr "format.headers utan värde" -#: builtin/log.c:682 +#: builtin/log.c:687 msgid "name of output directory is too long" msgstr "namnet pÃ¥ utdatakatalogen är för lÃ¥ngt" -#: builtin/log.c:693 +#: builtin/log.c:698 #, c-format msgid "Cannot open patch file %s" msgstr "Kan inte öppna patchfilen %s" -#: builtin/log.c:707 +#: builtin/log.c:712 msgid "Need exactly one range." msgstr "Behöver precis ett intervall." -#: builtin/log.c:715 +#: builtin/log.c:720 msgid "Not a range." msgstr "Inte ett intervall." -#: builtin/log.c:789 +#: builtin/log.c:794 msgid "Cover letter needs email format" msgstr "Omslagsbrevet behöver e-postformat" -#: builtin/log.c:862 +#: builtin/log.c:867 #, c-format msgid "insane in-reply-to: %s" msgstr "tokigt in-reply-to: %s" -#: builtin/log.c:890 +#: builtin/log.c:895 msgid "git format-patch [options] [<since> | <revision range>]" msgstr "git format-patch [flaggor] [<sedan> | <revisionsintervall>]" -#: builtin/log.c:935 +#: builtin/log.c:940 msgid "Two output directories?" msgstr "TvÃ¥ utdatakataloger?" -#: builtin/log.c:1063 +#: builtin/log.c:1068 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:1066 +#: builtin/log.c:1071 msgid "use [PATCH] even with multiple patches" msgstr "använd [PATCH] även för flera patchar" -#: builtin/log.c:1070 +#: builtin/log.c:1075 msgid "print patches to standard out" msgstr "skriv patcharna pÃ¥ stnadard ut" -#: builtin/log.c:1072 +#: builtin/log.c:1077 msgid "generate a cover letter" msgstr "generera ett följebrev" -#: builtin/log.c:1074 +#: builtin/log.c:1079 msgid "use simple number sequence for output file names" msgstr "använd enkel nummersekvens för utdatafilnamn" -#: builtin/log.c:1075 +#: builtin/log.c:1080 msgid "sfx" msgstr "sfx" -#: builtin/log.c:1076 +#: builtin/log.c:1081 msgid "use <sfx> instead of '.patch'" msgstr "använd <sfx> istället för \".patch\"" -#: builtin/log.c:1078 +#: builtin/log.c:1083 msgid "start numbering patches at <n> instead of 1" msgstr "börja numrera patchar pÃ¥ <n> istället för 1" -#: builtin/log.c:1080 +#: builtin/log.c:1085 msgid "Use [<prefix>] instead of [PATCH]" msgstr "Använd [<prefix>] istället för [PATCH]" -#: builtin/log.c:1083 +#: builtin/log.c:1088 msgid "store resulting files in <dir>" msgstr "spara filerna i <katalog>" -#: builtin/log.c:1086 +#: builtin/log.c:1091 msgid "don't strip/add [PATCH]" msgstr "ta inte bort eller lägg till [PATCH]" -#: builtin/log.c:1089 +#: builtin/log.c:1094 msgid "don't output binary diffs" msgstr "skriv inte binära diffar" -#: builtin/log.c:1091 +#: builtin/log.c:1096 msgid "don't include a patch matching a commit upstream" msgstr "ta inte med patchar som motsvarar en uppströmsincheckning" -#: builtin/log.c:1093 +#: builtin/log.c:1098 msgid "show patch format instead of default (patch + stat)" msgstr "visa patchformat istället för standard (patch + stat)" -#: builtin/log.c:1095 +#: builtin/log.c:1100 msgid "Messaging" msgstr "E-post" -#: builtin/log.c:1096 +#: builtin/log.c:1101 msgid "header" msgstr "huvud" -#: builtin/log.c:1097 +#: builtin/log.c:1102 msgid "add email header" msgstr "lägg till e-posthuvud" -#: builtin/log.c:1098 builtin/log.c:1100 +#: builtin/log.c:1103 builtin/log.c:1105 msgid "email" msgstr "epost" -#: builtin/log.c:1098 +#: builtin/log.c:1103 msgid "add To: header" msgstr "Lägg till mottagarhuvud (\"To:\")" -#: builtin/log.c:1100 +#: builtin/log.c:1105 msgid "add Cc: header" msgstr "Lägg till kopiehuvud (\"Cc:\")" -#: builtin/log.c:1102 +#: builtin/log.c:1107 msgid "message-id" msgstr "meddelande-id" -#: builtin/log.c:1103 +#: builtin/log.c:1108 msgid "make first mail a reply to <message-id>" msgstr "Gör det första brevet ett svar till <meddelande-id>" -#: builtin/log.c:1104 builtin/log.c:1107 +#: builtin/log.c:1109 builtin/log.c:1112 msgid "boundary" msgstr "gräns" -#: builtin/log.c:1105 +#: builtin/log.c:1110 msgid "attach the patch" msgstr "bifoga patchen" -#: builtin/log.c:1108 +#: builtin/log.c:1113 msgid "inline the patch" msgstr "gör patchen ett inline-objekt" -#: builtin/log.c:1112 +#: builtin/log.c:1117 msgid "enable message threading, styles: shallow, deep" msgstr "aktivera brevtrÃ¥dning, typer: shallow, deep" -#: builtin/log.c:1114 +#: builtin/log.c:1119 msgid "signature" msgstr "signatur" -#: builtin/log.c:1115 +#: builtin/log.c:1120 msgid "add a signature" msgstr "lägg till signatur" -#: builtin/log.c:1117 +#: builtin/log.c:1122 msgid "don't print the patch filenames" msgstr "visa inte filnamn för patchar" -#: builtin/log.c:1157 +#: builtin/log.c:1163 #, c-format msgid "bogus committer info %s" msgstr "felaktig incheckarinformation %s" -#: builtin/log.c:1202 +#: builtin/log.c:1208 msgid "-n and -k are mutually exclusive." msgstr "-n och -k kan inte användas samtidigt." -#: builtin/log.c:1204 +#: builtin/log.c:1210 msgid "--subject-prefix and -k are mutually exclusive." msgstr "--subject-prefix och -k kan inte användas samtidigt." -#: builtin/log.c:1212 +#: builtin/log.c:1218 msgid "--name-only does not make sense" msgstr "kan inte använda --name-only" -#: builtin/log.c:1214 +#: builtin/log.c:1220 msgid "--name-status does not make sense" msgstr "kan inte använda --name-status" -#: builtin/log.c:1216 +#: builtin/log.c:1222 msgid "--check does not make sense" msgstr "kan inte använda --check" -#: builtin/log.c:1239 +#: builtin/log.c:1245 msgid "standard output, or directory, which one?" msgstr "standard ut, eller katalog, vilken skall det vara?" -#: builtin/log.c:1241 +#: builtin/log.c:1247 #, c-format msgid "Could not create directory '%s'" msgstr "Kunde inte skapa katalogen \"%s\"" -#: builtin/log.c:1394 +#: builtin/log.c:1400 msgid "Failed to create output files" msgstr "Misslyckades skapa utdatafiler" -#: builtin/log.c:1443 +#: builtin/log.c:1449 msgid "git cherry [-v] [<upstream> [<head> [<limit>]]]" msgstr "git cherry [-v] [<uppström> [<huvud> [<gräns>]]]" -#: builtin/log.c:1498 +#: builtin/log.c:1504 #, 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:1511 builtin/log.c:1513 builtin/log.c:1525 +#: builtin/log.c:1517 builtin/log.c:1519 builtin/log.c:1531 #, c-format msgid "Unknown commit %s" msgstr "Okänd incheckning %s" @@ -5767,37 +5809,33 @@ msgstr "Felaktig branch.%s.mergeoptions-sträng: %s" msgid "git write-tree failed to write a tree" msgstr "git write-tree misslyckades skriva ett träd" -#: builtin/merge.c:678 -msgid "failed to read the cache" -msgstr "misslyckads läsa cachen" - -#: builtin/merge.c:709 +#: builtin/merge.c:656 msgid "Not handling anything other than two heads merge." msgstr "Hanterar inte nÃ¥got annat än en sammanslagning av tvÃ¥ huvuden." -#: builtin/merge.c:723 +#: builtin/merge.c:670 #, c-format msgid "Unknown option for merge-recursive: -X%s" msgstr "Felaktig flagga för merge-recursive: -X%s" -#: builtin/merge.c:737 +#: builtin/merge.c:684 #, c-format msgid "unable to write %s" msgstr "kunde inte skriva %s" -#: builtin/merge.c:876 +#: builtin/merge.c:773 #, c-format msgid "Could not read from '%s'" msgstr "Kunde inte läsa frÃ¥n \"%s\"" -#: builtin/merge.c:885 +#: builtin/merge.c:782 #, 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:891 +#: builtin/merge.c:788 msgid "" "Please enter a commit message to explain why this merge is necessary,\n" "especially if it merges an updated upstream into a topic branch.\n" @@ -5812,53 +5850,53 @@ msgstr "" "Rader som inleds med \"#\" kommer ignoreras, och ett tomt meddelande\n" "avbryter incheckningen.\n" -#: builtin/merge.c:915 +#: builtin/merge.c:812 msgid "Empty commit message." msgstr "Tomt incheckningsmeddelande." -#: builtin/merge.c:927 +#: builtin/merge.c:824 #, c-format msgid "Wonderful.\n" msgstr "Underbart.\n" -#: builtin/merge.c:992 +#: builtin/merge.c:889 #, 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:1008 +#: builtin/merge.c:905 #, c-format msgid "'%s' is not a commit" msgstr "\"%s\" är inte en incheckning" -#: builtin/merge.c:1049 +#: builtin/merge.c:946 msgid "No current branch." msgstr "Inte pÃ¥ nÃ¥gon gren." -#: builtin/merge.c:1051 +#: builtin/merge.c:948 msgid "No remote for the current branch." msgstr "Ingen fjärr för aktuell gren." -#: builtin/merge.c:1053 +#: builtin/merge.c:950 msgid "No default upstream defined for the current branch." msgstr "Ingen standarduppström angiven för aktuell gren." -#: builtin/merge.c:1058 +#: builtin/merge.c:955 #, 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:1145 builtin/merge.c:1302 +#: builtin/merge.c:1042 builtin/merge.c:1199 #, c-format msgid "%s - not something we can merge" msgstr "%s - inte nÃ¥got vi kan slÃ¥ ihop" -#: builtin/merge.c:1213 +#: builtin/merge.c:1110 msgid "There is no merge to abort (MERGE_HEAD missing)." msgstr "Det finns ingen sammanslagning att avbryta (MERGE_HEAD saknas)." -#: builtin/merge.c:1229 git-pull.sh:31 +#: builtin/merge.c:1126 git-pull.sh:31 msgid "" "You have not concluded your merge (MERGE_HEAD exists).\n" "Please, commit your changes before you can merge." @@ -5866,11 +5904,11 @@ msgstr "" "Du har inte avslutat sammanslagningen (MERGE_HEAD finns).\n" "Checka in dina ändringar innan du kan slÃ¥ ihop." -#: builtin/merge.c:1232 git-pull.sh:34 +#: builtin/merge.c:1129 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:1236 +#: builtin/merge.c:1133 msgid "" "You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists).\n" "Please, commit your changes before you can merge." @@ -5878,79 +5916,79 @@ 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:1239 +#: builtin/merge.c:1136 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:1248 +#: builtin/merge.c:1145 msgid "You cannot combine --squash with --no-ff." msgstr "Du kan inte kombinera --squash med --no-ff." -#: builtin/merge.c:1253 +#: builtin/merge.c:1150 msgid "You cannot combine --no-ff with --ff-only." msgstr "Du kan inte kombinera --no-ff med --ff-only." -#: builtin/merge.c:1260 +#: builtin/merge.c:1157 msgid "No commit specified and merge.defaultToUpstream not set." msgstr "Ingen incheckning angiven och merge.defaultToUpstream är ej satt." -#: builtin/merge.c:1292 +#: builtin/merge.c:1189 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:1295 +#: builtin/merge.c:1192 msgid "Squash commit into empty head not supported yet" msgstr "Stöder inte en tillplattningsincheckning pÃ¥ ett tomt huvud ännu" -#: builtin/merge.c:1297 +#: builtin/merge.c:1194 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:1412 +#: builtin/merge.c:1309 #, c-format msgid "Updating %s..%s\n" msgstr "Uppdaterar %s..%s\n" -#: builtin/merge.c:1450 +#: builtin/merge.c:1348 #, c-format msgid "Trying really trivial in-index merge...\n" msgstr "Försöker riktigt enkel sammanslagning i indexet...\n" -#: builtin/merge.c:1457 +#: builtin/merge.c:1355 #, c-format msgid "Nope.\n" msgstr "Nej.\n" -#: builtin/merge.c:1489 +#: builtin/merge.c:1387 msgid "Not possible to fast-forward, aborting." msgstr "Kan inte snabbspola, avbryter." -#: builtin/merge.c:1512 builtin/merge.c:1591 +#: builtin/merge.c:1410 builtin/merge.c:1489 #, c-format msgid "Rewinding the tree to pristine...\n" msgstr "Ã…terspolar trädet till orört...\n" -#: builtin/merge.c:1516 +#: builtin/merge.c:1414 #, c-format msgid "Trying merge strategy %s...\n" msgstr "Försöker sammanslagninsstrategin %s...\n" -#: builtin/merge.c:1582 +#: builtin/merge.c:1480 #, c-format msgid "No merge strategy handled the merge.\n" msgstr "Ingen sammanslagningsstrategi hanterade sammanslagningen.\n" -#: builtin/merge.c:1584 +#: builtin/merge.c:1482 #, c-format msgid "Merge with strategy %s failed.\n" msgstr "Sammanslagning med strategin %s misslyckades.\n" -#: builtin/merge.c:1593 +#: builtin/merge.c:1491 #, 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:1605 +#: builtin/merge.c:1503 #, c-format msgid "Automatic merge went well; stopped before committing as requested\n" msgstr "" @@ -6519,143 +6557,143 @@ msgstr "git pack-objects [flaggor...] basnamn [< reflista | < objektlista]" msgid "deflate error (%d)" msgstr "fel i deflate (%d)" -#: builtin/pack-objects.c:2398 +#: builtin/pack-objects.c:2397 #, c-format msgid "unsupported index version %s" msgstr "indexversionen %s stöds ej" -#: builtin/pack-objects.c:2402 +#: builtin/pack-objects.c:2401 #, c-format msgid "bad index version '%s'" msgstr "felaktig indexversion \"%s\"" -#: builtin/pack-objects.c:2425 +#: builtin/pack-objects.c:2424 #, c-format msgid "option %s does not accept negative form" msgstr "flaggan %s godtar inte negativ form" -#: builtin/pack-objects.c:2429 +#: builtin/pack-objects.c:2428 #, c-format msgid "unable to parse value '%s' for option %s" msgstr "kunde inte tolka värdet \"%s\" för flaggan %s" -#: builtin/pack-objects.c:2448 +#: builtin/pack-objects.c:2447 msgid "do not show progress meter" msgstr "visa inte förloppsindikator" -#: builtin/pack-objects.c:2450 +#: builtin/pack-objects.c:2449 msgid "show progress meter" msgstr "visa förloppsindikator" -#: builtin/pack-objects.c:2452 +#: builtin/pack-objects.c:2451 msgid "show progress meter during object writing phase" msgstr "visa förloppsindikator under objektskrivningsfasen" -#: builtin/pack-objects.c:2455 +#: builtin/pack-objects.c:2454 msgid "similar to --all-progress when progress meter is shown" msgstr "som --all-progress när förloppsmätaren visas" -#: builtin/pack-objects.c:2456 +#: builtin/pack-objects.c:2455 msgid "version[,offset]" msgstr "version[,offset]" -#: builtin/pack-objects.c:2457 +#: builtin/pack-objects.c:2456 msgid "write the pack index file in the specified idx format version" msgstr "skriv paketindexfilen i angiven indexformatversion" -#: builtin/pack-objects.c:2460 +#: builtin/pack-objects.c:2459 msgid "maximum size of each output pack file" msgstr "maximal storlek pÃ¥ varje utdatapaketfil" -#: builtin/pack-objects.c:2462 +#: builtin/pack-objects.c:2461 msgid "ignore borrowed objects from alternate object store" msgstr "ignorera lÃ¥nade objekt frÃ¥n alternativa objektlager" -#: builtin/pack-objects.c:2464 +#: builtin/pack-objects.c:2463 msgid "ignore packed objects" msgstr "ignorera packade objekt" -#: builtin/pack-objects.c:2466 +#: builtin/pack-objects.c:2465 msgid "limit pack window by objects" msgstr "begränsa paketfönster efter objekt" -#: builtin/pack-objects.c:2468 +#: builtin/pack-objects.c:2467 msgid "limit pack window by memory in addition to object limit" msgstr "begränsa paketfönster efter minne förutom objektgräns" -#: builtin/pack-objects.c:2470 +#: builtin/pack-objects.c:2469 msgid "maximum length of delta chain allowed in the resulting pack" msgstr "maximal längd pÃ¥ deltakedja tillÃ¥ten i slutligt paket" -#: builtin/pack-objects.c:2472 +#: builtin/pack-objects.c:2471 msgid "reuse existing deltas" msgstr "Ã¥teranvänd befintliga delta" -#: builtin/pack-objects.c:2474 +#: builtin/pack-objects.c:2473 msgid "reuse existing objects" msgstr "Ã¥teranvänd befintliga objekt" -#: builtin/pack-objects.c:2476 +#: builtin/pack-objects.c:2475 msgid "use OFS_DELTA objects" msgstr "använd OFS_DELTA-objekt" -#: builtin/pack-objects.c:2478 +#: builtin/pack-objects.c:2477 msgid "use threads when searching for best delta matches" msgstr "använd trÃ¥dar vid sökning efter bästa deltaträffar" -#: builtin/pack-objects.c:2480 +#: builtin/pack-objects.c:2479 msgid "do not create an empty pack output" msgstr "försök inte skapa tom paketutdata" -#: builtin/pack-objects.c:2482 +#: builtin/pack-objects.c:2481 msgid "read revision arguments from standard input" msgstr "läs revisionsargument frÃ¥n standard in" -#: builtin/pack-objects.c:2484 +#: builtin/pack-objects.c:2483 msgid "limit the objects to those that are not yet packed" msgstr "begränsa objekt till de som ännu inte packats" -#: builtin/pack-objects.c:2487 +#: builtin/pack-objects.c:2486 msgid "include objects reachable from any reference" msgstr "inkludera objekt som kan nÃ¥s frÃ¥n nÃ¥gon referens" -#: builtin/pack-objects.c:2490 +#: builtin/pack-objects.c:2489 msgid "include objects referred by reflog entries" msgstr "inkludera objekt som refereras frÃ¥n referensloggposter" -#: builtin/pack-objects.c:2493 +#: builtin/pack-objects.c:2492 msgid "output pack to stdout" msgstr "skriv paket pÃ¥ standard ut" -#: builtin/pack-objects.c:2495 +#: builtin/pack-objects.c:2494 msgid "include tag objects that refer to objects to be packed" msgstr "inkludera taggobjekt som refererar objekt som skall packas" -#: builtin/pack-objects.c:2497 +#: builtin/pack-objects.c:2496 msgid "keep unreachable objects" msgstr "behÃ¥ll onÃ¥bara objekt" -#: builtin/pack-objects.c:2498 parse-options.h:141 +#: builtin/pack-objects.c:2497 parse-options.h:141 msgid "time" msgstr "tid" -#: builtin/pack-objects.c:2499 +#: builtin/pack-objects.c:2498 msgid "unpack unreachable objects newer than <time>" msgstr "packa upp onÃ¥bara objekt nyare än <tid>" -#: builtin/pack-objects.c:2502 +#: builtin/pack-objects.c:2501 msgid "create thin packs" msgstr "skapa tunna paket" -#: builtin/pack-objects.c:2504 +#: builtin/pack-objects.c:2503 msgid "ignore packs that have companion .keep file" msgstr "ignorera paket som har tillhörande .keep-fil" -#: builtin/pack-objects.c:2506 +#: builtin/pack-objects.c:2505 msgid "pack compression level" msgstr "komprimeringsgrad för paket" -#: builtin/pack-objects.c:2508 +#: builtin/pack-objects.c:2507 msgid "do not hide commits by grafts" msgstr "göm inte incheckningar med ympningar (\"grafts\")" @@ -7066,7 +7104,7 @@ msgstr "git remote rename <gammal> <ny>" msgid "git remote remove <name>" msgstr "git remote remove <namn>" -#: builtin/remote.c:15 +#: builtin/remote.c:15 builtin/remote.c:42 msgid "git remote set-head <name> (-a | -d | <branch>)" msgstr "git remote set-head <namn> (-a | -d | <gren>)" @@ -7104,10 +7142,6 @@ msgstr "git remote set-url --delete <namn> <url>" msgid "git remote add [<options>] <name> <url>" msgstr "git remote add [<flaggor>] <namn> <url>" -#: builtin/remote.c:42 -msgid "git remote set-head <name> (-a | -d | <branch>])" -msgstr "git remote set-head <namn> (-a | -d | <gren>])" - #: builtin/remote.c:47 msgid "git remote set-branches <name> <branch>..." msgstr "git remote set-branches <namn> <gren>..." @@ -7556,15 +7590,15 @@ msgstr "git replace -d <objekt>..." msgid "git replace -l [<pattern>]" msgstr "git replace -l [<mönster>]" -#: builtin/replace.c:118 +#: builtin/replace.c:121 msgid "list replace refs" msgstr "visa ersättningsreferenser" -#: builtin/replace.c:119 +#: builtin/replace.c:122 msgid "delete replace refs" msgstr "ta bort ersättningsreferenser" -#: builtin/replace.c:120 +#: builtin/replace.c:123 msgid "replace the ref if it exists" msgstr "ersätt referensen om den finns" @@ -7810,11 +7844,21 @@ msgstr "\"revert\" misslyckades" msgid "cherry-pick failed" msgstr "\"cherry-pick\" misslyckades" -#: builtin/rm.c:14 +#: builtin/rm.c:15 msgid "git rm [options] [--] <file>..." msgstr "git rm [flaggor] [--] <fil>..." -#: builtin/rm.c:109 +#: builtin/rm.c:64 builtin/rm.c:186 +#, c-format +msgid "" +"submodule '%s' (or one of its nested submodules) uses a .git directory\n" +"(use 'rm -rf' if you really want to remove it including all of its history)" +msgstr "" +"undermodulen \"%s\" (eller en av dess undermoduler) använder en .git-" +"katalog\n" +"(använd \"rm -rf\" om du verkligen vill ta bort den och all dess historik)" + +#: builtin/rm.c:174 #, c-format msgid "" "'%s' has staged content different from both the file and the HEAD\n" @@ -7823,7 +7867,7 @@ msgstr "" "\"%s\" har köat ändringar som skiljer sig bÃ¥de frÃ¥n filen och HEAD\n" "(använd -f för att tvinga borttagning)" -#: builtin/rm.c:115 +#: builtin/rm.c:180 #, c-format msgid "" "'%s' has changes staged in the index\n" @@ -7832,7 +7876,7 @@ msgstr "" "\"%s\" har köade ändringar i indexet\n" "(använd --cached för att behÃ¥lla filen eller -f för att tvinga borttagning)" -#: builtin/rm.c:119 +#: builtin/rm.c:191 #, c-format msgid "" "'%s' has local modifications\n" @@ -7841,32 +7885,32 @@ msgstr "" "\"%s\" har lokala ändringar\n" "(använd --cached för att behÃ¥lla filen eller -f för att tvinga borttagning)" -#: builtin/rm.c:134 +#: builtin/rm.c:207 msgid "do not list removed files" msgstr "lista inte borttagna filer" -#: builtin/rm.c:135 +#: builtin/rm.c:208 msgid "only remove from the index" msgstr "ta bara bort frÃ¥n indexet" -#: builtin/rm.c:136 +#: builtin/rm.c:209 msgid "override the up-to-date check" msgstr "överstyr à jour-testet" -#: builtin/rm.c:137 +#: builtin/rm.c:210 msgid "allow recursive removal" msgstr "tillÃ¥t rekursiv borttagning" -#: builtin/rm.c:139 +#: builtin/rm.c:212 msgid "exit with a zero status even if nothing matched" msgstr "avsluta med nollstatus även om inget träffades" -#: builtin/rm.c:194 +#: builtin/rm.c:283 #, c-format msgid "not removing '%s' recursively without -r" msgstr "tar inte bort \"%s\" rekursivt utan -r" -#: builtin/rm.c:230 +#: builtin/rm.c:322 #, c-format msgid "git rm: unable to remove %s" msgstr "git rm: kan inte ta bort %s" @@ -7993,35 +8037,35 @@ msgstr "" msgid "git show-ref --exclude-existing[=pattern] < ref-list" msgstr "git show-ref --exclude-existing[=mönster] < reflista" -#: builtin/show-ref.c:182 +#: builtin/show-ref.c:165 msgid "only show tags (can be combined with heads)" msgstr "visa endast taggar (kan kombineras med huvuden)" -#: builtin/show-ref.c:183 +#: builtin/show-ref.c:166 msgid "only show heads (can be combined with tags)" msgstr "visa endast huvuden (kan kombineras med taggar)" -#: builtin/show-ref.c:184 +#: builtin/show-ref.c:167 msgid "stricter reference checking, requires exact ref path" msgstr "striktare referenskontroll, kräver exakt referenssökväg" -#: builtin/show-ref.c:187 builtin/show-ref.c:189 +#: builtin/show-ref.c:170 builtin/show-ref.c:172 msgid "show the HEAD reference" msgstr "visa HEAD-referensen" -#: builtin/show-ref.c:191 +#: builtin/show-ref.c:174 msgid "dereference tags into object IDs" msgstr "avreferera taggar till objekt-id" -#: builtin/show-ref.c:193 +#: builtin/show-ref.c:176 msgid "only show SHA1 hash using <n> digits" msgstr "visa SHA1-hash endast med <n> siffror" -#: builtin/show-ref.c:197 +#: builtin/show-ref.c:180 msgid "do not print results to stdout (useful with --verify)" msgstr "visa inte resultat pÃ¥ standard ut (användbart med --verify)" -#: builtin/show-ref.c:199 +#: builtin/show-ref.c:182 msgid "show refs from stdin that aren't in local repository" msgstr "visa referenser frÃ¥n standard in som inte finns i lokalt arkiv" @@ -8029,20 +8073,28 @@ msgstr "visa referenser frÃ¥n standard in som inte finns i lokalt arkiv" msgid "git symbolic-ref [options] name [ref]" msgstr "git symbolic-ref [flaggor] namn [ref]" -#: builtin/symbolic-ref.c:38 +#: builtin/symbolic-ref.c:8 +msgid "git symbolic-ref -d [-q] name" +msgstr "git symbolic-ref -d [-q] namn" + +#: builtin/symbolic-ref.c:40 msgid "suppress error message for non-symbolic (detached) refs" msgstr "" "undertryck felmeddelanden för icke-symboliska (frÃ¥nkopplade) referenser" -#: builtin/symbolic-ref.c:39 +#: builtin/symbolic-ref.c:41 +msgid "delete symbolic ref" +msgstr "ta bort symbolisk referens" + +#: builtin/symbolic-ref.c:42 msgid "shorten ref output" msgstr "förkorta ref-utdata" -#: builtin/symbolic-ref.c:40 builtin/update-ref.c:18 +#: builtin/symbolic-ref.c:43 builtin/update-ref.c:18 msgid "reason" msgstr "skäl" -#: builtin/symbolic-ref.c:40 builtin/update-ref.c:18 +#: builtin/symbolic-ref.c:43 builtin/update-ref.c:18 msgid "reason of the update" msgstr "skäl till uppdateringen" @@ -8266,111 +8318,111 @@ msgstr "Uppdaterad tagg \"%s\" (var %s)\n" msgid "git update-index [options] [--] [<file>...]" msgstr "git update-index [flaggor] [--] [<fil>...]" -#: builtin/update-index.c:717 +#: builtin/update-index.c:718 msgid "continue refresh even when index needs update" msgstr "fortsätt uppdatera även när index inte är à jour" -#: builtin/update-index.c:720 +#: builtin/update-index.c:721 msgid "refresh: ignore submodules" msgstr "refresh: ignorera undermoduler" -#: builtin/update-index.c:723 +#: builtin/update-index.c:724 msgid "do not ignore new files" msgstr "ignorera inte nya filer" -#: builtin/update-index.c:725 +#: builtin/update-index.c:726 msgid "let files replace directories and vice-versa" msgstr "lÃ¥t filer ersätta kataloger och omvänt" -#: builtin/update-index.c:727 +#: builtin/update-index.c:728 msgid "notice files missing from worktree" msgstr "lägg märke till filer som saknas i arbetskatalogen" -#: builtin/update-index.c:729 +#: builtin/update-index.c:730 msgid "refresh even if index contains unmerged entries" msgstr "uppdatera även om indexet innehÃ¥ller ej sammanslagna poster" -#: builtin/update-index.c:732 +#: builtin/update-index.c:733 msgid "refresh stat information" msgstr "uppdatera statusinformation" -#: builtin/update-index.c:736 +#: builtin/update-index.c:737 msgid "like --refresh, but ignore assume-unchanged setting" msgstr "som --refresh, men ignorera assume-unchanged-inställning" -#: builtin/update-index.c:740 +#: builtin/update-index.c:741 msgid "<mode> <object> <path>" msgstr "<läge> <objekt> <sökväg>" -#: builtin/update-index.c:741 +#: builtin/update-index.c:742 msgid "add the specified entry to the index" msgstr "lägg till angiven post i indexet" -#: builtin/update-index.c:745 +#: builtin/update-index.c:746 msgid "(+/-)x" msgstr "(+/-)x" -#: builtin/update-index.c:746 +#: builtin/update-index.c:747 msgid "override the executable bit of the listed files" msgstr "överstyr exekveringsbiten för angivna filer" -#: builtin/update-index.c:750 +#: builtin/update-index.c:751 msgid "mark files as \"not changing\"" msgstr "markera filer som \"ändras inte\"" -#: builtin/update-index.c:753 +#: builtin/update-index.c:754 msgid "clear assumed-unchanged bit" msgstr "rensa \"assume-unchanged\"-biten" -#: builtin/update-index.c:756 +#: builtin/update-index.c:757 msgid "mark files as \"index-only\"" msgstr "markera filer som \"endast index\"" -#: builtin/update-index.c:759 +#: builtin/update-index.c:760 msgid "clear skip-worktree bit" msgstr "töm \"skip-worktree\"-biten" -#: builtin/update-index.c:762 +#: builtin/update-index.c:763 msgid "add to index only; do not add content to object database" msgstr "lägg endast till indexet; lägg inte till innehÃ¥llet i objektdatabasen" -#: builtin/update-index.c:764 +#: builtin/update-index.c:765 msgid "remove named paths even if present in worktree" msgstr "ta bort namngivna sökvägar även om de finns i arbetskatalogen" -#: builtin/update-index.c:766 +#: builtin/update-index.c:767 msgid "with --stdin: input lines are terminated by null bytes" msgstr "med --stdin: indatarader termineras med null-byte" -#: builtin/update-index.c:768 +#: builtin/update-index.c:769 msgid "read list of paths to be updated from standard input" msgstr "läs lista över sökvägar att uppdatera frÃ¥n standard in" -#: builtin/update-index.c:772 +#: builtin/update-index.c:773 msgid "add entries from standard input to the index" msgstr "lägg poster frÃ¥n frÃ¥n standard in till indexet" -#: builtin/update-index.c:776 +#: builtin/update-index.c:777 msgid "repopulate stages #2 and #3 for the listed paths" msgstr "Ã¥terfyll etapp 2 och 3 frÃ¥n angivna sökvägar" -#: builtin/update-index.c:780 +#: builtin/update-index.c:781 msgid "only update entries that differ from HEAD" msgstr "uppdatera endast poster som skiljer sig frÃ¥n HEAD" -#: builtin/update-index.c:784 +#: builtin/update-index.c:785 msgid "ignore files missing from worktree" msgstr "ignorera filer som saknas i arbetskatalogen" -#: builtin/update-index.c:787 +#: builtin/update-index.c:788 msgid "report actions to standard output" msgstr "raportera Ã¥tgärder pÃ¥ standard ut" -#: builtin/update-index.c:789 +#: builtin/update-index.c:790 msgid "(for porcelains) forget saved unresolved conflicts" msgstr "(för porslin) glöm sparade olösta konflikter" -#: builtin/update-index.c:793 +#: builtin/update-index.c:794 msgid "write index in this format" msgstr "skriv index i detta format" @@ -8888,7 +8940,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:228 +#: git-pull.sh:229 #, sh-format msgid "" "Warning: fetch updated the current branch head.\n" @@ -8899,11 +8951,11 @@ msgstr "" "Varning: snabbspolar din arbetskatalog frÃ¥n\n" "Varning: incheckningen $orig_head." -#: git-pull.sh:253 +#: git-pull.sh:254 msgid "Cannot merge multiple branches into empty head" msgstr "Kan inte slÃ¥ ihop flera grenar i ett tomt huvud." -#: git-pull.sh:257 +#: git-pull.sh:258 msgid "Cannot rebase onto multiple branches" msgstr "Kan inte utföra en \"rebase\" ovanpÃ¥ flera grenar" @@ -9160,12 +9212,12 @@ 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:88 +#: git-submodule.sh:89 #, 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:167 +#: git-submodule.sh:168 #, sh-format msgid "No submodule mapping found in .gitmodules for path '$sm_path'" msgstr "" @@ -9181,17 +9233,17 @@ msgstr "Misslyckades klona \"$url\" till undermodulsökvägen \"$sm_path\"" 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:312 +#: git-submodule.sh:316 #, 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:329 +#: git-submodule.sh:333 #, sh-format msgid "'$sm_path' already exists in the index" msgstr "\"$sm_path\" finns redan i indexet" -#: git-submodule.sh:333 +#: git-submodule.sh:337 #, sh-format msgid "" "The following path is ignored by one of your .gitignore files:\n" @@ -9202,64 +9254,98 @@ msgstr "" "$sm_path\n" "Använd -f om du verkligen vill lägga till den" -#: git-submodule.sh:344 +#: git-submodule.sh:355 #, 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:346 +#: git-submodule.sh:357 #, 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:360 +#: git-submodule.sh:365 +#, 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:367 +#, sh-format +msgid "" +"If you want to reuse this local git directory instead of cloning again from" +msgstr "" +"För att Ã¥teranvända den lokala git-katalogen istället för att pÃ¥ nytt klona " +"frÃ¥n" + +#: git-submodule.sh:369 +#, 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:370 +#, sh-format +msgid "" +"or you are unsure what this means choose another name with the '--name' " +"option." +msgstr "" +"eller om du är osäker pÃ¥ vad det innebär, välj nytt namn med flaggan \"--name" +"\"." + +#: git-submodule.sh:372 +#, 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:384 #, sh-format msgid "Unable to checkout submodule '$sm_path'" msgstr "Kan inte checka ut undermodulen \"$sm_path\"" -#: git-submodule.sh:365 +#: git-submodule.sh:389 #, sh-format msgid "Failed to add submodule '$sm_path'" msgstr "Misslyckades lägga till undermodulen \"$sm_path\"" -#: git-submodule.sh:370 +#: git-submodule.sh:394 #, sh-format msgid "Failed to register submodule '$sm_path'" msgstr "Misslyckades registrera undermodulen \"$sm_path\"" -#: git-submodule.sh:413 +#: git-submodule.sh:437 #, sh-format msgid "Entering '$prefix$sm_path'" msgstr "GÃ¥r in i \"$prefix$sm_path\"" -#: git-submodule.sh:427 +#: git-submodule.sh:451 #, 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:471 +#: git-submodule.sh:495 #, 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:480 +#: git-submodule.sh:504 #, 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:482 +#: git-submodule.sh:506 #, 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:490 +#: git-submodule.sh:514 #, 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:590 +#: git-submodule.sh:614 #, sh-format msgid "" "Submodule path '$sm_path' not initialized\n" @@ -9268,92 +9354,95 @@ msgstr "" "Undermodulen \"$sm_path\" har inte initierats\n" "Kanske du vill köra \"update --init\"?" -#: git-submodule.sh:603 +#: git-submodule.sh:627 #, 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\"" -#: git-submodule.sh:622 +#: git-submodule.sh:646 #, 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:636 +#: git-submodule.sh:660 #, sh-format msgid "Unable to rebase '$sha1' in submodule path '$sm_path'" msgstr "Kan inte ombasera \"$sha1\" i undermodulsökväg \"$sm_path\"" -#: git-submodule.sh:637 +#: git-submodule.sh:661 #, sh-format msgid "Submodule path '$sm_path': rebased into '$sha1'" msgstr "Undermodulsökvägen \"$sm_path\": ombaserade in i \"$sha1\"" -#: git-submodule.sh:642 +#: git-submodule.sh:666 #, sh-format msgid "Unable to merge '$sha1' in submodule path '$sm_path'" msgstr "Kan inte slÃ¥ ihop \"$sha1\" i undermodulsökvägen \"$sm_path\"" -#: git-submodule.sh:643 +#: git-submodule.sh:667 #, sh-format msgid "Submodule path '$sm_path': merged in '$sha1'" msgstr "Undermodulsökvägen \"$sm_path\": sammanslagen i \"$sha1\"" -#: git-submodule.sh:648 +#: git-submodule.sh:672 #, sh-format msgid "Unable to checkout '$sha1' in submodule path '$sm_path'" msgstr "Kan inte checka ut \"$sha1\" i undermodulsökvägen \"$sm_path\"" -#: git-submodule.sh:649 +#: git-submodule.sh:673 #, sh-format msgid "Submodule path '$sm_path': checked out '$sha1'" msgstr "Undermodulsökvägen \"$sm_path\": checkade ut \"$sha1\"" -#: git-submodule.sh:671 git-submodule.sh:995 +#: git-submodule.sh:695 git-submodule.sh:1017 #, sh-format msgid "Failed to recurse into submodule path '$sm_path'" msgstr "Misslyckades rekursera in i undermodulsökvägen \"$sm_path\"" -#: git-submodule.sh:779 +#: git-submodule.sh:803 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:819 +#: git-submodule.sh:843 #, sh-format msgid "unexpected mode $mod_dst" msgstr "oväntat läge $mod_dst" -#: git-submodule.sh:837 +#: git-submodule.sh:861 #, sh-format msgid " Warn: $name doesn't contain commit $sha1_src" msgstr " Varning: $name innehÃ¥ller inte incheckning $sha1_src" -#: git-submodule.sh:840 +#: git-submodule.sh:864 #, sh-format msgid " Warn: $name doesn't contain commit $sha1_dst" msgstr " Varning: $name innehÃ¥ller inte incheckning $sha1_dst" -#: git-submodule.sh:843 +#: git-submodule.sh:867 #, 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:868 +#: git-submodule.sh:892 msgid "blob" msgstr "blob" -#: git-submodule.sh:906 +#: git-submodule.sh:930 msgid "# Submodules changed but not updated:" msgstr "# Undermoduler ändrade men inte uppdaterade:" -#: git-submodule.sh:908 +#: git-submodule.sh:932 msgid "# Submodule changes to be committed:" msgstr "# Undermodulers ändringar att checka in:" -#: git-submodule.sh:1054 +#: git-submodule.sh:1080 #, sh-format -msgid "Synchronizing submodule url for '$name'" -msgstr "Synkroniserar undermodul-url för \"$name\"" +msgid "Synchronizing submodule url for '$prefix$sm_path'" +msgstr "Synkroniserar undermodul-url för \"$prefix$sm_path\"" + +#~ msgid "git remote set-head <name> (-a | -d | <branch>])" +#~ msgstr "git remote set-head <namn> (-a | -d | <gren>])" #~ msgid " 0 files changed" #~ msgstr " 0 filer ändrade" @@ -6,10 +6,10 @@ # msgid "" msgstr "" -"Project-Id-Version: git-v1.8.0-rc2-4-g42e55\n" +"Project-Id-Version: git-v1.8.0.1-347-gf94c3\n" "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n" -"POT-Creation-Date: 2012-10-16 08:38+0800\n" -"PO-Revision-Date: 2012-10-17 08:09+0700\n" +"POT-Creation-Date: 2012-11-30 12:40+0800\n" +"PO-Revision-Date: 2012-11-30 13:40+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" @@ -37,9 +37,9 @@ msgid "" "or use 'git commit -a'." msgstr "" "Sá»a chúng trong cây là m việc,\n" -"và sau đó dùng lệnh `git add/rm <táºp-tin>'\n" -"dà nh riêng cho việc đánh dấu cần giải quyết và tạo lần chuyển giao,\n" -"hoặc là dùng lệnh `git commit -a'." +"và sau đó dùng lệnh “git add/rm <táºp-tin>†dà nh riêng\n" +"cho việc đánh dấu táºp tin cần giải quyết và tạo lần chuyển giao,\n" +"hoặc là dùng lệnh “git commit -aâ€." #: archive.c:10 msgid "git archive [options] <tree-ish> [<path>...]" @@ -68,7 +68,7 @@ msgstr "fmt" msgid "archive format" msgstr "định dạng lÆ°u trữ" -#: archive.c:323 builtin/log.c:1079 +#: archive.c:323 builtin/log.c:1084 msgid "prefix" msgstr "tiá»n tố" @@ -76,9 +76,9 @@ msgstr "tiá»n tố" msgid "prepend prefix to each pathname in the archive" msgstr "nối thêm tiá»n tố và o từng Ä‘Æ°á»ng dẫn táºp tin trong kho lÆ°u" -#: archive.c:325 builtin/archive.c:91 builtin/blame.c:2389 -#: builtin/blame.c:2390 builtin/config.c:56 builtin/fast-export.c:642 -#: builtin/fast-export.c:644 builtin/grep.c:801 builtin/hash-object.c:77 +#: archive.c:325 builtin/archive.c:91 builtin/blame.c:2390 +#: builtin/blame.c:2391 builtin/config.c:55 builtin/fast-export.c:642 +#: builtin/fast-export.c:644 builtin/grep.c:715 builtin/hash-object.c:77 #: builtin/ls-files.c:494 builtin/ls-files.c:497 builtin/notes.c:540 #: builtin/notes.c:697 builtin/read-tree.c:107 parse-options.h:149 msgid "file" @@ -98,7 +98,7 @@ msgstr "liệt kê các táºp tin được lÆ°u trữ và o stderr (đầu ra lá» #: archive.c:330 msgid "store only" -msgstr "chỉ lÆ°u" +msgstr "chỉ lÆ°u (không nén)" #: archive.c:331 msgid "compress faster" @@ -110,7 +110,7 @@ msgstr "nén nhá» hÆ¡n" #: archive.c:342 msgid "list supported archive formats" -msgstr "liệt kê các kiểu né được há»— trợ" +msgstr "liệt kê các kiểu nén được há»— trợ" #: archive.c:344 builtin/archive.c:93 builtin/clone.c:85 msgid "repo" @@ -128,30 +128,38 @@ msgstr "lệnh" msgid "path to the remote git-upload-archive command" msgstr "Ä‘Æ°á»ng dẫn đến lệnh git-upload-pack trên máy chủ" +#: attr.c:259 +msgid "" +"Negative patterns are forbidden in git attributes\n" +"Use '\\!' for literal leading exclamation." +msgstr "" +"Mấu dạng phủ định bị cấm chỉ dùng trong 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." + #: bundle.c:36 #, c-format msgid "'%s' does not look like a v2 bundle file" -msgstr "`%s' không giống nhÆ° táºp tin v2 bundle (cụm)" +msgstr "“%s†không giống nhÆ° táºp tin v2 bundle (định dạng dump của git)" #: bundle.c:63 #, c-format 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:672 +#: bundle.c:89 builtin/commit.c:674 #, c-format msgid "could not open '%s'" -msgstr "không thể mở `%s'" +msgstr "không thể mở “%sâ€" #: bundle.c:140 msgid "Repository lacks these prerequisite commits:" msgstr "Khó 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:562 sequencer.c:994 builtin/log.c:290 -#: builtin/log.c:727 builtin/log.c:1313 builtin/log.c:1529 builtin/merge.c:347 +#: builtin/log.c:732 builtin/log.c:1319 builtin/log.c:1535 builtin/merge.c:347 #: builtin/shortlog.c:181 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" +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 @@ -173,9 +181,9 @@ 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 bị chết" +msgstr "rev-list đã chết" -#: bundle.c:300 builtin/log.c:1209 builtin/shortlog.c:284 +#: bundle.c:300 builtin/log.c:1215 builtin/shortlog.c:284 #, c-format msgid "unrecognized argument: %s" msgstr "đối số không được thừa nháºn: %s" @@ -183,7 +191,7 @@ msgstr "đối số không được thừa nháºn: %s" #: bundle.c:335 #, c-format msgid "ref '%s' is excluded by the rev-list options" -msgstr "tham chiếu `%s' bị loại trừ bởi các tùy chá»n rev-list" +msgstr "th.chiếu “%s†bị loại trừ bởi các tùy chá»n rev-list" #: bundle.c:380 msgid "Refusing to create empty bundle." @@ -200,7 +208,7 @@ msgstr "pack-objects đã chết" #: bundle.c:419 #, c-format msgid "cannot create '%s'" -msgstr "không thể tạo `%s'" +msgstr "không thể tạo “%sâ€" #: bundle.c:441 msgid "index-pack died" @@ -218,11 +226,11 @@ msgstr "%s %s không phải là má»™t lần commit!" #: compat/obstack.c:406 compat/obstack.c:408 msgid "memory exhausted" -msgstr "cạn bá»™ nhá»›" +msgstr "hết bá»™ nhá»›" #: connected.c:39 msgid "Could not run 'git rev-list'" -msgstr "Không thể chạy `git rev-list'" +msgstr "Không thể chạy “git rev-listâ€" #: connected.c:48 #, c-format @@ -301,26 +309,31 @@ msgid_plural "%lu years ago" msgstr[0] "%lu năm trÆ°á»›c" msgstr[1] "%lu năm trÆ°á»›c" -#: diff.c:105 +#: diff.c:111 +#, c-format +msgid " Failed to parse dirstat cut-off percentage '%s'\n" +msgstr " Gặp lá»—i khi phân tÃch dirstat cắt bá» phần trăm '%s'\n" + +#: diff.c:116 #, c-format -msgid " Failed to parse dirstat cut-off percentage '%.*s'\n" -msgstr " Gặp lá»—i khi phân tÃch dirstat cắt bá» phần trăm `%.*s'\n" +msgid " Unknown dirstat parameter '%s'\n" +msgstr " Không hiểu đối số dirstat '%s'\n" -#: diff.c:110 +#: diff.c:194 #, c-format -msgid " Unknown dirstat parameter '%.*s'\n" -msgstr " Không hiểu đối số dirstat `%.*s'\n" +msgid "Unknown value for 'diff.submodule' config variable: '%s'" +msgstr "Không hiểu giá trị cho biến cấu hình “diff.submoduleâ€: `%s'" -#: diff.c:210 +#: diff.c:237 #, c-format msgid "" "Found errors in 'diff.dirstat' config variable:\n" "%s" msgstr "" -"Tìm thấy các lá»—i trong biến cấu hình 'diff.dirstat':\n" +"Tìm thấy các lá»—i trong biến cấu hình “diff.dirstatâ€:\n" "%s" -#: diff.c:3458 +#: diff.c:3494 #, c-format msgid "" "Failed to parse --dirstat/-X option parameter:\n" @@ -329,6 +342,11 @@ msgstr "" "Gặp lá»—i khi phân tÃch đối số tùy chá»n --dirstat/-X:\n" "%s" +#: diff.c:3508 +#, 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 msgid "could not run gpg." msgstr "không thể chạy gpg." @@ -341,25 +359,25 @@ msgstr "gpg đã không đồng ý dữ liệu" msgid "gpg failed to sign the data" msgstr "gpg gặp lá»—i khi ký dữ liệu" -#: grep.c:1441 +#: grep.c:1622 #, c-format msgid "'%s': unable to read %s" -msgstr "`%s': không thể Ä‘á»c %s" +msgstr "“%sâ€: không thể Ä‘á»c %s" -#: grep.c:1458 +#: grep.c:1639 #, c-format msgid "'%s': %s" -msgstr "`%s': %s" +msgstr "“%sâ€: %s" -#: grep.c:1469 +#: grep.c:1650 #, c-format msgid "'%s': short read %s" -msgstr "`%s': Ä‘á»c ngắn %s" +msgstr "“%sâ€: Ä‘á»c ngắn %s" #: help.c:212 #, c-format msgid "available git commands in '%s'" -msgstr "các lệnh git sẵn sà ng để dùng trong `%s'" +msgstr "các lệnh git sẵn sà ng để dùng trong “%sâ€" #: help.c:219 msgid "git commands available from elsewhere on your $PATH" @@ -371,7 +389,7 @@ msgid "" "'%s' appears to be a git command, but we were not\n" "able to execute it. Maybe git-%s is broken?" msgstr "" -"`%s' trông nhÆ° là má»™t lệnh git, nhÆ°ng chúng tôi không\n" +"“%s†trông nhÆ° là má»™t lệnh git, nhÆ°ng chúng tôi không\n" "thể thá»±c thi nó. Có lẽ là lệnh git-%s đã bị há»ng?" #: help.c:332 @@ -384,8 +402,8 @@ msgid "" "WARNING: You called a Git command named '%s', which does not exist.\n" "Continuing under the assumption that you meant '%s'" msgstr "" -"CẢNH BÃO: Bạn đã gá»i lệnh Git có tên `%s', mà nó lại không có sẵn.\n" -"Giả định rằng ý bạn là `%s'" +"CẢNH BÃO: Bạn đã gá»i lệnh Git có tên “%sâ€, mà nó lại không có sẵn.\n" +"Giả định rằng ý bạn là “%sâ€" #: help.c:359 #, c-format @@ -395,7 +413,7 @@ msgstr "trong %0.1f giây má»™t cách tá»± Ä‘á»™ng..." #: help.c:366 #, c-format msgid "git: '%s' is not a git command. See 'git --help'." -msgstr "git: `%s' không phải là má»™t lệnh của git. Xem `git --help'." +msgstr "git: “%s†không phải là má»™t lệnh của git. Xem “git --helpâ€." #: help.c:370 msgid "" @@ -411,6 +429,15 @@ msgstr[1] "" "\n" "Có phải ý bạn là má»™t trong số những cái nà y không?" +#: merge.c:56 +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 +msgid "unable to write new index file" +msgstr "không thể ghi táºp tin lÆ°u bảng mục lục má»›i" + #: merge-recursive.c:190 #, c-format msgid "(bad commit)\n" @@ -419,7 +446,7 @@ msgstr "(commit sai)\n" #: merge-recursive.c:206 #, c-format msgid "addinfo_cache failed for path '%s'" -msgstr "addinfo_cache gặp lá»—i đối vá»›i Ä‘Æ°á»ng dẫn `%s'" +msgstr "addinfo_cache gặp lá»—i đối vá»›i Ä‘Æ°á»ng dẫn “%sâ€" #: merge-recursive.c:268 msgid "error building trees" @@ -428,7 +455,7 @@ msgstr "gặp lá»—i khi xây dá»±ng cây" #: merge-recursive.c:672 #, c-format msgid "failed to create path '%s'%s" -msgstr "gặp lá»—i khi tạo Ä‘Æ°á»ng dẫn `%s'%s" +msgstr "gặp lá»—i khi tạo Ä‘Æ°á»ng dẫn “%sâ€%s" #: merge-recursive.c:683 #, c-format @@ -444,32 +471,32 @@ msgstr ": có lẽ là má»™t xung Ä‘á»™t D/F?" #: merge-recursive.c:708 #, c-format msgid "refusing to lose untracked file at '%s'" -msgstr "từ chối đóng táºp tin không được theo vết tại `%s'" +msgstr "từ chối đóng táºp tin không được theo vết tại “%sâ€" #: merge-recursive.c:748 #, c-format msgid "cannot read object %s '%s'" -msgstr "không thể Ä‘á»c đối tượng %s `%s'" +msgstr "không thể Ä‘á»c đối tượng %s “%sâ€" #: merge-recursive.c:750 #, c-format msgid "blob expected for %s '%s'" -msgstr "đối tượng blob được mong đợi cho %s `%s'" +msgstr "đối tượng blob được mong đợi cho %s “%sâ€" #: merge-recursive.c:773 builtin/clone.c:302 #, c-format msgid "failed to open '%s'" -msgstr "gặp lá»—i khi mở `%s'" +msgstr "gặp lá»—i khi mở “%sâ€" #: merge-recursive.c:781 #, c-format msgid "failed to symlink '%s'" -msgstr "gặp lá»—i khi tạo liên kết tượng trÆ°ng (symlink) `%s'" +msgstr "gặp lá»—i khi tạo liên kết tượng trÆ°ng (symlink) “%sâ€" #: merge-recursive.c:784 #, c-format msgid "do not know what to do with %06o %s '%s'" -msgstr "không hiểu phải là m gì vá»›i %06o %s `%s'" +msgstr "không hiểu phải là m gì vá»›i %06o %s “%sâ€" #: merge-recursive.c:922 msgid "Failed to execute internal merge" @@ -591,7 +618,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:869 +#: merge-recursive.c:1633 git-submodule.sh:893 msgid "submodule" msgstr "mô-Ä‘un-con" @@ -661,9 +688,9 @@ msgstr "hòa trá»™n không trả vá» lần chuyển giao (commit) nà o" #: merge-recursive.c:1997 #, c-format msgid "Could not parse object '%s'" -msgstr "Không thể phân tÃch đối tượng `%s'" +msgstr "Không thể phân tÃch đối tượng “%sâ€" -#: merge-recursive.c:2009 builtin/merge.c:696 +#: merge-recursive.c:2009 builtin/merge.c:643 msgid "Unable to write index." msgstr "Không thể ghi bảng mục lục" @@ -692,22 +719,30 @@ msgstr " %s" #, 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" +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:1637 +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:1638 +#: remote.c:1640 #, c-format msgid "Your branch is behind '%s' by %d commit, and can be fast-forwarded.\n" msgid_plural "" "Your branch is behind '%s' by %d commits, and can be fast-forwarded.\n" msgstr[0] "" -"Nhánh của bạn thì ở đằng sau `%s' bởi %d lần chuyển giao (commit), và có thể " +"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" msgstr[1] "" -"Nhánh của bạn thì ở đằng sau `%s' bởi %d lần chuyển giao (commit), và có thể " +"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:1646 +#: remote.c:1647 +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:1650 #, c-format msgid "" "Your branch and '%s' have diverged,\n" @@ -716,24 +751,30 @@ msgid_plural "" "Your branch and '%s' have diverged,\n" "and have %d and %d different commits each, respectively.\n" msgstr[0] "" -"Nhánh của bạn và `%s' bị phân kỳ,\n" +"Nhánh của bạn và “%s†bị phân kỳ,\n" "và có %d và %d lần chuyển giao (commit) khác nhau cho từng cái,\n" "tÆ°Æ¡ng ứng vá»›i má»—i lần.\n" msgstr[1] "" -"Your branch and `%s' have diverged,\n" +"Your branch and “%s†have diverged,\n" "and have %d and %d different commit each, respectively.\n" -#: sequencer.c:123 builtin/merge.c:864 builtin/merge.c:977 -#: builtin/merge.c:1087 builtin/merge.c:1097 +#: remote.c:1659 +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 #, c-format msgid "Could not open '%s' for writing" -msgstr "Không thể mở %s' để ghi" +msgstr "Không thể mở “%s†để ghi" -#: sequencer.c:125 builtin/merge.c:333 builtin/merge.c:867 -#: builtin/merge.c:1089 builtin/merge.c:1102 +#: sequencer.c:125 builtin/merge.c:333 builtin/merge.c:764 builtin/merge.c:986 +#: builtin/merge.c:999 #, c-format msgid "Could not write to '%s'" -msgstr "Không thể ghi và o `%s'" +msgstr "Không thể ghi và o “%sâ€" #: sequencer.c:146 msgid "" @@ -741,7 +782,7 @@ msgid "" "with 'git add <paths>' or 'git rm <paths>'" 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>'" +"vá»›i lệnh “git add <Ä‘Æ°á»ng_dẫn>†hoặc “git rm <Ä‘Æ°á»ng_dẫn>â€" #: sequencer.c:149 msgid "" @@ -750,8 +791,8 @@ msgid "" "and commit the result with 'git commit'" 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>'\n" -"và chuyển giao (commit) kết quả bằng lệnh `git commit'" +"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:770 sequencer.c:853 #, c-format @@ -953,7 +994,7 @@ msgstr "kết thúc táºp tin Ä‘á»™t xuất" #: sequencer.c:827 #, 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" +msgstr "táºp tin HEAD “pre-cherry-pick†đã lÆ°u “%s†bị há»ng" #: sequencer.c:850 #, c-format @@ -975,24 +1016,24 @@ msgstr "HEAD không chỉ đến má»™t nhánh nà o cả" #: sha1_name.c:1047 #, c-format msgid "No such branch: '%s'" -msgstr "Không có nhánh nà o nhÆ° thế: `%s'" +msgstr "Không có nhánh nà o nhÆ° thế: “%sâ€" #: sha1_name.c:1049 #, 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'" +msgstr "Không có thượng nguồn (upstream) được cấu hình cho nhánh “%sâ€" #: sha1_name.c:1052 #, c-format msgid "Upstream branch '%s' not stored as a remote-tracking branch" msgstr "" -"Nhánh thượng nguồn (upstream) `%s' không được lÆ°u lại nhÆ° là má»™t nhánh " -"'remote-tracking'" +"Nhánh thượng nguồn (upstream) “%s†không được lÆ°u lại nhÆ° là má»™t nhánh " +"“remote-trackingâ€" #: wrapper.c:408 #, c-format msgid "unable to access '%s': %s" -msgstr "không thể truy cáºp `%s': %s" +msgstr "không thể truy cáºp “%sâ€: %s" #: wrapper.c:426 #, c-format @@ -1177,7 +1218,7 @@ msgstr " (dùng \"git commit\" để hoà n tất việc hòa trá»™n)" #: wt-status.c:804 msgid "You are in the middle of an am session." -msgstr "Bạn Ä‘ang ở giữa của má»™t phiên 'am'." +msgstr "Bạn Ä‘ang ở giữa của má»™t phiên “amâ€." #: wt-status.c:807 msgid "The current patch is empty." @@ -1379,34 +1420,34 @@ msgstr "git add [các-tùy-chá»n] [--] <mẫu-táºp-tin>..." msgid "unexpected diff status %c" msgstr "trạng thái lệnh diff không nhÆ° mong đợi %c" -#: builtin/add.c:67 builtin/commit.c:230 +#: builtin/add.c:67 builtin/commit.c:231 msgid "updating files failed" msgstr "Cáºp nháºt táºp tin gặp lá»—i" #: builtin/add.c:77 #, c-format msgid "remove '%s'\n" -msgstr "gỡ bá» `%s'\n" +msgstr "gỡ bỠ“%sâ€\n" #: builtin/add.c:176 #, c-format msgid "Path '%s' is in submodule '%.*s'" -msgstr "ÄÆ°á»ng dẫn `%s' thì ở trong mô-Ä‘un-con `%.*s'" +msgstr "ÄÆ°á»ng dẫn “%s†thì ở trong mô-Ä‘un-con “%.*sâ€" #: builtin/add.c:192 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:195 builtin/add.c:460 builtin/rm.c:186 +#: builtin/add.c:195 builtin/add.c:460 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" +msgstr "pathspec “%s†không khá»›p vá»›i bất kỳ táºp tin nà o" #: builtin/add.c:209 #, c-format msgid "'%s' is beyond a symbolic link" -msgstr "`%s' nằm ngoà i má»™t liên kết tượng trÆ°ng" +msgstr "“%s†nằm ngoà i má»™t liên kết tượng trÆ°ng" #: builtin/add.c:276 msgid "Could not read the index" @@ -1415,7 +1456,7 @@ msgstr "Không thể Ä‘á»c bảng mục lục" #: builtin/add.c:286 #, c-format msgid "Could not open '%s' for writing." -msgstr "Không thể mở `%s' để ghi" +msgstr "Không thể mở “%s†để ghi" #: builtin/add.c:290 msgid "Could not write patch" @@ -1424,7 +1465,7 @@ msgstr "Không thể ghi ra miếng vá" #: builtin/add.c:295 #, c-format msgid "Could not stat '%s'" -msgstr "không thể lấy trạng thái vá» `%s'" +msgstr "không thể lấy trạng thái vỠ“%sâ€" #: builtin/add.c:297 msgid "Empty patch. Aborted." @@ -1433,7 +1474,7 @@ msgstr "Miếng vá trống rá»—ng. Äã bá» qua." #: builtin/add.c:303 #, c-format msgid "Could not apply '%s'" -msgstr "Không thể apply (áp dụng miếng vá) `%s'" +msgstr "Không thể apply (áp dụng miếng vá) “%sâ€" #: builtin/add.c:313 msgid "The following paths are ignored by one of your .gitignore files:\n" @@ -1443,12 +1484,12 @@ msgstr "" #: builtin/add.c:319 builtin/clean.c:52 builtin/fetch.c:78 builtin/mv.c:63 #: builtin/prune-packed.c:76 builtin/push.c:388 builtin/remote.c:1253 -#: builtin/rm.c:133 +#: builtin/rm.c:206 msgid "dry run" msgstr "chạy thá»" -#: builtin/add.c:320 builtin/apply.c:4354 builtin/commit.c:1154 -#: builtin/count-objects.c:82 builtin/fsck.c:613 builtin/log.c:1477 +#: builtin/add.c:320 builtin/apply.c:4354 builtin/commit.c:1160 +#: builtin/count-objects.c:82 builtin/fsck.c:613 builtin/log.c:1483 #: builtin/mv.c:62 builtin/read-tree.c:112 msgid "be verbose" msgstr "chi tiết" @@ -1457,9 +1498,9 @@ msgstr "chi tiết" msgid "interactive picking" msgstr "sá»a bằng cách tÆ°Æ¡ng tác" -#: builtin/add.c:323 builtin/checkout.c:1028 builtin/reset.c:248 +#: builtin/add.c:323 builtin/checkout.c:1031 builtin/reset.c:248 msgid "select hunks interactively" -msgstr "chá»n `hunks' má»™t cách tÆ°Æ¡ng tác" +msgstr "chá»n “hunks†má»™t cách tÆ°Æ¡ng tác" #: builtin/add.c:324 msgid "edit current diff and apply" @@ -1525,14 +1566,14 @@ msgstr "Không có gì được chỉ ra, không có gì được thêm và o.\n" #: builtin/add.c:415 #, 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" +msgstr "Có lẽ bạn muốn là “git add .†phải không?\n" -#: builtin/add.c:421 builtin/clean.c:95 builtin/commit.c:290 builtin/mv.c:82 -#: builtin/rm.c:162 +#: builtin/add.c:421 builtin/clean.c:95 builtin/commit.c:291 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:4450 builtin/mv.c:229 builtin/rm.c:260 +#: builtin/add.c:481 builtin/apply.c:4450 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" @@ -1543,12 +1584,12 @@ msgstr "git apply [các-tùy-chá»n] [<miếng-vá>...]" #: builtin/apply.c:110 #, c-format msgid "unrecognized whitespace option '%s'" -msgstr "không nháºn ra tùy chá»n vá» khoảng trắng `%s'" +msgstr "không nháºn ra tùy chá»n vá» khoảng trắng “%sâ€" #: builtin/apply.c:125 #, c-format msgid "unrecognized whitespace ignore option '%s'" -msgstr "không nháºn ra tùy chá»n bá» qua khoảng trắng `%s'" +msgstr "không nháºn ra tùy chá»n bá» qua khoảng trắng “%sâ€" #: builtin/apply.c:823 #, c-format @@ -1654,7 +1695,7 @@ msgstr "miếng vá định dạng nhị phân không được nháºn ra tại d #: builtin/apply.c:1984 #, c-format msgid "patch with only garbage at line %d" -msgstr "vá chỉ vá»›i 'garbage' tại dòng %d" +msgstr "vá chỉ vá»›i “garbage†tại dòng %d" #: builtin/apply.c:2074 #, c-format @@ -1673,7 +1714,7 @@ msgstr "ôi?" #: builtin/apply.c:2671 #, c-format msgid "invalid start of line: '%c'" -msgstr "sai khởi đầu dòng: `%c'" +msgstr "sai khởi đầu dòng: “%câ€" #: builtin/apply.c:2789 #, c-format @@ -1699,18 +1740,18 @@ msgstr "" #: builtin/apply.c:2826 #, 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'" +msgstr "thiếu dữ liệu của miếng vá định dạng nhị phân cho “%sâ€" #: builtin/apply.c:2929 #, 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'" +msgstr "miếng vá định dạng nhị phân không được áp dụng cho “%sâ€" #: builtin/apply.c:2935 #, 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 " +"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:2956 @@ -1795,7 +1836,7 @@ msgstr "Äang kiểm tra miếng vá %s..." #: builtin/apply.c:3624 builtin/checkout.c:215 builtin/reset.c:158 #, 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'" +msgstr "make_cache_entry gặp lá»—i đối vá»›i Ä‘Æ°á»ng dẫn “%sâ€" #: builtin/apply.c:3767 #, c-format @@ -1815,7 +1856,7 @@ msgstr "không thể lấy trạng thái vá» táºp tin %s má»›i hÆ¡n đã Ä‘Æ°á #: builtin/apply.c:3804 #, 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" +msgstr "không thể tạo “backing store†cho táºp tin được tạo má»›i hÆ¡n %s" #: builtin/apply.c:3807 builtin/apply.c:3915 #, c-format @@ -1825,12 +1866,12 @@ msgstr "không thể thêm mục nhá»› tạm cho %s" #: builtin/apply.c:3840 #, c-format msgid "closing file '%s'" -msgstr "Ä‘ang đóng táºp tin `%s'" +msgstr "Ä‘ang đóng táºp tin “%sâ€" #: builtin/apply.c:3889 #, c-format msgid "unable to write file '%s' mode %o" -msgstr "không thể ghi và o táºp tin `%s' chế Ä‘á»™ (mode) %o" +msgstr "không thể ghi và o táºp tin “%s†chế Ä‘á»™ (mode) %o" #: builtin/apply.c:3976 #, c-format @@ -2005,7 +2046,7 @@ msgstr "--cached ở ngoà i má»™t kho chứa" #: builtin/apply.c:4411 #, c-format msgid "can't open patch '%s'" -msgstr "không thể mở miếng vá `%s'" +msgstr "không thể mở miếng vá “%sâ€" #: builtin/apply.c:4425 #, c-format @@ -2024,7 +2065,7 @@ msgstr[1] "%d dòng thêm khoảng trắng lá»—i." #: builtin/archive.c:17 #, c-format msgid "could not create archive file '%s'" -msgstr "không thể tạo táºp tin kho (lÆ°u trữ, nén) `%s'" +msgstr "không thể tạo táºp tin kho (lÆ°u trữ, nén) “%sâ€" #: builtin/archive.c:20 msgid "could not redirect output" @@ -2062,7 +2103,7 @@ msgstr "git bisect--helper --next-all [--no-checkout]" #: builtin/bisect--helper.c:17 msgid "perform 'git bisect next'" -msgstr "thá»±c hiện `git bisect next'" +msgstr "thá»±c hiện “git bisect nextâ€" #: builtin/bisect--helper.c:19 msgid "update BISECT_HEAD instead of checking out the current commit" @@ -2078,97 +2119,97 @@ msgstr "git blame [các-tùy-chá»n] [rev-opts] [rev] [--] táºp-tin" msgid "[rev-opts] are documented in git-rev-list(1)" msgstr "[rev-opts] được mô tả trong git-rev-list(1)" -#: builtin/blame.c:2373 +#: builtin/blame.c:2374 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" +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:2374 +#: builtin/blame.c:2375 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)" +"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:2375 +#: builtin/blame.c:2376 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:2376 +#: builtin/blame.c:2377 msgid "Show work cost statistics" msgstr "Hiển thị thống kê công sức là m việc" -#: builtin/blame.c:2377 +#: builtin/blame.c:2378 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'" +msgstr "Hiển thị kết xuất Ä‘iểm số có các mục tin “blameâ€" -#: builtin/blame.c:2378 +#: builtin/blame.c:2379 msgid "Show original filename (Default: auto)" msgstr "Hiển thị tên táºp tin gốc (Mặc định: auto)" -#: builtin/blame.c:2379 +#: builtin/blame.c:2380 msgid "Show original linenumber (Default: off)" msgstr "Hiển thị số dòng gốc (Mặc định: off)" -#: builtin/blame.c:2380 +#: builtin/blame.c:2381 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:2381 +#: builtin/blame.c:2382 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" +msgstr "Hiển thị định dạng “porcelain†vá»›i thông tin chuyển giao má»—i dòng" -#: builtin/blame.c:2382 +#: builtin/blame.c:2383 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:2383 +#: builtin/blame.c:2384 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:2384 +#: builtin/blame.c:2385 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:2385 +#: builtin/blame.c:2386 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:2386 +#: builtin/blame.c:2387 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:2387 +#: builtin/blame.c:2388 msgid "Ignore whitespace differences" msgstr "Bá» qua các khác biệt do khoảng trắng gây ra" -#: builtin/blame.c:2388 +#: builtin/blame.c:2389 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:2389 +#: builtin/blame.c:2390 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'" +"Sá» dụng Ä‘iểm xét duyệt (revision) từ <táºp tin> thay vì gá»i “git-rev-listâ€" -#: builtin/blame.c:2390 +#: builtin/blame.c:2391 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:2391 builtin/blame.c:2392 +#: builtin/blame.c:2392 builtin/blame.c:2393 msgid "score" msgstr "Ä‘iểm số" -#: builtin/blame.c:2391 +#: builtin/blame.c:2392 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:2392 +#: builtin/blame.c:2393 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:2393 +#: builtin/blame.c:2394 msgid "n,m" msgstr "n,m" -#: builtin/blame.c:2393 +#: builtin/blame.c:2394 msgid "Process only line range n,m, counting from 1" msgstr "Xá» lý chỉ dòng vùng n,m, tÃnh từ 1" @@ -2194,8 +2235,8 @@ msgid "" "deleting branch '%s' that has been merged to\n" " '%s', but not yet merged to HEAD." 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." +"Ä‘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 #, c-format @@ -2203,269 +2244,269 @@ msgid "" "not deleting branch '%s' that is not yet merged to\n" " '%s', even though it is merged to HEAD." msgstr "" -"không xóa nhánh `%s' cái mà chÆ°a được hòa trá»™ng và o\n" -" `%s', cho dù là nó đã được hòa trá»™n và o HEAD." +"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 +#, 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 +#, 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 "" +"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:181 +#: builtin/branch.c:180 +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 msgid "cannot use -a with -d" msgstr "không thể dùng tùy chá»n -a vá»›i -d" -#: builtin/branch.c:187 +#: builtin/branch.c:214 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:192 +#: builtin/branch.c:222 #, 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 ở." +msgstr "Không thể xóa nhánh “%s†cái mà bạn hiện nay Ä‘ang ở." -#: builtin/branch.c:203 +#: builtin/branch.c:235 #, c-format msgid "remote branch '%s' not found." -msgstr "không tìm thấy nhánh máy chủ `%s'." +msgstr "không tìm thấy nhánh máy chủ “%sâ€." -#: builtin/branch.c:204 +#: builtin/branch.c:236 #, c-format msgid "branch '%s' not found." -msgstr "không tìm thấy nhánh `%s'." +msgstr "không tìm thấy nhánh “%sâ€." -#: builtin/branch.c:211 -#, 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:217 -#, 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 "" -"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:226 +#: builtin/branch.c:250 #, c-format msgid "Error deleting remote branch '%s'" -msgstr "Gặp lá»—i khi Ä‘ang xóa nhánh máy chủ `%s'" +msgstr "Gặp lá»—i khi Ä‘ang xóa nhánh máy chủ “%sâ€" -#: builtin/branch.c:227 +#: builtin/branch.c:251 #, c-format msgid "Error deleting branch '%s'" -msgstr "Lá»—i khi xoá bá» nhánh `%s'" +msgstr "Lá»—i khi xoá bá» nhánh “%sâ€" -#: builtin/branch.c:234 +#: builtin/branch.c:258 #, c-format msgid "Deleted remote branch %s (was %s).\n" msgstr "Nhánh máy chủ \"%s\" đã bị xóa (từng là %s).\n" -#: builtin/branch.c:235 +#: builtin/branch.c:259 #, c-format msgid "Deleted branch %s (was %s).\n" -msgstr "Nhánh `%s' đã bị xóa (từng là %s)\n" +msgstr "Nhánh “%s†đã bị xóa (từng là %s)\n" -#: builtin/branch.c:240 -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:338 +#: builtin/branch.c:361 #, 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ả" +msgstr "nhánh “%s†không chỉ đến má»™t lần chuyển giao (commit) nà o cả" -#: builtin/branch.c:410 +#: builtin/branch.c:433 #, c-format msgid "[%s: behind %d]" msgstr "[%s: đằng sau %d]" -#: builtin/branch.c:412 +#: builtin/branch.c:435 #, c-format msgid "[behind %d]" msgstr "[đằng sau %d]" -#: builtin/branch.c:416 +#: builtin/branch.c:439 #, c-format msgid "[%s: ahead %d]" msgstr "[%s: phÃa trÆ°á»›c %d]" -#: builtin/branch.c:418 +#: builtin/branch.c:441 #, c-format msgid "[ahead %d]" msgstr "[phÃa trÆ°á»›c %d]" -#: builtin/branch.c:421 +#: builtin/branch.c:444 #, c-format msgid "[%s: ahead %d, behind %d]" msgstr "[%s: trÆ°á»›c %d, sau %d]" -#: builtin/branch.c:424 +#: builtin/branch.c:447 #, c-format msgid "[ahead %d, behind %d]" msgstr "[trÆ°á»›c %d, sau %d]" -#: builtin/branch.c:537 +#: builtin/branch.c:560 msgid "(no branch)" msgstr "(không nhánh)" -#: builtin/branch.c:602 +#: builtin/branch.c:625 msgid "some refs could not be read" msgstr "má»™t số tham chiếu đã không thể Ä‘á»c được" -#: builtin/branch.c:615 +#: builtin/branch.c:638 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:625 +#: builtin/branch.c:648 #, c-format msgid "Invalid branch name: '%s'" -msgstr "Sai tên nhánh: `%s'" +msgstr "Sai tên nhánh: “%sâ€" -#: builtin/branch.c:640 +#: builtin/branch.c:663 msgid "Branch rename failed" msgstr "Äổi tên nhánh gặp lá»—i" -#: builtin/branch.c:644 +#: builtin/branch.c:667 #, c-format msgid "Renamed a misnamed branch '%s' away" -msgstr "Äã đổi tên nhánh khuyết danh `%s' Ä‘i" +msgstr "Äã đổi tên nhánh khuyết danh “%s†đi" -#: builtin/branch.c:648 +#: builtin/branch.c:671 #, 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:655 +#: builtin/branch.c:678 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:670 +#: builtin/branch.c:693 #, c-format msgid "malformed object name %s" msgstr "tên đối tượng dị hình %s" -#: builtin/branch.c:694 +#: builtin/branch.c:717 #, 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:724 +#: builtin/branch.c:747 msgid "Generic options" msgstr "Tùy chá»n chung" -#: builtin/branch.c:726 +#: builtin/branch.c:749 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:727 +#: builtin/branch.c:750 msgid "suppress informational messages" msgstr "Thu hồi các thông Ä‘iệp thông tin" -#: builtin/branch.c:728 +#: builtin/branch.c:751 msgid "set up tracking mode (see git-pull(1))" msgstr "cà i đặt chế Ä‘á»™ theo vết (xem git-pull(1))" -#: builtin/branch.c:730 +#: builtin/branch.c:753 msgid "change upstream info" msgstr "thay đổi thông tin thượng nguồn (upstream)" -#: builtin/branch.c:734 +#: builtin/branch.c:757 msgid "use colored output" msgstr "sá» dụng kết xuất có tô mà u" -#: builtin/branch.c:735 +#: builtin/branch.c:758 msgid "act on remote-tracking branches" -msgstr "thao tác trên nhánh `remote-tracking'" +msgstr "thao tác trên nhánh “remote-trackingâ€" -#: builtin/branch.c:738 builtin/branch.c:744 builtin/branch.c:765 -#: builtin/branch.c:771 builtin/commit.c:1362 builtin/commit.c:1363 -#: builtin/commit.c:1364 builtin/commit.c:1365 builtin/tag.c:470 +#: builtin/branch.c:761 builtin/branch.c:767 builtin/branch.c:788 +#: builtin/branch.c:794 builtin/commit.c:1376 builtin/commit.c:1377 +#: builtin/commit.c:1378 builtin/commit.c:1379 builtin/tag.c:470 msgid "commit" msgstr "commit" -#: builtin/branch.c:739 builtin/branch.c:745 +#: builtin/branch.c:762 builtin/branch.c:768 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:751 +#: builtin/branch.c:774 msgid "Specific git-branch actions:" msgstr "Hà nh Ä‘á»™ng git-branch:" -#: builtin/branch.c:752 +#: builtin/branch.c:775 msgid "list both remote-tracking and local branches" -msgstr "liệt kê cả nhánh `remote-tracking' và ná»™i bá»™" +msgstr "liệt kê cả nhánh “remote-tracking†và ná»™i bá»™" -#: builtin/branch.c:754 +#: builtin/branch.c:777 msgid "delete fully merged branch" msgstr "xóa má»™t cách đầy đủ nhánh đã hòa trá»™n" -#: builtin/branch.c:755 +#: builtin/branch.c:778 msgid "delete branch (even if not merged)" msgstr "xoá nhánh (cho dù là chÆ°a được hòa trá»™n)" -#: builtin/branch.c:756 +#: builtin/branch.c:779 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:757 +#: builtin/branch.c:780 msgid "move/rename a branch, even if target exists" -msgstr "di chuyể hoặc đổi tên má»™t nhánh, tháºm chà cả khi Ä‘Ãch đã có sẵn" +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:758 +#: builtin/branch.c:781 msgid "list branch names" msgstr "liệt kê các tên nhánh" -#: builtin/branch.c:759 +#: builtin/branch.c:782 msgid "create the branch's reflog" msgstr "tạo reflog của nhánh" -#: builtin/branch.c:761 +#: builtin/branch.c:784 msgid "edit the description for the branch" msgstr "sá»a mô tả cho nhánh" -#: builtin/branch.c:762 +#: builtin/branch.c:785 msgid "force creation (when already exists)" msgstr "ép buá»™c tạo (khi đã sẵn tồn tại rồi)" -#: builtin/branch.c:765 +#: builtin/branch.c:788 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:771 +#: builtin/branch.c:794 msgid "print only merged branches" msgstr "chỉ hiển thị các nhánh được hòa trá»™n" -#: builtin/branch.c:775 +#: builtin/branch.c:798 msgid "list branches in columns" msgstr "liệt kê các nhánh trong các cá»™t" -#: builtin/branch.c:788 +#: builtin/branch.c:811 msgid "Failed to resolve HEAD as a valid ref." msgstr "Gặp lá»—i khi giải quyết HEAD nhÆ° là má»™t tham chiếu (ref) hợp lệ." -#: builtin/branch.c:793 builtin/clone.c:561 +#: builtin/branch.c:816 builtin/clone.c:561 msgid "HEAD not found below refs/heads!" msgstr "không tìm thấy HEAD ở dÆ°á»›i refs/heads!" -#: builtin/branch.c:813 +#: builtin/branch.c:836 msgid "--column and --verbose are incompatible" msgstr "--column và --verbose xung khắc nhau" -#: builtin/branch.c:864 +#: builtin/branch.c:887 #, c-format msgid "branch '%s' does not exist" -msgstr "nhánh `%s' chÆ°a sẵn có" +msgstr "nhánh “%s†chÆ°a sẵn có" -#: builtin/branch.c:876 +#: builtin/branch.c:899 #, c-format msgid "Branch '%s' has no upstream information" -msgstr "Nhánh `%s' không có thông tin thượng nguồn (upstream)" +msgstr "Nhánh “%s†không có thông tin thượng nguồn (upstream)" -#: builtin/branch.c:891 +#: builtin/branch.c:914 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 " +"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:894 +#: builtin/branch.c:917 #, c-format msgid "" "The --set-upstream flag is deprecated and will be removed. Consider using --" @@ -2474,7 +2515,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:911 +#: builtin/branch.c:934 #, c-format msgid "" "\n" @@ -2482,15 +2523,15 @@ msgid "" "\n" msgstr "" "\n" -"Nếu bạn muốn `%s' theo dõi `%s', thá»±c hiện lệnh sau:\n" +"Nếu bạn muốn “%s†theo dõi “%sâ€, thá»±c hiện lệnh sau:\n" "\n" -#: builtin/branch.c:912 +#: builtin/branch.c:935 #, c-format msgid " git branch -d %s\n" msgstr " git branch -d %s\n" -#: builtin/branch.c:913 +#: builtin/branch.c:936 #, c-format msgid " git branch --set-upstream-to %s\n" msgstr " git branch --set-upstream-to %s\n" @@ -2498,7 +2539,7 @@ msgstr " git branch --set-upstream-to %s\n" #: builtin/bundle.c:47 #, c-format msgid "%s is okay\n" -msgstr "`%s' tốt\n" +msgstr "“%s†tốt\n" #: builtin/bundle.c:56 msgid "Need a repository to create a bundle." @@ -2630,49 +2671,49 @@ msgstr "git checkout [các-tùy-chá»n] [<nhánh>] -- <táºp-tin>..." #: builtin/checkout.c:116 builtin/checkout.c:149 #, 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" +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 #, 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" +msgstr "Ä‘Æ°á»ng dẫn “%s†không có các phiên bản của chúng" #: builtin/checkout.c:134 #, 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" +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 #, 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" +msgstr "Ä‘Æ°á»ng dẫn “%s†không có các phiên bản cần thiết" #: builtin/checkout.c:195 #, c-format msgid "path '%s': cannot merge" -msgstr "Ä‘Æ°á»ng dẫn `%s': không thể hòa trá»™n" +msgstr "Ä‘Æ°á»ng dẫn “%sâ€: không thể hòa trá»™n" #: builtin/checkout.c:212 #, 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'" +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 #, 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" +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 #, c-format msgid "'%s' cannot be used with %s" -msgstr "`%s' không thể được sá» dụng vá»›i %s" +msgstr "“%s†không thể được sá» dụng vá»›i %s" #: builtin/checkout.c:254 #, 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." +"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 msgid "corrupt index file" @@ -2681,12 +2722,7 @@ msgstr "táºp tin ghi bảng mục lục bị há»ng" #: builtin/checkout.c:295 builtin/checkout.c:302 #, c-format msgid "path '%s' is unmerged" -msgstr "Ä‘Æ°á»ng dẫn `%s' không được hòa trá»™n" - -#: builtin/checkout.c:333 builtin/checkout.c:534 builtin/clone.c:586 -#: builtin/merge.c:811 -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" +msgstr "Ä‘Æ°á»ng dẫn “%s†không được hòa trá»™n" #: builtin/checkout.c:448 msgid "you need to resolve your current index first" @@ -2695,7 +2731,7 @@ msgstr "bạn cần phải giải quyết bảng mục lục hiện tại của #: builtin/checkout.c:569 #, c-format msgid "Can not do reflog for '%s'\n" -msgstr "Không thể thá»±c hiện reflog cho `%s'\n" +msgstr "Không thể thá»±c hiện reflog cho “%sâ€\n" #: builtin/checkout.c:602 msgid "HEAD is now at" @@ -2704,27 +2740,27 @@ msgstr "HEAD hiện giá» tại" #: builtin/checkout.c:609 #, c-format msgid "Reset branch '%s'\n" -msgstr "Äặt lại nhánh `%s'\n" +msgstr "Äặt lại nhánh “%sâ€\n" #: builtin/checkout.c:612 #, c-format msgid "Already on '%s'\n" -msgstr "Äã sẵn sà ng trên `%s'\n" +msgstr "Äã sẵn sà ng trên “%sâ€\n" #: builtin/checkout.c:616 #, c-format msgid "Switched to and reset branch '%s'\n" -msgstr "Äã chuyển tá»›i và reset nhánh `%s'\n" +msgstr "Äã chuyển tá»›i và reset nhánh “%sâ€\n" -#: builtin/checkout.c:618 +#: builtin/checkout.c:618 builtin/checkout.c:955 #, c-format msgid "Switched to a new branch '%s'\n" -msgstr "Äã chuyển đến nhánh má»›i `%s'\n" +msgstr "Äã chuyển đến nhánh má»›i “%sâ€\n" #: builtin/checkout.c:620 #, c-format msgid "Switched to branch '%s'\n" -msgstr "Äã chuyển đến nhánh `%s'\n" +msgstr "Äã chuyển đến nhánh “%sâ€\n" #: builtin/checkout.c:676 #, c-format @@ -2797,129 +2833,129 @@ msgstr "tham chiếu sai: %s" 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:961 +#: builtin/checkout.c:964 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:964 builtin/checkout.c:968 +#: builtin/checkout.c:967 builtin/checkout.c:971 #, 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" +msgstr "“%s†không thể được sá» dụng vá»›i các nhánh chuyển" -#: builtin/checkout.c:972 builtin/checkout.c:975 builtin/checkout.c:980 -#: builtin/checkout.c:983 +#: builtin/checkout.c:975 builtin/checkout.c:978 builtin/checkout.c:983 +#: builtin/checkout.c:986 #, c-format msgid "'%s' cannot be used with '%s'" -msgstr "`%s' không thể được sá» dụng vá»›i `%s'" +msgstr "“%s†không thể được sá» dụng vá»›i “%sâ€" -#: builtin/checkout.c:988 +#: builtin/checkout.c:991 #, 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'" +msgstr "Không thể chuyển nhánh đến má»™t non-commit “%sâ€" -#: builtin/checkout.c:1009 builtin/gc.c:177 +#: builtin/checkout.c:1012 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/checkout.c:1010 builtin/checkout.c:1012 builtin/clone.c:89 +#: builtin/checkout.c:1013 builtin/checkout.c:1015 builtin/clone.c:89 #: builtin/remote.c:169 builtin/remote.c:171 msgid "branch" msgstr "nhánh" -#: builtin/checkout.c:1011 +#: builtin/checkout.c:1014 msgid "create and checkout a new branch" msgstr "tạo và checkout má»™t nhánh má»›i" -#: builtin/checkout.c:1013 +#: builtin/checkout.c:1016 msgid "create/reset and checkout a branch" msgstr "create/reset và checkout má»™t nhánh" -#: builtin/checkout.c:1014 +#: builtin/checkout.c:1017 msgid "create reflog for new branch" msgstr "tạo reflog cho nhánh má»›i" -#: builtin/checkout.c:1015 +#: builtin/checkout.c:1018 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:1016 +#: builtin/checkout.c:1019 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:1018 +#: builtin/checkout.c:1021 msgid "new branch" msgstr "nhánh má»›i" -#: builtin/checkout.c:1018 +#: builtin/checkout.c:1021 msgid "new unparented branch" msgstr "nhánh mồ côi má»›i" -#: builtin/checkout.c:1019 +#: builtin/checkout.c:1022 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:1021 +#: builtin/checkout.c:1024 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:1023 +#: builtin/checkout.c:1026 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:1024 +#: builtin/checkout.c:1027 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:1025 builtin/merge.c:215 +#: builtin/checkout.c:1028 builtin/merge.c:215 msgid "update ignored files (default)" msgstr "cáºp nháºt các táºp tin bị bá» qua (mặc định)" -#: builtin/checkout.c:1026 builtin/log.c:1111 parse-options.h:241 +#: builtin/checkout.c:1029 builtin/log.c:1116 parse-options.h:241 msgid "style" msgstr "kiểu" -#: builtin/checkout.c:1027 +#: builtin/checkout.c:1030 msgid "conflict style (merge or diff3)" msgstr "xung Ä‘á»™t kiểu (hòa trá»™n hay diff3)" -#: builtin/checkout.c:1030 +#: builtin/checkout.c:1033 msgid "second guess 'git checkout no-such-branch'" -msgstr "gợi ý thứ hai `git checkout không-nhánh-nà o-nhÆ°-váºy'" +msgstr "gợi ý thứ hai “git checkout không-nhánh-nà o-nhÆ°-váºyâ€" -#: builtin/checkout.c:1054 +#: builtin/checkout.c:1057 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:1071 +#: builtin/checkout.c:1074 msgid "--track needs a branch name" msgstr "--track cần tên má»™t nhánh" -#: builtin/checkout.c:1078 +#: builtin/checkout.c:1081 msgid "Missing branch name; try -b" msgstr "Thiếu tên nhánh; hãy thá» -b" -#: builtin/checkout.c:1113 +#: builtin/checkout.c:1116 msgid "invalid path specification" msgstr "Ä‘Æ°á»ng dẫn đã cho không hợp lệ" -#: builtin/checkout.c:1120 +#: builtin/checkout.c:1123 #, 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 "" -"Không thể cáºp nháºt và chuyển thà nh nhánh `%s' cùng lúc\n" -"Bạn đã có ý định checkout `%s' cái mà không thể được phân giải nhÆ° là lần " +"Không thể cáºp nháºt và chuyển thà nh nhánh “%s†cùng lúc\n" +"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:1125 +#: builtin/checkout.c:1128 #, 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'" +msgstr "git checkout: --detach không nháºn má»™t đối số Ä‘Æ°á»ng dẫn “%sâ€" -#: builtin/checkout.c:1129 +#: builtin/checkout.c:1132 msgid "" "git checkout: --ours/--theirs, --force and --merge are incompatible when\n" "checking out of the index." @@ -2943,8 +2979,8 @@ msgstr "ép buá»™c" msgid "remove whole directories" msgstr "gỡ bá» toà n bá»™ thÆ° mục" -#: builtin/clean.c:56 builtin/describe.c:413 builtin/grep.c:803 -#: builtin/ls-files.c:491 builtin/name-rev.c:231 builtin/show-ref.c:199 +#: builtin/clean.c:56 builtin/describe.c:413 builtin/grep.c:717 +#: builtin/ls-files.c:491 builtin/name-rev.c:231 builtin/show-ref.c:182 msgid "pattern" msgstr "mẫu" @@ -3059,7 +3095,7 @@ msgstr "tên" #: builtin/clone.c:88 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)" +msgstr "dùng <tên> thay vì “origin†để theo dõi thượng nguồn (uptream)" #: builtin/clone.c:90 msgid "checkout <branch> instead of the remote's HEAD" @@ -3069,7 +3105,7 @@ msgstr "lấy ra nhánh (checkout <nhánh>) thay vì HEAD của máy chủ" 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:748 +#: builtin/clone.c:93 builtin/fetch.c:83 builtin/grep.c:662 msgid "depth" msgstr "Ä‘á»™ sâu" @@ -3100,7 +3136,7 @@ msgstr "đặt cấu hình bên trong má»™t kho chứa má»›i" #: builtin/clone.c:243 #, 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á»™." +msgstr "kho tham chiếu “%s†không phải là má»™t thÆ° mục ná»™i bá»™." #: builtin/clone.c:306 #, c-format @@ -3110,7 +3146,7 @@ msgstr "tạo thÆ° mục \"%s\" gặp lá»—i" #: builtin/clone.c:308 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'" +msgstr "gặp lá»—i stat (lấy trạng thái vá») “%sâ€" #: builtin/clone.c:310 #, c-format @@ -3130,7 +3166,7 @@ msgstr "gặp lá»—i khi tạo được liên kết má»m %s" #: builtin/clone.c:350 #, c-format msgid "failed to copy file to '%s'" -msgstr "gặp lá»—i khi chép táºp tin tá»›i `%s'" +msgstr "gặp lá»—i khi chép táºp tin tá»›i “%sâ€" #: builtin/clone.c:373 #, c-format @@ -3162,7 +3198,7 @@ msgstr "tùy chá»n --bare và --origin %s xung khắc nhau." #: builtin/clone.c:719 #, c-format msgid "repository '%s' does not exist" -msgstr "kho chứa `%s' chÆ°a tồn tại" +msgstr "kho chứa “%s†chÆ°a tồn tại" #: builtin/clone.c:724 msgid "--depth is ignored in local clones; use file:// instead." @@ -3171,32 +3207,32 @@ msgstr "--depth bị lá» Ä‘i khi nhân bản ná»™i bá»™; hãy sá» dụng file: #: builtin/clone.c:734 #, 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." +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:744 #, c-format msgid "working tree '%s' already exists." -msgstr "cây là m việc `%s' đã sẵn tồn tại rồi." +msgstr "cây là m việc “%s†đã sẵn tồn tại rồi." #: builtin/clone.c:757 builtin/clone.c:771 #, 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'" +msgstr "không thể tạo các thÆ° mục dẫn đầu của “%sâ€" #: builtin/clone.c:760 #, 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'." +msgstr "không thể tạo cây thÆ° mục là m việc dir “%sâ€." #: builtin/clone.c:779 #, c-format msgid "Cloning into bare repository '%s'...\n" -msgstr "Äang nhân bản thà nh kho chứa bare `%s'...\n" +msgstr "Äang nhân bản thà nh kho chứa bare “%sâ€...\n" #: builtin/clone.c:781 #, c-format msgid "Cloning into '%s'...\n" -msgstr "Äang nhân bản thà nh `%s'...\n" +msgstr "Äang nhân bản thà nh “%sâ€...\n" #: builtin/clone.c:823 #, c-format @@ -3308,99 +3344,99 @@ msgstr "" "\n" " git commit --allow-empty\n" "\n" -"Nếu không, hãy thá» dùng `git reset'\n" +"Nếu không, hãy thá» dùng “git resetâ€\n" -#: builtin/commit.c:257 +#: builtin/commit.c:258 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:299 +#: builtin/commit.c:300 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:305 +#: builtin/commit.c:306 msgid "interactive add failed" msgstr "việc thêm tÆ°Æ¡ng tác gặp lá»—i" -#: builtin/commit.c:338 builtin/commit.c:359 builtin/commit.c:409 +#: builtin/commit.c:339 builtin/commit.c:360 builtin/commit.c:410 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:390 +#: builtin/commit.c:391 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:392 +#: builtin/commit.c:393 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:402 +#: builtin/commit.c:403 msgid "cannot read the index" msgstr "không Ä‘á»c được bảng mục lục" -#: builtin/commit.c:422 +#: builtin/commit.c:423 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:509 builtin/commit.c:515 +#: builtin/commit.c:511 builtin/commit.c:517 #, c-format msgid "invalid commit: %s" msgstr "lần chuyển giao (commit) không hợp lệ: %s" -#: builtin/commit.c:538 +#: builtin/commit.c:540 msgid "malformed --author parameter" msgstr "đối số --author bị dị hình" -#: builtin/commit.c:558 +#: builtin/commit.c:560 #, c-format msgid "Malformed ident string: '%s'" -msgstr "Chuá»—i thụt lỠđầu dòng dị hình: `%s'" +msgstr "Chuá»—i thụt lỠđầu dòng dị hình: “%sâ€" -#: builtin/commit.c:596 builtin/commit.c:629 builtin/commit.c:952 +#: builtin/commit.c:598 builtin/commit.c:631 builtin/commit.c:954 #, 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:608 builtin/shortlog.c:296 +#: builtin/commit.c:610 builtin/shortlog.c:296 #, 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:610 +#: builtin/commit.c:612 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:614 +#: builtin/commit.c:616 #, c-format msgid "could not read log file '%s'" -msgstr "không Ä‘á»c được tệp nháºt ký `%s'" +msgstr "không Ä‘á»c được tệp nháºt ký “%sâ€" -#: builtin/commit.c:620 +#: builtin/commit.c:622 msgid "commit has empty message" msgstr "lần chuyển giao (commit) có ghi chú trống rá»—ng" -#: builtin/commit.c:636 +#: builtin/commit.c:638 msgid "could not read MERGE_MSG" msgstr "không thể Ä‘á»c MERGE_MSG" -#: builtin/commit.c:640 +#: builtin/commit.c:642 msgid "could not read SQUASH_MSG" msgstr "không thể Ä‘á»c SQUASH_MSG" -#: builtin/commit.c:644 +#: builtin/commit.c:646 #, c-format msgid "could not read '%s'" -msgstr "Không thể Ä‘á»c `%s'." +msgstr "Không thể Ä‘á»c “%sâ€." -#: builtin/commit.c:705 +#: builtin/commit.c:707 msgid "could not write commit template" msgstr "không thể ghi mẫu commit" -#: builtin/commit.c:716 +#: builtin/commit.c:718 #, c-format msgid "" "\n" @@ -3415,7 +3451,7 @@ msgstr "" "\t%s\n" "và thá» lại.\n" -#: builtin/commit.c:721 +#: builtin/commit.c:723 #, c-format msgid "" "\n" @@ -3430,17 +3466,17 @@ msgstr "" "\t%s\n" "và thá» lại.\n" -#: builtin/commit.c:733 +#: builtin/commit.c:735 msgid "" "Please enter the commit message for your changes. Lines starting\n" "with '#' will be ignored, and an empty message aborts the commit.\n" msgstr "" "Hãy nháºp và o các thông tin để giải thÃch các thay đổi của bạn. Những dòng " "được\n" -"bắt đầu bằng `#' sẽ được bá» qua, phần chú thÃch nà y nếu rá»—ng sẽ là m hủy bá» " +"bắt đầu bằng “#†sẽ được bá» qua, phần chú thÃch nà y nếu rá»—ng sẽ là m hủy bá» " "lần chuyển giao (commit).\n" -#: builtin/commit.c:738 +#: builtin/commit.c:740 msgid "" "Please enter the commit message for your changes. Lines starting\n" "with '#' will be kept; you may remove them yourself if you want to.\n" @@ -3448,143 +3484,151 @@ msgid "" msgstr "" "Hãy nháºp và o các thông tin để giải thÃch các thay đổi của bạn.Những dòng " "được\n" -"bắt đầu bằng `#' sẽ được bá» qua; bạn có thể xóa chúng Ä‘i nếu muốn.\n" +"bắt đầu bằng “#†sẽ được bá» qua; bạn có thể xóa chúng Ä‘i nếu muốn.\n" "Phần chú thÃch nà y nếu rá»—ng sẽ là m hủy bá» lần chuyển giao (commit).\n" -#: builtin/commit.c:751 +#: builtin/commit.c:753 #, c-format msgid "%sAuthor: %s" msgstr "%sTác giả: %s" -#: builtin/commit.c:758 +#: builtin/commit.c:760 #, c-format msgid "%sCommitter: %s" msgstr "%sNgÆ°á»i chuyển giao (commit): %s" -#: builtin/commit.c:778 +#: builtin/commit.c:780 msgid "Cannot read index" msgstr "không Ä‘á»c được bảng mục lục" -#: builtin/commit.c:815 +#: builtin/commit.c:817 msgid "Error building trees" msgstr "Gặp lá»—i khi xây dá»±ng cây" -#: builtin/commit.c:830 builtin/tag.c:361 +#: builtin/commit.c:832 builtin/tag.c:361 #, 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:927 +#: builtin/commit.c:929 #, 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'" +msgstr "Không tìm thấy tác giả có sẵn vá»›i “%sâ€" -#: builtin/commit.c:942 builtin/commit.c:1142 +#: builtin/commit.c:944 builtin/commit.c:1148 #, 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'" +msgstr "Chế Ä‘á»™ cho các táºp tin không bị theo vết không hợp lệ “%sâ€" -#: builtin/commit.c:982 +#: builtin/commit.c:984 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:993 +#: builtin/commit.c:995 msgid "You have nothing to amend." msgstr "Không có gì để amend (tu bổ) cả." -#: builtin/commit.c:996 +#: builtin/commit.c:998 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:998 +#: builtin/commit.c:1000 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:1001 +#: builtin/commit.c:1003 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:1011 +#: builtin/commit.c:1013 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:1013 +#: builtin/commit.c:1015 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:1021 +#: builtin/commit.c:1023 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:1038 +#: builtin/commit.c:1040 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:1040 +#: builtin/commit.c:1042 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:1042 +#: builtin/commit.c:1044 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:1044 +#: builtin/commit.c:1046 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:1054 builtin/tag.c:577 +#: builtin/commit.c:1056 builtin/tag.c:577 #, c-format msgid "Invalid cleanup mode %s" msgstr "Chế Ä‘á»™ dá»n dẹp không hợp lệ %s" -#: builtin/commit.c:1059 +#: builtin/commit.c:1061 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:1156 builtin/commit.c:1384 +#: builtin/commit.c:1067 builtin/commit.c:1202 +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:1162 builtin/commit.c:1398 msgid "show status concisely" msgstr "hiển thị trạng thái ở dạng súc tÃch" -#: builtin/commit.c:1158 builtin/commit.c:1386 +#: builtin/commit.c:1164 builtin/commit.c:1400 msgid "show branch information" msgstr "hiển thị thông tin nhánh" -#: builtin/commit.c:1160 builtin/commit.c:1388 builtin/push.c:389 +#: builtin/commit.c:1166 builtin/commit.c:1402 builtin/push.c:389 msgid "machine-readable output" msgstr "kết xuất dạng máy-có-thể-Ä‘á»c" -#: builtin/commit.c:1163 builtin/commit.c:1390 +#: builtin/commit.c:1169 builtin/commit.c:1404 +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:1172 builtin/commit.c:1407 msgid "terminate entries with NUL" msgstr "chấm dứt các mục bằng NUL" -#: builtin/commit.c:1165 builtin/commit.c:1393 builtin/fast-export.c:636 +#: builtin/commit.c:1174 builtin/commit.c:1410 builtin/fast-export.c:636 #: builtin/fast-export.c:639 builtin/tag.c:461 msgid "mode" msgstr "chế Ä‘á»™" -#: builtin/commit.c:1166 builtin/commit.c:1393 +#: builtin/commit.c:1175 builtin/commit.c:1410 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:1169 +#: builtin/commit.c:1178 msgid "show ignored files" msgstr "hiển thị các táºp tin ẩn" -#: builtin/commit.c:1170 parse-options.h:151 +#: builtin/commit.c:1179 parse-options.h:151 msgid "when" msgstr "khi" -#: builtin/commit.c:1171 +#: builtin/commit.c:1180 msgid "" "ignore changes to submodules, optional when: all, dirty, untracked. " "(Default: all)" @@ -3592,223 +3636,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:1173 +#: builtin/commit.c:1182 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:1242 +#: builtin/commit.c:1256 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:1244 +#: builtin/commit.c:1258 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:1285 +#: builtin/commit.c:1299 msgid "detached HEAD" msgstr "đã rá»i khá»i HEAD" -#: builtin/commit.c:1287 +#: builtin/commit.c:1301 msgid " (root-commit)" msgstr " (root-commit)" -#: builtin/commit.c:1354 +#: builtin/commit.c:1368 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:1355 +#: builtin/commit.c:1369 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:1357 +#: builtin/commit.c:1371 msgid "Commit message options" msgstr "Các tùy chá»n ghi chú commit" -#: builtin/commit.c:1358 builtin/tag.c:459 +#: builtin/commit.c:1372 builtin/tag.c:459 msgid "read message from file" msgstr "Ä‘á»c chú thÃch từ táºp tin" -#: builtin/commit.c:1359 +#: builtin/commit.c:1373 msgid "author" msgstr "tác giả" -#: builtin/commit.c:1359 +#: builtin/commit.c:1373 msgid "override author for commit" msgstr "ghi đè tác giả cho commit" -#: builtin/commit.c:1360 builtin/gc.c:178 +#: builtin/commit.c:1374 builtin/gc.c:178 msgid "date" msgstr "ngà y tháng" -#: builtin/commit.c:1360 +#: builtin/commit.c:1374 msgid "override date for commit" msgstr "ghi đè ngà y tháng cho commit" -#: builtin/commit.c:1361 builtin/merge.c:206 builtin/notes.c:537 +#: builtin/commit.c:1375 builtin/merge.c:206 builtin/notes.c:537 #: builtin/notes.c:694 builtin/tag.c:457 msgid "message" msgstr "thông Ä‘iệp" -#: builtin/commit.c:1361 +#: builtin/commit.c:1375 msgid "commit message" msgstr "chú thÃch của lần commit" -#: builtin/commit.c:1362 +#: builtin/commit.c:1376 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:1363 +#: builtin/commit.c:1377 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:1364 +#: builtin/commit.c:1378 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:1365 +#: builtin/commit.c:1379 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:1366 +#: builtin/commit.c:1380 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:1367 builtin/log.c:1068 builtin/revert.c:109 +#: builtin/commit.c:1381 builtin/log.c:1073 builtin/revert.c:109 msgid "add Signed-off-by:" msgstr "thêm dòng Signed-off-by:" -#: builtin/commit.c:1368 +#: builtin/commit.c:1382 msgid "use specified template file" msgstr "sá» dụng táºp tin mẫu đã cho" -#: builtin/commit.c:1369 +#: builtin/commit.c:1383 msgid "force edit of commit" msgstr "ép buá»™c sá»a lần commit" -#: builtin/commit.c:1370 +#: builtin/commit.c:1384 msgid "default" msgstr "mặc định" -#: builtin/commit.c:1370 builtin/tag.c:462 +#: builtin/commit.c:1384 builtin/tag.c:462 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:1371 +#: builtin/commit.c:1385 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:1372 builtin/merge.c:213 builtin/tag.c:463 +#: builtin/commit.c:1386 builtin/merge.c:213 builtin/tag.c:463 msgid "key id" msgstr "id khóa" -#: builtin/commit.c:1373 builtin/merge.c:214 +#: builtin/commit.c:1387 builtin/merge.c:214 msgid "GPG sign commit" msgstr "ký lần commit dùng GPG" #. end commit message options -#: builtin/commit.c:1376 +#: builtin/commit.c:1390 msgid "Commit contents options" msgstr "Các tùy ná»™i dung ghi chú commit" -#: builtin/commit.c:1377 +#: builtin/commit.c:1391 msgid "commit all changed files" msgstr "chuyển giao tất cả các táºp tin có thay đổi" -#: builtin/commit.c:1378 +#: builtin/commit.c:1392 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:1379 +#: builtin/commit.c:1393 msgid "interactively add files" msgstr "thêm các táºp-tin bằng tÆ°Æ¡ng tác" -#: builtin/commit.c:1380 +#: builtin/commit.c:1394 msgid "interactively add changes" msgstr "thêm các thay đổi bằng tÆ°Æ¡ng tác" -#: builtin/commit.c:1381 +#: builtin/commit.c:1395 msgid "commit only specified files" msgstr "chỉ chuyển giao các táºp tin đã chỉ ra" -#: builtin/commit.c:1382 +#: builtin/commit.c:1396 msgid "bypass pre-commit hook" msgstr "vòng qua móc (hook) pre-commit" -#: builtin/commit.c:1383 +#: builtin/commit.c:1397 msgid "show what would be committed" msgstr "hiển thị xem cái gì có thể được chuyển giao" -#: builtin/commit.c:1391 +#: builtin/commit.c:1408 msgid "amend previous commit" msgstr "tu bổ (amend) lần commit trÆ°á»›c" -#: builtin/commit.c:1392 +#: builtin/commit.c:1409 msgid "bypass post-rewrite hook" msgstr "vòng qua móc (hook) post-rewrite" -#: builtin/commit.c:1397 +#: builtin/commit.c:1414 msgid "ok to record an empty change" msgstr "ok để ghi lại má»™t thay đổi trống rá»—ng" -#: builtin/commit.c:1400 +#: builtin/commit.c:1417 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:1432 +#: builtin/commit.c:1449 msgid "could not parse HEAD commit" msgstr "không thể phân tÃch commit (lần chuyển giao) HEAD" -#: builtin/commit.c:1470 builtin/merge.c:508 +#: builtin/commit.c:1487 builtin/merge.c:508 #, c-format msgid "could not open '%s' for reading" -msgstr "không thể mở `%s' để Ä‘á»c" +msgstr "không thể mở “%s†để Ä‘á»c" -#: builtin/commit.c:1477 +#: builtin/commit.c:1494 #, c-format msgid "Corrupt MERGE_HEAD file (%s)" msgstr "Táºp tin MERGE_HEAD sai há»ng (%s)" -#: builtin/commit.c:1484 +#: builtin/commit.c:1501 msgid "could not read MERGE_MODE" msgstr "không thể Ä‘á»c MERGE_MODE" -#: builtin/commit.c:1503 +#: builtin/commit.c:1520 #, 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:1517 +#: builtin/commit.c:1534 #, 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:1522 +#: builtin/commit.c:1539 #, 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:1537 builtin/merge.c:935 builtin/merge.c:960 +#: builtin/commit.c:1554 builtin/merge.c:832 builtin/merge.c:857 msgid "failed to write commit object" msgstr "gặp lá»—i khi ghi đối tượng chuyển giao (commit)" -#: builtin/commit.c:1558 +#: builtin/commit.c:1575 msgid "cannot lock HEAD ref" msgstr "không thể khóa HEAD ref (tham chiếu)" -#: builtin/commit.c:1562 +#: builtin/commit.c:1579 msgid "cannot update HEAD ref" msgstr "không thể cáºp nháºt ref (tham chiếu) HEAD" -#: builtin/commit.c:1573 +#: builtin/commit.c:1590 msgid "" "Repository has been updated, but unable to write\n" "new_index file. Check that disk is not full or quota is\n" @@ -3823,115 +3867,115 @@ msgstr "" msgid "git config [options]" msgstr "git config [các-tùy-chá»n]" -#: builtin/config.c:52 +#: builtin/config.c:51 msgid "Config file location" msgstr "Vị trà táºp tin cấu hình" -#: builtin/config.c:53 +#: builtin/config.c:52 msgid "use global config file" msgstr "đặt táºp tin cấu hình cần toà n cục" -#: builtin/config.c:54 +#: builtin/config.c:53 msgid "use system config file" msgstr "sá» dụng táºp tin cấu hình hệ thống" -#: builtin/config.c:55 +#: builtin/config.c:54 msgid "use repository config file" msgstr "dùng táºp tin cấu hình của kho" -#: builtin/config.c:56 +#: builtin/config.c:55 msgid "use given config file" msgstr "sá» dụng táºp tin cấu hình đã cho" -#: builtin/config.c:57 +#: builtin/config.c:56 msgid "Action" msgstr "Hà nh Ä‘á»™ng" -#: builtin/config.c:58 +#: builtin/config.c:57 msgid "get value: name [value-regex]" msgstr "lấy giá-trị: tên [value-regex]" -#: builtin/config.c:59 +#: builtin/config.c:58 msgid "get all values: key [value-regex]" msgstr "lấy tất cả giá-trị: khóa [value-regex]" -#: builtin/config.c:60 +#: builtin/config.c:59 msgid "get values for regexp: name-regex [value-regex]" msgstr "lấy giá trị cho regexp: name-regex [value-regex]" -#: builtin/config.c:61 +#: builtin/config.c:60 msgid "replace all matching variables: name value [value_regex]" msgstr "thay thế tất cả các biến khá»›p mẫu: tên giá-trị [value_regex]" -#: builtin/config.c:62 +#: builtin/config.c:61 msgid "add a new variable: name value" msgstr "thêm biến má»›i: tên giá-trị" -#: builtin/config.c:63 +#: builtin/config.c:62 msgid "remove a variable: name [value-regex]" msgstr "gỡ bá» biến: tên [value-regex]" -#: builtin/config.c:64 +#: builtin/config.c:63 msgid "remove all matches: name [value-regex]" msgstr "gỡ bá» má»i cái khá»›p: tên [value-regex]" -#: builtin/config.c:65 +#: builtin/config.c:64 msgid "rename section: old-name new-name" msgstr "đổi tên chÆ°Æ¡ng: tên-cÅ© tên-má»›i" -#: builtin/config.c:66 +#: builtin/config.c:65 msgid "remove a section: name" msgstr "gỡ bá» chÆ°Æ¡ng: tên" -#: builtin/config.c:67 +#: builtin/config.c:66 msgid "list all" msgstr "liệt kê tất" -#: builtin/config.c:68 +#: builtin/config.c:67 msgid "open an editor" msgstr "mở má»™t trình biên soạn" -#: builtin/config.c:69 builtin/config.c:70 +#: builtin/config.c:68 builtin/config.c:69 msgid "slot" msgstr "khe" -#: builtin/config.c:69 +#: builtin/config.c:68 msgid "find the color configured: [default]" msgstr "tìm cấu hình mà u sắc: [mặc định]" -#: builtin/config.c:70 +#: builtin/config.c:69 msgid "find the color setting: [stdout-is-tty]" msgstr "tìm các cà i đặt vá» mà u sắc: [stdout-là -tty]" -#: builtin/config.c:71 +#: builtin/config.c:70 msgid "Type" msgstr "Kiểu" -#: builtin/config.c:72 +#: builtin/config.c:71 msgid "value is \"true\" or \"false\"" msgstr "giá trị là \"true\" hoặc \"false\"" -#: builtin/config.c:73 +#: builtin/config.c:72 msgid "value is decimal number" msgstr "giá trị ở dạng số tháºp phân" -#: builtin/config.c:74 +#: builtin/config.c:73 msgid "value is --bool or --int" msgstr "giá trị là --bool hoặc --int" -#: builtin/config.c:75 +#: builtin/config.c:74 msgid "value is a path (file or directory name)" msgstr "giá trị là đưá»ng dẫn (tên táºp tin hay thÆ° mục)" -#: builtin/config.c:76 +#: builtin/config.c:75 msgid "Other" msgstr "Khác" -#: builtin/config.c:77 +#: builtin/config.c:76 msgid "terminate values with NUL byte" msgstr "chấm dứt giá trị vá»›i byte NUL" -#: builtin/config.c:78 +#: builtin/config.c:77 msgid "respect include directives on lookup" msgstr "tôn trá»ng kể cà các hÆ°á»›ng trong tìm kiếm" @@ -3960,7 +4004,7 @@ msgstr "thẻ được chú giải %s không có tên nhúng" #: builtin/describe.c:240 #, c-format msgid "tag '%s' is really '%s' here" -msgstr "thẻ `%s' đã thá»±c sá»± ở đây `%s' rồi" +msgstr "thẻ “%s†đã thá»±c sá»± ở đây “%s†rồi" #: builtin/describe.c:267 #, c-format @@ -3970,12 +4014,12 @@ msgstr "Không phải tên đối tượng %s hợp lệ" #: builtin/describe.c:270 #, 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ệ" +msgstr "%s không phải là má»™t đối tượng “%s†hợp lệ" #: builtin/describe.c:287 #, c-format msgid "no tag exactly matches '%s'" -msgstr "không có thẻ nà o khá»›p chÃnh xác vá»›i `%s'" +msgstr "không có thẻ nà o khá»›p chÃnh xác vá»›i “%sâ€" #: builtin/describe.c:289 #, c-format @@ -3993,7 +4037,7 @@ msgid "" "No annotated tags can describe '%s'.\n" "However, there were unannotated tags: try --tags." msgstr "" -"Không có thẻ được chú giải nà o được mô tả là `%s'.\n" +"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 @@ -4002,7 +4046,7 @@ msgid "" "No tags can describe '%s'.\n" "Try --always, or create some tags." msgstr "" -"Không có thẻ (tag) có thể mô tả `%s'.\n" +"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 @@ -4078,36 +4122,36 @@ msgstr "--dirty là xung khắc vá»›i các tùy chá»n dà nh cho chuyển giao ( #: builtin/diff.c:79 #, c-format msgid "'%s': not a regular file or symlink" -msgstr "`%s': không phải táºp tin bình thÆ°á»ng hay liên kết tượng trÆ°ng" +msgstr "“%sâ€: không phải táºp tin bình thÆ°á»ng hay liên kết tượng trÆ°ng" -#: builtin/diff.c:224 +#: builtin/diff.c:228 #, c-format msgid "invalid option: %s" msgstr "tùy chá»n sai: %s" -#: builtin/diff.c:301 +#: builtin/diff.c:305 msgid "Not a git repository" msgstr "Không phải là kho git" -#: builtin/diff.c:344 +#: builtin/diff.c:348 #, c-format msgid "invalid object '%s' given." -msgstr "đối tượng đã cho `%s' không hợp lệ." +msgstr "đối tượng đã cho “%s†không hợp lệ." -#: builtin/diff.c:349 +#: builtin/diff.c:353 #, c-format msgid "more than %d trees given: '%s'" -msgstr "đã chỉ ra nhiá»u hÆ¡n %d cây (tree): `%s'" +msgstr "đã chỉ ra nhiá»u hÆ¡n %d cây (tree): “%sâ€" -#: builtin/diff.c:359 +#: builtin/diff.c:363 #, c-format msgid "more than two blobs given: '%s'" -msgstr "đã cho nhiá»u hÆ¡n hai đối tượng blob: `%s'" +msgstr "đã cho nhiá»u hÆ¡n hai đối tượng blob: “%sâ€" -#: builtin/diff.c:367 +#: builtin/diff.c:371 #, c-format msgid "unhandled object '%s' given." -msgstr "đã cho đối tượng không thể nắm giữ `%s'." +msgstr "đã cho đối tượng không thể nắm giữ “%sâ€." #: builtin/fast-export.c:22 msgid "git fast-export [rev-list-opts]" @@ -4196,7 +4240,7 @@ msgstr "không lấy (fetch) tất cả các thẻ (--no-tags)" #: builtin/fetch.c:73 msgid "prune remote-tracking branches no longer on remote" msgstr "" -"cắt cụt (prune) các nhánh `remote-tracking' không còn tồn tại trên máy chủ " +"cắt cụt (prune) các nhánh “remote-tracking†không còn tồn tại trên máy chủ " "nữa" #: builtin/fetch.c:74 @@ -4219,7 +4263,7 @@ msgstr "cho phép cáºp nháºt ref (tham chiếu) HEAD" msgid "deepen history of shallow clone" msgstr "là m sâu hÆ¡n lịch sá» của bản sao" -#: builtin/fetch.c:85 builtin/log.c:1083 +#: builtin/fetch.c:85 builtin/log.c:1088 msgid "dir" msgstr "tmục" @@ -4307,7 +4351,7 @@ msgid "" " 'git remote prune %s' to remove any old, conflicting branches" msgstr "" "má»™t số tham chiếu (refs) ná»™i bá»™ không thể được cáºp nháºt; hãy thá» chạy\n" -" `git remote prune %s' để bá» Ä‘i những nhánh cÅ©, hay bị xung Ä‘á»™t" +" “git remote prune %s†để bá» Ä‘i những nhánh cÅ©, hay bị xung Ä‘á»™t" #: builtin/fetch.c:549 #, c-format @@ -4393,15 +4437,15 @@ 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:653 builtin/fmt-merge-msg.c:656 builtin/grep.c:787 -#: builtin/merge.c:188 builtin/show-branch.c:656 builtin/show-ref.c:192 +#: builtin/fmt-merge-msg.c:653 builtin/fmt-merge-msg.c:656 builtin/grep.c:701 +#: builtin/merge.c:188 builtin/show-branch.c:656 builtin/show-ref.c:175 #: builtin/tag.c:448 parse-options.h:133 parse-options.h:235 msgid "n" msgstr "n" #: builtin/fmt-merge-msg.c:654 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'" +msgstr "gắn nháºt ký vá»›i Ãt nhất <n> mục từ lệnh “shortlogâ€" #: builtin/fmt-merge-msg.c:657 msgid "alias for --log (deprecated)" @@ -4481,7 +4525,7 @@ msgstr "báo cáo node gốc" #: builtin/fsck.c:618 msgid "make index objects head nodes" -msgstr "tạo ` index objects head nodes'" +msgstr "tạo “ index objects head nodesâ€" #: builtin/fsck.c:619 msgid "make reflogs head nodes (default)" @@ -4510,7 +4554,7 @@ msgstr "git gc [các-tùy-chá»n]" #: builtin/gc.c:63 #, c-format msgid "Invalid %s: '%s'" -msgstr "%s không hợp lệ: `%s'" +msgstr "%s không hợp lệ: “%sâ€" #: builtin/gc.c:90 #, c-format @@ -4543,7 +4587,7 @@ msgstr "" msgid "" "There are too many unreachable loose objects; run 'git prune' to remove them." msgstr "" -"Có quá nhiá»u đối tượng tá»± do không được dùng đến; hãy chạy lệnh `git prune' " +"Có quá nhiá»u đối tượng tá»± do không được dùng đến; hãy chạy lệnh “git prune†" "để xóa bá» chúng Ä‘i." #: builtin/grep.c:22 @@ -4555,228 +4599,228 @@ msgstr "git grep [các-tùy-chá»n] [-e] <mẫu> [<rev>...] [[--] <Ä‘Æ°á»ng-dẠmsgid "grep: failed to create thread: %s" msgstr "grep: gặp lá»—i tạo tuyến (thread): %s" -#: builtin/grep.c:455 +#: builtin/grep.c:365 #, c-format msgid "Failed to chdir: %s" msgstr "Gặp lá»—i vá»›i lệnh chdir: %s" -#: builtin/grep.c:531 builtin/grep.c:565 +#: builtin/grep.c:443 builtin/grep.c:478 #, c-format msgid "unable to read tree (%s)" msgstr "không thể Ä‘á»c cây (%s)" -#: builtin/grep.c:579 +#: builtin/grep.c:493 #, c-format msgid "unable to grep from object of type %s" msgstr "không thể thá»±c hiện lệnh grep (lá»c tìm) từ đối tượng thuá»™c kiểu %s" -#: builtin/grep.c:637 +#: builtin/grep.c:551 #, c-format msgid "switch `%c' expects a numerical value" -msgstr "chuyển đến `%c' mong chá» má»™t giá trị bằng số" +msgstr "chuyển đến `%c' cần má»™t giá trị bằng số" -#: builtin/grep.c:654 +#: builtin/grep.c:568 #, c-format msgid "cannot open '%s'" -msgstr "không mở được `%s'" +msgstr "không mở được “%sâ€" -#: builtin/grep.c:729 +#: builtin/grep.c:643 msgid "search in index instead of in the work tree" msgstr "tìm trong bảng mục lục thay vì trong cây là m việc" -#: builtin/grep.c:731 +#: builtin/grep.c:645 msgid "find in contents not managed by git" msgstr "tìm trong ná»™i dung không được quản lý bởi git" -#: builtin/grep.c:733 +#: builtin/grep.c:647 msgid "search in both tracked and untracked files" msgstr "tìm kiếm các táºp tin được và chÆ°a được theo dõi dấu vết" -#: builtin/grep.c:735 +#: builtin/grep.c:649 msgid "search also in ignored files" msgstr "tìm cả trong các táºp tin đã bị lá» Ä‘i" -#: builtin/grep.c:738 +#: builtin/grep.c:652 msgid "show non-matching lines" msgstr "hiển thị những dòng không khá»›p vá»›i mẫu" -#: builtin/grep.c:740 +#: builtin/grep.c:654 msgid "case insensitive matching" msgstr "phân biệt chữ hoa/thÆ°á»ng" -#: builtin/grep.c:742 +#: builtin/grep.c:656 msgid "match patterns only at word boundaries" msgstr "chỉ khá»›p mẫu tại Ä‘Æ°á»ng ranh giá»›i từ" -#: builtin/grep.c:744 +#: builtin/grep.c:658 msgid "process binary files as text" msgstr "xá» lý táºp tin nhị phân nhÆ° là dạng văn bản thÆ°á»ng" -#: builtin/grep.c:746 +#: builtin/grep.c:660 msgid "don't match patterns in binary files" msgstr "không khá»›p mẫu trong các táºp tin nhị phân" -#: builtin/grep.c:749 +#: builtin/grep.c:663 msgid "descend at most <depth> levels" msgstr "giảm xuống Ãt nhất mức <sâu>" -#: builtin/grep.c:753 +#: builtin/grep.c:667 msgid "use extended POSIX regular expressions" msgstr "dùng biểu thức chÃnh qui POSIX có mở rá»™ng" -#: builtin/grep.c:756 +#: builtin/grep.c:670 msgid "use basic POSIX regular expressions (default)" msgstr "sá» dụng biểu thức chÃnh quy kiểu POSIX (mặc định)" -#: builtin/grep.c:759 +#: builtin/grep.c:673 msgid "interpret patterns as fixed strings" msgstr "diá»…n dịch các mẫu nhÆ° là chuá»—i cố định" -#: builtin/grep.c:762 +#: builtin/grep.c:676 msgid "use Perl-compatible regular expressions" msgstr "sá» dụng biểu thức chÃnh quy tÆ°Æ¡ng thÃch Perl" -#: builtin/grep.c:765 +#: builtin/grep.c:679 msgid "show line numbers" msgstr "hiển thị số của dòng" -#: builtin/grep.c:766 +#: builtin/grep.c:680 msgid "don't show filenames" msgstr "không hiển thị tên táºp tin" -#: builtin/grep.c:767 +#: builtin/grep.c:681 msgid "show filenames" msgstr "hiển thị các tên táºp tin" -#: builtin/grep.c:769 +#: builtin/grep.c:683 msgid "show filenames relative to top directory" msgstr "hiển thị tên táºp tin tÆ°Æ¡ng đối vá»›i thÆ° mục đỉnh (top)" -#: builtin/grep.c:771 +#: builtin/grep.c:685 msgid "show only filenames instead of matching lines" msgstr "chỉ hiển thị tên táºp tin thay vì những dòng khá»›p vá»›i mẫu" -#: builtin/grep.c:773 +#: builtin/grep.c:687 msgid "synonym for --files-with-matches" msgstr "đồng nghÄ©a vá»›i --files-with-matches" -#: builtin/grep.c:776 +#: builtin/grep.c:690 msgid "show only the names of files without match" msgstr "chỉ hiển thị tên cho những táºp tin không khá»›p vá»›i mẫu" -#: builtin/grep.c:778 +#: builtin/grep.c:692 msgid "print NUL after filenames" msgstr "thêm NUL và o sau tên táºp tin" -#: builtin/grep.c:780 +#: builtin/grep.c:694 msgid "show the number of matches instead of matching lines" msgstr "hiển thị số lượng khá»›p thay vì những dòng khá»›p vá»›i mẫu" -#: builtin/grep.c:781 +#: builtin/grep.c:695 msgid "highlight matches" msgstr "tô sáng cái khá»›p" -#: builtin/grep.c:783 +#: builtin/grep.c:697 msgid "print empty line between matches from different files" msgstr "hiển thị dòng trống giữa các lần khá»›p từ các táºp tin khác biệt" -#: builtin/grep.c:785 +#: builtin/grep.c:699 msgid "show filename only once above matches from same file" msgstr "" "hiển thị tên táºp tin má»™t lần phÃa trên các lần khá»›p từ cùng má»™t táºp tin" -#: builtin/grep.c:788 +#: builtin/grep.c:702 msgid "show <n> context lines before and after matches" msgstr "hiển thị <n> dòng ná»™i dung phÃa trÆ°á»›c và sau các lần khá»›p" -#: builtin/grep.c:791 +#: builtin/grep.c:705 msgid "show <n> context lines before matches" msgstr "hiển thị <n> dòng ná»™i dung trÆ°á»›c khá»›p" -#: builtin/grep.c:793 +#: builtin/grep.c:707 msgid "show <n> context lines after matches" msgstr "hiển thị <n> dòng ná»™i dung sau khá»›p" -#: builtin/grep.c:794 +#: builtin/grep.c:708 msgid "shortcut for -C NUM" msgstr "Dạng tắt cho -C Sá»" -#: builtin/grep.c:797 +#: builtin/grep.c:711 msgid "show a line with the function name before matches" msgstr "hiển thị dòng vói tên hà m trÆ°á»›c các lần khá»›p" -#: builtin/grep.c:799 +#: builtin/grep.c:713 msgid "show the surrounding function" msgstr "hiển thị hà m bao quanh" -#: builtin/grep.c:802 +#: builtin/grep.c:716 msgid "read patterns from file" msgstr "Ä‘á»c mẫu từ táºp-tin" -#: builtin/grep.c:804 +#: builtin/grep.c:718 msgid "match <pattern>" msgstr "match <mẫu>" -#: builtin/grep.c:806 +#: builtin/grep.c:720 msgid "combine patterns specified with -e" msgstr "tổ hợp mẫu được chỉ ra vá»›i tùy chá»n -e" -#: builtin/grep.c:818 +#: builtin/grep.c:732 msgid "indicate hit with exit status without output" msgstr "Ä‘Æ°a ra gợi ý vá»›i trạng thái thoát mà không có kết xuất" -#: builtin/grep.c:820 +#: builtin/grep.c:734 msgid "show only matches from files that match all patterns" msgstr "chỉ hiển thị những cái khá»›p từ táºp tin mà nó khá»›p toà n bá»™ các mẫu" -#: builtin/grep.c:822 +#: builtin/grep.c:736 msgid "show parse tree for grep expression" -msgstr "hiển thị cây phân tÃch cú pháp cho biểu thức `grep' (tìm kiếm)" +msgstr "hiển thị cây phân tÃch cú pháp cho biểu thức “grep†(tìm kiếm)" -#: builtin/grep.c:826 +#: builtin/grep.c:740 msgid "pager" msgstr "trang giấy" -#: builtin/grep.c:826 +#: builtin/grep.c:740 msgid "show matching files in the pager" msgstr "hiển thị các táºp tin khá»›p trong trang giấy" -#: builtin/grep.c:829 +#: builtin/grep.c:743 msgid "allow calling of grep(1) (ignored by this build)" msgstr "cho phép gá»i grep(1) (bị bá» qua bởi lần dịch nà y)" -#: builtin/grep.c:830 builtin/show-ref.c:201 +#: builtin/grep.c:744 builtin/show-ref.c:184 msgid "show usage" msgstr "hiển thị cách dùng" -#: builtin/grep.c:921 +#: builtin/grep.c:811 msgid "no pattern given." msgstr "chÆ°a chỉ ra mẫu." -#: builtin/grep.c:935 +#: builtin/grep.c:825 #, c-format msgid "bad object %s" msgstr "đối tượng sai %s" -#: builtin/grep.c:976 +#: 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:999 +#: 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:1004 +#: 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:1007 +#: 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:1015 +#: 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." @@ -4839,7 +4883,7 @@ msgstr "git help [--all] [--man|--web|--info] [lệnh]" #: builtin/help.c:65 #, c-format msgid "unrecognized help format '%s'" -msgstr "không nháºn ra định dạng trợ giúp `%s'" +msgstr "không nháºn ra định dạng trợ giúp “%sâ€" #: builtin/help.c:93 msgid "Failed to start emacsclient." @@ -4852,12 +4896,12 @@ msgstr "Gặp lá»—i khi phân tÃch phiên bản emacsclient." #: builtin/help.c:114 #, c-format msgid "emacsclient version '%d' too old (< 22)." -msgstr "phiên bản của emacsclient `%d' quá cÅ© (< 22)." +msgstr "phiên bản của emacsclient “%d†quá cÅ© (< 22)." #: builtin/help.c:132 builtin/help.c:160 builtin/help.c:169 builtin/help.c:177 #, c-format msgid "failed to exec '%s': %s" -msgstr "gặp lá»—i khi thá»±c thi `%s': %s" +msgstr "gặp lá»—i khi thá»±c thi “%sâ€: %s" #: builtin/help.c:217 #, c-format @@ -4865,8 +4909,8 @@ msgid "" "'%s': path for unsupported man viewer.\n" "Please consider using 'man.<tool>.cmd' instead." 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ế." +"“%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:229 #, c-format @@ -4874,8 +4918,8 @@ msgid "" "'%s': cmd for supported man viewer.\n" "Please consider using 'man.<tool>.path' instead." 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ế." +"“%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:299 msgid "The most commonly used git commands are:" @@ -4884,7 +4928,7 @@ msgstr "Những lệnh git hay được sá» dụng nhất là :" #: builtin/help.c:367 #, c-format msgid "'%s': unknown man viewer." -msgstr "`%s': không rõ chÆ°Æ¡ng trình xem man." +msgstr "“%sâ€: không rõ chÆ°Æ¡ng trình xem man." #: builtin/help.c:384 msgid "no man viewer handled the request" @@ -4939,12 +4983,12 @@ 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 #, c-format msgid "unable to create '%s'" -msgstr "không thể tạo `%s'" +msgstr "không thể tạo “%sâ€" #: builtin/index-pack.c:278 #, c-format msgid "cannot open packfile '%s'" -msgstr "không thể mở packfile `%s'" +msgstr "không thể mở packfile “%sâ€" #: builtin/index-pack.c:292 msgid "pack signature mismatch" @@ -5104,12 +5148,12 @@ msgstr "gặp lá»—i trong khi đóng táºp tin pack" #: builtin/index-pack.c:1266 #, c-format msgid "cannot write keep file '%s'" -msgstr "không thể ghi táºp tin giữ lại `%s'" +msgstr "không thể ghi táºp tin giữ lại “%sâ€" #: builtin/index-pack.c:1274 #, c-format msgid "cannot close written keep file '%s'" -msgstr "không thể đóng táºp tin giữ lại đã được ghi `%s'" +msgstr "không thể đóng táºp tin giữ lại đã được ghi “%sâ€" #: builtin/index-pack.c:1287 msgid "cannot store pack file" @@ -5137,12 +5181,12 @@ msgstr "không há»— trợ Ä‘a tuyến, bá» qua %s" #: builtin/index-pack.c:1399 #, c-format msgid "Cannot open existing pack file '%s'" -msgstr "Không thể mở táºp tin pack đã sẵn có `%s'" +msgstr "Không thể mở táºp tin pack đã sẵn có “%sâ€" #: builtin/index-pack.c:1401 #, c-format msgid "Cannot open existing pack idx file for '%s'" -msgstr "Không thể mở táºp tin 'pack idx' cho `%s'" +msgstr "Không thể mở táºp tin “pack idx†cho “%sâ€" #: builtin/index-pack.c:1448 #, c-format @@ -5175,7 +5219,7 @@ msgstr "--fix-thin không thể được dùng mà không có --stdin" #: builtin/index-pack.c:1563 builtin/index-pack.c:1573 #, 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'" +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 msgid "--verify with no packfile name given" @@ -5194,22 +5238,22 @@ msgstr "tên mẫu dà i má»™t cách Ä‘iên rồ %s" #: builtin/init-db.c:67 #, c-format msgid "cannot stat '%s'" -msgstr "không thể lấy trạng thái (stat) vá» `%s'" +msgstr "không thể lấy trạng thái (stat) vỠ“%sâ€" #: builtin/init-db.c:73 #, c-format msgid "cannot stat template '%s'" -msgstr "không thể stat (lấy trạng thái vá») mẫu `%s'" +msgstr "không thể stat (lấy trạng thái vá») mẫu “%sâ€" #: builtin/init-db.c:80 #, c-format msgid "cannot opendir '%s'" -msgstr "không thể opendir `%s'" +msgstr "không thể opendir “%sâ€" #: builtin/init-db.c:97 #, c-format msgid "cannot readlink '%s'" -msgstr "không thể readlink `%s'" +msgstr "không thể readlink “%sâ€" #: builtin/init-db.c:99 #, c-format @@ -5219,7 +5263,7 @@ msgstr "liên kết tượng trÆ°ng dà i má»™t cách Ä‘iên rồ %s" #: builtin/init-db.c:102 #, c-format msgid "cannot symlink '%s' '%s'" -msgstr "không thể tạo liên kết tượng trÆ°ng (symlink) `%s' `%s'" +msgstr "không thể tạo liên kết tượng trÆ°ng (symlink) “%s†“%sâ€" #: builtin/init-db.c:106 #, c-format @@ -5244,7 +5288,7 @@ msgstr "các mẫu không được tìm thấy %s" #: builtin/init-db.c:154 #, c-format msgid "not copying templates of a wrong format version %d from '%s'" -msgstr "không sao chép các mẫu của phiên bản sai định dạng %d từ `%s'" +msgstr "không sao chép các mẫu của phiên bản sai định dạng %d từ “%sâ€" #: builtin/init-db.c:192 #, c-format @@ -5269,7 +5313,7 @@ msgstr "không di chuyển được %s và o %s" #: builtin/init-db.c:363 #, c-format msgid "Could not create git link %s" -msgstr "Không thể tạo liên kết git `%s'" +msgstr "Không thể tạo liên kết git “%sâ€" #. #. * TRANSLATORS: The first '%s' is either "Reinitialized @@ -5343,7 +5387,7 @@ msgstr "Không thể truy cáºp thÆ° mục là m việc hiện hà nh" #: builtin/init-db.c:586 #, c-format msgid "Cannot access work tree '%s'" -msgstr "không thể truy cáºp cây (tree) là m việc `%s'" +msgstr "không thể truy cáºp cây (tree) là m việc “%sâ€" #: builtin/log.c:37 msgid "git log [<options>] [<since>..<until>] [[--] <path>...]\n" @@ -5370,213 +5414,213 @@ msgstr "các tùy chá»n trang trÃ" msgid "Final output: %d %s\n" msgstr "Kết xuất cuối cùng: %d %s\n" -#: builtin/log.c:403 builtin/log.c:494 +#: builtin/log.c:405 builtin/log.c:497 #, c-format msgid "Could not read object %s" msgstr "Không thể Ä‘á»c đối tượng %s" -#: builtin/log.c:518 +#: builtin/log.c:521 #, c-format msgid "Unknown type: %d" msgstr "Không nháºn ra kiểu: %d" -#: builtin/log.c:608 +#: builtin/log.c:613 msgid "format.headers without value" msgstr "format.headers không có giá trị cụ thể" -#: builtin/log.c:682 +#: builtin/log.c:687 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:693 +#: builtin/log.c:698 #, c-format msgid "Cannot open patch file %s" msgstr "Không thể mở táºp tin miếng vá: %s" -#: builtin/log.c:707 +#: builtin/log.c:712 msgid "Need exactly one range." msgstr "Cần chÃnh xác má»™t vùng." -#: builtin/log.c:715 +#: builtin/log.c:720 msgid "Not a range." msgstr "Không phải là má»™t vùng." -#: builtin/log.c:789 +#: builtin/log.c:794 msgid "Cover letter needs email format" -msgstr "'Cover letter' cần cho định dạng thÆ°" +msgstr "â€Cover letter†cần cho định dạng thÆ°" -#: builtin/log.c:862 +#: builtin/log.c:867 #, c-format msgid "insane in-reply-to: %s" msgstr "in-reply-to Ä‘iên rồ: %s" -#: builtin/log.c:890 +#: builtin/log.c:895 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:935 +#: builtin/log.c:940 msgid "Two output directories?" msgstr "Hai thÆ° mục kết xuất?" -#: builtin/log.c:1063 +#: builtin/log.c:1068 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:1066 +#: builtin/log.c:1071 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:1070 +#: builtin/log.c:1075 msgid "print patches to standard out" msgstr "hiển thị miếng vá ra đầu ra chuẩn" -#: builtin/log.c:1072 +#: builtin/log.c:1077 msgid "generate a cover letter" msgstr "tạo bì thÆ°" -#: builtin/log.c:1074 +#: builtin/log.c:1079 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:1075 +#: builtin/log.c:1080 msgid "sfx" msgstr "sfx" -#: builtin/log.c:1076 +#: builtin/log.c:1081 msgid "use <sfx> instead of '.patch'" -msgstr "sá» dụng <sfx> thay cho '.patch'" +msgstr "sá» dụng <sfx> thay cho “.patchâ€" -#: builtin/log.c:1078 +#: builtin/log.c:1083 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:1080 +#: builtin/log.c:1085 msgid "Use [<prefix>] instead of [PATCH]" msgstr "Dùng [<tiá»n-tố>] thay cho [VÃ]" -#: builtin/log.c:1083 +#: builtin/log.c:1088 msgid "store resulting files in <dir>" msgstr "lÆ°u các táºp tin kết quả trong <t.mục>" -#: builtin/log.c:1086 +#: builtin/log.c:1091 msgid "don't strip/add [PATCH]" msgstr "không strip/add [VÃ]" -#: builtin/log.c:1089 +#: builtin/log.c:1094 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:1091 +#: builtin/log.c:1096 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:1093 +#: builtin/log.c:1098 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:1095 +#: builtin/log.c:1100 msgid "Messaging" msgstr "Lá»i nhắn" -#: builtin/log.c:1096 +#: builtin/log.c:1101 msgid "header" msgstr "đầu Ä‘á» thÆ°" -#: builtin/log.c:1097 +#: builtin/log.c:1102 msgid "add email header" msgstr "thêm đầu Ä‘á» thÆ°" -#: builtin/log.c:1098 builtin/log.c:1100 +#: builtin/log.c:1103 builtin/log.c:1105 msgid "email" msgstr "thÆ° Ä‘iện tá»" -#: builtin/log.c:1098 +#: builtin/log.c:1103 msgid "add To: header" msgstr "thêm To: đầu Ä‘á» thÆ°" -#: builtin/log.c:1100 +#: builtin/log.c:1105 msgid "add Cc: header" msgstr "thêm Cc: đầu Ä‘á» thÆ°" -#: builtin/log.c:1102 +#: builtin/log.c:1107 msgid "message-id" msgstr "message-id" -#: builtin/log.c:1103 +#: builtin/log.c:1108 msgid "make first mail a reply to <message-id>" msgstr "dùng thÆ° đầu tiên để trả lá»i <message-id>" -#: builtin/log.c:1104 builtin/log.c:1107 +#: builtin/log.c:1109 builtin/log.c:1112 msgid "boundary" msgstr "ranh giá»›i" -#: builtin/log.c:1105 +#: builtin/log.c:1110 msgid "attach the patch" msgstr "Ä‘Ãnh kèm miếng vá" -#: builtin/log.c:1108 +#: builtin/log.c:1113 msgid "inline the patch" msgstr "dùng miếng vá là m ná»™i dung" -#: builtin/log.c:1112 +#: builtin/log.c:1117 msgid "enable message threading, styles: shallow, deep" -msgstr "cho phép luồng lá»i nhắn, kiểu: `shallow', `deep'" +msgstr "cho phép luồng lá»i nhắn, kiểu: “shallowâ€, “deepâ€" -#: builtin/log.c:1114 +#: builtin/log.c:1119 msgid "signature" msgstr "chữ ký" -#: builtin/log.c:1115 +#: builtin/log.c:1120 msgid "add a signature" msgstr "thêm chữ ký" -#: builtin/log.c:1117 +#: builtin/log.c:1122 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:1157 +#: builtin/log.c:1163 #, 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:1202 +#: builtin/log.c:1208 msgid "-n and -k are mutually exclusive." msgstr "-n và -k loại từ lẫn nhau." -#: builtin/log.c:1204 +#: builtin/log.c:1210 msgid "--subject-prefix and -k are mutually exclusive." msgstr "--subject-prefix và -k xung khắc nhau." -#: builtin/log.c:1212 +#: builtin/log.c:1218 msgid "--name-only does not make sense" msgstr "--name-only không hợp lý" -#: builtin/log.c:1214 +#: builtin/log.c:1220 msgid "--name-status does not make sense" msgstr "--name-status không hợp lý" -#: builtin/log.c:1216 +#: builtin/log.c:1222 msgid "--check does not make sense" msgstr "--check không hợp lý" -#: builtin/log.c:1239 +#: builtin/log.c:1245 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:1241 +#: builtin/log.c:1247 #, c-format msgid "Could not create directory '%s'" -msgstr "Không thể tạo thÆ° mục `%s'" +msgstr "Không thể tạo thÆ° mục “%sâ€" -#: builtin/log.c:1394 +#: builtin/log.c:1400 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:1443 +#: builtin/log.c:1449 msgid "git cherry [-v] [<upstream> [<head> [<limit>]]]" msgstr "git cherry [-v] [<thượng-nguồn> [<head> [<giá»›i-hạn>]]]" -#: builtin/log.c:1498 +#: builtin/log.c:1504 #, c-format msgid "" "Could not find a tracked remote branch, please specify <upstream> manually.\n" @@ -5584,7 +5628,7 @@ 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:1511 builtin/log.c:1513 builtin/log.c:1525 +#: builtin/log.c:1517 builtin/log.c:1519 builtin/log.c:1531 #, c-format msgid "Unknown commit %s" msgstr "Không hiểu lần chuyển giao (commit) %s" @@ -5600,7 +5644,7 @@ msgstr "nháºn dạng các trạng thái táºp tin vá»›i thẻ" #: builtin/ls-files.c:465 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 " +"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:467 @@ -5633,7 +5677,7 @@ msgstr "hiển thị các táºp tin trên hệ thống táºp tin mà nó cần Ä #: builtin/ls-files.c:482 msgid "show 'other' directories' name only" -msgstr "chỉ hiển thị tên của các thÆ° mục 'khác'" +msgstr "chỉ hiển thị tên của các thÆ° mục “khácâ€" #: builtin/ls-files.c:485 msgid "don't show empty directories" @@ -5739,7 +5783,7 @@ msgstr "switch `m' yêu cầu má»™t giá trị" #: builtin/merge.c:127 #, c-format msgid "Could not find merge strategy '%s'.\n" -msgstr "Không tìm thấy chiến lược hòa trá»™n `%s'.\n" +msgstr "Không tìm thấy chiến lược hòa trá»™n “%sâ€.\n" #: builtin/merge.c:128 #, c-format @@ -5854,7 +5898,7 @@ msgstr "Không thông Ä‘iệp hòa trá»™n -- không cáºp nháºt HEAD\n" #: builtin/merge.c:436 #, 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ả" +msgstr "“%s†không chỉ đến má»™t lần chuyển giao (commit) nà o cả" #: builtin/merge.c:535 #, c-format @@ -5865,37 +5909,33 @@ msgstr "Chuá»—i branch.%s.mergeoptions sai: %s" 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:678 -msgid "failed to read the cache" -msgstr "gặp lá»—i khi Ä‘á»c bá»™ nhá»› tạm" - -#: builtin/merge.c:709 +#: builtin/merge.c:656 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:723 +#: builtin/merge.c:670 #, 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:737 +#: builtin/merge.c:684 #, c-format msgid "unable to write %s" msgstr "không thể ghi %s" -#: builtin/merge.c:876 +#: builtin/merge.c:773 #, c-format msgid "Could not read from '%s'" -msgstr "Không thể Ä‘á»c từ `%s'" +msgstr "Không thể Ä‘á»c từ “%sâ€" -#: builtin/merge.c:885 +#: builtin/merge.c:782 #, 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' để " +"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:891 +#: builtin/merge.c:788 msgid "" "Please enter a commit message to explain why this merge is necessary,\n" "especially if it merges an updated upstream into a topic branch.\n" @@ -5908,59 +5948,59 @@ msgstr "" "đặc biệt là khi nó hòa trá»™n thượng nguồn đã cáºp nháºt và o trong má»™t nhánh " "topic.\n" "\n" -"Những dòng được bắt đầu bằng '#' sẽ được bá» qua, và phần chú thÃch nà y nếu " +"Những dòng được bắt đầu bằng “#†sẽ được bá» qua, và phần chú thÃch nà y nếu " "rá»—ng\n" "sẽ là m hủy bá» lần chuyển giao (commit).\n" -#: builtin/merge.c:915 +#: builtin/merge.c:812 msgid "Empty commit message." msgstr "Chú thÃch của lần commit (chuyển giao) bị trống rá»—ng." -#: builtin/merge.c:927 +#: builtin/merge.c:824 #, c-format msgid "Wonderful.\n" msgstr "Thần kỳ.\n" -#: builtin/merge.c:992 +#: builtin/merge.c:889 #, 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:1008 +#: builtin/merge.c:905 #, 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:1049 +#: builtin/merge.c:946 msgid "No current branch." msgstr "không phải nhánh hiện hà nh" -#: builtin/merge.c:1051 +#: builtin/merge.c:948 msgid "No remote for the current branch." msgstr "Không có máy chủ cho nhánh hiện hà nh." -#: builtin/merge.c:1053 +#: builtin/merge.c:950 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:1058 +#: builtin/merge.c:955 #, 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:1145 builtin/merge.c:1302 +#: builtin/merge.c:1042 builtin/merge.c:1199 #, 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:1213 +#: builtin/merge.c:1110 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:1229 git-pull.sh:31 +#: builtin/merge.c:1126 git-pull.sh:31 msgid "" "You have not concluded your merge (MERGE_HEAD exists).\n" "Please, commit your changes before you can merge." @@ -5968,11 +6008,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:1232 git-pull.sh:34 +#: builtin/merge.c:1129 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:1236 +#: builtin/merge.c:1133 msgid "" "You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists).\n" "Please, commit your changes before you can merge." @@ -5980,85 +6020,85 @@ 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:1239 +#: builtin/merge.c:1136 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:1248 +#: builtin/merge.c:1145 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:1253 +#: builtin/merge.c:1150 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:1260 +#: builtin/merge.c:1157 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:1292 +#: builtin/merge.c:1189 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:1295 +#: builtin/merge.c:1192 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:1297 +#: builtin/merge.c:1194 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:1412 +#: builtin/merge.c:1309 #, c-format msgid "Updating %s..%s\n" msgstr "Äang cáºp nháºt %s..%s\n" -#: builtin/merge.c:1450 +#: builtin/merge.c:1348 #, c-format msgid "Trying really trivial in-index merge...\n" -msgstr "Äang thá» hòa trá»™n kiểu 'trivial in-index'...\n" +msgstr "Äang thá» hòa trá»™n kiểu “trivial in-indexâ€...\n" -#: builtin/merge.c:1457 +#: builtin/merge.c:1355 #, c-format msgid "Nope.\n" msgstr "Không.\n" -#: builtin/merge.c:1489 +#: builtin/merge.c:1387 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:1512 builtin/merge.c:1591 +#: builtin/merge.c:1410 builtin/merge.c:1489 #, 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:1516 +#: builtin/merge.c:1414 #, c-format msgid "Trying merge strategy %s...\n" msgstr "Äang thá» chiến lược hòa trá»™n %s...\n" -#: builtin/merge.c:1582 +#: builtin/merge.c:1480 #, 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:1584 +#: builtin/merge.c:1482 #, 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:1593 +#: builtin/merge.c:1491 #, 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:1605 +#: builtin/merge.c:1503 #, c-format msgid "Automatic merge went well; stopped before committing as requested\n" msgstr "" @@ -6091,7 +6131,7 @@ msgstr "tìm tổ tiên của hòa trá»™n n-way Ä‘Æ¡n" #: builtin/merge-base.c:100 msgid "list revs not reachable from others" -msgstr "liệt kê các 'rev' mà nó không thể Ä‘á»c được từ cái khác" +msgstr "liệt kê các “rev†mà nó không thể Ä‘á»c được từ cái khác" #: builtin/merge-base.c:102 msgid "is the first one ancestor of the other?" @@ -6168,7 +6208,7 @@ msgstr "bá» qua các lá»—i liên quan đến di chuyển, đổi tên" #: builtin/mv.c:108 #, c-format msgid "Checking rename of '%s' to '%s'\n" -msgstr "Äang kiểm tra việc đổi tên của `%s' thà nh `%s'\n" +msgstr "Äang kiểm tra việc đổi tên của “%s†thà nh “%sâ€\n" #: builtin/mv.c:112 msgid "bad source" @@ -6202,7 +6242,7 @@ msgstr "Ä‘Ãch đã tồn tại sẵn rồi" #: builtin/mv.c:181 #, c-format msgid "overwriting '%s'" -msgstr "Ä‘ang ghi đè lên `%s'" +msgstr "Ä‘ang ghi đè lên “%sâ€" #: builtin/mv.c:184 msgid "Cannot overwrite" @@ -6262,7 +6302,7 @@ msgstr "Ä‘á»c từ đầu và o tiêu chuẩn" #: builtin/name-rev.c:236 msgid "allow to print `undefined` names" -msgstr "cho phép hiển thị các tên `chÆ°a định nghÄ©a'" +msgstr "cho phép hiển thị các tên `chÆ°a định nghÄ©a`" #: builtin/notes.c:26 msgid "git notes [--ref <notes_ref>] [list [<object>]]" @@ -6377,26 +6417,26 @@ msgstr "git notes get-ref" #: builtin/notes.c:142 #, c-format msgid "unable to start 'show' for object '%s'" -msgstr "không thể khởi chạy 'show' cho đối tượng `%s'" +msgstr "không thể khởi chạy “show†cho đối tượng “%sâ€" #: builtin/notes.c:148 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" +msgstr "không thể fdopen “show†(lệnh hiển thị) mô tả táºp tin (fd) kết xuất" #: builtin/notes.c:158 #, c-format msgid "failed to close pipe to 'show' for object '%s'" -msgstr "gặp lá»—i khi đóng Ä‘Æ°á»ng ống cho lệnh 'show' cho đối tượng `%s'" +msgstr "gặp lá»—i khi đóng Ä‘Æ°á»ng ống cho lệnh “show†cho đối tượng “%sâ€" #: builtin/notes.c:161 #, c-format msgid "failed to finish 'show' for object '%s'" -msgstr "gặp lá»—i khi hoà n thà nh `show' cho đối tượng `%s'" +msgstr "gặp lá»—i khi hoà n thà nh “show†cho đối tượng “%sâ€" #: builtin/notes.c:178 builtin/tag.c:347 #, c-format msgid "could not create file '%s'" -msgstr "không thể tạo táºp tin `%s'" +msgstr "không thể tạo táºp tin “%sâ€" #: builtin/notes.c:192 msgid "Please supply the note contents using either -m or -F option" @@ -6420,12 +6460,12 @@ msgstr "Ná»™i dung ghi chú còn lại %s" #: builtin/notes.c:254 builtin/tag.c:542 #, c-format msgid "cannot read '%s'" -msgstr "không thể Ä‘á»c `%s'" +msgstr "không thể Ä‘á»c “%sâ€" #: builtin/notes.c:256 builtin/tag.c:545 #, c-format msgid "could not open or read '%s'" -msgstr "không thể mở để Ä‘á»c hay ghi `%s'" +msgstr "không thể mở để Ä‘á»c hay ghi “%sâ€" #: builtin/notes.c:275 builtin/notes.c:448 builtin/notes.c:450 #: builtin/notes.c:510 builtin/notes.c:564 builtin/notes.c:647 @@ -6433,12 +6473,12 @@ msgstr "không thể mở để Ä‘á»c hay ghi `%s'" #: builtin/notes.c:971 builtin/reset.c:293 builtin/tag.c:558 #, c-format msgid "Failed to resolve '%s' as a valid ref." -msgstr "Gặp lá»—i khi giải quyết `%s' nhÆ° là má»™t tham chiếu (ref) hợp lệ." +msgstr "Gặp lá»—i khi giải quyết “%s†nhÆ° là má»™t tham chiếu (ref) hợp lệ." #: builtin/notes.c:278 #, c-format msgid "Failed to read object '%s'." -msgstr "Gặp lá»—i khi Ä‘á»c đối tượng `%s'." +msgstr "Gặp lá»—i khi Ä‘á»c đối tượng “%sâ€." #: builtin/notes.c:302 msgid "Cannot commit uninitialized/unreferenced notes tree" @@ -6449,7 +6489,7 @@ msgstr "" #: builtin/notes.c:343 #, c-format msgid "Bad notes.rewriteMode value: '%s'" -msgstr "Giá trị notes.rewriteMode sai: `%s'" +msgstr "Giá trị notes.rewriteMode sai: “%sâ€" #: builtin/notes.c:353 #, c-format @@ -6461,17 +6501,17 @@ msgstr "Từ chối ghi đè ghi chú trong %s (nằm ngoà i của refs/notes/)" #: builtin/notes.c:380 #, c-format msgid "Bad %s value: '%s'" -msgstr "Giá trị %s sai: `%s'" +msgstr "Giá trị %s sai: “%sâ€" #: builtin/notes.c:444 #, c-format msgid "Malformed input line: '%s'." -msgstr "Dòng nháºp và o dị hình: `%s'." +msgstr "Dòng nháºp và o dị hình: “%sâ€." #: builtin/notes.c:459 #, c-format msgid "Failed to copy notes from '%s' to '%s'" -msgstr "Gặp lá»—i khi sao chép ghi chú (note) từ `%s' tá»›i `%s'" +msgstr "Gặp lá»—i khi sao chép ghi chú (note) từ “%s†tá»›i “%sâ€" #: builtin/notes.c:503 builtin/notes.c:557 builtin/notes.c:630 #: builtin/notes.c:642 builtin/notes.c:715 builtin/notes.c:762 @@ -6516,7 +6556,7 @@ msgid "" "existing notes" msgstr "" "Không thể thêm các ghi chú. Äã tìm thấy các ghi chú đã có sẵn cho đối tượng " -"%s. Sá» dụng tùy chá»n '-f' để ghi đè lên các ghi chú cÅ©" +"%s. Sá» dụng tùy chá»n “-f†để ghi đè lên các ghi chú cÅ©" #: builtin/notes.c:588 builtin/notes.c:665 #, c-format @@ -6542,7 +6582,7 @@ msgid "" "existing notes" msgstr "" "Không thể sao chép các ghi chú. Äã tìm thấy các ghi chú đã có sẵn cho đối " -"tượng %s. Sá» dụng tùy chá»n '-f' để ghi đè lên các ghi chú cÅ©" +"tượng %s. Sá» dụng tùy chá»n “-f†để ghi đè lên các ghi chú cÅ©" #: builtin/notes.c:671 #, c-format @@ -6555,8 +6595,8 @@ msgid "" "The -m/-F/-c/-C options have been deprecated for the 'edit' subcommand.\n" "Please use 'git notes add -f -m/-F/-c/-C' instead.\n" msgstr "" -"Các tùy chá»n -m/-F/-c/-C đã cổ không còn dùng nữa cho lệnh con `edit'.\n" -"Xin hãy sá» dụng lệnh sau để thay thế: `git notes add -f -m/-F/-c/-C'.\n" +"Các tùy chá»n -m/-F/-c/-C đã cổ không còn dùng nữa cho lệnh con “editâ€.\n" +"Xin hãy sá» dụng lệnh sau để thay thế: “git notes add -f -m/-F/-c/-Câ€.\n" #: builtin/notes.c:867 msgid "General options" @@ -6571,7 +6611,7 @@ msgid "" "resolve notes conflicts using the given strategy (manual/ours/theirs/union/" "cat_sort_uniq)" msgstr "" -"phân giải các xung Ä‘á»™t `notes' sá» dụng chiến lược đã Ä‘Æ°a ra (manual/ours/" +"phân giải các xung Ä‘á»™t “notes†sá» dụng chiến lược đã Ä‘Æ°a ra (manual/ours/" "theirs/union/cat_sort_uniq)" #: builtin/notes.c:873 @@ -6611,7 +6651,7 @@ msgstr "notes_ref" #: builtin/notes.c:1071 msgid "use notes from <notes_ref>" -msgstr "dùng `notes' từ <notes_ref>" +msgstr "dùng “notes†từ <notes_ref>" #: builtin/notes.c:1106 builtin/remote.c:1598 #, c-format @@ -6635,146 +6675,146 @@ msgstr "" msgid "deflate error (%d)" msgstr "lá»—i giải nén (%d)" -#: builtin/pack-objects.c:2398 +#: builtin/pack-objects.c:2397 #, c-format msgid "unsupported index version %s" msgstr "phiên bản mục lục không được há»— trợ %s" -#: builtin/pack-objects.c:2402 +#: builtin/pack-objects.c:2401 #, c-format msgid "bad index version '%s'" -msgstr "phiên bản mục lục sai `%s'" +msgstr "phiên bản mục lục sai “%sâ€" -#: builtin/pack-objects.c:2425 +#: builtin/pack-objects.c:2424 #, c-format msgid "option %s does not accept negative form" msgstr "tùy chá»n %s không chấp nháºn dạng thức âm" -#: builtin/pack-objects.c:2429 +#: builtin/pack-objects.c:2428 #, c-format msgid "unable to parse value '%s' for option %s" -msgstr "không thể phân tÃch giá trị `%s' cho tùy chá»n %s" +msgstr "không thể phân tÃch giá trị “%s†cho tùy chá»n %s" -#: builtin/pack-objects.c:2448 +#: builtin/pack-objects.c:2447 msgid "do not show progress meter" msgstr "không hiển thị bá»™ Ä‘o tiến trình" -#: builtin/pack-objects.c:2450 +#: builtin/pack-objects.c:2449 msgid "show progress meter" msgstr "hiển thị bá»™ Ä‘o tiến trình" -#: builtin/pack-objects.c:2452 +#: builtin/pack-objects.c:2451 msgid "show progress meter during object writing phase" msgstr "hiển thị bá»™ Ä‘o tiến triển trong suốt pha ghi đối tượng" -#: builtin/pack-objects.c:2455 +#: builtin/pack-objects.c:2454 msgid "similar to --all-progress when progress meter is shown" msgstr "tÆ°Æ¡ng tá»± --all-progress khi bá»™ Ä‘o tiến trình được xuất hiện" -#: builtin/pack-objects.c:2456 +#: builtin/pack-objects.c:2455 msgid "version[,offset]" msgstr "phiên bản[,offset]" -#: builtin/pack-objects.c:2457 +#: builtin/pack-objects.c:2456 msgid "write the pack index file in the specified idx format version" msgstr "ghi táºp tin bảng mục lục gói (pack) ở phiên bản định dạng idx đã cho" -#: builtin/pack-objects.c:2460 +#: builtin/pack-objects.c:2459 msgid "maximum size of each output pack file" msgstr "kcÃh thÆ°á»›c tối Ä‘a cho táºp tin gói được tạo" -#: builtin/pack-objects.c:2462 +#: builtin/pack-objects.c:2461 msgid "ignore borrowed objects from alternate object store" msgstr "bá» qua các đối tượng vay mượn từ kho đối tượng thay thế" -#: builtin/pack-objects.c:2464 +#: builtin/pack-objects.c:2463 msgid "ignore packed objects" msgstr "bá» qua các đối tượng đóng gói" -#: builtin/pack-objects.c:2466 +#: builtin/pack-objects.c:2465 msgid "limit pack window by objects" msgstr "giá»›i hạn cá»a sổ đóng gói theo đối tượng" -#: builtin/pack-objects.c:2468 +#: builtin/pack-objects.c:2467 msgid "limit pack window by memory in addition to object limit" msgstr "giá»›i hạn cá»a sổ đóng gói theo bá»™ nhá»› cá»™ng thêm vá»›i giá»›i hạn đối tượng" -#: builtin/pack-objects.c:2470 +#: builtin/pack-objects.c:2469 msgid "maximum length of delta chain allowed in the resulting pack" -msgstr "Ä‘á»™ dà i tối Ä‘a của chuá»—i móc xÃch `delta' được phép trong gói kết quả" +msgstr "Ä‘á»™ dà i tối Ä‘a của chuá»—i móc xÃch “delta†được phép trong gói kết quả" -#: builtin/pack-objects.c:2472 +#: builtin/pack-objects.c:2471 msgid "reuse existing deltas" msgstr "dùng lại các delta sẵn có" -#: builtin/pack-objects.c:2474 +#: builtin/pack-objects.c:2473 msgid "reuse existing objects" msgstr "dùng lại các đối tượng sẵn có" -#: builtin/pack-objects.c:2476 +#: builtin/pack-objects.c:2475 msgid "use OFS_DELTA objects" msgstr "dùng các đối tượng OFS_DELTA" -#: builtin/pack-objects.c:2478 +#: builtin/pack-objects.c:2477 msgid "use threads when searching for best delta matches" msgstr "sá» dụng các tuyến trình khi tìm kiếm cho các mẫu khá»›p delta tốt nhất" -#: builtin/pack-objects.c:2480 +#: builtin/pack-objects.c:2479 msgid "do not create an empty pack output" msgstr "không thể tạo kết xuất gói (pack) trống rá»—ng" -#: builtin/pack-objects.c:2482 +#: builtin/pack-objects.c:2481 msgid "read revision arguments from standard input" -msgstr " Ä‘á»c tham số `revision' từ thiết bị nháºp chuẩn" +msgstr " Ä‘á»c tham số “revision†từ thiết bị nháºp chuẩn" -#: builtin/pack-objects.c:2484 +#: builtin/pack-objects.c:2483 msgid "limit the objects to those that are not yet packed" msgstr "giá»›i hạn các đối tượng thà nh những cái mà chúng vẫn chÆ°a được đóng gói" -#: builtin/pack-objects.c:2487 +#: builtin/pack-objects.c:2486 msgid "include objects reachable from any reference" msgstr "bao gồm các đối tượng có thể Ä‘á»c được từ bất kỳ tham chiếu nà o" -#: builtin/pack-objects.c:2490 +#: builtin/pack-objects.c:2489 msgid "include objects referred by reflog entries" msgstr "bao gồm các đối tượng được tham chiếu bởi các mục reflog" -#: builtin/pack-objects.c:2493 +#: builtin/pack-objects.c:2492 msgid "output pack to stdout" msgstr "xuất gói ra đầu ra tiêu chuẩn" -#: builtin/pack-objects.c:2495 +#: builtin/pack-objects.c:2494 msgid "include tag objects that refer to objects to be packed" msgstr "bao gồm các đối tượng tham chiếu đến các đối tượng được đóng gói" -#: builtin/pack-objects.c:2497 +#: builtin/pack-objects.c:2496 msgid "keep unreachable objects" msgstr "giữ lại các đối tượng không thể Ä‘á»c được" -#: builtin/pack-objects.c:2498 parse-options.h:141 +#: builtin/pack-objects.c:2497 parse-options.h:141 msgid "time" msgstr "thá»i-gian" -#: builtin/pack-objects.c:2499 +#: builtin/pack-objects.c:2498 msgid "unpack unreachable objects newer than <time>" msgstr "" "xả nén (gỡ khá»i gói) các đối tượng không thể Ä‘á»c được má»›i hÆ¡n <thá»i-gian>" -#: builtin/pack-objects.c:2502 +#: builtin/pack-objects.c:2501 msgid "create thin packs" msgstr "tạo gói nhẹ" -#: builtin/pack-objects.c:2504 +#: builtin/pack-objects.c:2503 msgid "ignore packs that have companion .keep file" msgstr "bá» qua các gói mà nó có táºp tin .keep Ä‘i kèm" -#: builtin/pack-objects.c:2506 +#: builtin/pack-objects.c:2505 msgid "pack compression level" msgstr "mức nén gói" -#: builtin/pack-objects.c:2508 +#: builtin/pack-objects.c:2507 msgid "do not hide commits by grafts" -msgstr "không ẩn các lần chuyển giao bởi `grafts'" +msgstr "không ẩn các lần chuyển giao bởi “graftsâ€" #: builtin/pack-refs.c:6 msgid "git pack-refs [options]" @@ -6826,8 +6866,8 @@ msgid "" "To choose either option permanently, see push.default in 'git help config'." msgstr "" "\n" -"Äể chá»n má»—i tùy chá»n má»™t cách cố định, xem push.default trong `git help " -"config'." +"Äể chá»n má»—i tùy chá»n má»™t cách cố định, xem push.default trong “git help " +"configâ€." #: builtin/push.c:102 #, c-format @@ -6895,9 +6935,9 @@ msgid "" "your current branch '%s', without telling me what to push\n" "to update which remote branch." msgstr "" -"Bạn Ä‘ang push (đẩy lên) máy chủ `%s', mà nó không phải là thượng nguồn " +"Bạn Ä‘ang push (đẩy lên) máy chủ “%sâ€, mà nó không phải là thượng nguồn " "(upstream) của\n" -"nhánh hiện tại `%s' của bạn, mà không báo cho tôi biết là cái gì được push\n" +"nhánh hiện tại “%s†của bạn, mà không báo cho tôi biết là cái gì được push\n" "để cáºp nháºt nhánh máy chủ nà o." #: builtin/push.c:151 @@ -6918,7 +6958,7 @@ msgid "" "'current' instead of 'simple' if you sometimes use older versions of Git)" msgstr "" "biến push.default chÆ°a được đặt; giá trị ngầm định của nó\n" -"đã được thay đổi trong Git 2.0 từ 'matching' thà nh 'simple'.\n" +"đã được thay đổi trong Git 2.0 từ “matching†thà nh “simpleâ€.\n" "Äể không hiển thị nhắc nhở nà y và duy trì cách xá» lý sau\n" "những thay đổi mặc định nà y, hãy chạy lệnh:\n" "\n" @@ -6928,10 +6968,10 @@ msgstr "" "\n" " git config --global push.default simple\n" "\n" -"Xem `git help config' và tìm đến `push.default' để có thêm thông tin.\n" -"(chế Ä‘á»™ 'simple' được bắt đầu sá» dụng từ Git 1.7.11. Sá» dụng chế Ä‘á»™ tÆ°Æ¡ng " +"Xem “git help config†và tìm đến “push.default†để có thêm thông tin.\n" +"(chế Ä‘á»™ “simple†được bắt đầu sá» dụng từ Git 1.7.11. Sá» dụng chế Ä‘á»™ tÆ°Æ¡ng " "tá»±\n" -"`current' thay vì `simple' nếu bạn thỉnh thoảng phải sá» dụng bản Git cÅ©)" +"“current†thay vì “simple†nếu bạn thỉnh thoảng phải sá» dụng bản Git cÅ©)" #: builtin/push.c:199 msgid "" @@ -6948,10 +6988,10 @@ msgid "" "See the 'Note about fast-forwards' in 'git push --help' for details." msgstr "" "Việc cáºp nháºt bị từ chối bởi vì đầu mút của nhánh được push nằm đằng sau bá»™\n" -"pháºn tÆ°Æ¡ng ứng của máy chủ. Hòa trá»™n vá»›i các thay đổi từ máy chủ (v.d. `git " -"pull')\n" +"pháºn tÆ°Æ¡ng ứng của máy chủ. Hòa trá»™n vá»›i các thay đổi từ máy chủ (v.d. “git " +"pullâ€)\n" "trÆ°á»›c khi lại push lần nữa.\n" -"Xem trong phần 'Note about fast-forwards' từ lệnh `git push --help' để có " +"Xem trong phần “Note about fast-forwards†từ lệnh “git push --help†để có " "thông tin chi tiết." #: builtin/push.c:212 @@ -6964,9 +7004,9 @@ msgstr "" "Việc cáºp nháºt bị từ chối bởi vì đầu mút của nhánh được push nằm đằng sau bá»™\n" "pháºn tÆ°Æ¡ng ứng của máy chủ. Nếu bạn không có ý định push nhánh đó, bạn có lẽ " "muốn\n" -"chỉ định các nhánh để push hoặt là đặt ná»™i dung cho biến cấu hình 'push." -"default'\n" -"thà nh 'simple', 'current' hoặc 'upstream' để chỉ push nhánh hiện hà nh mà " +"chỉ định các nhánh để push hoặt là đặt ná»™i dung cho biến cấu hình “push." +"defaultâ€\n" +"thà nh “simpleâ€, “current†hoặc “upstream†để chỉ push nhánh hiện hà nh mà " "thôi." #: builtin/push.c:218 @@ -6979,8 +7019,8 @@ msgstr "" "Việc cáºp nháºt bị từ chối bởi vì đầu mút của nhánh được push nằm đằng sau bá»™\n" "pháºn tÆ°Æ¡ng ứng của máy chủ. Checkou nhánh nà y và hòa trá»™n vá»›i các thay đổi " "từ máy chủ\n" -"(v.d. `git pull') trÆ°á»›c khi lại push lần nữa.\n" -"Xem trong phần 'Note about fast-forwards' từ lệnh `git push --help' để có " +"(v.d. “git pullâ€) trÆ°á»›c khi lại push lần nữa.\n" +"Xem trong phần “Note about fast-forwards†từ lệnh “git push --help†để có " "thông tin chi tiết." #: builtin/push.c:258 @@ -6991,12 +7031,12 @@ msgstr "Äang push (đẩy) lên %s\n" #: builtin/push.c:262 #, c-format msgid "failed to push some refs to '%s'" -msgstr "gặp lá»—i khi push (đẩy lên) má»™t số tham chiếu (ref) đến `%s'" +msgstr "gặp lá»—i khi push (đẩy lên) má»™t số tham chiếu (ref) đến “%sâ€" #: builtin/push.c:294 #, c-format msgid "bad repository '%s'" -msgstr "repository (kho) sai `%s'" +msgstr "repository (kho) sai “%sâ€" #: builtin/push.c:295 msgid "" @@ -7126,11 +7166,11 @@ msgstr "thá»±c hiện má»™t hòa trá»™n thêm và o việc Ä‘á»c" #: builtin/read-tree.c:117 msgid "3-way merge if no file level merging required" msgstr "" -"hòa trá»™n kiểu `3-way' nếu không có táºp tin mức hòa trá»™n nà o được yêu cầu " +"hòa trá»™n kiểu “3-way†nếu không có táºp tin mức hòa trá»™n nà o được yêu cầu " #: builtin/read-tree.c:119 msgid "3-way merge in presence of adds and removes" -msgstr "hòa trá»™n 3-way trong sá»± hiện diện của `adds' và `removes'" +msgstr "hòa trá»™n 3-way trong sá»± hiện diện của “adds†và “removesâ€" #: builtin/read-tree.c:121 msgid "same as -m, but discard unmerged entries" @@ -7192,7 +7232,7 @@ msgstr "git remote rename <tên-cÅ©> <tên-má»›i>" msgid "git remote remove <name>" msgstr "git remote remove <tên>" -#: builtin/remote.c:15 +#: builtin/remote.c:15 builtin/remote.c:42 msgid "git remote set-head <name> (-a | -d | <branch>)" msgstr "git remote set-head <tên> (-a | -d | <nhánh>)" @@ -7230,10 +7270,6 @@ msgstr "git remote set-url --delete <tên> <url>" msgid "git remote add [<options>] <name> <url>" msgstr "git remote add [<các-tùy-chá»n>] <tên> <url>" -#: builtin/remote.c:42 -msgid "git remote set-head <name> (-a | -d | <branch>])" -msgstr "git remote set-head <tên> (-a | -d | <nhánh>])" - #: builtin/remote.c:47 msgid "git remote set-branches <name> <branch>..." msgstr "git remote set-branches <tên> <nhánh>..." @@ -7307,7 +7343,7 @@ msgstr "Ä‘ang chỉ định má»™t nhánh master không hợp lý vá»›i tùy chá» #: builtin/remote.c:187 msgid "specifying branches to track makes sense only with fetch mirrors" -msgstr "chỉ định những nhánh để theo vết chỉ hợp lý vá»›i các 'fetch mirror'" +msgstr "chỉ định những nhánh để theo vết chỉ hợp lý vá»›i các “fetch mirrorâ€" #: builtin/remote.c:195 builtin/remote.c:646 #, c-format @@ -7317,12 +7353,12 @@ msgstr "máy chủ %s đã tồn tại rồi." #: builtin/remote.c:199 builtin/remote.c:650 #, c-format msgid "'%s' is not a valid remote name" -msgstr "`%s' không phải tên máy chủ hợp lệ" +msgstr "“%s†không phải tên máy chủ hợp lệ" #: builtin/remote.c:243 #, c-format msgid "Could not setup master '%s'" -msgstr "Không thể cà i đặt nhánh master `%s'" +msgstr "Không thể cà i đặt nhánh master “%sâ€" #: builtin/remote.c:299 #, c-format @@ -7345,7 +7381,7 @@ msgstr "(xoá)" #: builtin/remote.c:595 builtin/remote.c:601 builtin/remote.c:607 #, c-format msgid "Could not append '%s' to '%s'" -msgstr "Không thể nối thêm `%s' và o `%s'" +msgstr "Không thể nối thêm “%s†và o “%sâ€" #: builtin/remote.c:639 builtin/remote.c:792 builtin/remote.c:890 #, c-format @@ -7355,12 +7391,12 @@ msgstr "Không có máy chủ nà o nhÆ° thế: %s" #: builtin/remote.c:656 #, c-format msgid "Could not rename config section '%s' to '%s'" -msgstr "Không thể đổi tên chÆ°Æ¡ng (section) cấu hình từ `%s' thà nh `%s'" +msgstr "Không thể đổi tên chÆ°Æ¡ng (section) cấu hình từ “%s†thà nh “%sâ€" #: builtin/remote.c:662 builtin/remote.c:799 #, c-format msgid "Could not remove config section '%s'" -msgstr "Không thể gỡ bá» chÆ°Æ¡ng (section) cấu hình `%s'" +msgstr "Không thể gỡ bá» chÆ°Æ¡ng (section) cấu hình “%sâ€" #: builtin/remote.c:677 #, c-format @@ -7369,19 +7405,19 @@ msgid "" "\t%s\n" "\tPlease update the configuration manually if necessary." msgstr "" -"Không cáºp nháºt 'non-default fetch respec'\n" +"Không cáºp nháºt “non-default fetch respecâ€\n" "\t%s\n" "\tXin hãy cáºp nháºt phần cấu hình má»™t cách thủ công nếu thấy cần thiết." #: builtin/remote.c:683 #, c-format msgid "Could not append '%s'" -msgstr "Không thể nối thêm `%s'" +msgstr "Không thể nối thêm “%sâ€" #: builtin/remote.c:694 #, c-format msgid "Could not set '%s'" -msgstr "Không thể đặt `%s'" +msgstr "Không thể đặt “%sâ€" #: builtin/remote.c:716 #, c-format @@ -7424,7 +7460,7 @@ msgstr " được theo vết" #: builtin/remote.c:948 msgid " stale (use 'git remote prune' to remove)" -msgstr " cÅ© (dùng `git remote prune' để gỡ bá»)" +msgstr " cÅ© (dùng “git remote prune†để gỡ bá»)" #: builtin/remote.c:950 msgid " ???" @@ -7546,19 +7582,19 @@ msgstr " (trạng thái không được yêu cầu)" #: builtin/remote.c:1163 msgid " Local branch configured for 'git pull':" msgid_plural " Local branches configured for 'git pull':" -msgstr[0] " Nhánh ná»™i bá»™ đã được cấu hình cho lệnh `git pull':" -msgstr[1] " Những nhánh ná»™i bá»™ đã được cấu hình cho lệnh `git pull':" +msgstr[0] " Nhánh ná»™i bá»™ đã được cấu hình cho lệnh “git pullâ€:" +msgstr[1] " Những nhánh ná»™i bá»™ đã được cấu hình cho lệnh “git pullâ€:" #: builtin/remote.c:1171 msgid " Local refs will be mirrored by 'git push'" -msgstr " refs ná»™i bá»™ sẽ được phản chiếu bởi lệnh `git push'" +msgstr " refs ná»™i bá»™ sẽ được phản chiếu bởi lệnh “git pushâ€" #: builtin/remote.c:1178 #, c-format msgid " Local ref configured for 'git push'%s:" msgid_plural " Local refs configured for 'git push'%s:" -msgstr[0] " Tham chiếu ná»™i bá»™ được cấu hình cho lệnh `git push'%s:" -msgstr[1] " Những tham chiếu ná»™i bá»™ được cấu hình cho lệnh `git push'%s:" +msgstr[0] " Tham chiếu ná»™i bá»™ được cấu hình cho lệnh “git pushâ€%s:" +msgstr[1] " Những tham chiếu ná»™i bá»™ được cấu hình cho lệnh “git pushâ€%s:" #: builtin/remote.c:1199 msgid "set refs/remotes/<name>/HEAD according to remote" @@ -7628,7 +7664,7 @@ msgstr "cắt máy chủ sau khi lấy vá»" #: builtin/remote.c:1387 builtin/remote.c:1461 #, c-format msgid "No such remote '%s'" -msgstr "Không có máy chủ nà o có tên `%s'" +msgstr "Không có máy chủ nà o có tên “%sâ€" #: builtin/remote.c:1407 msgid "add branch" @@ -7640,7 +7676,7 @@ msgstr "chÆ°a chỉ ra máy chủ nà o" #: builtin/remote.c:1436 msgid "manipulate push URLs" -msgstr "đẩy các `URL' bằng tay" +msgstr "đẩy các “URL†bằng tay" #: builtin/remote.c:1438 msgid "add URL" @@ -7684,15 +7720,15 @@ msgstr "git replace -d <đối tượng>..." msgid "git replace -l [<pattern>]" msgstr "git replace -l [<mẫu>]" -#: builtin/replace.c:118 +#: builtin/replace.c:121 msgid "list replace refs" msgstr "liệt kê các refs thay thế" -#: builtin/replace.c:119 +#: builtin/replace.c:122 msgid "delete replace refs" msgstr "xóa tham chiếu (refs) thay thế" -#: builtin/replace.c:120 +#: builtin/replace.c:123 msgid "replace the ref if it exists" msgstr "thay thế tham chiếu (ref) nếu nó đã sẵn có" @@ -7796,7 +7832,7 @@ msgstr "đặt lại HEAD nhÆ°ng giữ lại các thay đổi ná»™i bá»™" #: builtin/reset.c:303 #, c-format msgid "Could not parse object '%s'." -msgstr "không thể phân tÃch đối tượng `%s'." +msgstr "không thể phân tÃch đối tượng “%sâ€." #: builtin/reset.c:308 msgid "--patch is incompatible with --{hard,mixed,soft}" @@ -7805,8 +7841,8 @@ msgstr "--patch xung khắc vá»›i --{hard,mixed,soft}" #: builtin/reset.c:317 msgid "--mixed with paths is deprecated; use 'git reset -- <paths>' instead." msgstr "" -"--mixed vá»›i các Ä‘Æ°á»ng dẫn không còn dùng nữa; hãy thay thế bằng lệnh `git " -"reset -- <Ä‘Æ°á»ng_dẫn>'." +"--mixed vá»›i các Ä‘Æ°á»ng dẫn không còn dùng nữa; hãy thay thế bằng lệnh “git " +"reset -- <Ä‘Æ°á»ng_dẫn>â€." #: builtin/reset.c:319 #, c-format @@ -7821,7 +7857,7 @@ msgstr "%s reset không được phép trên kho bare (trên máy chủ)" #: builtin/reset.c:347 #, c-format msgid "Could not reset index file to revision '%s'." -msgstr "Không thể đặt lại (reset) bảng mục lục thà nh Ä‘iểm xét lại `%s'." +msgstr "Không thể đặt lại (reset) bảng mục lục thà nh Ä‘iểm xét lại “%sâ€." #: builtin/rev-parse.c:339 msgid "git rev-parse --parseopt [options] -- [<args>...]" @@ -7829,7 +7865,7 @@ msgstr "git rev-parse --parseopt [các-tùy-chá»n] -- [<th.số>...]" #: builtin/rev-parse.c:344 msgid "keep the `--` passed as an arg" -msgstr "giữ '--' chuyển qua là m tham số" +msgstr "giữ `--` chuyển qua là m tham số" #: builtin/rev-parse.c:346 msgid "stop parsing after the first non-option argument" @@ -7938,63 +7974,73 @@ msgstr "revert gặp lá»—i" msgid "cherry-pick failed" msgstr "cherry-pick gặp lá»—i" -#: builtin/rm.c:14 +#: builtin/rm.c:15 msgid "git rm [options] [--] <file>..." msgstr "git rm [các-tùy-chá»n] [--] <táºp-tin>..." -#: builtin/rm.c:109 +#: builtin/rm.c:64 builtin/rm.c:186 +#, c-format +msgid "" +"submodule '%s' (or one of its nested submodules) uses a .git directory\n" +"(use 'rm -rf' if you really want to remove it including all of its history)" +msgstr "" +"mô-Ä‘un-con '%s' (hoặc cái nằm trong các mô-Ä‘un-con) dùng thÆ° mục .git\n" +"(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)" + +#: builtin/rm.c:174 #, c-format msgid "" "'%s' has staged content different from both the file and the HEAD\n" "(use -f to force removal)" msgstr "" -"`%s' có ná»™i dung được lÆ°u trạng thái khác biệt từ cả táºp tin và cả HEAD\n" +"“%s†có ná»™i dung được lÆ°u trạng thái khác biệt từ cả táºp tin và cả HEAD\n" "(dùng tùy chá»n -f để ép buá»™c gỡ bá»)" -#: builtin/rm.c:115 +#: builtin/rm.c:180 #, c-format msgid "" "'%s' has changes staged in the index\n" "(use --cached to keep the file, or -f to force removal)" msgstr "" -"`%s' có các thay đổi được lÆ°u trạng thái trong bảng mục lục\n" +"“%s†có các thay đổi được lÆ°u trạng thái trong bảng mục lục\n" "(dùng tùy chá»n --cached để giữ táºp tin, hoặc -f để ép buá»™c gỡ bá»)" -#: builtin/rm.c:119 +#: builtin/rm.c:191 #, c-format msgid "" "'%s' has local modifications\n" "(use --cached to keep the file, or -f to force removal)" msgstr "" -"`%s' có các thay đổi ná»™i bá»™\n" +"“%s†có các thay đổi ná»™i bá»™\n" "(dùng tùy chá»n --cached để giữ táºp tin, hoặc -f để ép buá»™c gỡ bá»)" -#: builtin/rm.c:134 +#: builtin/rm.c:207 msgid "do not list removed files" msgstr "không liệt kê các táºp tin đã gỡ bá»" -#: builtin/rm.c:135 +#: builtin/rm.c:208 msgid "only remove from the index" msgstr "chỉ gỡ bá» từ mục lục" -#: builtin/rm.c:136 +#: builtin/rm.c:209 msgid "override the up-to-date check" msgstr "ghi đè lên kiểm tra cáºp nháºt" -#: builtin/rm.c:137 +#: builtin/rm.c:210 msgid "allow recursive removal" msgstr "cho phép gỡ bỠđệ qui" -#: builtin/rm.c:139 +#: builtin/rm.c:212 msgid "exit with a zero status even if nothing matched" msgstr "thoát ra vá»›i trạng thái khác không tháºm chà nếu không có gì khá»›p" -#: builtin/rm.c:194 +#: builtin/rm.c:283 #, c-format msgid "not removing '%s' recursively without -r" -msgstr "không thể gỡ bá» `%s' má»™t cách đệ qui mà không có tùy chá»n -r" +msgstr "không thể gỡ bỠ“%s†má»™t cách đệ qui mà không có tùy chá»n -r" -#: builtin/rm.c:230 +#: builtin/rm.c:322 #, c-format msgid "git rm: unable to remove %s" msgstr "git rm: không thể gỡ bá» %s" @@ -8054,7 +8100,7 @@ msgstr "hiển thị các nhánh remote-tracking" #: builtin/show-branch.c:655 msgid "color '*!+-' corresponding to the branch" -msgstr "mà u '*!+-' tÆ°Æ¡ng ứng vá»›i nhánh" +msgstr "mà u “*!+-†tÆ°Æ¡ng ứng vá»›i nhánh" #: builtin/show-branch.c:657 msgid "show <n> more commits after the common ancestor" @@ -8106,7 +8152,7 @@ msgstr "<n>[,<cÆ¡ sở>]" #: builtin/show-branch.c:679 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)" +msgstr "hiển thị <n> các mục “ref-log†gần nhất kể từ ná»n (base)" #: builtin/show-ref.c:10 msgid "" @@ -8120,38 +8166,38 @@ msgstr "" msgid "git show-ref --exclude-existing[=pattern] < ref-list" msgstr "git show-ref --exclude-existing[=mẫu] < ref-list" -#: builtin/show-ref.c:182 +#: builtin/show-ref.c:165 msgid "only show tags (can be combined with heads)" msgstr "chỉ hiển thị thẻ (có thể tổ hợp cùng vá»›i đầu)" -#: builtin/show-ref.c:183 +#: builtin/show-ref.c:166 msgid "only show heads (can be combined with tags)" msgstr "chỉ hiển thị đầu (có thể tổ hợp cùng vá»›i thẻ)" -#: builtin/show-ref.c:184 +#: builtin/show-ref.c:167 msgid "stricter reference checking, requires exact ref path" msgstr "" "việc kiểm tra tham chiếu chÃnh xác, đòi há»i chÃnh xác Ä‘Æ°á»ng dẫn tham chiếu " "(ref)" -#: builtin/show-ref.c:187 builtin/show-ref.c:189 +#: builtin/show-ref.c:170 builtin/show-ref.c:172 msgid "show the HEAD reference" msgstr "hiển thị tham chiếu của HEAD" -#: builtin/show-ref.c:191 +#: builtin/show-ref.c:174 msgid "dereference tags into object IDs" msgstr "bãi bá» tham chiếu các thẻ thà nh ra các ID đối tượng" -#: builtin/show-ref.c:193 +#: builtin/show-ref.c:176 msgid "only show SHA1 hash using <n> digits" msgstr "chỉ hiển thị mã băm SHA1 sá» dụng <n> chữ số" -#: builtin/show-ref.c:197 +#: builtin/show-ref.c:180 msgid "do not print results to stdout (useful with --verify)" msgstr "" "không hiển thị kết quả ra đầu ra chuẩn (stdout) (chỉ hữu dụng vá»›i --verify)" -#: builtin/show-ref.c:199 +#: builtin/show-ref.c:182 msgid "show refs from stdin that aren't in local repository" msgstr "" "hiển thị các tham chiếu (refs) từ đầu và o tiêu chuẩn (stdin) cái mà không ở " @@ -8161,20 +8207,28 @@ msgstr "" msgid "git symbolic-ref [options] name [ref]" msgstr "git symbolic-ref [các-tùy-chá»n] tên [t.chiếu]" -#: builtin/symbolic-ref.c:38 +#: builtin/symbolic-ref.c:8 +msgid "git symbolic-ref -d [-q] name" +msgstr "git symbolic-ref -d [-q] tên" + +#: builtin/symbolic-ref.c:40 msgid "suppress error message for non-symbolic (detached) refs" msgstr "" -"chặn các thông tin lá»—i cho các tham chiếu (refs) `non-symbolic' (bị tách ra)" +"chặn các thông tin lá»—i cho các tham chiếu (refs) “non-symbolic†(bị tách ra)" -#: builtin/symbolic-ref.c:39 +#: builtin/symbolic-ref.c:41 +msgid "delete symbolic ref" +msgstr "xóa tham chiếu (ref) tượng trÆ°ng" + +#: builtin/symbolic-ref.c:42 msgid "shorten ref output" msgstr "là m ngắn kết xuất ref (tham chiếu)" -#: builtin/symbolic-ref.c:40 builtin/update-ref.c:18 +#: builtin/symbolic-ref.c:43 builtin/update-ref.c:18 msgid "reason" msgstr "lý do" -#: builtin/symbolic-ref.c:40 builtin/update-ref.c:18 +#: builtin/symbolic-ref.c:43 builtin/update-ref.c:18 msgid "reason of the update" msgstr "lý do cáºp nháºt" @@ -8203,7 +8257,7 @@ msgstr "git tag -v <tên-thẻ>..." #: builtin/tag.c:60 #, c-format msgid "malformed object at '%s'" -msgstr "đối tượng dị hình tại `%s'" +msgstr "đối tượng dị hình tại “%sâ€" #: builtin/tag.c:207 #, c-format @@ -8213,17 +8267,17 @@ msgstr "tên thẻ quá dà i: %.*s..." #: builtin/tag.c:212 #, c-format msgid "tag '%s' not found." -msgstr "không tìm thấy tìm thấy thẻ `%s'." +msgstr "không tìm thấy tìm thấy thẻ “%sâ€." #: builtin/tag.c:227 #, c-format msgid "Deleted tag '%s' (was %s)\n" -msgstr "Thẻ đã bị xóa `%s' (trÆ°á»›c là %s)\n" +msgstr "Thẻ đã bị xóa “%s†(trÆ°á»›c là %s)\n" #: builtin/tag.c:239 #, c-format msgid "could not verify the tag '%s'" -msgstr "không thể thẩm tra thẻ `%s'" +msgstr "không thể thẩm tra thẻ “%sâ€" #: builtin/tag.c:249 msgid "" @@ -8236,7 +8290,7 @@ msgstr "" "\n" "#\n" "# Viết các ghi chú cho (thẻ) tag\n" -"# Những dòng được bắt đầu bằng '#' sẽ được bá» qua.\n" +"# Những dòng được bắt đầu bằng “#†sẽ được bá» qua.\n" "#\n" #: builtin/tag.c:256 @@ -8251,7 +8305,7 @@ msgstr "" "\n" "#\n" "# Viết các ghi chú cho (thẻ) tag\n" -"# Những dòng được bắt đầu bằng '#' sẽ được bá» qua; bạn có thể xóa chúng Ä‘i " +"# Những dòng được bắt đầu bằng “#†sẽ được bá» qua; bạn có thể xóa chúng Ä‘i " "nếu muốn.\n" "#\n" @@ -8282,12 +8336,12 @@ msgstr "Ná»™i dung ghi chú còn lại %s\n" #: builtin/tag.c:425 msgid "switch 'points-at' requires an object" -msgstr "chuyển đến 'points-at' yêu cần má»™t đối tượng" +msgstr "chuyển đến “points-at†yêu cần má»™t đối tượng" #: builtin/tag.c:427 #, c-format msgid "malformed object name '%s'" -msgstr "tên đối tượng dị hình `%s'" +msgstr "tên đối tượng dị hình “%sâ€" #: builtin/tag.c:447 msgid "list tag names" @@ -8372,12 +8426,12 @@ msgstr "quá nhiá»u đối số" #: builtin/tag.c:561 #, c-format msgid "'%s' is not a valid tag name." -msgstr "`%s' không phải thẻ hợp lệ." +msgstr "“%s†không phải thẻ hợp lệ." #: builtin/tag.c:566 #, c-format msgid "tag '%s' already exists" -msgstr "Thẻ `%s' đã tồn tại rồi" +msgstr "Thẻ “%s†đã tồn tại rồi" #: builtin/tag.c:584 #, c-format @@ -8392,121 +8446,121 @@ msgstr "%s: không thể cáºp nháºt ref (tham chiếu)" #: builtin/tag.c:588 #, c-format msgid "Updated tag '%s' (was %s)\n" -msgstr "Thẻ đã cáºp nháºt `%s' (cÅ© là %s)\n" +msgstr "Äã cáºp nháºt thẻ “%s†(trÆ°á»›c là %s)\n" #: builtin/update-index.c:401 msgid "git update-index [options] [--] [<file>...]" msgstr "git update-index [các-tùy-chá»n] [<táºp-tin>...]" -#: builtin/update-index.c:717 +#: builtin/update-index.c:718 msgid "continue refresh even when index needs update" msgstr "tiếp tục là m má»›i ngay cả khi bảng mục lục cần được cáºp nháºt" -#: builtin/update-index.c:720 +#: builtin/update-index.c:721 msgid "refresh: ignore submodules" msgstr "refresh: lá» Ä‘i mô-Ä‘un-con" -#: builtin/update-index.c:723 +#: builtin/update-index.c:724 msgid "do not ignore new files" msgstr "không bá» qua các táºp tin má»›i tạo" -#: builtin/update-index.c:725 +#: builtin/update-index.c:726 msgid "let files replace directories and vice-versa" -msgstr "để các táºp tin thay thế các thÆ° mục và `vice-versa'" +msgstr "để các táºp tin thay thế các thÆ° mục và “vice-versaâ€" -#: builtin/update-index.c:727 +#: builtin/update-index.c:728 msgid "notice files missing from worktree" msgstr "thông báo các táºp-tin thiếu trong thÆ°-mục là m việc" -#: builtin/update-index.c:729 +#: builtin/update-index.c:730 msgid "refresh even if index contains unmerged entries" msgstr "" "là m tÆ°Æ¡i má»›i tháºm chà khi bảng mục lục chứa các mục tin chÆ°a được hòa trá»™n" -#: builtin/update-index.c:732 +#: builtin/update-index.c:733 msgid "refresh stat information" msgstr "lấy lại thông tin thống kê" -#: builtin/update-index.c:736 +#: builtin/update-index.c:737 msgid "like --refresh, but ignore assume-unchanged setting" -msgstr "giống --refresh, nhÆ°ng bá» qua các cà i đặt `assume-unchanged'" +msgstr "giống --refresh, nhÆ°ng bá» qua các cà i đặt “assume-unchangedâ€" -#: builtin/update-index.c:740 +#: builtin/update-index.c:741 msgid "<mode> <object> <path>" msgstr "<mode> <đối tượng> <Ä‘Æ°á»ng dẫn>" -#: builtin/update-index.c:741 +#: builtin/update-index.c:742 msgid "add the specified entry to the index" msgstr "thêm các táºp tin đã chỉ ra và o bảng mục lục" -#: builtin/update-index.c:745 +#: builtin/update-index.c:746 msgid "(+/-)x" msgstr "(+/-)x" -#: builtin/update-index.c:746 +#: builtin/update-index.c:747 msgid "override the executable bit of the listed files" msgstr "ghi đè lên bÃt thi hà nh của các táºp tin được liệt kê" -#: builtin/update-index.c:750 +#: builtin/update-index.c:751 msgid "mark files as \"not changing\"" msgstr "Äánh dấu các táºp tin là \"không thay đổi\"" -#: builtin/update-index.c:753 +#: builtin/update-index.c:754 msgid "clear assumed-unchanged bit" msgstr "xóa bÃt assumed-unchanged" -#: builtin/update-index.c:756 +#: builtin/update-index.c:757 msgid "mark files as \"index-only\"" -msgstr "đánh dấu các táºp tin là `chỉ-Ä‘á»c'" +msgstr "đánh dấu các táºp tin là “chỉ-Ä‘á»câ€" -#: builtin/update-index.c:759 +#: builtin/update-index.c:760 msgid "clear skip-worktree bit" msgstr "xóa bÃt skip-worktree" -#: builtin/update-index.c:762 +#: builtin/update-index.c:763 msgid "add to index only; do not add content to object database" msgstr "" "chỉ thêm và o bảng mục lục; không thêm ná»™i dung và o cÆ¡ sở dữ liệu đối tượng" -#: builtin/update-index.c:764 +#: builtin/update-index.c:765 msgid "remove named paths even if present in worktree" msgstr "" "gỡ bá» các Ä‘Æ°á»ng dẫn được đặt tên tháºm chà cả khi nó hiện diện trong thÆ° mục " "là m việc" -#: builtin/update-index.c:766 +#: builtin/update-index.c:767 msgid "with --stdin: input lines are terminated by null bytes" msgstr "vá»›i tùy chá»n --stdin: các dòng đầu và o được chấm dứt bởi ký tá»± null" -#: builtin/update-index.c:768 +#: builtin/update-index.c:769 msgid "read list of paths to be updated from standard input" msgstr "Ä‘á»c danh sách Ä‘Æ°á»ng dẫn cần cáºp nháºt từ đầu và o tiêu chuẩn" -#: builtin/update-index.c:772 +#: builtin/update-index.c:773 msgid "add entries from standard input to the index" msgstr "không thể Ä‘á»c các mục từ đầu và o tiêu chuẩn và o bảng mục lục" -#: builtin/update-index.c:776 +#: builtin/update-index.c:777 msgid "repopulate stages #2 and #3 for the listed paths" msgstr "phục hồi các trạng thái #2 và #3 cho các Ä‘Æ°á»ng dẫn được liệt kê" -#: builtin/update-index.c:780 +#: builtin/update-index.c:781 msgid "only update entries that differ from HEAD" msgstr "chỉ cáºp nháºt các mục tin mà nó khác biệt so vá»›i HEAD" -#: builtin/update-index.c:784 +#: builtin/update-index.c:785 msgid "ignore files missing from worktree" msgstr "bá» qua các táºp-tin thiếu trong thÆ°-mục là m việc" -#: builtin/update-index.c:787 +#: builtin/update-index.c:788 msgid "report actions to standard output" msgstr "báo cáo các thao tác ra thiết bị xuất chuẩn" -#: builtin/update-index.c:789 +#: builtin/update-index.c:790 msgid "(for porcelains) forget saved unresolved conflicts" -msgstr "(cho `porcelains') quên các xung Ä‘á»™t chÆ°a được giải quyết đã ghi" +msgstr "(cho “porcelainsâ€) quên các xung Ä‘á»™t chÆ°a được giải quyết đã ghi" -#: builtin/update-index.c:793 +#: builtin/update-index.c:794 msgid "write index in this format" msgstr "ghi mục lục ở định dạng nà y" @@ -8573,7 +8627,7 @@ 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." msgstr "" -"Chạy lệnh `git help <tên-lệnh>' để có thêm thông tin vá» lệnh được chỉ ra." +"Chạy lệnh “git help <tên-lệnh>†để có thêm thông tin vá» lệnh được chỉ ra." #: parse-options.h:156 msgid "no-op (backward compatibility)" @@ -8605,7 +8659,7 @@ msgstr "Liệt kê, tạo hay là xóa các nhánh" #: common-cmds.h:11 msgid "Checkout a branch or paths to the working tree" -msgstr "Checkout má»™t nhánh hay các Ä‘Æ°á»ng dẫn tá»›i cây là m việc" +msgstr "Lấy ra (checkout) má»™t nhánh hay các Ä‘Æ°á»ng dẫn tá»›i cây là m việc" #: common-cmds.h:12 msgid "Clone a repository into a new directory" @@ -8636,7 +8690,7 @@ msgstr "" #: common-cmds.h:18 msgid "Show commit logs" -msgstr "hiển thị nháºt ký các lần commit (chuyển giao)" +msgstr "Hiển thị nháºt ký các lần chuyển giao (commit)" #: common-cmds.h:19 msgid "Join two or more development histories together" @@ -8650,7 +8704,7 @@ msgstr "Di chuyển, đổi tên má»™t táºp tin, thÆ° mục hay liên kết tÆ° #: common-cmds.h:21 msgid "Fetch from and merge with another repository or a local branch" -msgstr "Fetch (lấy vá») và hòa trá»™ng vá»›i kho khác hay nhánh ná»™i bá»™" +msgstr "Lấy vá» (fetch) và hòa trá»™n vá»›i kho khác hay nhánh ná»™i bá»™" #: common-cmds.h:22 msgid "Update remote refs along with associated objects" @@ -8693,7 +8747,7 @@ msgid "" "You seem to have moved HEAD since the last 'am' failure.\n" "Not rewinding to ORIG_HEAD" msgstr "" -"Bạn có lẽ đã có HEAD đã bị di chuyển Ä‘i kể từ lần 'am' thất bại cuối cùng.\n" +"Bạn có lẽ đã có HEAD đã bị di chuyển Ä‘i kể từ lần “am†thất bại cuối cùng.\n" "Không thể chuyển tá»›i ORIG_HEAD" #: git-am.sh:105 @@ -8711,11 +8765,11 @@ msgstr "" #: git-am.sh:121 msgid "Cannot fall back to three-way merge." -msgstr "Äang trở lại để hòa trá»™n kiểu 'three-way'." +msgstr "Äang trở lại để hòa trá»™n kiểu “three-wayâ€." #: git-am.sh:137 msgid "Repository lacks necessary blobs to fall back on 3-way merge." -msgstr "Kho thiếu đối tượng blob cần thiết để trở vá» trên '3-way merge'." +msgstr "Kho thiếu đối tượng blob cần thiết để trở vá» trên “3-way mergeâ€." #: git-am.sh:139 msgid "Using index info to reconstruct a base tree..." @@ -8732,7 +8786,7 @@ msgstr "" #: git-am.sh:163 msgid "Falling back to patching base and 3-way merge..." -msgstr "Äang trở lại để vá cÆ¡ sở và '3-way merge'..." +msgstr "Äang trở lại để vá cÆ¡ sở và “3-way mergeâ€..." #: git-am.sh:179 msgid "Failed to merge in the changes." @@ -8824,7 +8878,7 @@ msgid "" "If there is nothing left to stage, chances are that something else\n" "already introduced the same changes; you might want to skip this patch." msgstr "" -"Không có thay đổi nà o - bạn đã quên sá» dụng lệnh `git add' à ?\n" +"Không có thay đổi nà o - bạn đã quên sá» dụng lệnh “git add†à ?\n" "Nếu ở đây không có gì còn lại stage, tình cá» là có má»™t số thứ khác\n" "đã sẵn được Ä‘Æ°a và o vá»›i cùng ná»™i dung thay đổi; bạn có lẽ muốn bá» qua miếng " "vá nà y." @@ -8835,7 +8889,7 @@ msgid "" "did you forget to use 'git add'?" msgstr "" "Bạn vẫn có những Ä‘Æ°á»ng dẫn chÆ°a được hòa trá»™n trong bảng mục lục của mình\n" -"bạn đã quên sá» dụng lệnh `git add' à ?" +"bạn đã quên sá» dụng lệnh “git add†à ?" #: git-am.sh:845 msgid "No changes -- Patch already applied." @@ -8873,12 +8927,12 @@ msgstr "Bạn có muốn tôi thá»±c hiện Ä‘iá»u nà y cho bạn không [Y/n]? #: git-bisect.sh:95 #, sh-format msgid "unrecognised option: '$arg'" -msgstr "không công nháºn tùy chá»n: '$arg'" +msgstr "không công nháºn tùy chá»n: “$argâ€" #: git-bisect.sh:99 #, sh-format msgid "'$arg' does not appear to be a valid revision" -msgstr "'$arg' không có vẻ nhÆ° là má»™t sá»± xét lại hợp lệ" +msgstr "â€$arg†không có vẻ nhÆ° là má»™t sá»± xét lại hợp lệ" #: git-bisect.sh:117 msgid "Bad HEAD - I need a HEAD" @@ -8889,8 +8943,8 @@ msgstr "HEAD sai - Tôi cần má»™t HEAD" msgid "" "Checking out '$start_head' failed. Try 'git bisect reset <validbranch>'." msgstr "" -"Việc checkout '$start_head' gặp lá»—i. Hãy thá» `git bisect reset " -"<nhánh_hợp_lệ>'." +"Việc checkout “$start_head†gặp lá»—i. Hãy thỠ“git bisect reset " +"<nhánh_hợp_lệ>â€." #: git-bisect.sh:140 msgid "won't bisect on seeked tree" @@ -8912,7 +8966,7 @@ msgstr "Äầu và o rev sai: $arg" #: git-bisect.sh:232 msgid "Please call 'bisect_state' with at least one argument." -msgstr "Hãy gá»i lệnhl 'bisect_state' vá»›i Ãt nhất má»™t đối số." +msgstr "Hãy gá»i lệnhl “bisect_state†vá»›i Ãt nhất má»™t đối số." #: git-bisect.sh:244 #, sh-format @@ -8921,7 +8975,7 @@ msgstr "Äầu và o rev sai: $rev" #: git-bisect.sh:250 msgid "'git bisect bad' can take only one argument." -msgstr "`git bisect bad' có thể lấy chỉ má»™t đối số." +msgstr "“git bisect bad†có thể lấy chỉ má»™t đối số." #. have bad but not good. we could bisect although #. this is less optimum. @@ -8963,7 +9017,7 @@ msgstr "Chúng tôi không bisect." #: git-bisect.sh:354 #, 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ệ" +msgstr "â€$invalid†không phải là lần chuyển giao (commit) hợp lệ" #: git-bisect.sh:363 #, sh-format @@ -8971,8 +9025,8 @@ msgid "" "Could not check out original HEAD '$branch'.\n" "Try 'git bisect reset <commit>'." msgstr "" -"Không thể check-out HEAD nguyên thủy của '$branch'.\n" -"Hãy thá» `git bisect reset <lần-chuyển-giao>'." +"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 msgid "No logfile given" @@ -8999,7 +9053,7 @@ msgid "" "exit code $res from '$command' is < 0 or >= 128" msgstr "" "chạy bisect gặp lá»—i:\n" -"mã trả vá» $res từ lệnh '$command' là < 0 hoặc >= 128" +"mã trả vá» $res từ lệnh “$command†là < 0 hoặc >= 128" #: git-bisect.sh:453 msgid "bisect run cannot continue any more" @@ -9012,7 +9066,7 @@ msgid "" "'bisect_state $state' exited with error code $res" msgstr "" "chạy bisect gặp lá»—i:\n" -"'bisect_state $state' đã thoát ra vá»›i mã lá»—i $res" +"â€bisect_state $state†đã thoát ra vá»›i mã lá»—i $res" #: git-bisect.sh:466 msgid "bisect run success" @@ -9025,9 +9079,9 @@ msgid "" "as appropriate to mark resolution, or use 'git commit -a'." msgstr "" "Pull là không thể được bởi vì bạn có những táºp tin chÆ°a được hòa trá»™n.\n" -"Xin hãy sá»a chữa chúng trÆ°á»›c, và sau đó sá» dụng lệnh `git add/rm <táºp-tin>'\n" -"để phê chuẩn việc đánh dấu đây cần được giải quyết, hoặc là sá» dụng `git " -"commit -a'." +"Xin hãy sá»a chữa chúng trÆ°á»›c, và sau đó sá» dụng lệnh “git add/rm <táºp-tin>â€\n" +"để phê chuẩn việc đánh dấu đây cần được giải quyết, hoặc là sá» dụng “git " +"commit -aâ€." #: git-pull.sh:25 msgid "Pull is not possible because you have unmerged files." @@ -9044,7 +9098,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:228 +#: git-pull.sh:229 #, sh-format msgid "" "Warning: fetch updated the current branch head.\n" @@ -9055,11 +9109,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:253 +#: git-pull.sh:254 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:257 +#: git-pull.sh:258 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" @@ -9078,7 +9132,7 @@ msgstr "" #: git-rebase.sh:160 msgid "The pre-rebase hook refused to rebase." -msgstr "hook (chÆ°Æ¡ng trình móc và o git) pre-rebase từ chối rebase." +msgstr "Móc (hook) pre-rebase từ chối rebase." #: git-rebase.sh:165 msgid "It looks like git-am is in progress. Cannot rebase." @@ -9097,7 +9151,7 @@ msgstr "Không có tiến trình rebase nà o phải không?" #: git-rebase.sh:312 msgid "The --edit-todo action can only be used during interactive rebase." msgstr "" -"Hà nh Ä‘á»™ng `--edit-todo' chỉ có thể dùng trong quá trình `rebase' (sá»a lịch " +"Hà nh Ä‘á»™ng “--edit-todo†chỉ có thể dùng trong quá trình “rebase†(sá»a lịch " "sá») tÆ°Æ¡ng tác." #: git-rebase.sh:319 @@ -9148,12 +9202,12 @@ msgstr "thượng nguồn không hợp lệ $upstream_name" #: git-rebase.sh:428 #, sh-format msgid "$onto_name: there are more than one merge bases" -msgstr "$onto_name: ở đây có nhiá»u hÆ¡n má»™t" +msgstr "$onto_name: ở đây có nhiá»u hÆ¡n má»™t ná»n móng hòa trá»™n" #: git-rebase.sh:431 git-rebase.sh:435 #, sh-format msgid "$onto_name: there is no merge base" -msgstr "$onto_name: ở đây không có gì để hòa trá»™n" +msgstr "$onto_name: ở đây không có ná»n móng hòa trá»™n nà o" #: git-rebase.sh:440 #, sh-format @@ -9167,7 +9221,7 @@ msgstr "nghiêm trá»ng: không có nhánh nhÆ° thế: $branch_name" #: git-rebase.sh:483 msgid "Please commit or stash them." -msgstr "Xin hãy commit hoặc stash chúng." +msgstr "Xin hãy commit hoặc tạm cất (stash) chúng." #: git-rebase.sh:501 #, sh-format @@ -9240,8 +9294,8 @@ msgid "" "error: unknown option for 'stash save': $option\n" " To provide a message, use git stash save -- '$option'" msgstr "" -"lá»—i: không hiểu tùy chá»n cho 'stash save': $option\n" -" Äể cung cấp má»™t thông Ä‘iệp, sá» dụng git stash save -- '$option'" +"lá»—i: không hiểu tùy chá»n cho “stash saveâ€: $option\n" +" Äể cung cấp má»™t thông Ä‘iệp, sá» dụng git stash save -- “$optionâ€" #: git-stash.sh:223 msgid "No local changes to save" @@ -9276,12 +9330,12 @@ msgstr "$reference không phải là tham chiếu hợp lệ" #: git-stash.sh:393 #, sh-format msgid "'$args' is not a stash-like commit" -msgstr "'$args' không phải là lần chuyển giao (commit) giống-stash" +msgstr "â€$args†không phải là lần chuyển giao (commit) giống-stash" #: git-stash.sh:404 #, sh-format msgid "'$args' is not a stash reference" -msgstr "'$args' không phải tham chiếu đến stash" +msgstr "â€$args†không phải tham chiếu đến stash" #: git-stash.sh:412 msgid "unable to refresh index" @@ -9325,41 +9379,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:88 +#: git-submodule.sh:89 #, 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 url '$remoteurl'" +msgstr "không thể tháo bá» má»™t thà nh phần ra khá»i “$remoteurl†url" -#: git-submodule.sh:167 +#: git-submodule.sh:168 #, 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'" +"“$sm_pathâ€" #: git-submodule.sh:211 #, 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" +msgstr "Nhân bản “$url†và o Ä‘Æ°á»ng dẫn mô-Ä‘un-con “$sm_path†gặp lá»—i" #: git-submodule.sh:223 #, 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\"" +"Gitdir “$a†là bá»™ pháºn của Ä‘Æ°á»ng dẫn mô-Ä‘un-con “$b†hoặc \"vice versa\"" -#: git-submodule.sh:312 +#: git-submodule.sh:316 #, 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 ./|../" +"repo URL: “$repo†phải là đưá»ng dẫn tuyệt đối hoặc là bắt đầu bằng ./|../" -#: git-submodule.sh:329 +#: git-submodule.sh:333 #, 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" +msgstr "â€$sm_path†thá»±c sá»± đã tồn tại ở bảng mục lục rồi" -#: git-submodule.sh:333 +#: git-submodule.sh:337 #, sh-format msgid "" "The following path is ignored by one of your .gitignore files:\n" @@ -9371,162 +9425,199 @@ 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:344 +#: git-submodule.sh:355 #, 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" +msgstr "Äang thêm repo có sẵn tại “$sm_path†và o bảng mục lục" -#: git-submodule.sh:346 +#: git-submodule.sh:357 #, 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ệ" +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:365 +#, 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:360 +#: git-submodule.sh:367 +#, 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:369 +#, 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:370 +#, sh-format +msgid "" +"or you are unsure what this means choose another name with the '--name' " +"option." +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:372 +#, 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:384 #, sh-format msgid "Unable to checkout submodule '$sm_path'" -msgstr "Không thể checkout mô-Ä‘un con '$sm_path'" +msgstr "Không thể checkout mô-Ä‘un con “$sm_pathâ€" -#: git-submodule.sh:365 +#: git-submodule.sh:389 #, sh-format msgid "Failed to add submodule '$sm_path'" -msgstr "Gặp lá»—i khi thêm mô-Ä‘un con '$sm_path'" +msgstr "Gặp lá»—i khi thêm mô-Ä‘un con “$sm_pathâ€" -#: git-submodule.sh:370 +#: git-submodule.sh:394 #, 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'" +msgstr "Gặp lá»—i khi đăng ký vá»›i hệ thống mô-Ä‘un con “$sm_pathâ€" -#: git-submodule.sh:413 +#: git-submodule.sh:437 #, sh-format msgid "Entering '$prefix$sm_path'" -msgstr "Äang nháºp '$prefix$sm_path'" +msgstr "Äang nháºp “$prefix$sm_pathâ€" -#: git-submodule.sh:427 +#: git-submodule.sh:451 #, 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." +msgstr "Dừng lại tại “$sm_pathâ€; script trả vá» trạng thái khác không." -#: git-submodule.sh:471 +#: git-submodule.sh:495 #, 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" +"Không tìm thấy url cho Ä‘Æ°á»ng dẫn mô-Ä‘un-con “$sm_path†trong .gitmodules" -#: git-submodule.sh:480 +#: git-submodule.sh:504 #, 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'" +msgstr "Gặp lá»—i khi đăng ký url cho Ä‘Æ°á»ng dẫn mô-Ä‘un-con “$sm_pathâ€" -#: git-submodule.sh:482 +#: git-submodule.sh:506 #, 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'" +msgstr "Mô-Ä‘un-con “$name†($url) được đăng ký cho Ä‘Æ°á»ng dẫn “$sm_pathâ€" -#: git-submodule.sh:490 +#: git-submodule.sh:514 #, 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'" +"Gặp lá»—i khi đăng ký chế Ä‘á»™ cáºp nháºt cho Ä‘Æ°á»ng dẫn mô-Ä‘un-con “$sm_pathâ€" -#: git-submodule.sh:590 +#: git-submodule.sh:614 #, sh-format msgid "" "Submodule path '$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" -"Có lẽ bạn muốn sá» dụng lệnh 'update --init'?" +"ÄÆ°á»ng dẫn mô-Ä‘un-con “$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:603 +#: git-submodule.sh:627 #, sh-format msgid "Unable to find current revision in submodule path '$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 “$sm_pathâ€" -#: git-submodule.sh:622 +#: git-submodule.sh:646 #, 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'" +msgstr "Không thể lấy vá» (fetch) trong Ä‘Æ°á»ng dẫn mô-Ä‘un-con “$sm_pathâ€" -#: git-submodule.sh:636 +#: git-submodule.sh:660 #, 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'" +msgstr "Không thể rebase “$sha1†trong Ä‘Æ°á»ng dẫn mô-Ä‘un-con “$sm_pathâ€" -#: git-submodule.sh:637 +#: git-submodule.sh:661 #, 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'" +msgstr "ÄÆ°á»ng dẫn mô-Ä‘un-con “$sm_pathâ€: được rebase và o trong “$sha1â€" -#: git-submodule.sh:642 +#: git-submodule.sh:666 #, sh-format msgid "Unable to merge '$sha1' in submodule path '$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 “$sm_pathâ€" -#: git-submodule.sh:643 +#: git-submodule.sh:667 #, 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'" +msgstr "ÄÆ°á»ng dẫn mô-Ä‘un-con “$sm_pathâ€: được hòa trá»™n và o “$sha1â€" -#: git-submodule.sh:648 +#: git-submodule.sh:672 #, 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'" +msgstr "Không thể checkout “$sha1†trong Ä‘Æ°á»ng dẫn mô-Ä‘un-con “$sm_pathâ€" -#: git-submodule.sh:649 +#: git-submodule.sh:673 #, sh-format msgid "Submodule path '$sm_path': checked out '$sha1'" -msgstr "ÄÆ°á»ng dẫn mô-Ä‘un-con '$sm_path': được checkout '$sha1'" +msgstr "ÄÆ°á»ng dẫn mô-Ä‘un-con “$sm_pathâ€: được checkout “$sha1â€" -#: git-submodule.sh:671 git-submodule.sh:995 +#: git-submodule.sh:695 git-submodule.sh:1017 #, 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'" +msgstr "Gặp lá»—i khi đệ quy và o trong Ä‘Æ°á»ng dẫn mô-Ä‘un-con “$sm_pathâ€" -#: git-submodule.sh:779 +#: git-submodule.sh:803 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:819 +#: git-submodule.sh:843 #, sh-format msgid "unexpected mode $mod_dst" msgstr "chế Ä‘á»™ không nhÆ° mong chá» $mod_dst" -#: git-submodule.sh:837 +#: git-submodule.sh:861 #, 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:840 +#: git-submodule.sh:864 #, 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:843 +#: git-submodule.sh:867 #, 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:868 +#: git-submodule.sh:892 msgid "blob" msgstr "blob" -#: git-submodule.sh:906 +#: git-submodule.sh:930 msgid "# Submodules changed but not updated:" -msgstr "# Những mô-Ä‘un-con đã bị thay đổi nhÆ°ng chÆ°a được cáºp nháºt:" +msgstr "# Các mô-Ä‘un-con đã bị thay đổi nhÆ°ng chÆ°a được cáºp nháºt:" -#: git-submodule.sh:908 +#: git-submodule.sh:932 msgid "# Submodule changes to be committed:" msgstr "# Những thay đổi mô-Ä‘un-con được chuyển giao (commit):" -#: git-submodule.sh:1054 +#: git-submodule.sh:1080 #, sh-format -msgid "Synchronizing submodule url for '$name'" -msgstr "Äang đồng bá»™ hóa url mô-Ä‘un-con cho '$name'" +msgid "Synchronizing submodule url for '$prefix$sm_path'" +msgstr "Url Mô-Ä‘un-con đồng bá»™ hóa cho '$prefix$sm_path'" + +#~ msgid "git remote set-head <name> (-a | -d | <branch>])" +#~ msgstr "git remote set-head <tên> (-a | -d | <nhánh>])" #~ msgid " 0 files changed" #~ msgstr " 0 có táºp tin nà o thay đổi cả" @@ -9595,7 +9686,7 @@ msgstr "Äang đồng bá»™ hóa url mô-Ä‘un-con cho '$name'" #~ msgstr "%s: đã được xóa/thay-tên" #~ msgid "'%s': not a documentation directory." -#~ msgstr "'%s': không phải là má»™t thÆ° mục tà i liệu." +#~ msgstr "â€%sâ€: không phải là má»™t thÆ° mục tà i liệu." #~ msgid "--" #~ msgstr "--" @@ -9604,10 +9695,5 @@ msgstr "Äang đồng bá»™ hóa url mô-Ä‘un-con cho '$name'" #~ msgstr "" #~ "Không thể rút trÃch địa chỉ thÆ° Ä‘iện tá» từ định danh ngÆ°á»i chuyển giao" -#, fuzzy #~ msgid "could not parse commit %s\n" -#~ msgstr "Không thể phân tÃch commit (lần chuyển giao) %s\n" - -#, fuzzy -#~ msgid "cherry-pick" -#~ msgstr "< Chá»n D-Mod" +#~ msgstr "không thể phân tÃch commit (lần chuyển giao) %s\n" @@ -567,7 +567,7 @@ char *logmsg_reencode(const struct commit *commit, char *encoding; char *out; - if (!*output_encoding) + if (!output_encoding || !*output_encoding) return NULL; encoding = get_header(commit, "encoding"); use_encoding = encoding ? encoding : utf8; @@ -960,12 +960,19 @@ static size_t format_commit_one(struct strbuf *sb, const char *placeholder, switch (placeholder[0]) { case 'C': if (placeholder[1] == '(') { - const char *end = strchr(placeholder + 2, ')'); + const char *begin = placeholder + 2; + const char *end = strchr(begin, ')'); char color[COLOR_MAXLEN]; + if (!end) return 0; - color_parse_mem(placeholder + 2, - end - (placeholder + 2), + if (!memcmp(begin, "auto,", 5)) { + 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; @@ -1100,9 +1107,8 @@ static size_t format_commit_one(struct strbuf *sb, const char *placeholder, } return 0; /* unknown %g placeholder */ case 'N': - if (c->pretty_ctx->show_notes) { - format_display_notes(commit->object.sha1, sb, - get_log_output_encoding(), 0); + if (c->pretty_ctx->notes_message) { + strbuf_addstr(sb, c->pretty_ctx->notes_message); return 1; } return 0; @@ -1251,23 +1257,15 @@ void format_commit_message(const struct commit *commit, const struct pretty_print_context *pretty_ctx) { struct format_commit_context context; - static const char utf8[] = "UTF-8"; const char *output_enc = pretty_ctx->output_encoding; memset(&context, 0, sizeof(context)); context.commit = commit; context.pretty_ctx = pretty_ctx; context.wrap_start = sb->len; - context.message = commit->buffer; - if (output_enc) { - char *enc = get_header(commit, "encoding"); - if (strcmp(enc ? enc : utf8, output_enc)) { - context.message = logmsg_reencode(commit, output_enc); - if (!context.message) - context.message = commit->buffer; - } - free(enc); - } + context.message = logmsg_reencode(commit, output_enc); + if (!context.message) + context.message = commit->buffer; strbuf_expand(sb, format, format_commit_item, &context); rewrap_message_tail(sb, &context, 0, 0, 0); @@ -1414,16 +1412,6 @@ void pp_remainder(const struct pretty_print_context *pp, } } -char *reencode_commit_message(const struct commit *commit, const char **encoding_p) -{ - const char *encoding; - - encoding = get_log_output_encoding(); - if (encoding_p) - *encoding_p = encoding; - return logmsg_reencode(commit, encoding); -} - void pretty_print_commit(const struct pretty_print_context *pp, const struct commit *commit, struct strbuf *sb) @@ -1440,7 +1428,8 @@ void pretty_print_commit(const struct pretty_print_context *pp, return; } - reencoded = reencode_commit_message(commit, &encoding); + encoding = get_log_output_encoding(); + reencoded = logmsg_reencode(commit, encoding); if (reencoded) { msg = reencoded; } @@ -1500,10 +1489,6 @@ void pretty_print_commit(const struct pretty_print_context *pp, if (pp->fmt == CMIT_FMT_EMAIL && sb->len <= beginning_of_body) strbuf_addch(sb, '\n'); - if (pp->show_notes) - format_display_notes(commit->object.sha1, sb, encoding, - NOTES_SHOW_HEADER | NOTES_INDENT); - free(reencoded); } @@ -1202,6 +1202,8 @@ int peel_ref(const char *refname, unsigned char *sha1) 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; } @@ -1223,9 +1225,16 @@ int peel_ref(const char *refname, unsigned char *sha1) } fallback: - o = parse_object(base); - if (o && o->type == OBJ_TAG) { - o = deref_tag(o, refname, 0); + 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; @@ -1735,7 +1744,8 @@ static struct lock_file packlock; static int repack_without_ref(const char *refname) { struct repack_without_ref_sb data; - struct ref_dir *packed = get_packed_refs(get_ref_cache(NULL)); + struct ref_cache *refs = get_ref_cache(NULL); + struct ref_dir *packed = get_packed_refs(refs); if (find_ref(packed, refname) == NULL) return 0; data.refname = refname; @@ -1744,6 +1754,8 @@ static int repack_without_ref(const char *refname) 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); return commit_lock_file(&packlock); } diff --git a/remote-curl.c b/remote-curl.c index 42716c5..9a8b123 100644 --- a/remote-curl.c +++ b/remote-curl.c @@ -356,7 +356,7 @@ static int run_slot(struct active_request_slot *slot) slot->curl_result = curl_easy_perform(slot->curl); finish_active_slot(slot); - err = handle_curl_result(slot, &results); + err = handle_curl_result(&results); if (err != HTTP_OK && err != HTTP_REAUTH) { error("RPC failed; result=%d, HTTP code = %ld", results.curl_result, results.http_code); @@ -400,6 +400,7 @@ static int post_rpc(struct rpc_state *rpc) struct curl_slist *headers = NULL; int use_gzip = rpc->gzip_request; char *gzip_body = NULL; + size_t gzip_size = 0; int err, large_request = 0; /* Try to load the entire request, if we can fit it into the @@ -431,6 +432,11 @@ static int post_rpc(struct rpc_state *rpc) return -1; } + headers = curl_slist_append(headers, rpc->hdr_content_type); + headers = curl_slist_append(headers, rpc->hdr_accept); + headers = curl_slist_append(headers, "Expect:"); + +retry: slot = get_active_slot(); curl_easy_setopt(slot->curl, CURLOPT_NOBODY, 0); @@ -438,10 +444,6 @@ static int post_rpc(struct rpc_state *rpc) curl_easy_setopt(slot->curl, CURLOPT_URL, rpc->service_url); curl_easy_setopt(slot->curl, CURLOPT_ENCODING, "gzip"); - headers = curl_slist_append(headers, rpc->hdr_content_type); - headers = curl_slist_append(headers, rpc->hdr_accept); - headers = curl_slist_append(headers, "Expect:"); - if (large_request) { /* The request body is large and the size cannot be predicted. * We must use chunked encoding to send it. @@ -459,24 +461,32 @@ static int post_rpc(struct rpc_state *rpc) fflush(stderr); } + } else if (gzip_body) { + /* + * If we are looping to retry authentication, then the previous + * run will have set up the headers and gzip buffer already, + * and we just need to send it. + */ + curl_easy_setopt(slot->curl, CURLOPT_POSTFIELDS, gzip_body); + curl_easy_setopt(slot->curl, CURLOPT_POSTFIELDSIZE, gzip_size); + } else if (use_gzip && 1024 < rpc->len) { /* The client backend isn't giving us compressed data so * we can try to deflate it ourselves, this may save on. * the transfer time. */ - size_t size; git_zstream stream; int ret; memset(&stream, 0, sizeof(stream)); git_deflate_init_gzip(&stream, Z_BEST_COMPRESSION); - size = git_deflate_bound(&stream, rpc->len); - gzip_body = xmalloc(size); + gzip_size = git_deflate_bound(&stream, rpc->len); + gzip_body = xmalloc(gzip_size); stream.next_in = (unsigned char *)rpc->buf; stream.avail_in = rpc->len; stream.next_out = (unsigned char *)gzip_body; - stream.avail_out = size; + stream.avail_out = gzip_size; ret = git_deflate(&stream, Z_FINISH); if (ret != Z_STREAM_END) @@ -486,16 +496,16 @@ static int post_rpc(struct rpc_state *rpc) if (ret != Z_OK) die("cannot deflate request; zlib end error %d", ret); - size = stream.total_out; + gzip_size = stream.total_out; headers = curl_slist_append(headers, "Content-Encoding: gzip"); curl_easy_setopt(slot->curl, CURLOPT_POSTFIELDS, gzip_body); - curl_easy_setopt(slot->curl, CURLOPT_POSTFIELDSIZE, size); + curl_easy_setopt(slot->curl, CURLOPT_POSTFIELDSIZE, gzip_size); if (options.verbosity > 1) { fprintf(stderr, "POST %s (gzip %lu to %lu bytes)\n", rpc->service_name, - (unsigned long)rpc->len, (unsigned long)size); + (unsigned long)rpc->len, (unsigned long)gzip_size); fflush(stderr); } } else { @@ -515,9 +525,9 @@ static int post_rpc(struct rpc_state *rpc) curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, rpc_in); curl_easy_setopt(slot->curl, CURLOPT_FILE, rpc); - do { - err = run_slot(slot); - } while (err == HTTP_REAUTH && !large_request && !use_gzip); + err = run_slot(slot); + if (err == HTTP_REAUTH && !large_request) + goto retry; if (err != HTTP_OK) err = -1; diff --git a/remote-testsvn.c b/remote-testsvn.c new file mode 100644 index 0000000..5ddf11c --- /dev/null +++ b/remote-testsvn.c @@ -0,0 +1,344 @@ +#include "cache.h" +#include "remote.h" +#include "strbuf.h" +#include "url.h" +#include "exec_cmd.h" +#include "run-command.h" +#include "vcs-svn/svndump.h" +#include "notes.h" +#include "argv-array.h" + +static const char *url; +static int dump_from_file; +static const char *private_ref; +static const char *remote_ref = "refs/heads/master"; +static const char *marksfilename, *notes_ref; +struct rev_note { unsigned int rev_nr; }; + +static int cmd_capabilities(const char *line); +static int cmd_import(const char *line); +static int cmd_list(const char *line); + +typedef int (*input_command_handler)(const char *); +struct input_command_entry { + const char *name; + input_command_handler fn; + unsigned char batchable; /* whether the command starts or is part of a batch */ +}; + +static const struct input_command_entry input_command_list[] = { + { "capabilities", cmd_capabilities, 0 }, + { "import", cmd_import, 1 }, + { "list", cmd_list, 0 }, + { NULL, NULL } +}; + +static int cmd_capabilities(const char *line) +{ + printf("import\n"); + printf("bidi-import\n"); + printf("refspec %s:%s\n\n", remote_ref, private_ref); + fflush(stdout); + return 0; +} + +static void terminate_batch(void) +{ + /* terminate a current batch's fast-import stream */ + printf("done\n"); + fflush(stdout); +} + +/* NOTE: 'ref' refers to a git reference, while 'rev' refers to a svn revision. */ +static char *read_ref_note(const unsigned char sha1[20]) +{ + const unsigned char *note_sha1; + char *msg = NULL; + unsigned long msglen; + enum object_type type; + + init_notes(NULL, notes_ref, NULL, 0); + if (!(note_sha1 = get_note(NULL, sha1))) + return NULL; /* note tree not found */ + if (!(msg = read_sha1_file(note_sha1, &type, &msglen))) + error("Empty notes tree. %s", notes_ref); + else if (!msglen || type != OBJ_BLOB) { + error("Note contains unusable content. " + "Is something else using this notes tree? %s", notes_ref); + free(msg); + msg = NULL; + } + free_notes(NULL); + return msg; +} + +static int parse_rev_note(const char *msg, struct rev_note *res) +{ + const char *key, *value, *end; + size_t len; + + while (*msg) { + end = strchr(msg, '\n'); + len = end ? end - msg : strlen(msg); + + key = "Revision-number: "; + if (!prefixcmp(msg, key)) { + long i; + char *end; + value = msg + strlen(key); + i = strtol(value, &end, 0); + if (end == value || i < 0 || i > UINT32_MAX) + return -1; + res->rev_nr = i; + return 0; + } + msg += len + 1; + } + /* didn't find it */ + return -1; +} + +static int note2mark_cb(const unsigned char *object_sha1, + const unsigned char *note_sha1, char *note_path, + void *cb_data) +{ + FILE *file = (FILE *)cb_data; + char *msg; + unsigned long msglen; + enum object_type type; + struct rev_note note; + + if (!(msg = read_sha1_file(note_sha1, &type, &msglen)) || + !msglen || type != OBJ_BLOB) { + free(msg); + return 1; + } + if (parse_rev_note(msg, ¬e)) + return 2; + if (fprintf(file, ":%d %s\n", note.rev_nr, sha1_to_hex(object_sha1)) < 1) + return 3; + return 0; +} + +static void regenerate_marks(void) +{ + int ret; + FILE *marksfile = fopen(marksfilename, "w+"); + + if (!marksfile) + die_errno("Couldn't create mark file %s.", marksfilename); + ret = for_each_note(NULL, 0, note2mark_cb, marksfile); + if (ret) + die("Regeneration of marks failed, returned %d.", ret); + fclose(marksfile); +} + +static void check_or_regenerate_marks(int latestrev) +{ + FILE *marksfile; + struct strbuf sb = STRBUF_INIT; + struct strbuf line = STRBUF_INIT; + int found = 0; + + if (latestrev < 1) + return; + + init_notes(NULL, notes_ref, NULL, 0); + marksfile = fopen(marksfilename, "r"); + if (!marksfile) { + regenerate_marks(); + marksfile = fopen(marksfilename, "r"); + if (!marksfile) + die_errno("cannot read marks file %s!", marksfilename); + fclose(marksfile); + } else { + strbuf_addf(&sb, ":%d ", latestrev); + while (strbuf_getline(&line, marksfile, '\n') != EOF) { + if (!prefixcmp(line.buf, sb.buf)) { + found++; + break; + } + } + fclose(marksfile); + if (!found) + regenerate_marks(); + } + free_notes(NULL); + strbuf_release(&sb); + strbuf_release(&line); +} + +static int cmd_import(const char *line) +{ + int code; + int dumpin_fd; + char *note_msg; + unsigned char head_sha1[20]; + unsigned int startrev; + struct argv_array svndump_argv = ARGV_ARRAY_INIT; + struct child_process svndump_proc; + + if (read_ref(private_ref, head_sha1)) + startrev = 0; + else { + note_msg = read_ref_note(head_sha1); + if(note_msg == NULL) { + warning("No note found for %s.", private_ref); + startrev = 0; + } else { + struct rev_note note = { 0 }; + if (parse_rev_note(note_msg, ¬e)) + die("Revision number couldn't be parsed from note."); + startrev = note.rev_nr + 1; + free(note_msg); + } + } + check_or_regenerate_marks(startrev - 1); + + if (dump_from_file) { + dumpin_fd = open(url, O_RDONLY); + if(dumpin_fd < 0) + die_errno("Couldn't open svn dump file %s.", url); + } else { + memset(&svndump_proc, 0, sizeof(struct child_process)); + svndump_proc.out = -1; + argv_array_push(&svndump_argv, "svnrdump"); + argv_array_push(&svndump_argv, "dump"); + argv_array_push(&svndump_argv, url); + argv_array_pushf(&svndump_argv, "-r%u:HEAD", startrev); + svndump_proc.argv = svndump_argv.argv; + + code = start_command(&svndump_proc); + if (code) + die("Unable to start %s, code %d", svndump_proc.argv[0], code); + dumpin_fd = svndump_proc.out; + } + /* setup marks file import/export */ + printf("feature import-marks-if-exists=%s\n" + "feature export-marks=%s\n", marksfilename, marksfilename); + + svndump_init_fd(dumpin_fd, STDIN_FILENO); + svndump_read(url, private_ref, notes_ref); + svndump_deinit(); + svndump_reset(); + + close(dumpin_fd); + if (!dump_from_file) { + code = finish_command(&svndump_proc); + if (code) + warning("%s, returned %d", svndump_proc.argv[0], code); + argv_array_clear(&svndump_argv); + } + + return 0; +} + +static int cmd_list(const char *line) +{ + printf("? %s\n\n", remote_ref); + fflush(stdout); + return 0; +} + +static int do_command(struct strbuf *line) +{ + const struct input_command_entry *p = input_command_list; + static struct string_list batchlines = STRING_LIST_INIT_DUP; + static const struct input_command_entry *batch_cmd; + /* + * commands can be grouped together in a batch. + * Batches are ended by \n. If no batch is active the program ends. + * During a batch all lines are buffered and passed to the handler function + * when the batch is terminated. + */ + if (line->len == 0) { + if (batch_cmd) { + struct string_list_item *item; + for_each_string_list_item(item, &batchlines) + batch_cmd->fn(item->string); + terminate_batch(); + batch_cmd = NULL; + string_list_clear(&batchlines, 0); + return 0; /* end of the batch, continue reading other commands. */ + } + return 1; /* end of command stream, quit */ + } + if (batch_cmd) { + if (prefixcmp(batch_cmd->name, line->buf)) + die("Active %s batch interrupted by %s", batch_cmd->name, line->buf); + /* buffer batch lines */ + string_list_append(&batchlines, line->buf); + return 0; + } + + for (p = input_command_list; p->name; p++) { + if (!prefixcmp(line->buf, p->name) && (strlen(p->name) == line->len || + line->buf[strlen(p->name)] == ' ')) { + if (p->batchable) { + batch_cmd = p; + string_list_append(&batchlines, line->buf); + return 0; + } + return p->fn(line->buf); + } + } + die("Unknown command '%s'\n", line->buf); + return 0; +} + +int main(int argc, const char **argv) +{ + struct strbuf buf = STRBUF_INIT, url_sb = STRBUF_INIT, + private_ref_sb = STRBUF_INIT, marksfilename_sb = STRBUF_INIT, + notes_ref_sb = STRBUF_INIT; + static struct remote *remote; + const char *url_in; + + git_extract_argv0_path(argv[0]); + setup_git_directory(); + if (argc < 2 || argc > 3) { + usage("git-remote-svn <remote-name> [<url>]"); + return 1; + } + + remote = remote_get(argv[1]); + url_in = (argc == 3) ? argv[2] : remote->url[0]; + + if (!prefixcmp(url_in, "file://")) { + dump_from_file = 1; + url = url_decode(url_in + sizeof("file://")-1); + } else { + dump_from_file = 0; + end_url_with_slash(&url_sb, url_in); + url = url_sb.buf; + } + + strbuf_addf(&private_ref_sb, "refs/svn/%s/master", remote->name); + private_ref = private_ref_sb.buf; + + strbuf_addf(¬es_ref_sb, "refs/notes/%s/revs", remote->name); + notes_ref = notes_ref_sb.buf; + + strbuf_addf(&marksfilename_sb, "%s/info/fast-import/remote-svn/%s.marks", + get_git_dir(), remote->name); + marksfilename = marksfilename_sb.buf; + + while (1) { + if (strbuf_getline(&buf, stdin, '\n') == EOF) { + if (ferror(stdin)) + die("Error reading command stream"); + else + die("Unexpected end of command stream"); + } + if (do_command(&buf)) + break; + strbuf_reset(&buf); + } + + strbuf_release(&buf); + strbuf_release(&url_sb); + strbuf_release(&private_ref_sb); + strbuf_release(¬es_ref_sb); + strbuf_release(&marksfilename_sb); + return 0; +} @@ -1279,12 +1279,34 @@ int match_push_refs(struct ref *src, struct ref **dst, return 0; } +static inline int is_forwardable(struct ref* ref) +{ + struct object *o; + + if (!prefixcmp(ref->name, "refs/tags/")) + return 0; + + /* old object must be a commit */ + o = parse_object(ref->old_sha1); + if (!o || o->type != OBJ_COMMIT) + return 0; + + /* new object must be commit-ish */ + o = deref_tag(parse_object(ref->new_sha1), NULL, 0); + if (!o || o->type != OBJ_COMMIT) + return 0; + + return 1; +} + void set_ref_status_for_push(struct ref *remote_refs, int send_mirror, int force_update) { struct ref *ref; for (ref = remote_refs; ref; ref = ref->next) { + int force_ref_update = ref->force || force_update; + if (ref->peer_ref) hashcpy(ref->new_sha1, ref->peer_ref->new_sha1); else if (!send_mirror) @@ -1297,34 +1319,55 @@ void set_ref_status_for_push(struct ref *remote_refs, int send_mirror, continue; } - /* This part determines what can overwrite what. - * The rules are: + /* + * The below logic determines whether an individual + * refspec A:B can be pushed. The push will succeed + * if any of the following are true: + * + * (1) the remote reference B does not exist * - * (0) you can always use --force or +A:B notation to - * selectively force individual ref pairs. + * (2) the remote reference B is being removed (i.e., + * pushing :B where no source is specified) * - * (1) if the old thing does not exist, it is OK. + * (3) the update meets all fast-forwarding criteria: * - * (2) if you do not have the old thing, you are not allowed - * to overwrite it; you would not know what you are losing - * otherwise. + * (a) the destination is not under refs/tags/ + * (b) the old is a commit + * (c) the new is a descendant of the old * - * (3) if both new and old are commit-ish, and new is a - * descendant of old, it is OK. + * NOTE: We must actually have the old object in + * order to overwrite it in the remote reference, + * and the new object must be commit-ish. These are + * implied by (b) and (c) respectively. * - * (4) regardless of all of the above, removing :B is - * always allowed. + * (4) it is forced using the +A:B notation, or by + * passing the --force argument */ - ref->nonfastforward = - !ref->deletion && - !is_null_sha1(ref->old_sha1) && - (!has_sha1_file(ref->old_sha1) - || !ref_newer(ref->new_sha1, ref->old_sha1)); + ref->not_forwardable = !is_forwardable(ref); - if (ref->nonfastforward && !ref->force && !force_update) { - ref->status = REF_STATUS_REJECT_NONFASTFORWARD; - continue; + ref->update = + !ref->deletion && + !is_null_sha1(ref->old_sha1); + + if (ref->update) { + ref->nonfastforward = + !has_sha1_file(ref->old_sha1) + || !ref_newer(ref->new_sha1, ref->old_sha1); + + if (ref->not_forwardable) { + ref->requires_force = 1; + if (!force_ref_update) { + ref->status = REF_STATUS_REJECT_ALREADY_EXISTS; + continue; + } + } else if (ref->nonfastforward) { + ref->requires_force = 1; + if (!force_ref_update) { + ref->status = REF_STATUS_REJECT_NONFASTFORWARD; + continue; + } + } } } } @@ -1370,6 +1413,16 @@ int branch_merge_matches(struct branch *branch, return refname_match(branch->merge[i]->src, refname, ref_fetch_rules); } +static int ignore_symref_update(const char *refname) +{ + unsigned char sha1[20]; + int flag; + + if (!resolve_ref_unsafe(refname, sha1, 0, &flag)) + return 0; /* non-existing refs are OK */ + return (flag & REF_ISSYMREF); +} + static struct ref *get_expanded_map(const struct ref *remote_refs, const struct refspec *refspec) { @@ -1383,7 +1436,8 @@ static struct ref *get_expanded_map(const struct ref *remote_refs, if (strchr(ref->name, '^')) continue; /* a dereference item */ if (match_name_with_pattern(refspec->src, ref->name, - refspec->dst, &expn_name)) { + refspec->dst, &expn_name) && + !ignore_symref_update(expn_name)) { struct ref *cpy = copy_ref(ref); cpy->peer_ref = alloc_ref(expn_name); @@ -1458,8 +1512,8 @@ int get_fetch_map(const struct ref *remote_refs, for (rmp = &ref_map; *rmp; ) { if ((*rmp)->peer_ref) { - if (check_refname_format((*rmp)->peer_ref->name + 5, - REFNAME_ALLOW_ONELEVEL)) { + if (prefixcmp((*rmp)->peer_ref->name, "refs/") || + check_refname_format((*rmp)->peer_ref->name, 0)) { struct ref *ignore = *rmp; error("* Ignoring funny ref '%s' locally", (*rmp)->peer_ref->name); @@ -1627,13 +1681,16 @@ int format_tracking_info(struct branch *branch, struct strbuf *sb) base = branch->merge[0]->dst; base = shorten_unambiguous_ref(base, 0); - if (!num_theirs) + if (!num_theirs) { strbuf_addf(sb, Q_("Your branch is ahead of '%s' by %d commit.\n", "Your branch is ahead of '%s' by %d commits.\n", num_ours), base, num_ours); - else if (!num_ours) + if (advice_status_hints) + strbuf_addf(sb, + _(" (use \"git push\" to publish your local commits)\n")); + } else if (!num_ours) { strbuf_addf(sb, Q_("Your branch is behind '%s' by %d commit, " "and can be fast-forwarded.\n", @@ -1641,7 +1698,10 @@ int format_tracking_info(struct branch *branch, struct strbuf *sb) "and can be fast-forwarded.\n", num_theirs), base, num_theirs); - else + if (advice_status_hints) + strbuf_addf(sb, + _(" (use \"git pull\" to update your local branch)\n")); + } else { strbuf_addf(sb, Q_("Your branch and '%s' have diverged,\n" "and have %d and %d different commit each, " @@ -1651,6 +1711,10 @@ int format_tracking_info(struct branch *branch, struct strbuf *sb) "respectively.\n", num_theirs), base, num_ours, num_theirs); + if (advice_status_hints) + strbuf_addf(sb, + _(" (use \"git pull\" to merge the remote branch into yours)\n")); + } return 1; } @@ -1603,6 +1603,8 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg return argcount; } else if (!strcmp(arg, "--grep-debug")) { revs->grep_filter.debug = 1; + } else if (!strcmp(arg, "--basic-regexp")) { + grep_set_pattern_type_option(GREP_PATTERN_TYPE_BRE, &revs->grep_filter); } else if (!strcmp(arg, "--extended-regexp") || !strcmp(arg, "-E")) { grep_set_pattern_type_option(GREP_PATTERN_TYPE_ERE, &revs->grep_filter); } else if (!strcmp(arg, "--regexp-ignore-case") || !strcmp(arg, "-i")) { @@ -1610,6 +1612,8 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg DIFF_OPT_SET(&revs->diffopt, PICKAXE_IGNORE_CASE); } else if (!strcmp(arg, "--fixed-strings") || !strcmp(arg, "-F")) { grep_set_pattern_type_option(GREP_PATTERN_TYPE_FIXED, &revs->grep_filter); + } else if (!strcmp(arg, "--perl-regexp")) { + grep_set_pattern_type_option(GREP_PATTERN_TYPE_PCRE, &revs->grep_filter); } else if (!strcmp(arg, "--all-match")) { revs->grep_filter.all_match = 1; } else if ((argcount = parse_long_opt("encoding", argv, &optarg))) { @@ -2238,7 +2242,7 @@ static int commit_match(struct commit *commit, struct rev_info *opt) if (!buf.len) strbuf_addstr(&buf, commit->buffer); format_display_notes(commit->object.sha1, &buf, - get_log_output_encoding(), 0); + get_log_output_encoding(), 1); } /* Find either in the commit object, or in the temporary */ @@ -111,6 +111,7 @@ struct rev_info { /* Format info */ unsigned int shown_one:1, + shown_dashes:1, show_merge:1, show_notes:1, show_notes_given:1, diff --git a/run-command.c b/run-command.c index 1101ef7..24eaad5 100644 --- a/run-command.c +++ b/run-command.c @@ -226,7 +226,7 @@ static inline void set_cloexec(int fd) fcntl(fd, F_SETFD, flags | FD_CLOEXEC); } -static int wait_or_whine(pid_t pid, const char *argv0, int silent_exec_failure) +static int wait_or_whine(pid_t pid, const char *argv0) { int status, code = -1; pid_t waiting; @@ -242,7 +242,8 @@ static int wait_or_whine(pid_t pid, const char *argv0, int silent_exec_failure) error("waitpid is confused (%s)", argv0); } else if (WIFSIGNALED(status)) { code = WTERMSIG(status); - error("%s died of signal %d", argv0, code); + if (code != SIGINT && code != SIGQUIT) + error("%s died of signal %d", argv0, code); /* * This return value is chosen so that code & 0xff * mimics the exit code that a POSIX shell would report for @@ -397,16 +398,6 @@ fail_pipe: unsetenv(*cmd->env); } } - if (cmd->preexec_cb) { - /* - * We cannot predict what the pre-exec callback does. - * Forgo parent notification. - */ - close(child_notifier); - child_notifier = -1; - - cmd->preexec_cb(); - } if (cmd->git_cmd) { execv_git_cmd(cmd->argv); } else if (cmd->use_shell) { @@ -442,8 +433,7 @@ fail_pipe: * At this point we know that fork() succeeded, but execvp() * failed. Errors have been reported to our stderr. */ - wait_or_whine(cmd->pid, cmd->argv[0], - cmd->silent_exec_failure); + wait_or_whine(cmd->pid, cmd->argv[0]); failed_errno = errno; cmd->pid = -1; } @@ -548,7 +538,7 @@ fail_pipe: int finish_command(struct child_process *cmd) { - return wait_or_whine(cmd->pid, cmd->argv[0], cmd->silent_exec_failure); + return wait_or_whine(cmd->pid, cmd->argv[0]); } int run_command(struct child_process *cmd) @@ -735,7 +725,7 @@ error: int finish_async(struct async *async) { #ifdef NO_PTHREADS - return wait_or_whine(async->pid, "child process", 0); + return wait_or_whine(async->pid, "child process"); #else void *ret = (void *)(intptr_t)(-1); diff --git a/run-command.h b/run-command.h index 44f7d2b..850c638 100644 --- a/run-command.h +++ b/run-command.h @@ -39,7 +39,6 @@ struct child_process { unsigned stdout_to_stderr:1; unsigned use_shell:1; unsigned clean_on_exit:1; - void (*preexec_cb)(void); }; int start_command(struct child_process *); diff --git a/send-pack.c b/send-pack.c new file mode 100644 index 0000000..1c375f0 --- /dev/null +++ b/send-pack.c @@ -0,0 +1,345 @@ +#include "builtin.h" +#include "commit.h" +#include "refs.h" +#include "pkt-line.h" +#include "sideband.h" +#include "run-command.h" +#include "remote.h" +#include "send-pack.h" +#include "quote.h" +#include "transport.h" +#include "version.h" + +static int feed_object(const unsigned char *sha1, int fd, int negative) +{ + char buf[42]; + + if (negative && !has_sha1_file(sha1)) + return 1; + + memcpy(buf + negative, sha1_to_hex(sha1), 40); + if (negative) + buf[0] = '^'; + buf[40 + negative] = '\n'; + return write_or_whine(fd, buf, 41 + negative, "send-pack: send refs"); +} + +/* + * Make a pack stream and spit it out into file descriptor fd + */ +static int pack_objects(int fd, struct ref *refs, struct extra_have_objects *extra, struct send_pack_args *args) +{ + /* + * The child becomes pack-objects --revs; we feed + * the revision parameters to it via its stdin and + * let its stdout go back to the other end. + */ + const char *argv[] = { + "pack-objects", + "--all-progress-implied", + "--revs", + "--stdout", + NULL, + NULL, + NULL, + NULL, + NULL, + }; + struct child_process po; + int i; + + i = 4; + if (args->use_thin_pack) + argv[i++] = "--thin"; + if (args->use_ofs_delta) + argv[i++] = "--delta-base-offset"; + if (args->quiet || !args->progress) + argv[i++] = "-q"; + if (args->progress) + argv[i++] = "--progress"; + memset(&po, 0, sizeof(po)); + po.argv = argv; + po.in = -1; + po.out = args->stateless_rpc ? -1 : fd; + po.git_cmd = 1; + if (start_command(&po)) + die_errno("git pack-objects failed"); + + /* + * We feed the pack-objects we just spawned with revision + * parameters by writing to the pipe. + */ + for (i = 0; i < extra->nr; i++) + if (!feed_object(extra->array[i], po.in, 1)) + break; + + while (refs) { + if (!is_null_sha1(refs->old_sha1) && + !feed_object(refs->old_sha1, po.in, 1)) + break; + if (!is_null_sha1(refs->new_sha1) && + !feed_object(refs->new_sha1, po.in, 0)) + break; + refs = refs->next; + } + + close(po.in); + + if (args->stateless_rpc) { + char *buf = xmalloc(LARGE_PACKET_MAX); + while (1) { + ssize_t n = xread(po.out, buf, LARGE_PACKET_MAX); + if (n <= 0) + break; + send_sideband(fd, -1, buf, n, LARGE_PACKET_MAX); + } + free(buf); + close(po.out); + po.out = -1; + } + + if (finish_command(&po)) + return -1; + return 0; +} + +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)) + 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'; + error("unpack failed: %s", line + 7); + ret = -1; + } + hint = NULL; + while (1) { + char *refname; + char *msg; + len = packet_read_line(in, line, sizeof(line)); + if (!len) + break; + if (len < 3 || + (memcmp(line, "ok ", 3) && memcmp(line, "ng ", 3))) { + fprintf(stderr, "protocol error: %s\n", line); + ret = -1; + break; + } + + line[strlen(line)-1] = '\0'; + refname = line + 3; + msg = strchr(refname, ' '); + if (msg) + *msg++ = '\0'; + + /* first try searching at our hint, falling back to all refs */ + if (hint) + hint = find_ref_by_name(hint, refname); + if (!hint) + hint = find_ref_by_name(refs, refname); + if (!hint) { + warning("remote reported status on unknown ref: %s", + refname); + continue; + } + if (hint->status != REF_STATUS_EXPECTING_REPORT) { + warning("remote reported status on unexpected ref: %s", + refname); + continue; + } + + if (line[0] == 'o' && line[1] == 'k') + hint->status = REF_STATUS_OK; + else { + hint->status = REF_STATUS_REMOTE_REJECT; + ret = -1; + } + if (msg) + hint->remote_status = xstrdup(msg); + /* start our next search from the next ref */ + hint = hint->next; + } + return ret; +} + +static int sideband_demux(int in, int out, void *data) +{ + int *fd = data, ret; +#ifdef NO_PTHREADS + close(fd[1]); +#endif + ret = recv_sideband("send-pack", fd[0], out); + close(out); + return ret; +} + +int send_pack(struct send_pack_args *args, + int fd[], struct child_process *conn, + struct ref *remote_refs, + struct extra_have_objects *extra_have) +{ + int in = fd[0]; + int out = fd[1]; + struct strbuf req_buf = STRBUF_INIT; + struct ref *ref; + int new_refs; + int allow_deleting_refs = 0; + int status_report = 0; + int use_sideband = 0; + int quiet_supported = 0; + int agent_supported = 0; + unsigned cmds_sent = 0; + int ret; + struct async demux; + + /* Does the other end support the reporting? */ + if (server_supports("report-status")) + status_report = 1; + if (server_supports("delete-refs")) + allow_deleting_refs = 1; + if (server_supports("ofs-delta")) + args->use_ofs_delta = 1; + if (server_supports("side-band-64k")) + use_sideband = 1; + if (server_supports("quiet")) + quiet_supported = 1; + if (server_supports("agent")) + agent_supported = 1; + + if (!remote_refs) { + fprintf(stderr, "No refs in common and none specified; doing nothing.\n" + "Perhaps you should specify a branch such as 'master'.\n"); + return 0; + } + + /* + * Finally, tell the other end! + */ + new_refs = 0; + for (ref = remote_refs; ref; ref = ref->next) { + if (!ref->peer_ref && !args->send_mirror) + continue; + + /* Check for statuses set by set_ref_status_for_push() */ + switch (ref->status) { + case REF_STATUS_REJECT_NONFASTFORWARD: + case REF_STATUS_REJECT_ALREADY_EXISTS: + case REF_STATUS_UPTODATE: + continue; + default: + ; /* do nothing */ + } + + if (ref->deletion && !allow_deleting_refs) { + ref->status = REF_STATUS_REJECT_NODELETE; + continue; + } + + if (!ref->deletion) + new_refs++; + + if (args->dry_run) { + ref->status = REF_STATUS_OK; + } else { + char *old_hex = sha1_to_hex(ref->old_sha1); + char *new_hex = sha1_to_hex(ref->new_sha1); + int quiet = quiet_supported && (args->quiet || !args->progress); + + if (!cmds_sent && (status_report || use_sideband || + quiet || agent_supported)) { + packet_buf_write(&req_buf, + "%s %s %s%c%s%s%s%s%s", + old_hex, new_hex, ref->name, 0, + status_report ? " report-status" : "", + use_sideband ? " side-band-64k" : "", + quiet ? " quiet" : "", + agent_supported ? " agent=" : "", + agent_supported ? git_user_agent_sanitized() : "" + ); + } + else + packet_buf_write(&req_buf, "%s %s %s", + old_hex, new_hex, ref->name); + ref->status = status_report ? + REF_STATUS_EXPECTING_REPORT : + REF_STATUS_OK; + cmds_sent++; + } + } + + if (args->stateless_rpc) { + if (!args->dry_run && cmds_sent) { + packet_buf_flush(&req_buf); + send_sideband(out, -1, req_buf.buf, req_buf.len, LARGE_PACKET_MAX); + } + } else { + safe_write(out, req_buf.buf, req_buf.len); + packet_flush(out); + } + strbuf_release(&req_buf); + + if (use_sideband && cmds_sent) { + memset(&demux, 0, sizeof(demux)); + demux.proc = sideband_demux; + demux.data = fd; + demux.out = -1; + if (start_async(&demux)) + die("send-pack: unable to fork off sideband demultiplexer"); + in = demux.out; + } + + if (new_refs && cmds_sent) { + if (pack_objects(out, remote_refs, extra_have, args) < 0) { + for (ref = remote_refs; ref; ref = ref->next) + ref->status = REF_STATUS_NONE; + if (args->stateless_rpc) + close(out); + if (git_connection_is_socket(conn)) + shutdown(fd[0], SHUT_WR); + if (use_sideband) + finish_async(&demux); + return -1; + } + } + if (args->stateless_rpc && cmds_sent) + packet_flush(out); + + if (status_report && cmds_sent) + ret = receive_status(in, remote_refs); + else + ret = 0; + if (args->stateless_rpc) + packet_flush(out); + + if (use_sideband && cmds_sent) { + if (finish_async(&demux)) { + error("error in sideband demultiplexer"); + ret = -1; + } + close(demux.out); + } + + if (ret < 0) + return ret; + + if (args->porcelain) + return 0; + + for (ref = remote_refs; ref; ref = ref->next) { + switch (ref->status) { + case REF_STATUS_NONE: + case REF_STATUS_UPTODATE: + case REF_STATUS_OK: + break; + default: + return -1; + } + } + return 0; +} diff --git a/sequencer.c b/sequencer.c index 73c396b..2260490 100644 --- a/sequencer.c +++ b/sequencer.c @@ -191,7 +191,7 @@ static int fast_forward_to(const unsigned char *to, const unsigned char *from) struct ref_lock *ref_lock; read_cache(); - if (checkout_fast_forward(from, to)) + if (checkout_fast_forward(from, to, 1)) exit(1); /* the callee should have complained already */ ref_lock = lock_any_ref_for_update("HEAD", from, 0); return write_ref_sha1(ref_lock, to, "cherry-pick"); @@ -1,5 +1,6 @@ #include "cache.h" #include "dir.h" +#include "string-list.h" static int inside_git_dir = -1; static int inside_work_tree = -1; @@ -621,16 +622,38 @@ static dev_t get_device_or_die(const char *path, const char *prefix, int prefix_ } /* + * A "string_list_each_func_t" function that canonicalizes an entry + * from GIT_CEILING_DIRECTORIES using real_path_if_valid(), or + * discards it if unusable. + */ +static int canonicalize_ceiling_entry(struct string_list_item *item, + void *unused) +{ + char *ceil = item->string; + const char *real_path; + + if (!*ceil || !is_absolute_path(ceil)) + return 0; + real_path = real_path_if_valid(ceil); + if (!real_path) + return 0; + free(item->string); + item->string = xstrdup(real_path); + return 1; +} + +/* * We cannot decide in this function whether we are in the work tree or * not, since the config can only be read _after_ this function was called. */ static const char *setup_git_directory_gently_1(int *nongit_ok) { const char *env_ceiling_dirs = getenv(CEILING_DIRECTORIES_ENVIRONMENT); + struct string_list ceiling_dirs = STRING_LIST_INIT_DUP; static char cwd[PATH_MAX+1]; const char *gitdirenv, *ret; char *gitfile; - int len, offset, offset_parent, ceil_offset; + int len, offset, offset_parent, ceil_offset = -1; dev_t current_device = 0; int one_filesystem = 1; @@ -655,7 +678,14 @@ static const char *setup_git_directory_gently_1(int *nongit_ok) if (gitdirenv) return setup_explicit_git_dir(gitdirenv, cwd, len, nongit_ok); - ceil_offset = longest_ancestor_length(cwd, env_ceiling_dirs); + if (env_ceiling_dirs) { + string_list_split(&ceiling_dirs, env_ceiling_dirs, PATH_SEP, -1); + filter_string_list(&ceiling_dirs, 0, + canonicalize_ceiling_entry, NULL); + ceil_offset = longest_ancestor_length(cwd, &ceiling_dirs); + string_list_clear(&ceiling_dirs, 0); + } + if (ceil_offset < 0 && has_dos_drive_prefix(cwd)) ceil_offset = 1; diff --git a/sha1_file.c b/sha1_file.c index 9152974..40b2329 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -7,6 +7,7 @@ * creation etc. */ #include "cache.h" +#include "string-list.h" #include "delta.h" #include "pack.h" #include "blob.h" @@ -246,7 +247,7 @@ static int git_open_noatime(const char *name); * SHA1, an extra slash for the first level indirection, and the * terminating NUL. */ -static int link_alt_odb_entry(const char * entry, int len, const char * relative_base, int depth) +static int link_alt_odb_entry(const char *entry, const char *relative_base, int depth) { const char *objdir = get_object_directory(); struct alternate_object_database *ent; @@ -258,7 +259,7 @@ static int link_alt_odb_entry(const char * entry, int len, const char * relative strbuf_addstr(&pathbuf, real_path(relative_base)); strbuf_addch(&pathbuf, '/'); } - strbuf_add(&pathbuf, entry, len); + strbuf_addstr(&pathbuf, entry); normalize_path_copy(pathbuf.buf, pathbuf.buf); @@ -316,10 +317,12 @@ static int link_alt_odb_entry(const char * entry, int len, const char * relative return 0; } -static void link_alt_odb_entries(const char *alt, const char *ep, int sep, +static void link_alt_odb_entries(const char *alt, int len, int sep, const char *relative_base, int depth) { - const char *cp, *last; + struct string_list entries = STRING_LIST_INIT_NODUP; + char *alt_copy; + int i; if (depth > 5) { error("%s: ignoring alternate object stores, nesting too deep.", @@ -327,30 +330,21 @@ static void link_alt_odb_entries(const char *alt, const char *ep, int sep, return; } - last = alt; - while (last < ep) { - cp = last; - if (cp < ep && *cp == '#') { - while (cp < ep && *cp != sep) - cp++; - last = cp + 1; + alt_copy = xmemdupz(alt, len); + string_list_split_in_place(&entries, alt_copy, sep, -1); + for (i = 0; i < entries.nr; i++) { + const char *entry = entries.items[i].string; + if (entry[0] == '\0' || entry[0] == '#') continue; + if (!is_absolute_path(entry) && depth) { + error("%s: ignoring relative alternate object store %s", + relative_base, entry); + } else { + link_alt_odb_entry(entry, relative_base, depth); } - while (cp < ep && *cp != sep) - cp++; - if (last != cp) { - if (!is_absolute_path(last) && depth) { - error("%s: ignoring relative alternate object store %s", - relative_base, last); - } else { - link_alt_odb_entry(last, cp - last, - relative_base, depth); - } - } - while (cp < ep && *cp == sep) - cp++; - last = cp; } + string_list_clear(&entries, 0); + free(alt_copy); } void read_info_alternates(const char * relative_base, int depth) @@ -377,7 +371,7 @@ void read_info_alternates(const char * relative_base, int depth) map = xmmap(NULL, mapsz, PROT_READ, MAP_PRIVATE, fd, 0); close(fd); - link_alt_odb_entries(map, map + mapsz, '\n', relative_base, depth); + link_alt_odb_entries(map, mapsz, '\n', relative_base, depth); munmap(map, mapsz); } @@ -391,7 +385,7 @@ void add_to_alternates_file(const char *reference) if (commit_lock_file(lock)) die("could not close alternates file"); if (alt_odb_tail) - link_alt_odb_entries(alt, alt + strlen(alt), '\n', NULL, 0); + link_alt_odb_entries(alt, strlen(alt), '\n', NULL, 0); } void foreach_alt_odb(alt_odb_fn fn, void *cb) @@ -415,7 +409,7 @@ void prepare_alt_odb(void) if (!alt) alt = ""; alt_odb_tail = &alt_odb_list; - link_alt_odb_entries(alt, alt + strlen(alt), PATH_SEP, NULL, 0); + link_alt_odb_entries(alt, strlen(alt), PATH_SEP, NULL, 0); read_info_alternates(get_object_directory(), 0); } @@ -44,7 +44,9 @@ void strbuf_release(struct strbuf *sb) char *strbuf_detach(struct strbuf *sb, size_t *sz) { - char *res = sb->alloc ? sb->buf : NULL; + char *res; + strbuf_grow(sb, 0); + res = sb->buf; if (sz) *sz = sb->len; strbuf_init(sb, 0); @@ -104,35 +106,30 @@ void strbuf_ltrim(struct strbuf *sb) sb->buf[sb->len] = '\0'; } -struct strbuf **strbuf_split_buf(const char *str, size_t slen, int delim, int max) +struct strbuf **strbuf_split_buf(const char *str, size_t slen, + int terminator, int max) { - int alloc = 2, pos = 0; - const char *n, *p; - struct strbuf **ret; + struct strbuf **ret = NULL; + size_t nr = 0, alloc = 0; struct strbuf *t; - ret = xcalloc(alloc, sizeof(struct strbuf *)); - p = n = str; - while (n < str + slen) { - int len; - if (max <= 0 || pos + 1 < max) - n = memchr(n, delim, slen - (n - str)); - else - n = NULL; - if (pos + 1 >= alloc) { - alloc = alloc * 2; - ret = xrealloc(ret, sizeof(struct strbuf *) * alloc); + while (slen) { + int len = slen; + if (max <= 0 || nr + 1 < max) { + const char *end = memchr(str, terminator, slen); + if (end) + len = end - str + 1; } - if (!n) - n = str + slen - 1; - len = n - p + 1; t = xmalloc(sizeof(struct strbuf)); strbuf_init(t, len); - strbuf_add(t, p, len); - ret[pos] = t; - ret[++pos] = NULL; - p = ++n; + strbuf_add(t, str, len); + ALLOC_GROW(ret, nr + 2, alloc); + ret[nr++] = t; + str += len; + slen -= len; } + ALLOC_GROW(ret, nr + 1, alloc); /* In case string was empty */ + ret[nr] = NULL; return ret; } @@ -428,6 +425,32 @@ void strbuf_add_lines(struct strbuf *out, const char *prefix, strbuf_complete_line(out); } +void strbuf_addstr_xml_quoted(struct strbuf *buf, const char *s) +{ + while (*s) { + size_t len = strcspn(s, "\"<>&"); + strbuf_add(buf, s, len); + s += len; + switch (*s) { + case '"': + strbuf_addstr(buf, """); + break; + case '<': + strbuf_addstr(buf, "<"); + break; + case '>': + strbuf_addstr(buf, ">"); + break; + case '&': + strbuf_addstr(buf, "&"); + break; + case 0: + return; + } + s++; + } +} + static int is_rfc3986_reserved(char ch) { switch (ch) { @@ -44,22 +44,56 @@ extern void strbuf_rtrim(struct strbuf *); extern void strbuf_ltrim(struct strbuf *); extern int strbuf_cmp(const struct strbuf *, const struct strbuf *); +/* + * Split str (of length slen) at the specified terminator character. + * Return a null-terminated array of pointers to strbuf objects + * holding the substrings. The substrings include the terminator, + * except for the last substring, which might be unterminated if the + * original string did not end with a terminator. If max is positive, + * then split the string into at most max substrings (with the last + * substring containing everything following the (max-1)th terminator + * character). + * + * For lighter-weight alternatives, see string_list_split() and + * string_list_split_in_place(). + */ extern struct strbuf **strbuf_split_buf(const char *, size_t, - int delim, int max); + int terminator, int max); + +/* + * Split a NUL-terminated string at the specified terminator + * character. See strbuf_split_buf() for more information. + */ static inline struct strbuf **strbuf_split_str(const char *str, - int delim, int max) + int terminator, int max) { - return strbuf_split_buf(str, strlen(str), delim, max); + return strbuf_split_buf(str, strlen(str), terminator, max); } + +/* + * Split a strbuf at the specified terminator character. See + * strbuf_split_buf() for more information. + */ static inline struct strbuf **strbuf_split_max(const struct strbuf *sb, - int delim, int max) + int terminator, int max) { - return strbuf_split_buf(sb->buf, sb->len, delim, max); + return strbuf_split_buf(sb->buf, sb->len, terminator, max); } -static inline struct strbuf **strbuf_split(const struct strbuf *sb, int delim) + +/* + * Split a strbuf at the specified terminator character. See + * strbuf_split_buf() for more information. + */ +static inline struct strbuf **strbuf_split(const struct strbuf *sb, + int terminator) { - return strbuf_split_max(sb, delim, 0); + return strbuf_split_max(sb, terminator, 0); } + +/* + * Free a NULL-terminated list of strbufs (for example, the return + * values of the strbuf_split*() functions). + */ extern void strbuf_list_free(struct strbuf **); /*----- add data in your buffer -----*/ @@ -102,6 +136,12 @@ extern void strbuf_vaddf(struct strbuf *sb, const char *fmt, va_list ap); extern void strbuf_add_lines(struct strbuf *sb, const char *prefix, const char *buf, size_t size); +/* + * Append s to sb, with the characters '<', '>', '&' and '"' converted + * into XML entities. + */ +extern void strbuf_addstr_xml_quoted(struct strbuf *sb, const char *s); + static inline void strbuf_complete_line(struct strbuf *sb) { if (sb->len && sb->buf[sb->len - 1] != '\n') diff --git a/string-list.c b/string-list.c index c54b816..480173f 100644 --- a/string-list.c +++ b/string-list.c @@ -136,24 +136,13 @@ void filter_string_list(struct string_list *list, int free_util, list->nr = dst; } -char *string_list_longest_prefix(const struct string_list *prefixes, - const char *string) +static int item_is_not_empty(struct string_list_item *item, void *unused) { - int i, max_len = -1; - char *retval = NULL; - - for (i = 0; i < prefixes->nr; i++) { - char *prefix = prefixes->items[i].string; - if (!prefixcmp(string, prefix)) { - int len = strlen(prefix); - if (len > max_len) { - retval = prefix; - max_len = len; - } - } - } + return *item->string != '\0'; +} - return retval; +void string_list_remove_empty_items(struct string_list *list, int free_util) { + filter_string_list(list, free_util, item_is_not_empty, NULL); } void string_list_clear(struct string_list *list, int free_util) diff --git a/string-list.h b/string-list.h index 5efd07b..db12848 100644 --- a/string-list.h +++ b/string-list.h @@ -39,13 +39,11 @@ void filter_string_list(struct string_list *list, int free_util, string_list_each_func_t want, void *cb_data); /* - * Return the longest string in prefixes that is a prefix (in the - * sense of prefixcmp()) of string, or NULL if no such prefix exists. - * This function does not require the string_list to be sorted (it - * does a linear search). + * Remove any empty strings from the list. If free_util is true, call + * free() on the util members of any items that have to be deleted. + * Preserve the order of the items that are retained. */ -char *string_list_longest_prefix(const struct string_list *prefixes, const char *string); - +void string_list_remove_empty_items(struct string_list *list, int free_util); /* Use these functions only on sorted lists: */ int string_list_has_string(const struct string_list *list, const char *string); diff --git a/submodule.c b/submodule.c index 50f213e..2f55436 100644 --- a/submodule.c +++ b/submodule.c @@ -258,7 +258,7 @@ int parse_fetch_recurse_submodules_arg(const char *opt, const char *arg) void show_submodule_summary(FILE *f, const char *path, unsigned char one[20], unsigned char two[20], - unsigned dirty_submodule, + unsigned dirty_submodule, const char *meta, const char *del, const char *add, const char *reset) { struct rev_info rev; @@ -292,15 +292,15 @@ void show_submodule_summary(FILE *f, const char *path, return; } - strbuf_addf(&sb, "Submodule %s %s..", path, + strbuf_addf(&sb, "%sSubmodule %s %s..", meta, path, find_unique_abbrev(one, DEFAULT_ABBREV)); if (!fast_backward && !fast_forward) strbuf_addch(&sb, '.'); strbuf_addf(&sb, "%s", find_unique_abbrev(two, DEFAULT_ABBREV)); if (message) - strbuf_addf(&sb, " %s\n", message); + strbuf_addf(&sb, " %s%s\n", message, reset); else - strbuf_addf(&sb, "%s:\n", fast_backward ? " (rewind)" : ""); + strbuf_addf(&sb, "%s:%s\n", fast_backward ? " (rewind)" : "", reset); fwrite(sb.buf, sb.len, 1, f); if (!message) { @@ -759,6 +759,86 @@ unsigned is_submodule_modified(const char *path, int ignore_untracked) return dirty_submodule; } +int submodule_uses_gitfile(const char *path) +{ + struct child_process cp; + const char *argv[] = { + "submodule", + "foreach", + "--quiet", + "--recursive", + "test -f .git", + NULL, + }; + struct strbuf buf = STRBUF_INIT; + const char *git_dir; + + strbuf_addf(&buf, "%s/.git", path); + git_dir = read_gitfile(buf.buf); + if (!git_dir) { + strbuf_release(&buf); + return 0; + } + strbuf_release(&buf); + + /* Now test that all nested submodules use a gitfile too */ + memset(&cp, 0, sizeof(cp)); + cp.argv = argv; + cp.env = local_repo_env; + cp.git_cmd = 1; + cp.no_stdin = 1; + cp.no_stderr = 1; + cp.no_stdout = 1; + cp.dir = path; + if (run_command(&cp)) + return 0; + + return 1; +} + +int ok_to_remove_submodule(const char *path) +{ + struct stat st; + ssize_t len; + struct child_process cp; + const char *argv[] = { + "status", + "--porcelain", + "-u", + "--ignore-submodules=none", + NULL, + }; + struct strbuf buf = STRBUF_INIT; + int ok_to_remove = 1; + + if ((lstat(path, &st) < 0) || is_empty_dir(path)) + return 1; + + if (!submodule_uses_gitfile(path)) + return 0; + + memset(&cp, 0, sizeof(cp)); + cp.argv = argv; + cp.env = local_repo_env; + cp.git_cmd = 1; + cp.no_stdin = 1; + cp.out = -1; + cp.dir = path; + if (start_command(&cp)) + die("Could not run 'git status --porcelain -uall --ignore-submodules=none' in submodule %s", path); + + len = strbuf_read(&buf, cp.out, 1024); + if (len > 2) + ok_to_remove = 0; + close(cp.out); + + if (finish_command(&cp)) + die("'git status --porcelain -uall --ignore-submodules=none' failed in submodule %s", path); + + strbuf_release(&buf); + return ok_to_remove; +} + static int find_first_merges(struct object_array *result, const char *path, struct commit *a, struct commit *b) { diff --git a/submodule.h b/submodule.h index 594b50d..3dc1b3f 100644 --- a/submodule.h +++ b/submodule.h @@ -20,7 +20,7 @@ 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, unsigned char one[20], unsigned char two[20], - unsigned dirty_submodule, + unsigned dirty_submodule, const char *meta, const char *del, const char *add, const char *reset); void set_config_fetch_recurse_submodules(int value); void check_for_new_submodule_commits(unsigned char new_sha1[20]); @@ -28,6 +28,8 @@ int fetch_populated_submodules(const struct argv_array *options, const char *prefix, int command_line_option, int quiet); unsigned is_submodule_modified(const char *path, int ignore_untracked); +int submodule_uses_gitfile(const char *path); +int ok_to_remove_submodule(const char *path); int merge_submodule(unsigned char result[20], const char *path, const unsigned char base[20], const unsigned char a[20], const unsigned char b[20], int search); int find_unpushed_submodules(unsigned char new_sha1[20], const char *remotes_name, @@ -6,7 +6,7 @@ -include ../config.mak.autogen -include ../config.mak -#GIT_TEST_OPTS=--verbose --debug +#GIT_TEST_OPTS = --verbose --debug SHELL_PATH ?= $(SHELL) PERL_PATH ?= /usr/bin/perl TAR ?= $(TAR) diff --git a/t/lib-gettext.sh b/t/lib-gettext.sh index 0f76f6c..ae8883a 100644 --- a/t/lib-gettext.sh +++ b/t/lib-gettext.sh @@ -14,12 +14,14 @@ export GIT_TEXTDOMAINDIR GIT_PO_PATH if test_have_prereq GETTEXT && ! test_have_prereq GETTEXT_POISON then # is_IS.UTF-8 on Solaris and FreeBSD, is_IS.utf8 on Debian - is_IS_locale=$(locale -a | sed -n '/^is_IS\.[uU][tT][fF]-*8$/{ + is_IS_locale=$(locale -a 2>/dev/null | + sed -n '/^is_IS\.[uU][tT][fF]-*8$/{ p q }') # is_IS.ISO8859-1 on Solaris and FreeBSD, is_IS.iso88591 on Debian - is_IS_iso_locale=$(locale -a | sed -n '/^is_IS\.[iI][sS][oO]8859-*1$/{ + is_IS_iso_locale=$(locale -a 2>/dev/null | + sed -n '/^is_IS\.[iI][sS][oO]8859-*1$/{ p q }') diff --git a/t/lib-httpd/apache.conf b/t/lib-httpd/apache.conf index 49d5d87..fe76e84 100644 --- a/t/lib-httpd/apache.conf +++ b/t/lib-httpd/apache.conf @@ -99,6 +99,13 @@ SSLEngine On Require valid-user </LocationMatch> +<LocationMatch "^/auth-fetch/.*/git-upload-pack$"> + AuthType Basic + AuthName "git-auth" + AuthUserFile passwd + Require valid-user +</LocationMatch> + <IfDefine DAV> LoadModule dav_module modules/mod_dav.so LoadModule dav_fs_module modules/mod_dav_fs.so diff --git a/t/t0000-basic.sh b/t/t0000-basic.sh index 08677df..cefe33d 100755 --- a/t/t0000-basic.sh +++ b/t/t0000-basic.sh @@ -45,39 +45,176 @@ test_expect_failure 'pretend we have a known breakage' ' false ' -test_expect_success 'pretend we have fixed a known breakage (run in sub test-lib)' " - mkdir passing-todo && - (cd passing-todo && - cat >passing-todo.sh <<-EOF && - #!$SHELL_PATH - - test_description='A passing TODO test +run_sub_test_lib_test () { + name="$1" descr="$2" # stdin is the body of the test code + mkdir "$name" && + ( + cd "$name" && + cat >"$name.sh" <<-EOF && + #!$SHELL_PATH + + test_description='$descr (run in sub test-lib) + + This is run in a sub test-lib so that we do not get incorrect + passing metrics + ' + + # Point to the t/test-lib.sh, which isn't in ../ as usual + . "\$TEST_DIRECTORY"/test-lib.sh + EOF + cat >>"$name.sh" && + chmod +x "$name.sh" && + export TEST_DIRECTORY && + ./"$name.sh" >out 2>err + ) +} - This is run in a sub test-lib so that we do not get incorrect - passing metrics - ' +check_sub_test_lib_test () { + name="$1" # stdin is the expected output from the test + ( + cd "$name" && + ! test -s err && + sed -e 's/^> //' -e 's/Z$//' >expect && + test_cmp expect out + ) +} + +test_expect_success 'pretend we have a fully passing test suite' " + run_sub_test_lib_test full-pass '3 passing tests' <<-\\EOF && + for i in 1 2 3 + do + test_expect_success \"passing test #\$i\" 'true' + done + test_done + EOF + check_sub_test_lib_test full-pass <<-\\EOF + > ok 1 - passing test #1 + > ok 2 - passing test #2 + > ok 3 - passing test #3 + > # passed all 3 test(s) + > 1..3 + EOF +" - # Point to the t/test-lib.sh, which isn't in ../ as usual - TEST_DIRECTORY=\"$TEST_DIRECTORY\" - . \"\$TEST_DIRECTORY\"/test-lib.sh +test_expect_success 'pretend we have a partially passing test suite' " + test_must_fail run_sub_test_lib_test \ + partial-pass '2/3 tests passing' <<-\\EOF && + test_expect_success 'passing test #1' 'true' + test_expect_success 'failing test #2' 'false' + test_expect_success 'passing test #3' 'true' + test_done + EOF + check_sub_test_lib_test partial-pass <<-\\EOF + > ok 1 - passing test #1 + > not ok 2 - failing test #2 + # false + > ok 3 - passing test #3 + > # failed 1 among 3 test(s) + > 1..3 + EOF +" - test_expect_failure 'pretend we have fixed a known breakage' ' - : - ' +test_expect_success 'pretend we have a known breakage' " + run_sub_test_lib_test failing-todo 'A failing TODO test' <<-\\EOF && + test_expect_success 'passing test' 'true' + test_expect_failure 'pretend we have a known breakage' 'false' + test_done + EOF + check_sub_test_lib_test failing-todo <<-\\EOF + > ok 1 - passing test + > not ok 2 - pretend we have a known breakage # TODO known breakage + > # still have 1 known breakage(s) + > # passed all remaining 1 test(s) + > 1..2 + EOF +" +test_expect_success 'pretend we have fixed a known breakage' " + run_sub_test_lib_test passing-todo 'A passing TODO test' <<-\\EOF && + test_expect_failure 'pretend we have fixed a known breakage' 'true' test_done EOF - chmod +x passing-todo.sh && - ./passing-todo.sh >out 2>err && - ! test -s err && - sed -e 's/^> //' >expect <<-\\EOF && - > ok 1 - pretend we have fixed a known breakage # TODO known breakage - > # fixed 1 known breakage(s) - > # passed all 1 test(s) + check_sub_test_lib_test passing-todo <<-\\EOF + > ok 1 - pretend we have fixed a known breakage # TODO known breakage vanished + > # 1 known breakage(s) vanished; please update test(s) > 1..1 EOF - test_cmp expect out) " + +test_expect_success 'pretend we have fixed one of two known breakages (run in sub test-lib)' " + run_sub_test_lib_test partially-passing-todos \ + '2 TODO tests, one passing' <<-\\EOF && + test_expect_failure 'pretend we have a known breakage' 'false' + test_expect_success 'pretend we have a passing test' 'true' + test_expect_failure 'pretend we have fixed another known breakage' 'true' + test_done + EOF + check_sub_test_lib_test partially-passing-todos <<-\\EOF + > not ok 1 - pretend we have a known breakage # TODO known breakage + > ok 2 - pretend we have a passing test + > ok 3 - pretend we have fixed another known breakage # TODO known breakage vanished + > # 1 known breakage(s) vanished; please update test(s) + > # still have 1 known breakage(s) + > # passed all remaining 1 test(s) + > 1..3 + EOF +" + +test_expect_success 'pretend we have a pass, fail, and known breakage' " + test_must_fail run_sub_test_lib_test \ + mixed-results1 'mixed results #1' <<-\\EOF && + test_expect_success 'passing test' 'true' + test_expect_success 'failing test' 'false' + test_expect_failure 'pretend we have a known breakage' 'false' + test_done + EOF + check_sub_test_lib_test mixed-results1 <<-\\EOF + > ok 1 - passing test + > not ok 2 - failing test + > # false + > not ok 3 - pretend we have a known breakage # TODO known breakage + > # still have 1 known breakage(s) + > # failed 1 among remaining 2 test(s) + > 1..3 + EOF +" + +test_expect_success 'pretend we have a mix of all possible results' " + test_must_fail run_sub_test_lib_test \ + mixed-results2 'mixed results #2' <<-\\EOF && + test_expect_success 'passing test' 'true' + test_expect_success 'passing test' 'true' + test_expect_success 'passing test' 'true' + test_expect_success 'passing test' 'true' + test_expect_success 'failing test' 'false' + test_expect_success 'failing test' 'false' + test_expect_success 'failing test' 'false' + test_expect_failure 'pretend we have a known breakage' 'false' + test_expect_failure 'pretend we have a known breakage' 'false' + test_expect_failure 'pretend we have fixed a known breakage' 'true' + test_done + EOF + check_sub_test_lib_test mixed-results2 <<-\\EOF + > ok 1 - passing test + > ok 2 - passing test + > ok 3 - passing test + > ok 4 - passing test + > not ok 5 - failing test + > # false + > not ok 6 - failing test + > # false + > not ok 7 - failing test + > # false + > not ok 8 - pretend we have a known breakage # TODO known breakage + > not ok 9 - pretend we have a known breakage # TODO known breakage + > ok 10 - pretend we have fixed a known breakage # TODO known breakage vanished + > # 1 known breakage(s) vanished; please update test(s) + > # still have 2 known breakage(s) + > # failed 3 among remaining 7 test(s) + > 1..10 + EOF +" + test_set_prereq HAVEIT haveit=no test_expect_success HAVEIT 'test runs if prerequisite is satisfied' ' @@ -115,6 +252,38 @@ then exit 1 fi +test_lazy_prereq LAZY_TRUE true +havetrue=no +test_expect_success LAZY_TRUE 'test runs if lazy prereq is satisfied' ' + havetrue=yes +' +donthavetrue=yes +test_expect_success !LAZY_TRUE 'missing lazy prereqs skip tests' ' + donthavetrue=no +' + +if test "$havetrue$donthavetrue" != yesyes +then + say 'bug in test framework: lazy prerequisites do not work' + exit 1 +fi + +test_lazy_prereq LAZY_FALSE false +nothavefalse=no +test_expect_success !LAZY_FALSE 'negative lazy prereqs checked' ' + nothavefalse=yes +' +havefalse=yes +test_expect_success LAZY_FALSE 'missing negative lazy prereqs will skip' ' + havefalse=no +' + +if test "$nothavefalse$havefalse" != yesyes +then + say 'bug in test framework: negative lazy prerequisites do not work' + exit 1 +fi + clean=no test_expect_success 'tests clean up after themselves' ' test_when_finished clean=yes @@ -127,19 +296,8 @@ then fi test_expect_success 'tests clean up even on failures' " - mkdir failing-cleanup && - ( - cd failing-cleanup && - - cat >failing-cleanup.sh <<-EOF && - #!$SHELL_PATH - - test_description='Failing tests with cleanup commands' - - # Point to the t/test-lib.sh, which isn't in ../ as usual - TEST_DIRECTORY=\"$TEST_DIRECTORY\" - . \"\$TEST_DIRECTORY\"/test-lib.sh - + test_must_fail run_sub_test_lib_test \ + failing-cleanup 'Failing tests with cleanup commands' <<-\\EOF && test_expect_success 'tests clean up even after a failure' ' touch clean-after-failure && test_when_finished rm clean-after-failure && @@ -149,29 +307,21 @@ test_expect_success 'tests clean up even on failures' " test_when_finished \"(exit 2)\" ' test_done - EOF - - chmod +x failing-cleanup.sh && - test_must_fail ./failing-cleanup.sh >out 2>err && - ! test -s err && - ! test -f \"trash directory.failing-cleanup/clean-after-failure\" && - sed -e 's/Z$//' -e 's/^> //' >expect <<-\\EOF && - > not ok - 1 tests clean up even after a failure + check_sub_test_lib_test failing-cleanup <<-\\EOF + > not ok 1 - tests clean up even after a failure > # Z > # touch clean-after-failure && > # test_when_finished rm clean-after-failure && > # (exit 1) > # Z - > not ok - 2 failure to clean up causes the test to fail + > not ok 2 - failure to clean up causes the test to fail > # Z > # test_when_finished \"(exit 2)\" > # Z > # failed 2 among 2 test(s) > 1..2 EOF - test_cmp expect out - ) " ################################################################ diff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh index febc45c..807b8b8 100755 --- a/t/t0003-attributes.sh +++ b/t/t0003-attributes.sh @@ -196,6 +196,16 @@ test_expect_success 'root subdir attribute test' ' attr_check subdir/a/i unspecified ' +test_expect_success 'negative patterns' ' + echo "!f test=bar" >.gitattributes && + test_must_fail git check-attr test -- f +' + +test_expect_success 'patterns starting with exclamation' ' + echo "\!f test=foo" >.gitattributes && + attr_check "!f" foo +' + test_expect_success 'setup bare' ' git clone --bare . bare.git && cd bare.git diff --git a/t/t0007-git-var.sh b/t/t0007-git-var.sh new file mode 100755 index 0000000..5868a87 --- /dev/null +++ b/t/t0007-git-var.sh @@ -0,0 +1,49 @@ +#!/bin/sh + +test_description='basic sanity checks for git var' +. ./test-lib.sh + +test_expect_success 'get GIT_AUTHOR_IDENT' ' + test_tick && + echo "$GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL> $GIT_AUTHOR_DATE" >expect && + git var GIT_AUTHOR_IDENT >actual && + test_cmp expect actual +' + +test_expect_success 'get GIT_COMMITTER_IDENT' ' + test_tick && + echo "$GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE" >expect && + git var GIT_COMMITTER_IDENT >actual && + test_cmp expect actual +' + +test_expect_success !AUTOIDENT 'requested identites are strict' ' + ( + sane_unset GIT_COMMITTER_NAME && + sane_unset GIT_COMMITTER_EMAIL && + test_must_fail git var GIT_COMMITTER_IDENT + ) +' + +# For git var -l, we check only a representative variable; +# testing the whole output would make our test too brittle with +# respect to unrelated changes in the test suite's environment. +test_expect_success 'git var -l lists variables' ' + git var -l >actual && + echo "$GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL> $GIT_AUTHOR_DATE" >expect && + sed -n s/GIT_AUTHOR_IDENT=//p <actual >actual.author && + test_cmp expect actual.author +' + +test_expect_success 'git var -l lists config' ' + git var -l >actual && + echo false >expect && + sed -n s/core\\.bare=//p <actual >actual.bare && + test_cmp expect actual.bare +' + +test_expect_success 'listing and asking for variables are exclusive' ' + test_must_fail git var -l GIT_COMMITTER_IDENT +' + +test_done diff --git a/t/t0060-path-utils.sh b/t/t0060-path-utils.sh index 4ef2345..09a42a4 100755 --- a/t/t0060-path-utils.sh +++ b/t/t0060-path-utils.sh @@ -93,47 +93,32 @@ norm_path /d1/s1//../s2/../../d2 /d2 POSIX norm_path /d1/.../d2 /d1/.../d2 POSIX norm_path /d1/..././../d2 /d1/d2 POSIX -ancestor / "" -1 ancestor / / -1 -ancestor /foo "" -1 -ancestor /foo : -1 -ancestor /foo ::. -1 -ancestor /foo ::..:: -1 ancestor /foo / 0 ancestor /foo /fo -1 ancestor /foo /foo -1 -ancestor /foo /foo/ -1 ancestor /foo /bar -1 -ancestor /foo /bar/ -1 ancestor /foo /foo/bar -1 -ancestor /foo /foo:/bar/ -1 -ancestor /foo /foo/:/bar/ -1 -ancestor /foo /foo::/bar/ -1 -ancestor /foo /:/foo:/bar/ 0 -ancestor /foo /foo:/:/bar/ 0 -ancestor /foo /:/bar/:/foo 0 -ancestor /foo/bar "" -1 +ancestor /foo /foo:/bar -1 +ancestor /foo /:/foo:/bar 0 +ancestor /foo /foo:/:/bar 0 +ancestor /foo /:/bar:/foo 0 ancestor /foo/bar / 0 ancestor /foo/bar /fo -1 -ancestor /foo/bar foo -1 ancestor /foo/bar /foo 4 -ancestor /foo/bar /foo/ 4 ancestor /foo/bar /foo/ba -1 ancestor /foo/bar /:/fo 0 ancestor /foo/bar /foo:/foo/ba 4 ancestor /foo/bar /bar -1 -ancestor /foo/bar /bar/ -1 -ancestor /foo/bar /fo: -1 -ancestor /foo/bar :/fo -1 -ancestor /foo/bar /foo:/bar/ 4 -ancestor /foo/bar /:/foo:/bar/ 4 -ancestor /foo/bar /foo:/:/bar/ 4 -ancestor /foo/bar /:/bar/:/fo 0 -ancestor /foo/bar /:/bar/ 0 -ancestor /foo/bar .:/foo/. 4 -ancestor /foo/bar .:/foo/.:.: 4 -ancestor /foo/bar /foo/./:.:/bar 4 -ancestor /foo/bar .:/bar -1 +ancestor /foo/bar /fo -1 +ancestor /foo/bar /foo:/bar 4 +ancestor /foo/bar /:/foo:/bar 4 +ancestor /foo/bar /foo:/:/bar 4 +ancestor /foo/bar /:/bar:/fo 0 +ancestor /foo/bar /:/bar 0 +ancestor /foo/bar /foo 4 +ancestor /foo/bar /foo:/bar 4 +ancestor /foo/bar /bar -1 test_expect_success 'strip_path_suffix' ' test c:/msysgit = $(test-path-utils strip_path_suffix \ diff --git a/t/t0063-string-list.sh b/t/t0063-string-list.sh index 41c8826..dbfc05e 100755 --- a/t/t0063-string-list.sh +++ b/t/t0063-string-list.sh @@ -17,14 +17,6 @@ test_split () { " } -test_longest_prefix () { - test "$(test-string-list longest_prefix "$1" "$2")" = "$3" -} - -test_no_longest_prefix () { - test_must_fail test-string-list longest_prefix "$1" "$2" -} - test_split "foo:bar:baz" ":" "-1" <<EOF 3 [0]: "foo" @@ -96,26 +88,4 @@ test_expect_success "test remove_duplicates" ' test a:b:c = "$(test-string-list remove_duplicates a:a:a:b:b:b:c:c:c)" ' -test_expect_success "test longest_prefix" ' - test_no_longest_prefix - '' && - test_no_longest_prefix - x && - test_longest_prefix "" x "" && - test_longest_prefix x x x && - test_longest_prefix "" foo "" && - test_longest_prefix : foo "" && - test_longest_prefix f foo f && - test_longest_prefix foo foobar foo && - test_longest_prefix foo foo foo && - test_no_longest_prefix bar foo && - test_no_longest_prefix bar:bar foo && - test_no_longest_prefix foobar foo && - test_longest_prefix foo:bar foo foo && - test_longest_prefix foo:bar bar bar && - test_longest_prefix foo::bar foo foo && - test_longest_prefix foo:foobar foo foo && - test_longest_prefix foobar:foo foo foo && - test_longest_prefix foo: bar "" && - test_longest_prefix :foo bar "" -' - test_done diff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh index 7c4c372..3c96fda 100755 --- a/t/t1300-repo-config.sh +++ b/t/t1300-repo-config.sh @@ -55,11 +55,13 @@ test_expect_success 'uppercase section' ' test_cmp expect .git/config ' -test_expect_success 'replace with non-match' \ - 'git config core.penguin kingpin !blue' +test_expect_success 'replace with non-match' ' + git config core.penguin kingpin !blue +' -test_expect_success 'replace with non-match (actually matching)' \ - 'git config core.penguin "very blue" !kingpin' +test_expect_success 'replace with non-match (actually matching)' ' + git config core.penguin "very blue" !kingpin +' cat > expect << EOF [core] @@ -108,8 +110,9 @@ baz = multiple \ lines EOF -test_expect_success 'unset with cont. lines' \ - 'git config --unset beta.baz' +test_expect_success 'unset with cont. lines' ' + git config --unset beta.baz +' cat > expect <<\EOF [alpha] @@ -133,8 +136,9 @@ EOF cp .git/config .git/config2 -test_expect_success 'multiple unset' \ - 'git config --unset-all beta.haha' +test_expect_success 'multiple unset' ' + git config --unset-all beta.haha +' cat > expect << EOF [beta] ; silly comment # another comment @@ -145,7 +149,9 @@ noIndent= sillyValue ; 'nother silly comment [nextSection] noNewline = ouch EOF -test_expect_success 'multiple unset is correct' 'test_cmp expect .git/config' +test_expect_success 'multiple unset is correct' ' + test_cmp expect .git/config +' cp .git/config2 .git/config @@ -156,8 +162,9 @@ test_expect_success '--replace-all missing value' ' rm .git/config2 -test_expect_success '--replace-all' \ - 'git config --replace-all beta.haha gamma' +test_expect_success '--replace-all' ' + git config --replace-all beta.haha gamma +' cat > expect << EOF [beta] ; silly comment # another comment @@ -169,7 +176,9 @@ noIndent= sillyValue ; 'nother silly comment [nextSection] noNewline = ouch EOF -test_expect_success 'all replaced' 'test_cmp expect .git/config' +test_expect_success 'all replaced' ' + test_cmp expect .git/config +' cat > expect << EOF [beta] ; silly comment # another comment @@ -200,7 +209,11 @@ test_expect_success 'really really mean test' ' test_cmp expect .git/config ' -test_expect_success 'get value' 'test alpha = $(git config beta.haha)' +test_expect_success 'get value' ' + echo alpha >expect && + git config beta.haha >actual && + test_cmp expect actual +' cat > expect << EOF [beta] ; silly comment # another comment @@ -231,18 +244,30 @@ test_expect_success 'multivar' ' test_cmp expect .git/config ' -test_expect_success 'non-match' \ - 'git config --get nextsection.nonewline !for' +test_expect_success 'non-match' ' + git config --get nextsection.nonewline !for +' -test_expect_success 'non-match value' \ - 'test wow = $(git config --get nextsection.nonewline !for)' +test_expect_success 'non-match value' ' + echo wow >expect && + git config --get nextsection.nonewline !for >actual && + test_cmp expect actual +' -test_expect_success 'ambiguous get' ' - test_must_fail git config --get nextsection.nonewline +test_expect_success 'multi-valued get returns final one' ' + echo "wow2 for me" >expect && + git config --get nextsection.nonewline >actual && + test_cmp expect actual ' -test_expect_success 'get multivar' \ - 'git config --get-all nextsection.nonewline' +test_expect_success 'multi-valued get-all returns all' ' + cat >expect <<-\EOF && + wow + wow2 for me + EOF + git config --get-all nextsection.nonewline >actual && + test_cmp expect actual +' cat > expect << EOF [beta] ; silly comment # another comment @@ -259,10 +284,6 @@ test_expect_success 'multivar replace' ' test_cmp expect .git/config ' -test_expect_success 'ambiguous value' ' - test_must_fail git config nextsection.nonewline -' - test_expect_success 'ambiguous unset' ' test_must_fail git config --unset nextsection.nonewline ' @@ -290,8 +311,9 @@ test_expect_success 'invalid key' 'test_must_fail git config inval.2key blabla' test_expect_success 'correct key' 'git config 123456.a123 987' -test_expect_success 'hierarchical section' \ - 'git config Version.1.2.3eX.Alpha beta' +test_expect_success 'hierarchical section' ' + git config Version.1.2.3eX.Alpha beta +' cat > expect << EOF [beta] ; silly comment # another comment @@ -307,7 +329,9 @@ noIndent= sillyValue ; 'nother silly comment Alpha = beta EOF -test_expect_success 'hierarchical section value' 'test_cmp expect .git/config' +test_expect_success 'hierarchical section value' ' + test_cmp expect .git/config +' cat > expect << EOF beta.noindent=sillyValue @@ -316,9 +340,10 @@ nextsection.nonewline=wow2 for me version.1.2.3eX.alpha=beta EOF -test_expect_success 'working --list' \ - 'git config --list > output && cmp output expect' - +test_expect_success 'working --list' ' + git config --list > output && + test_cmp expect output +' cat > expect << EOF EOF @@ -332,8 +357,10 @@ beta.noindent sillyValue nextsection.nonewline wow2 for me EOF -test_expect_success '--get-regexp' \ - 'git config --get-regexp in > output && cmp output expect' +test_expect_success '--get-regexp' ' + git config --get-regexp in >output && + test_cmp expect output +' cat > expect << EOF wow2 for me @@ -353,41 +380,48 @@ cat > .git/config << EOF variable = EOF -test_expect_success 'get variable with no value' \ - 'git config --get novalue.variable ^$' +test_expect_success 'get variable with no value' ' + git config --get novalue.variable ^$ +' -test_expect_success 'get variable with empty value' \ - 'git config --get emptyvalue.variable ^$' +test_expect_success 'get variable with empty value' ' + git config --get emptyvalue.variable ^$ +' echo novalue.variable > expect -test_expect_success 'get-regexp variable with no value' \ - 'git config --get-regexp novalue > output && - cmp output expect' +test_expect_success 'get-regexp variable with no value' ' + git config --get-regexp novalue > output && + test_cmp expect output +' echo 'novalue.variable true' > expect -test_expect_success 'get-regexp --bool variable with no value' \ - 'git config --bool --get-regexp novalue > output && - cmp output expect' +test_expect_success 'get-regexp --bool variable with no value' ' + git config --bool --get-regexp novalue > output && + test_cmp expect output +' echo 'emptyvalue.variable ' > expect -test_expect_success 'get-regexp variable with empty value' \ - 'git config --get-regexp emptyvalue > output && - cmp output expect' +test_expect_success 'get-regexp variable with empty value' ' + git config --get-regexp emptyvalue > output && + test_cmp expect output +' echo true > expect -test_expect_success 'get bool variable with no value' \ - 'git config --bool novalue.variable > output && - cmp output expect' +test_expect_success 'get bool variable with no value' ' + git config --bool novalue.variable > output && + test_cmp expect output +' echo false > expect -test_expect_success 'get bool variable with empty value' \ - 'git config --bool emptyvalue.variable > output && - cmp output expect' +test_expect_success 'get bool variable with empty value' ' + git config --bool emptyvalue.variable > output && + test_cmp expect output +' test_expect_success 'no arguments, but no crash' ' test_must_fail git config >output 2>&1 && @@ -427,8 +461,9 @@ test_expect_success 'new variable inserts into proper section' ' test_cmp expect .git/config ' -test_expect_success 'alternative GIT_CONFIG (non-existing file should fail)' \ - 'test_must_fail git config --file non-existing-config -l' +test_expect_success 'alternative GIT_CONFIG (non-existing file should fail)' ' + test_must_fail git config --file non-existing-config -l +' cat > other-config << EOF [ein] @@ -444,8 +479,10 @@ test_expect_success 'alternative GIT_CONFIG' ' test_cmp expect output ' -test_expect_success 'alternative GIT_CONFIG (--file)' \ - 'git config --file other-config -l > output && cmp output expect' +test_expect_success 'alternative GIT_CONFIG (--file)' ' + git config --file other-config -l > output && + test_cmp expect output +' test_expect_success 'refer config from subdirectory' ' mkdir x && @@ -489,8 +526,9 @@ cat > .git/config << EOF weird EOF -test_expect_success "rename section" \ - "git config --rename-section branch.eins branch.zwei" +test_expect_success 'rename section' ' + git config --rename-section branch.eins branch.zwei +' cat > expect << EOF # Hallo @@ -503,17 +541,22 @@ cat > expect << EOF weird EOF -test_expect_success "rename succeeded" "test_cmp expect .git/config" +test_expect_success 'rename succeeded' ' + test_cmp expect .git/config +' -test_expect_success "rename non-existing section" ' +test_expect_success 'rename non-existing section' ' test_must_fail git config --rename-section \ branch."world domination" branch.drei ' -test_expect_success "rename succeeded" "test_cmp expect .git/config" +test_expect_success 'rename succeeded' ' + test_cmp expect .git/config +' -test_expect_success "rename another section" \ - 'git config --rename-section branch."1 234 blabl/a" branch.drei' +test_expect_success 'rename another section' ' + git config --rename-section branch."1 234 blabl/a" branch.drei +' cat > expect << EOF # Hallo @@ -526,14 +569,17 @@ cat > expect << EOF weird EOF -test_expect_success "rename succeeded" "test_cmp expect .git/config" +test_expect_success 'rename succeeded' ' + test_cmp expect .git/config +' cat >> .git/config << EOF [branch "vier"] z = 1 EOF -test_expect_success "rename a section with a var on the same line" \ - 'git config --rename-section branch.vier branch.zwei' +test_expect_success 'rename a section with a var on the same line' ' + git config --rename-section branch.vier branch.zwei +' cat > expect << EOF # Hallo @@ -548,7 +594,9 @@ weird z = 1 EOF -test_expect_success "rename succeeded" "test_cmp expect .git/config" +test_expect_success 'rename succeeded' ' + test_cmp expect .git/config +' test_expect_success 'renaming empty section name is rejected' ' test_must_fail git config --rename-section branch.zwei "" @@ -562,7 +610,9 @@ cat >> .git/config << EOF [branch "zwei"] a = 1 [branch "vier"] EOF -test_expect_success "remove section" "git config --remove-section branch.zwei" +test_expect_success 'remove section' ' + git config --remove-section branch.zwei +' cat > expect << EOF # Hallo @@ -571,8 +621,9 @@ cat > expect << EOF weird EOF -test_expect_success "section was removed properly" \ - "test_cmp expect .git/config" +test_expect_success 'section was removed properly' ' + test_cmp expect .git/config +' cat > expect << EOF [gitcvs] @@ -583,7 +634,6 @@ cat > expect << EOF EOF test_expect_success 'section ending' ' - rm -f .git/config && git config gitcvs.enabled true && git config gitcvs.ext.dbname %Ggitcvs1.%a.%m.sqlite && @@ -593,30 +643,25 @@ test_expect_success 'section ending' ' ' test_expect_success numbers ' - git config kilo.gram 1k && git config mega.ton 1m && - k=$(git config --int --get kilo.gram) && - test z1024 = "z$k" && - m=$(git config --int --get mega.ton) && - test z1048576 = "z$m" + echo 1024 >expect && + echo 1048576 >>expect && + git config --int --get kilo.gram >actual && + git config --int --get mega.ton >>actual && + test_cmp expect actual ' -cat > expect <<EOF -fatal: bad config value for 'aninvalid.unit' in .git/config -EOF - test_expect_success 'invalid unit' ' - git config aninvalid.unit "1auto" && - s=$(git config aninvalid.unit) && - test "z1auto" = "z$s" && - if git config --int --get aninvalid.unit 2>actual - then - echo config should have failed - false - fi && - cmp actual expect + echo 1auto >expect && + git config aninvalid.unit >actual && + test_cmp expect actual && + cat > expect <<-\EOF + fatal: bad config value for '\''aninvalid.unit'\'' in .git/config + EOF + test_must_fail git config --int --get aninvalid.unit 2>actual && + test_cmp actual expect ' cat > expect << EOF @@ -646,7 +691,7 @@ test_expect_success bool ' git config --bool --get bool.true$i >>result git config --bool --get bool.false$i >>result done && - cmp expect result' + test_cmp expect result' test_expect_success 'invalid bool (--get)' ' @@ -680,7 +725,7 @@ test_expect_success 'set --bool' ' git config --bool bool.false2 "" && git config --bool bool.false3 nO && git config --bool bool.false4 FALSE && - cmp expect .git/config' + test_cmp expect .git/config' cat > expect <<\EOF [int] @@ -695,39 +740,37 @@ test_expect_success 'set --int' ' git config --int int.val1 01 && git config --int int.val2 -1 && git config --int int.val3 5m && - cmp expect .git/config' + test_cmp expect .git/config +' -cat >expect <<\EOF -[bool] - true1 = true +test_expect_success 'get --bool-or-int' ' + cat >.git/config <<-\EOF && + [bool] + true1 true2 = true - false1 = false - false2 = false -[int] + false = false + [int] int1 = 0 int2 = 1 int3 = -1 -EOF - -test_expect_success 'get --bool-or-int' ' - rm -f .git/config && - ( - echo "[bool]" - echo true1 - echo true2 = true - echo false = false - echo "[int]" - echo int1 = 0 - echo int2 = 1 - echo int3 = -1 - ) >>.git/config && - test $(git config --bool-or-int bool.true1) = true && - test $(git config --bool-or-int bool.true2) = true && - test $(git config --bool-or-int bool.false) = false && - test $(git config --bool-or-int int.int1) = 0 && - test $(git config --bool-or-int int.int2) = 1 && - test $(git config --bool-or-int int.int3) = -1 - + EOF + cat >expect <<-\EOF && + true + true + false + 0 + 1 + -1 + EOF + { + git config --bool-or-int bool.true1 && + git config --bool-or-int bool.true2 && + git config --bool-or-int bool.false && + git config --bool-or-int int.int1 && + git config --bool-or-int int.int2 && + git config --bool-or-int int.int3 + } >actual && + test_cmp expect actual ' cat >expect <<\EOF @@ -849,7 +892,7 @@ EOF test_expect_success 'value continued on next line' ' git config --list > result && - cmp result expect + test_cmp result expect ' cat > .git/config <<\EOF @@ -885,11 +928,12 @@ test_expect_success '--null --get-regexp' ' test_expect_success 'inner whitespace kept verbatim' ' git config section.val "foo bar" && - test "z$(git config section.val)" = "zfoo bar" + echo "foo bar" >expect && + git config section.val >actual && + test_cmp expect actual ' test_expect_success SYMLINKS 'symlinked configuration' ' - ln -s notyet myconfig && GIT_CONFIG=myconfig git config test.frotz nitfol && test -h myconfig && @@ -898,9 +942,15 @@ test_expect_success SYMLINKS 'symlinked configuration' ' GIT_CONFIG=myconfig git config test.xyzzy rezrov && test -h myconfig && test -f notyet && - test "z$(GIT_CONFIG=notyet git config test.frotz)" = znitfol && - test "z$(GIT_CONFIG=notyet git config test.xyzzy)" = zrezrov - + cat >expect <<-\EOF && + nitfol + rezrov + EOF + { + GIT_CONFIG=notyet git config test.frotz && + GIT_CONFIG=notyet git config test.xyzzy + } >actual && + test_cmp expect actual ' test_expect_success 'nonexistent configuration' ' @@ -932,12 +982,20 @@ test_expect_success 'check split_cmdline return' " git commit -m 'initial commit' && git config branch.master.mergeoptions 'echo \"' && test_must_fail git merge master - " +" test_expect_success 'git -c "key=value" support' ' - test "z$(git -c core.name=value config core.name)" = zvalue && - test "z$(git -c foo.CamelCase=value config foo.camelcase)" = zvalue && - test "z$(git -c foo.flag config --bool foo.flag)" = ztrue && + cat >expect <<-\EOF && + value + value + true + EOF + { + git -c core.name=value config core.name && + git -c foo.CamelCase=value config foo.camelcase && + git -c foo.flag config --bool foo.flag + } >actual && + test_cmp expect actual && test_must_fail git -c name=value config core.name ' diff --git a/t/t1401-symbolic-ref.sh b/t/t1401-symbolic-ref.sh index 2c96551..36378b0 100755 --- a/t/t1401-symbolic-ref.sh +++ b/t/t1401-symbolic-ref.sh @@ -33,4 +33,34 @@ test_expect_success 'symbolic-ref refuses bare sha1' ' ' reset_to_sane +test_expect_success 'symbolic-ref deletes HEAD' ' + git symbolic-ref -d HEAD && + test_path_is_file .git/refs/heads/foo && + test_path_is_missing .git/HEAD +' +reset_to_sane + +test_expect_success 'symbolic-ref deletes dangling HEAD' ' + git symbolic-ref HEAD refs/heads/missing && + git symbolic-ref -d HEAD && + test_path_is_missing .git/refs/heads/missing && + test_path_is_missing .git/HEAD +' +reset_to_sane + +test_expect_success 'symbolic-ref fails to delete missing FOO' ' + echo "fatal: Cannot delete FOO, not a symbolic ref" >expect && + test_must_fail git symbolic-ref -d FOO >actual 2>&1 && + test_cmp expect actual +' +reset_to_sane + +test_expect_success 'symbolic-ref fails to delete real ref' ' + echo "fatal: Cannot delete refs/heads/foo, not a symbolic ref" >expect && + test_must_fail git symbolic-ref -d refs/heads/foo >actual 2>&1 && + test_path_is_file .git/refs/heads/foo && + test_cmp expect actual +' +reset_to_sane + test_done diff --git a/t/t1450-fsck.sh b/t/t1450-fsck.sh index 08aa24c..d730734 100755 --- a/t/t1450-fsck.sh +++ b/t/t1450-fsck.sh @@ -237,4 +237,35 @@ test_expect_success 'fsck notices submodule entry pointing to null sha1' ' ) ' +test_expect_success 'fsck notices "." and ".." in trees' ' + ( + git init dots && + cd dots && + blob=$(echo foo | git hash-object -w --stdin) && + tab=$(printf "\\t") && + git mktree <<-EOF && + 100644 blob $blob$tab. + 100644 blob $blob$tab.. + EOF + git fsck 2>out && + cat out && + grep "warning.*\\." out + ) +' + +test_expect_success 'fsck notices ".git" in trees' ' + ( + git init dotgit && + cd dotgit && + blob=$(echo foo | git hash-object -w --stdin) && + tab=$(printf "\\t") && + git mktree <<-EOF && + 100644 blob $blob$tab.git + EOF + git fsck 2>out && + cat out && + grep "warning.*\\.git" out + ) +' + test_done diff --git a/t/t2020-checkout-detach.sh b/t/t2020-checkout-detach.sh index 8100537..5d68729 100755 --- a/t/t2020-checkout-detach.sh +++ b/t/t2020-checkout-detach.sh @@ -151,6 +151,7 @@ test_expect_success 'checkout does not warn leaving reachable commit' ' cat >expect <<'EOF' Your branch is behind 'master' by 1 commit, and can be fast-forwarded. + (use "git pull" to update your local branch) EOF test_expect_success 'tracking count is accurate after orphan check' ' reset && diff --git a/t/t2203-add-intent.sh b/t/t2203-add-intent.sh index ec35409..2a4a749 100755 --- a/t/t2203-add-intent.sh +++ b/t/t2203-add-intent.sh @@ -62,5 +62,25 @@ test_expect_success 'can "commit -a" with an i-t-a entry' ' git commit -a -m all ' +test_expect_success 'cache-tree invalidates i-t-a paths' ' + git reset --hard && + mkdir dir && + : >dir/foo && + git add dir/foo && + git commit -m foo && + + : >dir/bar && + git add -N dir/bar && + git diff --cached --name-only >actual && + echo dir/bar >expect && + test_cmp expect actual && + + git write-tree >/dev/null && + + git diff --cached --name-only >actual && + echo dir/bar >expect && + test_cmp expect actual +' + test_done diff --git a/t/t3001-ls-files-others-exclude.sh b/t/t3001-ls-files-others-exclude.sh index c8fe978..dc2f045 100755 --- a/t/t3001-ls-files-others-exclude.sh +++ b/t/t3001-ls-files-others-exclude.sh @@ -214,4 +214,10 @@ test_expect_success 'subdirectory ignore (l1)' ' test_cmp expect actual ' +test_expect_success 'pattern matches prefix completely' ' + : >expect && + git ls-files -i -o --exclude "/three/a.3[abc]" >actual && + test_cmp expect actual +' + test_done diff --git a/t/t3600-rm.sh b/t/t3600-rm.sh index 9fd28bcf..37bf5f1 100755 --- a/t/t3600-rm.sh +++ b/t/t3600-rm.sh @@ -262,4 +262,364 @@ test_expect_success 'rm removes subdirectories recursively' ' ! test -d dir ' +cat >expect <<EOF +D submod +EOF + +cat >expect.modified <<EOF + M submod +EOF + +test_expect_success 'rm removes empty submodules from work tree' ' + mkdir submod && + git update-index --add --cacheinfo 160000 $(git rev-parse HEAD) submod && + git config -f .gitmodules submodule.sub.url ./. && + git config -f .gitmodules submodule.sub.path submod && + git submodule init && + git add .gitmodules && + git commit -m "add submodule" && + git rm submod && + test ! -e submod && + git status -s -uno --ignore-submodules=none > actual && + test_cmp expect actual +' + +test_expect_success 'rm removes removed submodule from index' ' + git reset --hard && + git submodule update && + rm -rf submod && + git rm submod && + git status -s -uno --ignore-submodules=none > actual && + test_cmp expect actual +' + +test_expect_success 'rm removes work tree of unmodified submodules' ' + git reset --hard && + git submodule update && + git rm submod && + test ! -d submod && + git status -s -uno --ignore-submodules=none > actual && + test_cmp expect actual +' + +test_expect_success 'rm removes a submodule with a trailing /' ' + git reset --hard && + git submodule update && + git rm submod/ && + test ! -d submod && + git status -s -uno --ignore-submodules=none > actual && + test_cmp expect actual +' + +test_expect_success 'rm fails when given a file with a trailing /' ' + test_must_fail git rm empty/ +' + +test_expect_success 'rm succeeds when given a directory with a trailing /' ' + git rm -r frotz/ +' + +test_expect_success 'rm of a populated submodule with different HEAD fails unless forced' ' + git reset --hard && + git submodule update && + (cd submod && + git checkout HEAD^ + ) && + test_must_fail git rm submod && + test -d submod && + test -f submod/.git && + git status -s -uno --ignore-submodules=none > actual && + test_cmp expect.modified actual && + git rm -f submod && + test ! -d submod && + git status -s -uno --ignore-submodules=none > actual && + test_cmp expect actual +' + +test_expect_success 'rm of a populated submodule with modifications fails unless forced' ' + git reset --hard && + git submodule update && + (cd submod && + echo X >empty + ) && + test_must_fail git rm submod && + test -d submod && + test -f submod/.git && + git status -s -uno --ignore-submodules=none > actual && + test_cmp expect.modified actual && + git rm -f submod && + test ! -d submod && + git status -s -uno --ignore-submodules=none > actual && + test_cmp expect actual +' + +test_expect_success 'rm of a populated submodule with untracked files fails unless forced' ' + git reset --hard && + git submodule update && + (cd submod && + echo X >untracked + ) && + test_must_fail git rm submod && + test -d submod && + test -f submod/.git && + git status -s -uno --ignore-submodules=none > actual && + test_cmp expect.modified actual && + git rm -f submod && + test ! -d submod && + git status -s -uno --ignore-submodules=none > actual && + test_cmp expect actual +' + +test_expect_success 'setup submodule conflict' ' + git reset --hard && + git submodule update && + git checkout -b branch1 && + echo 1 >nitfol && + git add nitfol && + git commit -m "added nitfol 1" && + git checkout -b branch2 master && + echo 2 >nitfol && + git add nitfol && + git commit -m "added nitfol 2" && + git checkout -b conflict1 master && + (cd submod && + git fetch && + git checkout branch1 + ) && + git add submod && + git commit -m "submod 1" && + git checkout -b conflict2 master && + (cd submod && + git checkout branch2 + ) && + git add submod && + git commit -m "submod 2" +' + +cat >expect.conflict <<EOF +UU submod +EOF + +test_expect_success 'rm removes work tree of unmodified conflicted submodule' ' + git checkout conflict1 && + git reset --hard && + git submodule update && + test_must_fail git merge conflict2 && + git rm submod && + test ! -d submod && + git status -s -uno --ignore-submodules=none > actual && + test_cmp expect actual +' + +test_expect_success 'rm of a conflicted populated submodule with different HEAD fails unless forced' ' + git checkout conflict1 && + git reset --hard && + git submodule update && + (cd submod && + git checkout HEAD^ + ) && + test_must_fail git merge conflict2 && + test_must_fail git rm submod && + test -d submod && + test -f submod/.git && + git status -s -uno --ignore-submodules=none > actual && + test_cmp expect.conflict actual && + git rm -f submod && + test ! -d submod && + git status -s -uno --ignore-submodules=none > actual && + test_cmp expect actual +' + +test_expect_success 'rm of a conflicted populated submodule with modifications fails unless forced' ' + git checkout conflict1 && + git reset --hard && + git submodule update && + (cd submod && + echo X >empty + ) && + test_must_fail git merge conflict2 && + test_must_fail git rm submod && + test -d submod && + test -f submod/.git && + git status -s -uno --ignore-submodules=none > actual && + test_cmp expect.conflict actual && + git rm -f submod && + test ! -d submod && + git status -s -uno --ignore-submodules=none > actual && + test_cmp expect actual +' + +test_expect_success 'rm of a conflicted populated submodule with untracked files fails unless forced' ' + git checkout conflict1 && + git reset --hard && + git submodule update && + (cd submod && + echo X >untracked + ) && + test_must_fail git merge conflict2 && + test_must_fail git rm submod && + test -d submod && + test -f submod/.git && + git status -s -uno --ignore-submodules=none > actual && + test_cmp expect.conflict actual && + git rm -f submod && + test ! -d submod && + git status -s -uno --ignore-submodules=none > actual && + test_cmp expect actual +' + +test_expect_success 'rm of a conflicted populated submodule with a .git directory fails even when forced' ' + git checkout conflict1 && + git reset --hard && + git submodule update && + (cd submod && + rm .git && + cp -R ../.git/modules/sub .git && + GIT_WORK_TREE=. git config --unset core.worktree + ) && + test_must_fail git merge conflict2 && + test_must_fail git rm submod && + test -d submod && + test -d submod/.git && + git status -s -uno --ignore-submodules=none > actual && + test_cmp expect.conflict actual && + test_must_fail git rm -f submod && + test -d submod && + test -d submod/.git && + git status -s -uno --ignore-submodules=none > actual && + test_cmp expect.conflict actual && + git merge --abort && + rm -rf submod +' + +test_expect_success 'rm of a conflicted unpopulated submodule succeeds' ' + git checkout conflict1 && + git reset --hard && + test_must_fail git merge conflict2 && + git rm submod && + test ! -d submod && + git status -s -uno --ignore-submodules=none > actual && + test_cmp expect actual +' + +test_expect_success 'rm of a populated submodule with a .git directory fails even when forced' ' + git checkout -f master && + git reset --hard && + git submodule update && + (cd submod && + rm .git && + cp -R ../.git/modules/sub .git && + GIT_WORK_TREE=. git config --unset core.worktree + ) && + test_must_fail git rm submod && + test -d submod && + test -d submod/.git && + git status -s -uno --ignore-submodules=none > actual && + ! test -s actual && + test_must_fail git rm -f submod && + test -d submod && + test -d submod/.git && + git status -s -uno --ignore-submodules=none > actual && + ! test -s actual && + rm -rf submod +' + +cat >expect.deepmodified <<EOF + M submod/subsubmod +EOF + +test_expect_success 'setup subsubmodule' ' + git reset --hard && + git submodule update && + (cd submod && + git update-index --add --cacheinfo 160000 $(git rev-parse HEAD) subsubmod && + git config -f .gitmodules submodule.sub.url ../. && + git config -f .gitmodules submodule.sub.path subsubmod && + git submodule init && + git add .gitmodules && + git commit -m "add subsubmodule" && + git submodule update subsubmod + ) && + git commit -a -m "added deep submodule" +' + +test_expect_success 'rm recursively removes work tree of unmodified submodules' ' + git rm submod && + test ! -d submod && + git status -s -uno --ignore-submodules=none > actual && + test_cmp expect actual +' + +test_expect_success 'rm of a populated nested submodule with different nested HEAD fails unless forced' ' + git reset --hard && + git submodule update --recursive && + (cd submod/subsubmod && + git checkout HEAD^ + ) && + test_must_fail git rm submod && + test -d submod && + test -f submod/.git && + git status -s -uno --ignore-submodules=none > actual && + test_cmp expect.modified actual && + git rm -f submod && + test ! -d submod && + git status -s -uno --ignore-submodules=none > actual && + test_cmp expect actual +' + +test_expect_success 'rm of a populated nested submodule with nested modifications fails unless forced' ' + git reset --hard && + git submodule update --recursive && + (cd submod/subsubmod && + echo X >empty + ) && + test_must_fail git rm submod && + test -d submod && + test -f submod/.git && + git status -s -uno --ignore-submodules=none > actual && + test_cmp expect.modified actual && + git rm -f submod && + test ! -d submod && + git status -s -uno --ignore-submodules=none > actual && + test_cmp expect actual +' + +test_expect_success 'rm of a populated nested submodule with nested untracked files fails unless forced' ' + git reset --hard && + git submodule update --recursive && + (cd submod/subsubmod && + echo X >untracked + ) && + test_must_fail git rm submod && + test -d submod && + test -f submod/.git && + git status -s -uno --ignore-submodules=none > actual && + test_cmp expect.modified actual && + git rm -f submod && + test ! -d submod && + git status -s -uno --ignore-submodules=none > actual && + test_cmp expect actual +' + +test_expect_success 'rm of a populated nested submodule with a nested .git directory fails even when forced' ' + git reset --hard && + git submodule update --recursive && + (cd submod/subsubmod && + rm .git && + cp -R ../../.git/modules/sub/modules/sub .git && + GIT_WORK_TREE=. git config --unset core.worktree + ) && + test_must_fail git rm submod && + test -d submod && + test -d submod/subsubmod/.git && + git status -s -uno --ignore-submodules=none > actual && + ! test -s actual && + test_must_fail git rm -f submod && + test -d submod && + test -d submod/subsubmod/.git && + git status -s -uno --ignore-submodules=none > actual && + ! test -s actual && + rm -rf submod +' + test_done diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh index ad9f69e..90fd598 100755 --- a/t/t4014-format-patch.sh +++ b/t/t4014-format-patch.sh @@ -155,7 +155,7 @@ test_expect_failure 'additional command line cc (rfc822)' ' git config --replace-all format.headers "Cc: R E Cipient <rcipient@example.com>" && git format-patch --cc="S. E. Cipient <scipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch5 && grep "^Cc: R E Cipient <rcipient@example.com>,\$" patch5 && - grep "^ *"S. E. Cipient" <scipient@example.com>\$" patch5 + grep "^ *\"S. E. Cipient\" <scipient@example.com>\$" patch5 ' test_expect_success 'command line headers' ' @@ -183,7 +183,7 @@ test_expect_success 'command line To: header (ascii)' ' test_expect_failure 'command line To: header (rfc822)' ' git format-patch --to="R. E. Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch8 && - grep "^To: "R. E. Cipient" <rcipient@example.com>\$" patch8 + grep "^To: \"R. E. Cipient\" <rcipient@example.com>\$" patch8 ' test_expect_failure 'command line To: header (rfc2047)' ' @@ -203,7 +203,7 @@ test_expect_failure 'configuration To: header (rfc822)' ' git config format.to "R. E. Cipient <rcipient@example.com>" && git format-patch --stdout master..side | sed -e "/^\$/q" >patch9 && - grep "^To: "R. E. Cipient" <rcipient@example.com>\$" patch9 + grep "^To: \"R. E. Cipient\" <rcipient@example.com>\$" patch9 ' test_expect_failure 'configuration To: header (rfc2047)' ' @@ -650,8 +650,19 @@ test_expect_success 'format-patch --in-reply-to' ' ' test_expect_success 'format-patch --signoff' ' - git format-patch -1 --signoff --stdout | - grep "^Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" + git format-patch -1 --signoff --stdout >out && + grep "^Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" out +' + +test_expect_success 'format-patch --notes --signoff' ' + git notes --ref test add -m "test message" HEAD && + git format-patch -1 --signoff --stdout --notes=test >out && + # Three dashes must come after S-o-b + ! sed "/^Signed-off-by: /q" out | grep "test message" && + sed "1,/^Signed-off-by: /d" out | grep "test message" && + # Notes message must come after three dashes + ! sed "/^---$/q" out | grep "test message" && + sed "1,/^---$/d" out | grep "test message" ' echo "fatal: --name-only does not make sense" > expect.name-only diff --git a/t/t4041-diff-submodule-option.sh b/t/t4041-diff-submodule-option.sh index 6c01d0c..32d4a60 100755 --- a/t/t4041-diff-submodule-option.sh +++ b/t/t4041-diff-submodule-option.sh @@ -11,18 +11,18 @@ This test tries to verify the sanity of the --submodule option of git diff. . ./test-lib.sh add_file () { - sm=$1 - shift - owd=$(pwd) - cd "$sm" - for name; do - echo "$name" > "$name" && - git add "$name" && - test_tick && - git commit -m "Add $name" - done >/dev/null - git rev-parse --verify HEAD | cut -c1-7 - cd "$owd" + ( + cd "$1" && + shift && + for name + do + echo "$name" >"$name" && + git add "$name" && + test_tick && + git commit -m "Add $name" || exit + done >/dev/null && + git rev-parse --short --verify HEAD + ) } commit_file () { test_tick && @@ -33,92 +33,133 @@ test_create_repo sm1 && add_file . foo >/dev/null head1=$(add_file sm1 foo1 foo2) +fullhead1=$(cd sm1; git rev-parse --verify HEAD) -test_expect_success 'added submodule' " +test_expect_success 'added submodule' ' git add sm1 && git diff-index -p --submodule=log HEAD >actual && cat >expected <<-EOF && -Submodule sm1 0000000...$head1 (new submodule) -EOF + Submodule sm1 0000000...$head1 (new submodule) + EOF + test_cmp expected actual +' + +test_expect_success 'added submodule, set diff.submodule' ' + git config diff.submodule log && + git add sm1 && + git diff --cached >actual && + cat >expected <<-EOF && + Submodule sm1 0000000...$head1 (new submodule) + EOF + git config --unset diff.submodule && + test_cmp expected actual +' + +test_expect_success '--submodule=short overrides diff.submodule' ' + test_config diff.submodule log && + git add sm1 && + git diff --submodule=short --cached >actual && + cat >expected <<-EOF && + diff --git a/sm1 b/sm1 + new file mode 160000 + index 0000000..$head1 + --- /dev/null + +++ b/sm1 + @@ -0,0 +1 @@ + +Subproject commit $fullhead1 + EOF test_cmp expected actual -" +' + +test_expect_success 'diff.submodule does not affect plumbing' ' + test_config diff.submodule log && + git diff-index -p HEAD >actual && + cat >expected <<-EOF && + diff --git a/sm1 b/sm1 + new file mode 160000 + index 0000000..$head1 + --- /dev/null + +++ b/sm1 + @@ -0,0 +1 @@ + +Subproject commit $fullhead1 + EOF + test_cmp expected actual +' commit_file sm1 && head2=$(add_file sm1 foo3) -test_expect_success 'modified submodule(forward)' " +test_expect_success 'modified submodule(forward)' ' git diff-index -p --submodule=log HEAD >actual && cat >expected <<-EOF && -Submodule sm1 $head1..$head2: - > Add foo3 -EOF + Submodule sm1 $head1..$head2: + > Add foo3 + EOF test_cmp expected actual -" +' -test_expect_success 'modified submodule(forward)' " +test_expect_success 'modified submodule(forward)' ' git diff --submodule=log >actual && cat >expected <<-EOF && -Submodule sm1 $head1..$head2: - > Add foo3 -EOF + Submodule sm1 $head1..$head2: + > Add foo3 + EOF test_cmp expected actual -" +' -test_expect_success 'modified submodule(forward) --submodule' " +test_expect_success 'modified submodule(forward) --submodule' ' git diff --submodule >actual && cat >expected <<-EOF && -Submodule sm1 $head1..$head2: - > Add foo3 -EOF + Submodule sm1 $head1..$head2: + > Add foo3 + EOF test_cmp expected actual -" +' -fullhead1=$(cd sm1; git rev-list --max-count=1 $head1) -fullhead2=$(cd sm1; git rev-list --max-count=1 $head2) -test_expect_success 'modified submodule(forward) --submodule=short' " +fullhead2=$(cd sm1; git rev-parse --verify HEAD) +test_expect_success 'modified submodule(forward) --submodule=short' ' git diff --submodule=short >actual && cat >expected <<-EOF && -diff --git a/sm1 b/sm1 -index $head1..$head2 160000 ---- a/sm1 -+++ b/sm1 -@@ -1 +1 @@ --Subproject commit $fullhead1 -+Subproject commit $fullhead2 -EOF + diff --git a/sm1 b/sm1 + index $head1..$head2 160000 + --- a/sm1 + +++ b/sm1 + @@ -1 +1 @@ + -Subproject commit $fullhead1 + +Subproject commit $fullhead2 + EOF test_cmp expected actual -" +' commit_file sm1 && head3=$( cd sm1 && git reset --hard HEAD~2 >/dev/null && - git rev-parse --verify HEAD | cut -c1-7 + git rev-parse --short --verify HEAD ) -test_expect_success 'modified submodule(backward)' " +test_expect_success 'modified submodule(backward)' ' git diff-index -p --submodule=log HEAD >actual && cat >expected <<-EOF && -Submodule sm1 $head2..$head3 (rewind): - < Add foo3 - < Add foo2 -EOF + Submodule sm1 $head2..$head3 (rewind): + < Add foo3 + < Add foo2 + EOF test_cmp expected actual -" +' -head4=$(add_file sm1 foo4 foo5) && -head4_full=$(GIT_DIR=sm1/.git git rev-parse --verify HEAD) -test_expect_success 'modified submodule(backward and forward)' " +head4=$(add_file sm1 foo4 foo5) +test_expect_success 'modified submodule(backward and forward)' ' git diff-index -p --submodule=log HEAD >actual && cat >expected <<-EOF && -Submodule sm1 $head2...$head4: - > Add foo5 - > Add foo4 - < Add foo3 - < Add foo2 -EOF + Submodule sm1 $head2...$head4: + > Add foo5 + > Add foo4 + < Add foo3 + < Add foo2 + EOF test_cmp expected actual -" +' commit_file sm1 && mv sm1 sm1-bak && @@ -128,319 +169,319 @@ git add sm1 && rm -f sm1 && mv sm1-bak sm1 -test_expect_success 'typechanged submodule(submodule->blob), --cached' " +test_expect_success 'typechanged submodule(submodule->blob), --cached' ' git diff --submodule=log --cached >actual && cat >expected <<-EOF && -Submodule sm1 41fbea9...0000000 (submodule deleted) -diff --git a/sm1 b/sm1 -new file mode 100644 -index 0000000..9da5fb8 ---- /dev/null -+++ b/sm1 -@@ -0,0 +1 @@ -+sm1 -EOF + Submodule sm1 $head4...0000000 (submodule deleted) + diff --git a/sm1 b/sm1 + new file mode 100644 + index 0000000..$head5 + --- /dev/null + +++ b/sm1 + @@ -0,0 +1 @@ + +sm1 + EOF test_cmp expected actual -" +' -test_expect_success 'typechanged submodule(submodule->blob)' " +test_expect_success 'typechanged submodule(submodule->blob)' ' git diff --submodule=log >actual && cat >expected <<-EOF && -diff --git a/sm1 b/sm1 -deleted file mode 100644 -index 9da5fb8..0000000 ---- a/sm1 -+++ /dev/null -@@ -1 +0,0 @@ --sm1 -Submodule sm1 0000000...$head4 (new submodule) -EOF + diff --git a/sm1 b/sm1 + deleted file mode 100644 + index $head5..0000000 + --- a/sm1 + +++ /dev/null + @@ -1 +0,0 @@ + -sm1 + Submodule sm1 0000000...$head4 (new submodule) + EOF test_cmp expected actual -" +' rm -rf sm1 && git checkout-index sm1 -test_expect_success 'typechanged submodule(submodule->blob)' " +test_expect_success 'typechanged submodule(submodule->blob)' ' git diff-index -p --submodule=log HEAD >actual && cat >expected <<-EOF && -Submodule sm1 $head4...0000000 (submodule deleted) -diff --git a/sm1 b/sm1 -new file mode 100644 -index 0000000..$head5 ---- /dev/null -+++ b/sm1 -@@ -0,0 +1 @@ -+sm1 -EOF + Submodule sm1 $head4...0000000 (submodule deleted) + diff --git a/sm1 b/sm1 + new file mode 100644 + index 0000000..$head5 + --- /dev/null + +++ b/sm1 + @@ -0,0 +1 @@ + +sm1 + EOF test_cmp expected actual -" +' rm -f sm1 && test_create_repo sm1 && head6=$(add_file sm1 foo6 foo7) -fullhead6=$(cd sm1; git rev-list --max-count=1 $head6) -test_expect_success 'nonexistent commit' " +fullhead6=$(cd sm1; git rev-parse --verify HEAD) +test_expect_success 'nonexistent commit' ' git diff-index -p --submodule=log HEAD >actual && cat >expected <<-EOF && -Submodule sm1 $head4...$head6 (commits not present) -EOF + Submodule sm1 $head4...$head6 (commits not present) + EOF test_cmp expected actual -" +' commit_file -test_expect_success 'typechanged submodule(blob->submodule)' " +test_expect_success 'typechanged submodule(blob->submodule)' ' git diff-index -p --submodule=log HEAD >actual && cat >expected <<-EOF && -diff --git a/sm1 b/sm1 -deleted file mode 100644 -index $head5..0000000 ---- a/sm1 -+++ /dev/null -@@ -1 +0,0 @@ --sm1 -Submodule sm1 0000000...$head6 (new submodule) -EOF + diff --git a/sm1 b/sm1 + deleted file mode 100644 + index $head5..0000000 + --- a/sm1 + +++ /dev/null + @@ -1 +0,0 @@ + -sm1 + Submodule sm1 0000000...$head6 (new submodule) + EOF test_cmp expected actual -" +' commit_file sm1 && -test_expect_success 'submodule is up to date' " +test_expect_success 'submodule is up to date' ' git diff-index -p --submodule=log HEAD >actual && cat >expected <<-EOF && -EOF + EOF test_cmp expected actual -" +' -test_expect_success 'submodule contains untracked content' " +test_expect_success 'submodule contains untracked content' ' echo new > sm1/new-file && git diff-index -p --submodule=log HEAD >actual && cat >expected <<-EOF && -Submodule sm1 contains untracked content -EOF + Submodule sm1 contains untracked content + EOF test_cmp expected actual -" +' -test_expect_success 'submodule contains untracked content (untracked ignored)' " +test_expect_success 'submodule contains untracked content (untracked ignored)' ' git diff-index -p --ignore-submodules=untracked --submodule=log HEAD >actual && ! test -s actual -" +' -test_expect_success 'submodule contains untracked content (dirty ignored)' " +test_expect_success 'submodule contains untracked content (dirty ignored)' ' git diff-index -p --ignore-submodules=dirty --submodule=log HEAD >actual && ! test -s actual -" +' -test_expect_success 'submodule contains untracked content (all ignored)' " +test_expect_success 'submodule contains untracked content (all ignored)' ' git diff-index -p --ignore-submodules=all --submodule=log HEAD >actual && ! test -s actual -" +' -test_expect_success 'submodule contains untracked and modifed content' " +test_expect_success 'submodule contains untracked and modifed content' ' echo new > sm1/foo6 && git diff-index -p --submodule=log HEAD >actual && cat >expected <<-EOF && -Submodule sm1 contains untracked content -Submodule sm1 contains modified content -EOF + Submodule sm1 contains untracked content + Submodule sm1 contains modified content + EOF test_cmp expected actual -" +' -test_expect_success 'submodule contains untracked and modifed content (untracked ignored)' " +test_expect_success 'submodule contains untracked and modifed content (untracked ignored)' ' echo new > sm1/foo6 && git diff-index -p --ignore-submodules=untracked --submodule=log HEAD >actual && cat >expected <<-EOF && -Submodule sm1 contains modified content -EOF + Submodule sm1 contains modified content + EOF test_cmp expected actual -" +' -test_expect_success 'submodule contains untracked and modifed content (dirty ignored)' " +test_expect_success 'submodule contains untracked and modifed content (dirty ignored)' ' echo new > sm1/foo6 && git diff-index -p --ignore-submodules=dirty --submodule=log HEAD >actual && ! test -s actual -" +' -test_expect_success 'submodule contains untracked and modifed content (all ignored)' " +test_expect_success 'submodule contains untracked and modifed content (all ignored)' ' echo new > sm1/foo6 && git diff-index -p --ignore-submodules --submodule=log HEAD >actual && ! test -s actual -" +' -test_expect_success 'submodule contains modifed content' " +test_expect_success 'submodule contains modifed content' ' rm -f sm1/new-file && git diff-index -p --submodule=log HEAD >actual && cat >expected <<-EOF && -Submodule sm1 contains modified content -EOF + Submodule sm1 contains modified content + EOF test_cmp expected actual -" +' (cd sm1; git commit -mchange foo6 >/dev/null) && -head8=$(cd sm1; git rev-parse --verify HEAD | cut -c1-7) && -test_expect_success 'submodule is modified' " +head8=$(cd sm1; git rev-parse --short --verify HEAD) && +test_expect_success 'submodule is modified' ' git diff-index -p --submodule=log HEAD >actual && cat >expected <<-EOF && -Submodule sm1 $head6..$head8: - > change -EOF + Submodule sm1 $head6..$head8: + > change + EOF test_cmp expected actual -" +' -test_expect_success 'modified submodule contains untracked content' " +test_expect_success 'modified submodule contains untracked content' ' echo new > sm1/new-file && git diff-index -p --submodule=log HEAD >actual && cat >expected <<-EOF && -Submodule sm1 contains untracked content -Submodule sm1 $head6..$head8: - > change -EOF + Submodule sm1 contains untracked content + Submodule sm1 $head6..$head8: + > change + EOF test_cmp expected actual -" +' -test_expect_success 'modified submodule contains untracked content (untracked ignored)' " +test_expect_success 'modified submodule contains untracked content (untracked ignored)' ' git diff-index -p --ignore-submodules=untracked --submodule=log HEAD >actual && cat >expected <<-EOF && -Submodule sm1 $head6..$head8: - > change -EOF + Submodule sm1 $head6..$head8: + > change + EOF test_cmp expected actual -" +' -test_expect_success 'modified submodule contains untracked content (dirty ignored)' " +test_expect_success 'modified submodule contains untracked content (dirty ignored)' ' git diff-index -p --ignore-submodules=dirty --submodule=log HEAD >actual && cat >expected <<-EOF && -Submodule sm1 $head6..$head8: - > change -EOF + Submodule sm1 $head6..$head8: + > change + EOF test_cmp expected actual -" +' -test_expect_success 'modified submodule contains untracked content (all ignored)' " +test_expect_success 'modified submodule contains untracked content (all ignored)' ' git diff-index -p --ignore-submodules=all --submodule=log HEAD >actual && ! test -s actual -" +' -test_expect_success 'modified submodule contains untracked and modifed content' " +test_expect_success 'modified submodule contains untracked and modifed content' ' echo modification >> sm1/foo6 && git diff-index -p --submodule=log HEAD >actual && cat >expected <<-EOF && -Submodule sm1 contains untracked content -Submodule sm1 contains modified content -Submodule sm1 $head6..$head8: - > change -EOF + Submodule sm1 contains untracked content + Submodule sm1 contains modified content + Submodule sm1 $head6..$head8: + > change + EOF test_cmp expected actual -" +' -test_expect_success 'modified submodule contains untracked and modifed content (untracked ignored)' " +test_expect_success 'modified submodule contains untracked and modifed content (untracked ignored)' ' echo modification >> sm1/foo6 && git diff-index -p --ignore-submodules=untracked --submodule=log HEAD >actual && cat >expected <<-EOF && -Submodule sm1 contains modified content -Submodule sm1 $head6..$head8: - > change -EOF + Submodule sm1 contains modified content + Submodule sm1 $head6..$head8: + > change + EOF test_cmp expected actual -" +' -test_expect_success 'modified submodule contains untracked and modifed content (dirty ignored)' " +test_expect_success 'modified submodule contains untracked and modifed content (dirty ignored)' ' echo modification >> sm1/foo6 && git diff-index -p --ignore-submodules=dirty --submodule=log HEAD >actual && cat >expected <<-EOF && -Submodule sm1 $head6..$head8: - > change -EOF + Submodule sm1 $head6..$head8: + > change + EOF test_cmp expected actual -" +' -test_expect_success 'modified submodule contains untracked and modifed content (all ignored)' " +test_expect_success 'modified submodule contains untracked and modifed content (all ignored)' ' echo modification >> sm1/foo6 && git diff-index -p --ignore-submodules --submodule=log HEAD >actual && ! test -s actual -" +' -test_expect_success 'modified submodule contains modifed content' " +test_expect_success 'modified submodule contains modifed content' ' rm -f sm1/new-file && git diff-index -p --submodule=log HEAD >actual && cat >expected <<-EOF && -Submodule sm1 contains modified content -Submodule sm1 $head6..$head8: - > change -EOF + Submodule sm1 contains modified content + Submodule sm1 $head6..$head8: + > change + EOF test_cmp expected actual -" +' rm -rf sm1 -test_expect_success 'deleted submodule' " +test_expect_success 'deleted submodule' ' git diff-index -p --submodule=log HEAD >actual && cat >expected <<-EOF && -Submodule sm1 $head6...0000000 (submodule deleted) -EOF + Submodule sm1 $head6...0000000 (submodule deleted) + EOF test_cmp expected actual -" +' test_create_repo sm2 && head7=$(add_file sm2 foo8 foo9) && git add sm2 -test_expect_success 'multiple submodules' " +test_expect_success 'multiple submodules' ' git diff-index -p --submodule=log HEAD >actual && cat >expected <<-EOF && -Submodule sm1 $head6...0000000 (submodule deleted) -Submodule sm2 0000000...$head7 (new submodule) -EOF + Submodule sm1 $head6...0000000 (submodule deleted) + Submodule sm2 0000000...$head7 (new submodule) + EOF test_cmp expected actual -" +' -test_expect_success 'path filter' " +test_expect_success 'path filter' ' git diff-index -p --submodule=log HEAD sm2 >actual && cat >expected <<-EOF && -Submodule sm2 0000000...$head7 (new submodule) -EOF + Submodule sm2 0000000...$head7 (new submodule) + EOF test_cmp expected actual -" +' commit_file sm2 -test_expect_success 'given commit' " +test_expect_success 'given commit' ' git diff-index -p --submodule=log HEAD^ >actual && cat >expected <<-EOF && -Submodule sm1 $head6...0000000 (submodule deleted) -Submodule sm2 0000000...$head7 (new submodule) -EOF + Submodule sm1 $head6...0000000 (submodule deleted) + Submodule sm2 0000000...$head7 (new submodule) + EOF test_cmp expected actual -" +' -test_expect_success 'given commit --submodule' " +test_expect_success 'given commit --submodule' ' git diff-index -p --submodule HEAD^ >actual && cat >expected <<-EOF && -Submodule sm1 $head6...0000000 (submodule deleted) -Submodule sm2 0000000...$head7 (new submodule) -EOF + Submodule sm1 $head6...0000000 (submodule deleted) + Submodule sm2 0000000...$head7 (new submodule) + EOF test_cmp expected actual -" +' -fullhead7=$(cd sm2; git rev-list --max-count=1 $head7) +fullhead7=$(cd sm2; git rev-parse --verify HEAD) -test_expect_success 'given commit --submodule=short' " +test_expect_success 'given commit --submodule=short' ' git diff-index -p --submodule=short HEAD^ >actual && cat >expected <<-EOF && -diff --git a/sm1 b/sm1 -deleted file mode 160000 -index $head6..0000000 ---- a/sm1 -+++ /dev/null -@@ -1 +0,0 @@ --Subproject commit $fullhead6 -diff --git a/sm2 b/sm2 -new file mode 160000 -index 0000000..$head7 ---- /dev/null -+++ b/sm2 -@@ -0,0 +1 @@ -+Subproject commit $fullhead7 -EOF - test_cmp expected actual -" + diff --git a/sm1 b/sm1 + deleted file mode 160000 + index $head6..0000000 + --- a/sm1 + +++ /dev/null + @@ -1 +0,0 @@ + -Subproject commit $fullhead6 + diff --git a/sm2 b/sm2 + new file mode 160000 + index 0000000..$head7 + --- /dev/null + +++ b/sm2 + @@ -0,0 +1 @@ + +Subproject commit $fullhead7 + EOF + test_cmp expected actual +' test_expect_success 'setup .git file for sm2' ' (cd sm2 && @@ -452,9 +493,9 @@ test_expect_success 'setup .git file for sm2' ' test_expect_success 'diff --submodule with .git file' ' git diff --submodule HEAD^ >actual && cat >expected <<-EOF && -Submodule sm1 $head6...0000000 (submodule deleted) -Submodule sm2 0000000...$head7 (new submodule) -EOF + Submodule sm1 $head6...0000000 (submodule deleted) + Submodule sm2 0000000...$head7 (new submodule) + EOF test_cmp expected actual ' diff --git a/t/t4055-diff-context.sh b/t/t4055-diff-context.sh new file mode 100755 index 0000000..97172b4 --- /dev/null +++ b/t/t4055-diff-context.sh @@ -0,0 +1,92 @@ +#!/bin/sh +# +# Copyright (c) 2012 Mozilla Foundation +# + +test_description='diff.context configuration' + +. ./test-lib.sh + +test_expect_success 'setup' ' + cat >template <<-\EOF && + firstline + b + c + d + e + f + preline + TARGET + postline + i + j + k + l + m + n + EOF + sed "/TARGET/d" >x <template && + git update-index --add x && + git commit -m initial && + + sed "s/TARGET/ADDED/" >x <template && + git update-index --add x && + git commit -m next && + + sed "s/TARGET/MODIFIED/" >x <template +' + +test_expect_success 'the default number of context lines is 3' ' + git diff >output && + ! grep "^ d" output && + grep "^ e" output && + grep "^ j" output && + ! grep "^ k" output +' + +test_expect_success 'diff.context honored by "log"' ' + git log -1 -p >output && + ! grep firstline output && + git config diff.context 8 && + git log -1 -p >output && + grep "^ firstline" output +' + +test_expect_success 'The -U option overrides diff.context' ' + git config diff.context 8 && + git log -U4 -1 >output && + ! grep "^ firstline" output +' + +test_expect_success 'diff.context honored by "diff"' ' + git config diff.context 8 && + git diff >output && + grep "^ firstline" output +' + +test_expect_success 'plumbing not affected' ' + git config diff.context 8 && + git diff-files -p >output && + ! grep "^ firstline" output +' + +test_expect_success 'non-integer config parsing' ' + git config diff.context no && + test_must_fail git diff 2>output && + test_i18ngrep "bad config value" output +' + +test_expect_success 'negative integer config parsing' ' + git config diff.context -1 && + test_must_fail git diff 2>output && + test_i18ngrep "bad config file" output +' + +test_expect_success '-U0 is valid, so is diff.context=0' ' + git config diff.context 0 && + git diff >output && + grep "^-ADDED" output && + grep "^+MODIFIED" output +' + +test_done diff --git a/t/t4201-shortlog.sh b/t/t4201-shortlog.sh index 6872ba1..5493500 100755 --- a/t/t4201-shortlog.sh +++ b/t/t4201-shortlog.sh @@ -120,6 +120,30 @@ test_expect_success 'shortlog from non-git directory' ' test_cmp expect out ' +test_expect_success 'shortlog should add newline when input line matches wraplen' ' + cat >expect <<\EOF && +A U Thor (2): + bbbbbbbbbbbbbbbbbb: bbbbbbbb bbb bbbb bbbbbbb bb bbbb bbb bbbbb bbbbbb + aaaaaaaaaaaaaaaaaaaaaa: aaaaaa aaaaaaaaaa aaaa aaaaaaaa aa aaaa aa aaa + +EOF + git shortlog -w >out <<\EOF && +commit 0000000000000000000000000000000000000001 +Author: A U Thor <author@example.com> +Date: Thu Apr 7 15:14:13 2005 -0700 + + aaaaaaaaaaaaaaaaaaaaaa: aaaaaa aaaaaaaaaa aaaa aaaaaaaa aa aaaa aa aaa + +commit 0000000000000000000000000000000000000002 +Author: A U Thor <author@example.com> +Date: Thu Apr 7 15:14:13 2005 -0700 + + bbbbbbbbbbbbbbbbbb: bbbbbbbb bbb bbbb bbbbbbb bb bbbb bbb bbbbb bbbbbb + +EOF + test_cmp expect out +' + iconvfromutf8toiso88591() { printf "%s" "$*" | iconv -f UTF-8 -t ISO8859-1 } diff --git a/t/t4202-log.sh b/t/t4202-log.sh index a343bf6..fa686b8 100755 --- a/t/t4202-log.sh +++ b/t/t4202-log.sh @@ -280,6 +280,16 @@ test_expect_success 'log --graph with merge' ' test_cmp expect actual ' +test_expect_success 'log --raw --graph -m with merge' ' + git log --raw --graph --oneline -m master | head -n 500 >actual && + grep "initial" actual +' + +test_expect_success 'diff-tree --graph' ' + git diff-tree --graph master^ | head -n 500 >actual && + grep "one" actual +' + cat > expect <<\EOF * commit master |\ Merge: A B diff --git a/t/t4203-mailmap.sh b/t/t4203-mailmap.sh index 1f182f6..aae30d9 100755 --- a/t/t4203-mailmap.sh +++ b/t/t4203-mailmap.sh @@ -149,6 +149,104 @@ test_expect_success 'No mailmap files, but configured' ' test_cmp expect actual ' +test_expect_success 'setup mailmap blob tests' ' + git checkout -b map && + test_when_finished "git checkout master" && + cat >just-bugs <<-\EOF && + Blob Guy <bugs@company.xx> + EOF + cat >both <<-\EOF && + Blob Guy <author@example.com> + Blob Guy <bugs@company.xx> + EOF + git add just-bugs both && + git commit -m "my mailmaps" && + echo "Repo Guy <author@example.com>" >.mailmap && + echo "Internal Guy <author@example.com>" >internal.map +' + +test_expect_success 'mailmap.blob set' ' + cat >expect <<-\EOF && + Blob Guy (1): + second + + Repo Guy (1): + initial + + EOF + git -c mailmap.blob=map:just-bugs shortlog HEAD >actual && + test_cmp expect actual +' + +test_expect_success 'mailmap.blob overrides .mailmap' ' + cat >expect <<-\EOF && + Blob Guy (2): + initial + second + + EOF + git -c mailmap.blob=map:both shortlog HEAD >actual && + test_cmp expect actual +' + +test_expect_success 'mailmap.file overrides mailmap.blob' ' + cat >expect <<-\EOF && + Blob Guy (1): + second + + Internal Guy (1): + initial + + EOF + git \ + -c mailmap.blob=map:both \ + -c mailmap.file=internal.map \ + shortlog HEAD >actual && + test_cmp expect actual +' + +test_expect_success 'mailmap.blob can be missing' ' + cat >expect <<-\EOF && + Repo Guy (1): + initial + + nick1 (1): + second + + EOF + git -c mailmap.blob=map:nonexistent shortlog HEAD >actual && + test_cmp expect actual +' + +test_expect_success 'mailmap.blob defaults to off in non-bare repo' ' + git init non-bare && + ( + cd non-bare && + test_commit one .mailmap "Fake Name <author@example.com>" && + echo " 1 Fake Name" >expect && + git shortlog -ns HEAD >actual && + test_cmp expect actual && + rm .mailmap && + echo " 1 A U Thor" >expect && + git shortlog -ns HEAD >actual && + test_cmp expect actual + ) +' + +test_expect_success 'mailmap.blob defaults to HEAD:.mailmap in bare repo' ' + git clone --bare non-bare bare && + ( + cd bare && + echo " 1 Fake Name" >expect && + git shortlog -ns HEAD >actual && + test_cmp expect actual + ) +' + +test_expect_success 'cleanup after mailmap.blob tests' ' + rm -f .mailmap +' + # Extended mailmap configurations should give us the following output for shortlog cat >expect <<\EOF A U Thor <author@example.com> (1): diff --git a/t/t5002-archive-attr-pattern.sh b/t/t5002-archive-attr-pattern.sh new file mode 100755 index 0000000..0c847fb --- /dev/null +++ b/t/t5002-archive-attr-pattern.sh @@ -0,0 +1,57 @@ +#!/bin/sh + +test_description='git archive attribute pattern tests' + +. ./test-lib.sh + +test_expect_exists() { + test_expect_success " $1 exists" "test -e $1" +} + +test_expect_missing() { + test_expect_success " $1 does not exist" "test ! -e $1" +} + +test_expect_success 'setup' ' + echo ignored >ignored && + echo ignored export-ignore >>.git/info/attributes && + git add ignored && + + mkdir not-ignored-dir && + echo ignored-in-tree >not-ignored-dir/ignored && + echo not-ignored-in-tree >not-ignored-dir/ignored-only-if-dir && + git add not-ignored-dir && + + mkdir ignored-only-if-dir && + echo ignored by ignored dir >ignored-only-if-dir/ignored-by-ignored-dir && + echo ignored-only-if-dir/ export-ignore >>.git/info/attributes && + git add ignored-only-if-dir && + + + mkdir -p one-level-lower/two-levels-lower/ignored-only-if-dir && + echo ignored by ignored dir >one-level-lower/two-levels-lower/ignored-only-if-dir/ignored-by-ignored-dir && + git add one-level-lower && + + git commit -m. && + + git clone --bare . bare && + cp .git/info/attributes bare/info/attributes +' + +test_expect_success 'git archive' ' + git archive HEAD >archive.tar && + (mkdir archive && cd archive && "$TAR" xf -) <archive.tar +' + +test_expect_missing archive/ignored +test_expect_missing archive/not-ignored-dir/ignored +test_expect_exists archive/not-ignored-dir/ignored-only-if-dir +test_expect_exists archive/not-ignored-dir/ +test_expect_missing archive/ignored-only-if-dir/ +test_expect_missing archive/ignored-ony-if-dir/ignored-by-ignored-dir +test_expect_exists archive/one-level-lower/ +test_expect_missing archive/one-level-lower/two-levels-lower/ignored-only-if-dir/ +test_expect_missing archive/one-level-lower/two-levels-lower/ignored-ony-if-dir/ignored-by-ignored-dir + + +test_done diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh index b5417cc..6009372 100755 --- a/t/t5516-fetch-push.sh +++ b/t/t5516-fetch-push.sh @@ -368,7 +368,7 @@ test_expect_success 'push with colon-less refspec (2)' ' git branch -D frotz fi && git tag -f frotz && - git push testrepo frotz && + git push -f testrepo frotz && check_push_result $the_commit tags/frotz && check_push_result $the_first_commit heads/frotz @@ -929,6 +929,48 @@ 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 && + ( + cd child1 && + git tag Tag && + git push ../child2 Tag && + git push ../child2 Tag && + >file1 && + git add file1 && + git commit -m "file1" && + git tag -f Tag && + test_must_fail git push ../child2 Tag && + git push --force ../child2 Tag && + git tag -f Tag && + test_must_fail git push ../child2 Tag HEAD~ && + git push --force ../child2 Tag + ) +' + +test_expect_success 'push requires --force to update annotated tag' ' + mk_test heads/master && + mk_child child1 && + mk_child child2 && + ( + cd child1 && + git tag -a -m "message 1" Tag && + git push ../child2 Tag:refs/tmp/Tag && + git push ../child2 Tag:refs/tmp/Tag && + >file1 && + git add file1 && + git commit -m "file1" && + git tag -f -a -m "message 2" Tag && + test_must_fail git push ../child2 Tag:refs/tmp/Tag && + git push --force ../child2 Tag:refs/tmp/Tag && + git tag -f -a -m "message 3" Tag HEAD~ && + test_must_fail git push ../child2 Tag:refs/tmp/Tag && + git push --force ../child2 Tag:refs/tmp/Tag + ) +' + test_expect_success 'push --porcelain' ' mk_empty && echo >.git/foo "To testrepo" && diff --git a/t/t5535-fetch-push-symref.sh b/t/t5535-fetch-push-symref.sh new file mode 100755 index 0000000..8ed58d2 --- /dev/null +++ b/t/t5535-fetch-push-symref.sh @@ -0,0 +1,42 @@ +#!/bin/sh + +test_description='avoiding conflicting update thru symref aliasing' + +. ./test-lib.sh + +test_expect_success 'setup' ' + test_commit one && + git clone . src && + git clone src dst1 && + git clone src dst2 && + test_commit two && + ( cd src && git pull ) +' + +test_expect_success 'push' ' + ( + cd src && + git push ../dst1 "refs/remotes/*:refs/remotes/*" + ) && + git ls-remote src "refs/remotes/*" >expect && + git ls-remote dst1 "refs/remotes/*" >actual && + test_cmp expect actual && + ( cd src && git symbolic-ref refs/remotes/origin/HEAD ) >expect && + ( cd dst1 && git symbolic-ref refs/remotes/origin/HEAD ) >actual && + test_cmp expect actual +' + +test_expect_success 'fetch' ' + ( + cd dst2 && + git fetch ../src "refs/remotes/*:refs/remotes/*" + ) && + git ls-remote src "refs/remotes/*" >expect && + git ls-remote dst2 "refs/remotes/*" >actual && + test_cmp expect actual && + ( cd src && git symbolic-ref refs/remotes/origin/HEAD ) >expect && + ( cd dst2 && git symbolic-ref refs/remotes/origin/HEAD ) >actual && + test_cmp expect actual +' + +test_done diff --git a/t/t5551-http-fetch.sh b/t/t5551-http-fetch.sh index 5060879..c5cd2e3 100755 --- a/t/t5551-http-fetch.sh +++ b/t/t5551-http-fetch.sh @@ -130,6 +130,21 @@ test_expect_success 'clone from auth-only-for-push repository' ' test_cmp expect actual ' +test_expect_success 'clone from auth-only-for-objects repository' ' + echo two >expect && + set_askpass user@host && + git clone --bare "$HTTPD_URL/auth-fetch/smart/repo.git" half-auth && + expect_askpass both user@host && + git --git-dir=half-auth log -1 --format=%s >actual && + test_cmp expect actual +' + +test_expect_success 'no-op half-auth fetch does not require a password' ' + set_askpass wrong && + git --git-dir=half-auth fetch && + expect_askpass none +' + test_expect_success 'disable dumb http on server' ' git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH/repo.git" \ config http.getanyfile false diff --git a/t/t5800-remote-helpers.sh b/t/t5800-remote-testpy.sh index e7dc668..6750961 100755 --- a/t/t5800-remote-helpers.sh +++ b/t/t5800-remote-testpy.sh @@ -3,12 +3,12 @@ # Copyright (c) 2010 Sverre Rabbelier # -test_description='Test remote-helper import and export commands' +test_description='Test python remote-helper framework' . ./test-lib.sh if ! test_have_prereq PYTHON ; then - skip_all='skipping git-remote-hg tests, python not available' + skip_all='skipping python remote-helper tests, python not available' test_done fi @@ -17,7 +17,7 @@ import sys if sys.hexversion < 0x02040000: sys.exit(1) ' || { - skip_all='skipping git-remote-hg tests, python version < 2.4' + skip_all='skipping python remote-helper tests, python version < 2.4' test_done } @@ -38,12 +38,12 @@ test_expect_success 'setup repository' ' ' test_expect_success 'cloning from local repo' ' - git clone "testgit::${PWD}/server" localclone && + git clone "testpy::${PWD}/server" localclone && test_cmp public/file localclone/file ' test_expect_success 'cloning from remote repo' ' - git clone "testgit::file://${PWD}/server" clone && + git clone "testpy::file://${PWD}/server" clone && test_cmp public/file clone/file ' @@ -73,11 +73,11 @@ test_expect_success 'pushing to local repo' ' ' # Generally, skip this test. It demonstrates a now-fixed race in -# git-remote-testgit, but is too slow to leave in for general use. +# git-remote-testpy, but is too slow to leave in for general use. : test_expect_success 'racily pushing to local repo' ' test_when_finished "rm -rf server2 localclone2" && cp -R server server2 && - git clone "testgit::${PWD}/server2" localclone2 && + git clone "testpy::${PWD}/server2" localclone2 && (cd localclone2 && echo content >>file && git commit -a -m three && diff --git a/t/t5801-remote-helpers.sh b/t/t5801-remote-helpers.sh new file mode 100755 index 0000000..f387027 --- /dev/null +++ b/t/t5801-remote-helpers.sh @@ -0,0 +1,169 @@ +#!/bin/sh +# +# Copyright (c) 2010 Sverre Rabbelier +# + +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 + +compare_refs() { + git --git-dir="$1/.git" rev-parse --verify $2 >expect && + git --git-dir="$3/.git" rev-parse --verify $4 >actual && + test_cmp expect actual +} + +test_expect_success 'setup repository' ' + git init server && + (cd server && + echo content >file && + git add file && + git commit -m one) +' + +test_expect_success 'cloning from local repo' ' + git clone "testgit::${PWD}/server" local && + test_cmp server/file local/file +' + +test_expect_success 'create new commit on remote' ' + (cd server && + echo content >>file && + git commit -a -m two) +' + +test_expect_success 'pulling from local repo' ' + (cd local && git pull) && + test_cmp server/file local/file +' + +test_expect_success 'pushing to local repo' ' + (cd local && + echo content >>file && + git commit -a -m three && + git push) && + compare_refs local HEAD server HEAD +' + +test_expect_success 'fetch new branch' ' + (cd server && + git reset --hard && + git checkout -b new && + echo content >>file && + git commit -a -m five + ) && + (cd local && + git fetch origin new + ) && + compare_refs server HEAD local FETCH_HEAD +' + +test_expect_success 'fetch multiple branches' ' + (cd local && + git fetch + ) && + compare_refs server master local refs/remotes/origin/master && + compare_refs server new local refs/remotes/origin/new +' + +test_expect_success 'push when remote has extra refs' ' + (cd local && + git reset --hard origin/master && + echo content >>file && + git commit -a -m six && + git push + ) && + compare_refs local master server master +' + +test_expect_success 'push new branch by name' ' + (cd local && + git checkout -b new-name && + echo content >>file && + git commit -a -m seven && + git push origin new-name + ) && + compare_refs local HEAD server refs/heads/new-name +' + +test_expect_failure 'push new branch with old:new refspec' ' + (cd local && + git push origin new-name:new-refspec + ) && + compare_refs local HEAD server refs/heads/new-refspec +' + +test_expect_success 'cloning without refspec' ' + GIT_REMOTE_TESTGIT_REFSPEC="" \ + git clone "testgit::${PWD}/server" local2 && + compare_refs local2 HEAD server HEAD +' + +test_expect_success 'pulling without refspecs' ' + (cd local2 && + git reset --hard && + GIT_REMOTE_TESTGIT_REFSPEC="" git pull) && + compare_refs local2 HEAD server HEAD +' + +test_expect_failure '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 +' + +test_expect_success 'pulling without marks' ' + (cd local2 && + GIT_REMOTE_TESTGIT_NO_MARKS=1 git pull) && + compare_refs local2 HEAD server HEAD +' + +test_expect_failure 'pushing without marks' ' + test_when_finished "(cd local2 && git reset --hard origin)" && + (cd local2 && + echo content >>file && + git commit -a -m twelve && + GIT_REMOTE_TESTGIT_NO_MARKS=1 git push) && + compare_refs local2 HEAD server HEAD +' + +test_expect_success 'push all with existing object' ' + (cd local && + git branch dup2 master && + git push origin --all + ) && + compare_refs local dup2 server dup2 +' + +test_expect_success 'push ref with existing object' ' + (cd local && + git branch dup master && + git push origin dup + ) && + compare_refs local dup server dup +' + +test_done diff --git a/t/t6006-rev-list-format.sh b/t/t6006-rev-list-format.sh index f94f0c4..3fc3b74 100755 --- a/t/t6006-rev-list-format.sh +++ b/t/t6006-rev-list-format.sh @@ -3,6 +3,7 @@ test_description='git rev-list --pretty=format test' . ./test-lib.sh +. "$TEST_DIRECTORY"/lib-terminal.sh test_tick test_expect_success 'setup' ' @@ -11,12 +12,24 @@ touch foo && git add foo && git commit -m "added foo" && ' # usage: test_format name format_string <expected_output -test_format() { +test_format () { cat >expect.$1 test_expect_success "format $1" " -git rev-list --pretty=format:'$2' master >output.$1 && -test_cmp expect.$1 output.$1 -" + git rev-list --pretty=format:'$2' master >output.$1 && + test_cmp expect.$1 output.$1 + " +} + +# Feed to --format to provide predictable colored sequences. +AUTO_COLOR='%C(auto,red)foo%C(auto,reset)' +has_color () { + printf '\033[31mfoo\033[m\n' >expect && + test_cmp expect "$1" +} + +has_no_color () { + echo foo >expect && + test_cmp expect "$1" } test_format percent %%h <<'EOF' @@ -124,6 +137,48 @@ commit 86c75cfd708a0e5868dc876ed5b8bb66c80b4873 [1;31;43mfoo[m EOF +test_expect_success '%C(auto) does not enable color by default' ' + git log --format=$AUTO_COLOR -1 >actual && + has_no_color actual +' + +test_expect_success '%C(auto) enables colors for color.diff' ' + git -c color.diff=always log --format=$AUTO_COLOR -1 >actual && + has_color actual +' + +test_expect_success '%C(auto) enables colors for color.ui' ' + git -c color.ui=always log --format=$AUTO_COLOR -1 >actual && + has_color actual +' + +test_expect_success '%C(auto) respects --color' ' + git log --format=$AUTO_COLOR -1 --color >actual && + has_color actual +' + +test_expect_success '%C(auto) respects --no-color' ' + git -c color.ui=always log --format=$AUTO_COLOR -1 --no-color >actual && + has_no_color actual +' + +test_expect_success TTY '%C(auto) respects --color=auto (stdout is tty)' ' + ( + TERM=vt100 && export TERM && + test_terminal \ + git log --format=$AUTO_COLOR -1 --color=auto >actual && + has_color actual + ) +' + +test_expect_success '%C(auto) respects --color=auto (stdout not tty)' ' + ( + TERM=vt100 && export TERM && + git log --format=$AUTO_COLOR -1 --color=auto >actual && + has_no_color actual + ) +' + cat >commit-msg <<'EOF' Test printing of complex bodies diff --git a/t/t6050-replace.sh b/t/t6050-replace.sh index 5c87f28..decdc33 100755 --- a/t/t6050-replace.sh +++ b/t/t6050-replace.sh @@ -140,6 +140,17 @@ test_expect_success '"git replace" replacing' ' test "$HASH2" = "$(git replace)" ' +test_expect_success '"git replace" resolves sha1' ' + SHORTHASH2=$(git rev-parse --short=8 $HASH2) && + git replace -d $SHORTHASH2 && + git replace $SHORTHASH2 $R && + git show $HASH2 | grep "O Thor" && + test_must_fail git replace $HASH2 $R && + git replace -f $HASH2 $R && + test_must_fail git replace -f && + test "$HASH2" = "$(git replace)" +' + # This creates a side branch where the bug in H2 # does not appear because P2 is created by applying # H2 and squashing H5 into it. diff --git a/t/t6130-pathspec-noglob.sh b/t/t6130-pathspec-noglob.sh new file mode 100755 index 0000000..39ef619 --- /dev/null +++ b/t/t6130-pathspec-noglob.sh @@ -0,0 +1,68 @@ +#!/bin/sh + +test_description='test globbing (and noglob) of pathspec limiting' +. ./test-lib.sh + +test_expect_success 'create commits with glob characters' ' + test_commit unrelated bar && + test_commit vanilla foo && + # insert file "f*" in the commit, but in a way that avoids + # the name "f*" in the worktree, because it is not allowed + # on Windows (the tests below do not depend on the presence + # of the file in the worktree) + git update-index --add --cacheinfo 100644 "$(git rev-parse HEAD:foo)" "f*" && + test_tick && + git commit -m star && + test_commit bracket "f[o][o]" +' + +test_expect_success 'vanilla pathspec matches literally' ' + echo vanilla >expect && + git log --format=%s -- foo >actual && + test_cmp expect actual +' + +test_expect_success 'star pathspec globs' ' + cat >expect <<-\EOF && + bracket + star + vanilla + EOF + git log --format=%s -- "f*" >actual && + test_cmp expect actual +' + +test_expect_success 'bracket pathspec globs and matches literal brackets' ' + cat >expect <<-\EOF && + bracket + vanilla + EOF + git log --format=%s -- "f[o][o]" >actual && + test_cmp expect actual +' + +test_expect_success 'no-glob option matches literally (vanilla)' ' + echo vanilla >expect && + git --literal-pathspecs log --format=%s -- foo >actual && + test_cmp expect actual +' + +test_expect_success 'no-glob option matches literally (star)' ' + echo star >expect && + git --literal-pathspecs log --format=%s -- "f*" >actual && + test_cmp expect actual +' + +test_expect_success 'no-glob option matches literally (bracket)' ' + echo bracket >expect && + git --literal-pathspecs log --format=%s -- "f[o][o]" >actual && + test_cmp expect actual +' + +test_expect_success 'no-glob environment variable works' ' + echo star >expect && + GIT_LITERAL_PATHSPECS=1 git log --format=%s -- "f*" >actual && + test_cmp expect actual +' + +test_done diff --git a/t/t7003-filter-branch.sh b/t/t7003-filter-branch.sh index 4d13e10..1e7a209 100755 --- a/t/t7003-filter-branch.sh +++ b/t/t7003-filter-branch.sh @@ -167,10 +167,11 @@ test_expect_success 'author information is preserved' ' test_tick && GIT_AUTHOR_NAME="B V Uips" git commit -m bvuips && git branch preserved-author && - git filter-branch -f --msg-filter "cat; \ + (sane_unset GIT_AUTHOR_NAME && + git filter-branch -f --msg-filter "cat; \ test \$GIT_COMMIT != $(git rev-parse master) || \ echo Hallo" \ - preserved-author && + preserved-author) && test 1 = $(git rev-list --author="B V Uips" preserved-author | wc -l) ' diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh index 5397037..2683cba 100755 --- a/t/t7400-submodule-basic.sh +++ b/t/t7400-submodule-basic.sh @@ -133,6 +133,7 @@ test_expect_success 'submodule add --branch' ' ( cd addtest && git submodule add -b initial "$submodurl" submod-branch && + test "initial" = "$(git config -f .gitmodules submodule.submod-branch.branch)" && git submodule init ) && @@ -681,4 +682,79 @@ test_expect_success 'moving the superproject does not break submodules' ' ) ' +test_expect_success 'submodule add --name allows to replace a submodule with another at the same path' ' + ( + cd addtest2 && + ( + cd repo && + echo "$submodurl/repo" >expect && + git config remote.origin.url >actual && + test_cmp expect actual && + echo "gitdir: ../.git/modules/repo" >expect && + test_cmp expect .git + ) && + rm -rf repo && + git rm repo && + git submodule add -q --name repo_new "$submodurl/bare.git" repo >actual && + test ! -s actual && + echo "gitdir: ../.git/modules/submod" >expect && + test_cmp expect submod/.git && + ( + cd repo && + echo "$submodurl/bare.git" >expect && + git config remote.origin.url >actual && + test_cmp expect actual && + echo "gitdir: ../.git/modules/repo_new" >expect && + test_cmp expect .git + ) && + echo "repo" >expect && + git config -f .gitmodules submodule.repo.path >actual && + test_cmp expect actual && + git config -f .gitmodules submodule.repo_new.path >actual && + test_cmp expect actual&& + echo "$submodurl/repo" >expect && + git config -f .gitmodules submodule.repo.url >actual && + test_cmp expect actual && + echo "$submodurl/bare.git" >expect && + git config -f .gitmodules submodule.repo_new.url >actual && + test_cmp expect actual && + echo "$submodurl/repo" >expect && + git config submodule.repo.url >actual && + test_cmp expect actual && + echo "$submodurl/bare.git" >expect && + git config submodule.repo_new.url >actual && + test_cmp expect actual + ) +' + +test_expect_success 'submodule add with an existing name fails unless forced' ' + ( + cd addtest2 && + rm -rf repo && + git rm repo && + test_must_fail git submodule add -q --name repo_new "$submodurl/repo.git" repo && + test ! -d repo && + echo "repo" >expect && + git config -f .gitmodules submodule.repo_new.path >actual && + test_cmp expect actual&& + echo "$submodurl/bare.git" >expect && + git config -f .gitmodules submodule.repo_new.url >actual && + test_cmp expect actual && + echo "$submodurl/bare.git" >expect && + git config submodule.repo_new.url >actual && + test_cmp expect actual && + git submodule add -f -q --name repo_new "$submodurl/repo.git" repo && + test -d repo && + echo "repo" >expect && + git config -f .gitmodules submodule.repo_new.path >actual && + test_cmp expect actual&& + echo "$submodurl/repo.git" >expect && + git config -f .gitmodules submodule.repo_new.url >actual && + test_cmp expect actual && + echo "$submodurl/repo.git" >expect && + git config submodule.repo_new.url >actual && + test_cmp expect actual + ) +' + test_done diff --git a/t/t7403-submodule-sync.sh b/t/t7403-submodule-sync.sh index 524d5c1..94e26c4 100755 --- a/t/t7403-submodule-sync.sh +++ b/t/t7403-submodule-sync.sh @@ -17,18 +17,25 @@ test_expect_success setup ' git commit -m upstream && git clone . super && git clone super submodule && + (cd submodule && + git submodule add ../submodule sub-submodule && + test_tick && + git commit -m "sub-submodule" + ) && (cd super && git submodule add ../submodule submodule && test_tick && git commit -m "submodule" ) && git clone super super-clone && - (cd super-clone && git submodule update --init) && + (cd super-clone && git submodule update --init --recursive) && git clone super empty-clone && (cd empty-clone && git submodule init) && git clone super top-only-clone && git clone super relative-clone && - (cd relative-clone && git submodule update --init) + (cd relative-clone && git submodule update --init --recursive) && + git clone super recursive-clone && + (cd recursive-clone && git submodule update --init --recursive) ' test_expect_success 'change submodule' ' @@ -46,6 +53,11 @@ test_expect_success 'change submodule url' ' git pull ) && mv submodule moved-submodule && + (cd moved-submodule && + git config -f .gitmodules submodule.sub-submodule.url ../moved-submodule && + test_tick && + git commit -a -m moved-sub-submodule + ) && (cd super && git config -f .gitmodules submodule.submodule.url ../moved-submodule && test_tick && @@ -61,6 +73,9 @@ test_expect_success '"git submodule sync" should update submodule URLs' ' test -d "$(cd super-clone/submodule && git config remote.origin.url )" && + test ! -d "$(cd super-clone/submodule/sub-submodule && + git config remote.origin.url + )" && (cd super-clone/submodule && git checkout master && git pull @@ -70,6 +85,25 @@ test_expect_success '"git submodule sync" should update submodule URLs' ' ) ' +test_expect_success '"git submodule sync --recursive" should update all submodule URLs' ' + (cd super-clone && + (cd submodule && + git pull --no-recurse-submodules + ) && + git submodule sync --recursive + ) && + test -d "$(cd super-clone/submodule && + git config remote.origin.url + )" && + test -d "$(cd super-clone/submodule/sub-submodule && + git config remote.origin.url + )" && + (cd super-clone/submodule/sub-submodule && + git checkout master && + git pull + ) +' + test_expect_success '"git submodule sync" should update known submodule URLs' ' (cd empty-clone && git pull && @@ -107,6 +141,23 @@ test_expect_success '"git submodule sync" handles origin URL of the form foo/bar #actual foo/submodule test "$(git config remote.origin.url)" = "../foo/submodule" ) + (cd submodule/sub-submodule && + test "$(git config remote.origin.url)" != "../../foo/submodule" + ) + ) +' + +test_expect_success '"git submodule sync --recursive" propagates changes in origin' ' + (cd recursive-clone && + git remote set-url origin foo/bar && + git submodule sync --recursive && + (cd submodule && + #actual foo/submodule + test "$(git config remote.origin.url)" = "../foo/submodule" + ) + (cd submodule/sub-submodule && + test "$(git config remote.origin.url)" = "../../foo/submodule" + ) ) ' diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh index 1542653..4975ec0 100755 --- a/t/t7406-submodule-update.sh +++ b/t/t7406-submodule-update.sh @@ -135,6 +135,37 @@ test_expect_success 'submodule update --force forcibly checks out submodules' ' ) ' +test_expect_success 'submodule update --remote should fetch upstream changes' ' + (cd submodule && + echo line4 >> file && + git add file && + test_tick && + git commit -m "upstream line4" + ) && + (cd super && + git submodule update --remote --force submodule && + cd submodule && + test "$(git log -1 --oneline)" = "$(GIT_DIR=../../submodule/.git git log -1 --oneline)" + ) +' + +test_expect_success 'local config should override .gitmodules branch' ' + (cd submodule && + git checkout -b test-branch && + echo line5 >> file && + git add file && + test_tick && + git commit -m "upstream line5" && + git checkout master + ) && + (cd super && + git config submodule.submodule.branch test-branch && + git submodule update --remote --force submodule && + cd submodule && + test "$(git log -1 --oneline)" = "$(GIT_DIR=../../submodule/.git git log -1 --oneline test-branch)" + ) +' + test_expect_success 'submodule update --rebase staying on master' ' (cd super/submodule && git checkout master @@ -627,7 +658,7 @@ test_expect_success 'submodule add properly re-creates deeper level submodules' (cd super && git reset --hard master && rm -rf deeper/ && - git submodule add ../submodule deeper/submodule + git submodule add --force ../submodule deeper/submodule ) ' diff --git a/t/t7407-submodule-foreach.sh b/t/t7407-submodule-foreach.sh index 9b69fe2..107b4b7 100755 --- a/t/t7407-submodule-foreach.sh +++ b/t/t7407-submodule-foreach.sh @@ -226,14 +226,14 @@ test_expect_success 'test "status --recursive"' ' test_cmp expect actual ' -sed -e "/nested1 /s/.*/+$nested1sha1 nested1 (file2~1)/;/sub[1-3]/d" < expect > expect2 +sed -e "/nested2 /s/.*/+$nested2sha1 nested1\/nested2 (file2~1)/;/sub[1-3]/d" < expect > expect2 mv -f expect2 expect test_expect_success 'ensure "status --cached --recursive" preserves the --cached flag' ' ( cd clone3 && ( - cd nested1 && + cd nested1/nested2 && test_commit file2 ) && git submodule status --cached --recursive -- nested1 > ../actual diff --git a/t/t7502-commit.sh b/t/t7502-commit.sh index deb187e..1a5cb69 100755 --- a/t/t7502-commit.sh +++ b/t/t7502-commit.sh @@ -243,16 +243,6 @@ test_expect_success 'message shows author when it is not equal to committer' ' .git/COMMIT_EDITMSG ' -test_expect_success 'setup auto-ident prerequisite' ' - if (sane_unset GIT_COMMITTER_EMAIL && - sane_unset GIT_COMMITTER_NAME && - git var GIT_COMMITTER_IDENT); then - test_set_prereq AUTOIDENT - else - test_set_prereq NOAUTOIDENT - fi -' - test_expect_success AUTOIDENT 'message shows committer when it is automatic' ' echo >>negative && @@ -271,7 +261,7 @@ echo editor started > "$(pwd)/.git/result" exit 0 EOF -test_expect_success NOAUTOIDENT 'do not fire editor when committer is bogus' ' +test_expect_success !AUTOIDENT 'do not fire editor when committer is bogus' ' >.git/result >expect && diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh index 0351228..97d6f4c 100755 --- a/t/t9001-send-email.sh +++ b/t/t9001-send-email.sh @@ -191,17 +191,44 @@ test_expect_success $PREREQ 'Show all headers' ' test_expect_success $PREREQ 'Prompting works' ' clean_fake_sendmail && - (echo "Example <from@example.com>" - echo "to@example.com" + (echo "to@example.com" echo "" ) | GIT_SEND_EMAIL_NOTTY=1 git send-email \ --smtp-server="$(pwd)/fake.sendmail" \ $patches \ 2>errors && - grep "^From: Example <from@example.com>\$" msgtxt1 && + grep "^From: A U Thor <author@example.com>\$" msgtxt1 && grep "^To: to@example.com\$" msgtxt1 ' +test_expect_success $PREREQ,AUTOIDENT 'implicit ident is allowed' ' + clean_fake_sendmail && + (sane_unset GIT_AUTHOR_NAME && + sane_unset GIT_AUTHOR_EMAIL && + sane_unset GIT_COMMITTER_NAME && + sane_unset GIT_COMMITTER_EMAIL && + GIT_SEND_EMAIL_NOTTY=1 git send-email \ + --smtp-server="$(pwd)/fake.sendmail" \ + --to=to@example.com \ + $patches </dev/null 2>errors + ) +' + +test_expect_success $PREREQ,!AUTOIDENT 'broken implicit ident aborts send-email' ' + clean_fake_sendmail && + (sane_unset GIT_AUTHOR_NAME && + sane_unset GIT_AUTHOR_EMAIL && + sane_unset GIT_COMMITTER_NAME && + sane_unset GIT_COMMITTER_EMAIL && + GIT_SEND_EMAIL_NOTTY=1 && export GIT_SEND_EMAIL_NOTTY && + test_must_fail git send-email \ + --smtp-server="$(pwd)/fake.sendmail" \ + --to=to@example.com \ + $patches </dev/null 2>errors && + test_i18ngrep "tell me who you are" errors + ) +' + test_expect_success $PREREQ 'tocmd works' ' clean_fake_sendmail && cp $patches tocmd.patch && @@ -854,6 +881,75 @@ test_expect_success $PREREQ 'utf8 author is correctly passed on' ' grep "^From: Füñný Nâmé <odd_?=mail@example.com>" msgtxt1 ' +test_expect_success $PREREQ 'sendemail.composeencoding works' ' + clean_fake_sendmail && + git config sendemail.composeencoding iso-8859-1 && + (echo "#!$SHELL_PATH" && + echo "echo utf8 body: à éìöú >>\"\$1\"" + ) >fake-editor-utf8 && + chmod +x fake-editor-utf8 && + GIT_EDITOR="\"$(pwd)/fake-editor-utf8\"" \ + git send-email \ + --compose --subject foo \ + --from="Example <nobody@example.com>" \ + --to=nobody@example.com \ + --smtp-server="$(pwd)/fake.sendmail" \ + $patches && + grep "^utf8 body" msgtxt1 && + grep "^Content-Type: text/plain; charset=iso-8859-1" msgtxt1 +' + +test_expect_success $PREREQ '--compose-encoding works' ' + clean_fake_sendmail && + (echo "#!$SHELL_PATH" && + echo "echo utf8 body: à éìöú >>\"\$1\"" + ) >fake-editor-utf8 && + chmod +x fake-editor-utf8 && + GIT_EDITOR="\"$(pwd)/fake-editor-utf8\"" \ + git send-email \ + --compose-encoding iso-8859-1 \ + --compose --subject foo \ + --from="Example <nobody@example.com>" \ + --to=nobody@example.com \ + --smtp-server="$(pwd)/fake.sendmail" \ + $patches && + grep "^utf8 body" msgtxt1 && + grep "^Content-Type: text/plain; charset=iso-8859-1" msgtxt1 +' + +test_expect_success $PREREQ '--compose-encoding overrides sendemail.composeencoding' ' + clean_fake_sendmail && + git config sendemail.composeencoding iso-8859-1 && + (echo "#!$SHELL_PATH" && + echo "echo utf8 body: à éìöú >>\"\$1\"" + ) >fake-editor-utf8 && + chmod +x fake-editor-utf8 && + GIT_EDITOR="\"$(pwd)/fake-editor-utf8\"" \ + git send-email \ + --compose-encoding iso-8859-2 \ + --compose --subject foo \ + --from="Example <nobody@example.com>" \ + --to=nobody@example.com \ + --smtp-server="$(pwd)/fake.sendmail" \ + $patches && + grep "^utf8 body" msgtxt1 && + grep "^Content-Type: text/plain; charset=iso-8859-2" msgtxt1 +' + +test_expect_success $PREREQ '--compose-encoding adds correct MIME for subject' ' + clean_fake_sendmail && + GIT_EDITOR="\"$(pwd)/fake-editor\"" \ + git send-email \ + --compose-encoding iso-8859-2 \ + --compose --subject utf8-sübjëct \ + --from="Example <nobody@example.com>" \ + --to=nobody@example.com \ + --smtp-server="$(pwd)/fake.sendmail" \ + $patches && + grep "^fake edit" msgtxt1 && + grep "^Subject: =?iso-8859-2?q?utf8-s=C3=BCbj=C3=ABct?=" msgtxt1 +' + test_expect_success $PREREQ 'detects ambiguous reference/file conflict' ' echo master > master && git add master && @@ -1074,6 +1170,23 @@ EOF ' test_expect_success $PREREQ 'setup expect' ' +cat >expected <<EOF +Subject: subject goes here +EOF +' + +test_expect_success $PREREQ 'ASCII subject is not RFC2047 quoted' ' + clean_fake_sendmail && + echo bogus | + git send-email --from=author@example.com --to=nobody@example.com \ + --smtp-server="$(pwd)/fake.sendmail" \ + --8bit-encoding=UTF-8 \ + email-using-8bit >stdout && + grep "Subject" msgtxt1 >actual && + test_cmp expected actual +' + +test_expect_success $PREREQ 'setup expect' ' cat >content-type-decl <<EOF MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 diff --git a/t/t9020-remote-svn.sh b/t/t9020-remote-svn.sh new file mode 100755 index 0000000..2d2f016 --- /dev/null +++ b/t/t9020-remote-svn.sh @@ -0,0 +1,88 @@ +#!/bin/sh + +test_description='tests remote-svn' + +. ./test-lib.sh + +MARKSPATH=.git/info/fast-import/remote-svn + +if ! test_have_prereq PYTHON +then + skip_all='skipping remote-svn tests, python not available' + test_done +fi + +# Override svnrdump with our simulator +PATH="$HOME:$PATH" +export PATH PYTHON_PATH GIT_BUILD_DIR + +write_script "$HOME/svnrdump" <<\EOF +exec "$PYTHON_PATH" "$GIT_BUILD_DIR/contrib/svn-fe/svnrdump_sim.py" "$@" +EOF + +init_git () { + rm -fr .git && + git init && + #git remote add svnsim testsvn::sim:///$TEST_DIRECTORY/t9020/example.svnrdump + # let's reuse an exisiting dump file!? + git remote add svnsim testsvn::sim://$TEST_DIRECTORY/t9154/svn.dump + git remote add svnfile testsvn::file://$TEST_DIRECTORY/t9154/svn.dump +} + +if test -e "$GIT_BUILD_DIR/git-remote-testsvn" +then + test_set_prereq REMOTE_SVN +fi + +test_debug ' + git --version + type git + type svnrdump +' + +test_expect_success REMOTE_SVN 'simple fetch' ' + init_git && + git fetch svnsim && + test_cmp .git/refs/svn/svnsim/master .git/refs/remotes/svnsim/master && + cp .git/refs/remotes/svnsim/master master.good +' + +test_debug ' + cat .git/refs/svn/svnsim/master + cat .git/refs/remotes/svnsim/master +' + +test_expect_success REMOTE_SVN 'repeated fetch, nothing shall change' ' + git fetch svnsim && + test_cmp master.good .git/refs/remotes/svnsim/master +' + +test_expect_success REMOTE_SVN 'fetch from a file:// url gives the same result' ' + git fetch svnfile +' + +test_expect_failure REMOTE_SVN 'the sha1 differ because the git-svn-id line in the commit msg contains the url' ' + test_cmp .git/refs/remotes/svnfile/master .git/refs/remotes/svnsim/master +' + +test_expect_success REMOTE_SVN 'mark-file regeneration' ' + # filter out any other marks, that can not be regenerated. Only up to 3 digit revisions are allowed here + grep ":[0-9]\{1,3\} " $MARKSPATH/svnsim.marks > $MARKSPATH/svnsim.marks.old && + rm $MARKSPATH/svnsim.marks && + git fetch svnsim && + test_cmp $MARKSPATH/svnsim.marks.old $MARKSPATH/svnsim.marks +' + +test_expect_success REMOTE_SVN 'incremental imports must lead to the same head' ' + export SVNRMAX=3 && + init_git && + git fetch svnsim && + test_cmp .git/refs/svn/svnsim/master .git/refs/remotes/svnsim/master && + unset SVNRMAX && + git fetch svnsim && + test_cmp master.good .git/refs/remotes/svnsim/master +' + +test_debug 'git branch -a' + +test_done diff --git a/t/t9200-git-cvsexportcommit.sh b/t/t9200-git-cvsexportcommit.sh index b59be9a..3fb3368 100755 --- a/t/t9200-git-cvsexportcommit.sh +++ b/t/t9200-git-cvsexportcommit.sh @@ -19,14 +19,15 @@ then test_done fi -CVSROOT=$PWD/cvsroot +CVSROOT=$PWD/tmpcvsroot CVSWORK=$PWD/cvswork GIT_DIR=$PWD/.git export CVSROOT CVSWORK GIT_DIR rm -rf "$CVSROOT" "$CVSWORK" -mkdir "$CVSROOT" && + cvs init && +test -d "$CVSROOT" && cvs -Q co -d "$CVSWORK" . && echo >empty && git add empty && diff --git a/t/t9350-fast-export.sh b/t/t9350-fast-export.sh index 3e821f9..9320b4f 100755 --- a/t/t9350-fast-export.sh +++ b/t/t9350-fast-export.sh @@ -303,7 +303,7 @@ test_expect_success 'dropping tag of filtered out object' ' ( cd limit-by-paths && git fast-export --tag-of-filtered-object=drop mytag -- there > output && - test_cmp output expected + test_cmp expected output ) ' @@ -320,7 +320,7 @@ test_expect_success 'rewriting tag of filtered out object' ' ( cd limit-by-paths && git fast-export --tag-of-filtered-object=rewrite mytag -- there > output && - test_cmp output expected + test_cmp expected output ) ' @@ -351,7 +351,7 @@ test_expect_failure 'no exact-ref revisions included' ' ( cd limit-by-paths && git fast-export master~2..master~1 > output && - test_cmp output expected + test_cmp expected output ) ' @@ -440,4 +440,63 @@ test_expect_success 'fast-export quotes pathnames' ' ) ' +test_expect_success 'test bidirectionality' ' + >marks-cur && + >marks-new && + git init marks-test && + git fast-export --export-marks=marks-cur --import-marks=marks-cur --branches | \ + git --git-dir=marks-test/.git fast-import --export-marks=marks-new --import-marks=marks-new && + (cd marks-test && + git reset --hard && + echo Wohlauf > file && + git commit -a -m "back in time") && + git --git-dir=marks-test/.git fast-export --export-marks=marks-new --import-marks=marks-new --branches | \ + git fast-import --export-marks=marks-cur --import-marks=marks-cur +' + +cat > expected << EOF +blob +mark :13 +data 5 +bump + +commit refs/heads/master +mark :14 +author A U Thor <author@example.com> 1112912773 -0700 +committer C O Mitter <committer@example.com> 1112912773 -0700 +data 5 +bump +from :12 +M 100644 :13 file + +EOF + +test_expect_success 'avoid uninteresting refs' ' + > tmp-marks && + git fast-export --import-marks=tmp-marks \ + --export-marks=tmp-marks master > /dev/null && + git tag v1.0 && + git branch uninteresting && + echo bump > file && + git commit -a -m bump && + git fast-export --import-marks=tmp-marks \ + --export-marks=tmp-marks ^uninteresting ^v1.0 master > actual && + test_cmp expected actual +' + +cat > expected << EOF +reset refs/heads/master +from :14 + +EOF + +test_expect_success 'refs are updated even if no commits need to be exported' ' + > tmp-marks && + git fast-export --import-marks=tmp-marks \ + --export-marks=tmp-marks master > /dev/null && + git fast-export --import-marks=tmp-marks \ + --export-marks=tmp-marks master > actual && + test_cmp expected actual +' + test_done diff --git a/t/t9400-git-cvsserver-server.sh b/t/t9400-git-cvsserver-server.sh index 806623e..9502f24 100755 --- a/t/t9400-git-cvsserver-server.sh +++ b/t/t9400-git-cvsserver-server.sh @@ -400,7 +400,7 @@ cat >expected.C <<EOF Line 0 ======= LINE 0 ->>>>>>> merge.3 +>>>>>>> merge.1.3 EOF for i in 1 2 3 4 5 6 7 8 @@ -505,6 +505,76 @@ test_expect_success 'cvs co -c (shows module database)' ' ' #------------ +# CVS LOG +#------------ + +# Known issues with git-cvsserver current log output: +# - Hard coded "lines: +2 -3" placeholder, instead of real numbers. +# - CVS normally does not internally add a blank first line +# nor a last line with nothing but a space to log messages. +# - The latest cvs 1.12.x server sends +0000 timezone (with some hidden "MT" +# tagging in the protocol), and if cvs 1.12.x client sees the MT tags, +# it converts to local time zone. git-cvsserver doesn't do the +0000 +# or the MT tags... +# - The latest 1.12.x releases add a "commitid:" field on to the end of the +# "date:" line (after "lines:"). Maybe we could stick git's commit id +# in it? Or does CVS expect a certain number of bits (too few for +# a full sha1)? +# +# Given the above, expect the following test to break if git-cvsserver's +# log output is improved. The test is just to ensure it doesn't +# accidentally get worse. + +sed -e 's/^x//' -e 's/SP$/ /' > "$WORKDIR/expect" <<EOF +x +xRCS file: $WORKDIR/gitcvs.git/master/merge,v +xWorking file: merge +xhead: 1.4 +xbranch: +xlocks: strict +xaccess list: +xsymbolic names: +xkeyword substitution: kv +xtotal revisions: 4; selected revisions: 4 +xdescription: +x---------------------------- +xrevision 1.4 +xdate: __DATE__; author: author; state: Exp; lines: +2 -3 +x +xMerge test (no-op) +xSP +x---------------------------- +xrevision 1.3 +xdate: __DATE__; author: author; state: Exp; lines: +2 -3 +x +xMerge test (conflict) +xSP +x---------------------------- +xrevision 1.2 +xdate: __DATE__; author: author; state: Exp; lines: +2 -3 +x +xMerge test (merge) +xSP +x---------------------------- +xrevision 1.1 +xdate: __DATE__; author: author; state: Exp; lines: +2 -3 +x +xMerge test (pre-merge) +xSP +x============================================================================= +EOF +expectStat="$?" + +cd "$WORKDIR" +test_expect_success 'cvs log' ' + cd cvswork && + test x"$expectStat" = x"0" && + GIT_CONFIG="$git_config" cvs log merge >../out && + sed -e "s%2[0-9][0-9][0-9]/[01][0-9]/[0-3][0-9] [0-2][0-9]:[0-5][0-9]:[0-5][0-9]%__DATE__%" ../out > ../actual && + test_cmp ../expect ../actual +' + +#------------ # CVS ANNOTATE #------------ diff --git a/t/t9401-git-cvsserver-crlf.sh b/t/t9401-git-cvsserver-crlf.sh index ff6d6fb..1c5bc84 100755 --- a/t/t9401-git-cvsserver-crlf.sh +++ b/t/t9401-git-cvsserver-crlf.sh @@ -38,6 +38,25 @@ not_present() { fi } +check_status_options() { + (cd "$1" && + GIT_CONFIG="$git_config" cvs -Q status "$2" > "${WORKDIR}/status.out" 2>&1 + ) + if [ x"$?" != x"0" ] ; then + echo "Error from cvs status: $1 $2" >> "${WORKDIR}/marked.log" + return 1; + fi + got="$(sed -n -e 's/^[ ]*Sticky Options:[ ]*//p' "${WORKDIR}/status.out")" + expect="$3" + if [ x"$expect" = x"" ] ; then + expect="(none)" + fi + test x"$got" = x"$expect" + stat=$? + echo "cvs status: $1 $2 $stat '$3' '$got'" >> "${WORKDIR}/marked.log" + return $stat +} + cvs >/dev/null 2>&1 if test $? -ne 1 then @@ -233,6 +252,22 @@ test_expect_success 'cvs co another copy (guess)' ' marked_as cvswork2/subdir newfile.c "" ' +test_expect_success 'cvs status - sticky options' ' + check_status_options cvswork2 textfile.c "" && + check_status_options cvswork2 binfile.bin -kb && + check_status_options cvswork2 .gitattributes "" && + check_status_options cvswork2 mixedUp.c -kb && + check_status_options cvswork2 multiline.c -kb && + check_status_options cvswork2 multilineTxt.c "" && + check_status_options cvswork2/subdir withCr.bin -kb && + check_status_options cvswork2 subdir/withCr.bin -kb && + check_status_options cvswork2/subdir file.h "" && + check_status_options cvswork2 subdir/file.h "" && + check_status_options cvswork2/subdir unspecified.other "" && + check_status_options cvswork2/subdir newfile.bin "" && + check_status_options cvswork2/subdir newfile.c "" +' + test_expect_success 'add text (guess)' ' (cd cvswork && echo "simpleText" > simpleText.c && diff --git a/t/t9502-gitweb-standalone-parse-output.sh b/t/t9502-gitweb-standalone-parse-output.sh index 3a8e7d3..86dfee2 100755 --- a/t/t9502-gitweb-standalone-parse-output.sh +++ b/t/t9502-gitweb-standalone-parse-output.sh @@ -40,7 +40,7 @@ check_snapshot () { echo "basename=$basename" grep "filename=.*$basename.tar" gitweb.headers >/dev/null 2>&1 && "$TAR" tf gitweb.body >file_list && - ! grep -v "^$prefix/" file_list + ! grep -v -e "^$prefix$" -e "^$prefix/" -e "^pax_global_header$" file_list } test_expect_success setup ' diff --git a/t/t9604-cvsimport-timestamps.sh b/t/t9604-cvsimport-timestamps.sh new file mode 100755 index 0000000..1fd5142 --- /dev/null +++ b/t/t9604-cvsimport-timestamps.sh @@ -0,0 +1,71 @@ +#!/bin/sh + +test_description='git cvsimport timestamps' +. ./lib-cvs.sh + +setup_cvs_test_repository t9604 + +test_expect_success 'check timestamps are UTC (TZ=CST6CDT)' ' + + TZ=CST6CDT git cvsimport -p"-x" -C module-1 module && + git cvsimport -p"-x" -C module-1 module && + ( + cd module-1 && + git log --format="%s %ai" + ) >actual-1 && + cat >expect-1 <<-EOF && + Rev 16 2006-10-29 07:00:01 +0000 + Rev 15 2006-10-29 06:59:59 +0000 + Rev 14 2006-04-02 08:00:01 +0000 + Rev 13 2006-04-02 07:59:59 +0000 + Rev 12 2005-12-01 00:00:00 +0000 + Rev 11 2005-11-01 00:00:00 +0000 + Rev 10 2005-10-01 00:00:00 +0000 + Rev 9 2005-09-01 00:00:00 +0000 + Rev 8 2005-08-01 00:00:00 +0000 + Rev 7 2005-07-01 00:00:00 +0000 + Rev 6 2005-06-01 00:00:00 +0000 + Rev 5 2005-05-01 00:00:00 +0000 + Rev 4 2005-04-01 00:00:00 +0000 + Rev 3 2005-03-01 00:00:00 +0000 + Rev 2 2005-02-01 00:00:00 +0000 + Rev 1 2005-01-01 00:00:00 +0000 + EOF + test_cmp actual-1 expect-1 +' + +test_expect_success 'check timestamps with author-specific timezones' ' + + cat >cvs-authors <<-EOF && + user1=User One <user1@domain.org> + user2=User Two <user2@domain.org> CST6CDT + user3=User Three <user3@domain.org> EST5EDT + user4=User Four <user4@domain.org> MST7MDT + EOF + git cvsimport -p"-x" -A cvs-authors -C module-2 module && + ( + cd module-2 && + git log --format="%s %ai %an" + ) >actual-2 && + cat >expect-2 <<-EOF && + Rev 16 2006-10-29 01:00:01 -0600 User Two + Rev 15 2006-10-29 01:59:59 -0500 User Two + Rev 14 2006-04-02 03:00:01 -0500 User Two + Rev 13 2006-04-02 01:59:59 -0600 User Two + Rev 12 2005-11-30 17:00:00 -0700 User Four + Rev 11 2005-10-31 19:00:00 -0500 User Three + Rev 10 2005-09-30 19:00:00 -0500 User Two + Rev 9 2005-09-01 00:00:00 +0000 User One + Rev 8 2005-07-31 18:00:00 -0600 User Four + Rev 7 2005-06-30 20:00:00 -0400 User Three + Rev 6 2005-05-31 19:00:00 -0500 User Two + Rev 5 2005-05-01 00:00:00 +0000 User One + Rev 4 2005-03-31 17:00:00 -0700 User Four + Rev 3 2005-02-28 19:00:00 -0500 User Three + Rev 2 2005-01-31 18:00:00 -0600 User Two + Rev 1 2005-01-01 00:00:00 +0000 User One + EOF + test_cmp actual-2 expect-2 +' + +test_done diff --git a/t/t9604/cvsroot/.gitattributes b/t/t9604/cvsroot/.gitattributes new file mode 100644 index 0000000..562b12e --- /dev/null +++ b/t/t9604/cvsroot/.gitattributes @@ -0,0 +1 @@ +* -whitespace diff --git a/t/t9604/cvsroot/CVSROOT/.gitignore b/t/t9604/cvsroot/CVSROOT/.gitignore new file mode 100644 index 0000000..3bb9b34 --- /dev/null +++ b/t/t9604/cvsroot/CVSROOT/.gitignore @@ -0,0 +1,2 @@ +history +val-tags diff --git a/t/t9604/cvsroot/module/a,v b/t/t9604/cvsroot/module/a,v new file mode 100644 index 0000000..80658c3 --- /dev/null +++ b/t/t9604/cvsroot/module/a,v @@ -0,0 +1,264 @@ +head 1.16; +access; +symbols; +locks; strict; +comment @# @; + + +1.16 +date 2006.10.29.07.00.01; author user2; state Exp; +branches; +next 1.15; + +1.15 +date 2006.10.29.06.59.59; author user2; state Exp; +branches; +next 1.14; + +1.14 +date 2006.04.02.08.00.01; author user2; state Exp; +branches; +next 1.13; + +1.13 +date 2006.04.02.07.59.59; author user2; state Exp; +branches; +next 1.12; + +1.12 +date 2005.12.01.00.00.00; author user4; state Exp; +branches; +next 1.11; + +1.11 +date 2005.11.01.00.00.00; author user3; state Exp; +branches; +next 1.10; + +1.10 +date 2005.10.01.00.00.00; author user2; state Exp; +branches; +next 1.9; + +1.9 +date 2005.09.01.00.00.00; author user1; state Exp; +branches; +next 1.8; + +1.8 +date 2005.08.01.00.00.00; author user4; state Exp; +branches; +next 1.7; + +1.7 +date 2005.07.01.00.00.00; author user3; state Exp; +branches; +next 1.6; + +1.6 +date 2005.06.01.00.00.00; author user2; state Exp; +branches; +next 1.5; + +1.5 +date 2005.05.01.00.00.00; author user1; state Exp; +branches; +next 1.4; + +1.4 +date 2005.04.01.00.00.00; author user4; state Exp; +branches; +next 1.3; + +1.3 +date 2005.03.01.00.00.00; author user3; state Exp; +branches; +next 1.2; + +1.2 +date 2005.02.01.00.00.00; author user2; state Exp; +branches; +next 1.1; + +1.1 +date 2005.01.01.00.00.00; author user1; state Exp; +branches; +next ; + + +desc +@@ + + +1.16 +log +@Rev 16 +@ +text +@Rev 16 +@ + + +1.15 +log +@Rev 15 +@ +text +@d1 1 +a1 1 +Rev 15 +@ + + +1.14 +log +@Rev 14 +@ +text +@d1 1 +a1 1 +Rev 14 +@ + + +1.13 +log +@Rev 13 +@ +text +@d1 1 +a1 1 +Rev 13 +@ + + +1.12 +log +@Rev 12 +@ +text +@d1 1 +a1 1 +Rev 12 +@ + + +1.11 +log +@Rev 11 +@ +text +@d1 1 +a1 1 +Rev 11 +@ + + +1.10 +log +@Rev 10 +@ +text +@d1 1 +a1 1 +Rev 10 +@ + + +1.9 +log +@Rev 9 +@ +text +@d1 1 +a1 1 +Rev 9 +@ + + +1.8 +log +@Rev 8 +@ +text +@d1 1 +a1 1 +Rev 8 +@ + + +1.7 +log +@Rev 7 +@ +text +@d1 1 +a1 1 +Rev 7 +@ + + +1.6 +log +@Rev 6 +@ +text +@d1 1 +a1 1 +Rev 6 +@ + + +1.5 +log +@Rev 5 +@ +text +@d1 1 +a1 1 +Rev 5 +@ + + +1.4 +log +@Rev 4 +@ +text +@d1 1 +a1 1 +Rev 4 +@ + + +1.3 +log +@Rev 3 +@ +text +@d1 1 +a1 1 +Rev 3 +@ + + +1.2 +log +@Rev 2 +@ +text +@d1 1 +a1 1 +Rev 2 +@ + + +1.1 +log +@Rev 1 +@ +text +@d1 1 +a1 1 +Rev 1 +@ diff --git a/t/t9700/test.pl b/t/t9700/test.pl index 3b9b484..0d4e366 100755 --- a/t/t9700/test.pl +++ b/t/t9700/test.pl @@ -46,8 +46,7 @@ is($r->get_color("color.test.slot1", "red"), $ansi_green, "get_color"); # Save and restore STDERR; we will probably extract this into a # "dies_ok" method and possibly move the STDERR handling to Git.pm. open our $tmpstderr, ">&STDERR" or die "cannot save STDERR"; close STDERR; -eval { $r->config("test.dupstring") }; -ok($@, "config: duplicate entry in scalar context fails"); +is($r->config("test.dupstring"), "value2", "config: multivar"); eval { $r->config_bool("test.boolother") }; ok($@, "config_bool: non-boolean values fail"); open STDERR, ">&", $tmpstderr or die "cannot restore STDERR"; diff --git a/t/t9800-git-p4-basic.sh b/t/t9800-git-p4-basic.sh index b7ad716..8c59796 100755 --- a/t/t9800-git-p4-basic.sh +++ b/t/t9800-git-p4-basic.sh @@ -143,7 +143,18 @@ test_expect_success 'exit when p4 fails to produce marshaled output' ' ! test_i18ngrep Traceback errs ' -test_expect_success 'clone bare' ' +# Hide a file from p4d, make sure we catch its complaint. This won't fail in +# p4 changes, files, or describe; just in p4 print. If P4CLIENT is unset, the +# message will include "Librarian checkout". +test_expect_success 'exit gracefully for p4 server errors' ' + test_when_finished "mv \"$db\"/depot/file1,v,hidden \"$db\"/depot/file1,v" && + mv "$db"/depot/file1,v "$db"/depot/file1,v,hidden && + test_when_finished cleanup_git && + test_expect_code 1 git p4 clone --dest="$git" //depot@1 >out 2>err && + test_i18ngrep "Error from p4 print" err +' + +test_expect_success 'clone --bare should make a bare repository' ' rm -rf "$git" && git p4 clone --dest="$git" --bare //depot && test_when_finished cleanup_git && @@ -172,6 +183,18 @@ test_expect_success 'initial import time from top change time' ' ) ' +test_expect_success 'unresolvable host in P4PORT should display error' ' + test_when_finished cleanup_git && + git p4 clone --dest="$git" //depot && + ( + cd "$git" && + P4PORT=nosuchhost:65537 && + export P4PORT && + test_expect_code 1 git p4 sync >out 2>err && + grep "connect to nosuchhost" err + ) +' + test_expect_success 'kill p4d' ' kill_p4d ' diff --git a/t/t9810-git-p4-rcs.sh b/t/t9810-git-p4-rcs.sh index 0c2fc3e..34fbc90 100755 --- a/t/t9810-git-p4-rcs.sh +++ b/t/t9810-git-p4-rcs.sh @@ -26,10 +26,8 @@ test_expect_success 'init depot' ' line7 line8 EOF - cp filek fileko && - sed -i "s/Revision/Revision: do not scrub me/" fileko - cp fileko file_text && - sed -i "s/Id/Id: do not scrub me/" file_text + sed "s/Revision/Revision: do not scrub me/" <filek >fileko && + sed "s/Id/Id: do not scrub me/" <fileko >file_text && p4 add -t text+k filek && p4 submit -d "filek" && p4 add -t text+ko fileko && @@ -88,7 +86,8 @@ test_expect_success 'edit far away from RCS lines' ' ( cd "$git" && git config git-p4.skipSubmitEdit true && - sed -i "s/^line7/line7 edit/" filek && + sed "s/^line7/line7 edit/" <filek >filek.tmp && + mv -f filek.tmp filek && git commit -m "filek line7 edit" filek && git p4 submit && scrub_k_check filek @@ -105,7 +104,8 @@ test_expect_success 'edit near RCS lines' ' cd "$git" && git config git-p4.skipSubmitEdit true && git config git-p4.attemptRCSCleanup true && - sed -i "s/^line4/line4 edit/" filek && + sed "s/^line4/line4 edit/" <filek >filek.tmp && + mv -f filek.tmp filek && git commit -m "filek line4 edit" filek && git p4 submit && scrub_k_check filek @@ -122,7 +122,8 @@ test_expect_success 'edit keyword lines' ' cd "$git" && git config git-p4.skipSubmitEdit true && git config git-p4.attemptRCSCleanup true && - sed -i "/Revision/d" filek && + sed "/Revision/d" <filek >filek.tmp && + mv -f filek.tmp filek && git commit -m "filek remove Revision line" filek && git p4 submit && scrub_k_check filek @@ -139,7 +140,8 @@ test_expect_success 'scrub ko files differently' ' cd "$git" && git config git-p4.skipSubmitEdit true && git config git-p4.attemptRCSCleanup true && - sed -i "s/^line4/line4 edit/" fileko && + sed "s/^line4/line4 edit/" <fileko >fileko.tmp && + mv -f fileko.tmp fileko && git commit -m "fileko line4 edit" fileko && git p4 submit && scrub_ko_check fileko && @@ -189,12 +191,14 @@ test_expect_success 'do not scrub plain text' ' cd "$git" && git config git-p4.skipSubmitEdit true && git config git-p4.attemptRCSCleanup true && - sed -i "s/^line4/line4 edit/" file_text && + sed "s/^line4/line4 edit/" <file_text >file_text.tmp && + mv -f file_text.tmp file_text && git commit -m "file_text line4 edit" file_text && ( cd "$cli" && p4 open file_text && - sed -i "s/^line5/line5 p4 edit/" file_text && + sed "s/^line5/line5 p4 edit/" <file_text >file_text.tmp && + mv -f file_text.tmp file_text && p4 submit -d "file5 p4 edit" ) && echo s | test_expect_code 1 git p4 submit && diff --git a/t/t9814-git-p4-rename.sh b/t/t9814-git-p4-rename.sh index 3bf1224..be802e0 100755 --- a/t/t9814-git-p4-rename.sh +++ b/t/t9814-git-p4-rename.sh @@ -199,6 +199,41 @@ test_expect_success 'detect copies' ' ) ' +# See if configurables can be set, and in particular if the run.move.allow +# variable exists, which allows admins to disable the "p4 move" command. +test_expect_success 'p4 configure command and run.move.allow are available' ' + p4 configure show run.move.allow >out ; retval=$? && + test $retval = 0 && + { + egrep ^run.move.allow: out && + test_set_prereq P4D_HAVE_CONFIGURABLE_RUN_MOVE_ALLOW || + true + } || true +' + +# If move can be disabled, turn it off and test p4 move handling +test_expect_success P4D_HAVE_CONFIGURABLE_RUN_MOVE_ALLOW \ + 'do not use p4 move when administratively disabled' ' + test_when_finished "p4 configure set run.move.allow=1" && + p4 configure set run.move.allow=0 && + ( + cd "$cli" && + echo move-disallow-file >move-disallow-file && + p4 add move-disallow-file && + p4 submit -d "add move-disallow-file" + ) && + test_when_finished cleanup_git && + git p4 clone --dest="$git" //depot && + ( + cd "$git" && + git config git-p4.skipSubmitEdit true && + git config git-p4.detectRenames true && + git mv move-disallow-file move-disallow-file-moved && + git commit -m "move move-disallow-file" && + git p4 submit + ) +' + test_expect_success 'kill p4d' ' kill_p4d ' diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh index cbd0fb6..3cd53f8 100755 --- a/t/t9902-completion.sh +++ b/t/t9902-completion.sh @@ -54,105 +54,78 @@ run_completion () __git_wrap__git_main && print_comp } +# Test high-level completion +# Arguments are: +# 1: typed text so far (cur) +# 2: expected completion test_completion () { - test $# -gt 1 && echo "$2" > expected - run_completion "$@" && + if test $# -gt 1 + then + printf '%s\n' "$2" >expected + else + sed -e 's/Z$//' >expected + fi && + run_completion "$1" && test_cmp expected out } -# Like test_completion, but reads expectation from stdin, -# which is convenient when it is multiline. We also process "_" into -# spaces to make test vectors more readable. -test_completion_long () +# Test __gitcomp. +# The first argument is the typed text so far (cur); the rest are +# passed to __gitcomp. Expected output comes is read from the +# standard input, like test_completion(). +test_gitcomp () { - tr _ " " >expected && - test_completion "$1" + local -a COMPREPLY && + sed -e 's/Z$//' >expected && + cur="$1" && + shift && + __gitcomp "$@" && + print_comp && + test_cmp expected out } -newline=$'\n' - test_expect_success '__gitcomp - trailing space - options' ' - sed -e "s/Z$//" >expected <<-\EOF && + test_gitcomp "--re" "--dry-run --reuse-message= --reedit-message= + --reset-author" <<-EOF --reuse-message=Z --reedit-message=Z --reset-author Z EOF - ( - local -a COMPREPLY && - cur="--re" && - __gitcomp "--dry-run --reuse-message= --reedit-message= - --reset-author" && - IFS="$newline" && - echo "${COMPREPLY[*]}" > out - ) && - test_cmp expected out ' test_expect_success '__gitcomp - trailing space - config keys' ' - sed -e "s/Z$//" >expected <<-\EOF && + test_gitcomp "br" "branch. branch.autosetupmerge + branch.autosetuprebase browser." <<-\EOF branch.Z branch.autosetupmerge Z branch.autosetuprebase Z browser.Z EOF - ( - local -a COMPREPLY && - cur="br" && - __gitcomp "branch. branch.autosetupmerge - branch.autosetuprebase browser." && - IFS="$newline" && - echo "${COMPREPLY[*]}" > out - ) && - test_cmp expected out ' test_expect_success '__gitcomp - option parameter' ' - sed -e "s/Z$//" >expected <<-\EOF && + test_gitcomp "--strategy=re" "octopus ours recursive resolve subtree" \ + "" "re" <<-\EOF recursive Z resolve Z EOF - ( - local -a COMPREPLY && - cur="--strategy=re" && - __gitcomp "octopus ours recursive resolve subtree - " "" "re" && - IFS="$newline" && - echo "${COMPREPLY[*]}" > out - ) && - test_cmp expected out ' test_expect_success '__gitcomp - prefix' ' - sed -e "s/Z$//" >expected <<-\EOF && + test_gitcomp "branch.me" "remote merge mergeoptions rebase" \ + "branch.maint." "me" <<-\EOF branch.maint.merge Z branch.maint.mergeoptions Z EOF - ( - local -a COMPREPLY && - cur="branch.me" && - __gitcomp "remote merge mergeoptions rebase - " "branch.maint." "me" && - IFS="$newline" && - echo "${COMPREPLY[*]}" > out - ) && - test_cmp expected out ' test_expect_success '__gitcomp - suffix' ' - sed -e "s/Z$//" >expected <<-\EOF && + test_gitcomp "branch.me" "master maint next pu" "branch." \ + "ma" "." <<-\EOF branch.master.Z branch.maint.Z EOF - ( - local -a COMPREPLY && - cur="branch.me" && - __gitcomp "master maint next pu - " "branch." "ma" "." && - IFS="$newline" && - echo "${COMPREPLY[*]}" > out - ) && - test_cmp expected out ' test_expect_success 'basic' ' @@ -169,7 +142,7 @@ test_expect_success 'basic' ' ' test_expect_success 'double dash "git" itself' ' - sed -e "s/Z$//" >expected <<-\EOF && + test_completion "git --" <<-\EOF --paginate Z --no-pager Z --git-dir= @@ -184,11 +157,10 @@ test_expect_success 'double dash "git" itself' ' --no-replace-objects Z --help Z EOF - test_completion "git --" ' test_expect_success 'double dash "git checkout"' ' - sed -e "s/Z$//" >expected <<-\EOF && + test_completion "git checkout --" <<-\EOF --quiet Z --ours Z --theirs Z @@ -199,17 +171,15 @@ test_expect_success 'double dash "git checkout"' ' --orphan Z --patch Z EOF - test_completion "git checkout --" ' test_expect_success 'general options' ' test_completion "git --ver" "--version " && test_completion "git --hel" "--help " && - sed -e "s/Z$//" >expected <<-\EOF && + test_completion "git --exe" <<-\EOF && --exec-path Z --exec-path= EOF - test_completion "git --exe" && test_completion "git --htm" "--html-path " && test_completion "git --pag" "--paginate " && test_completion "git --no-p" "--no-pager " && @@ -247,25 +217,25 @@ test_expect_success 'setup for ref completion' ' ' test_expect_success 'checkout completes ref names' ' - test_completion_long "git checkout m" <<-\EOF - master_ - mybranch_ - mytag_ + test_completion "git checkout m" <<-\EOF + master Z + mybranch Z + mytag Z EOF ' test_expect_success 'show completes all refs' ' - test_completion_long "git show m" <<-\EOF - master_ - mybranch_ - mytag_ + test_completion "git show m" <<-\EOF + master Z + mybranch Z + mytag Z EOF ' test_expect_success '<ref>: completes paths' ' - test_completion_long "git show mytag:f" <<-\EOF - file1_ - file2_ + test_completion "git show mytag:f" <<-\EOF + file1 Z + file2 Z EOF ' @@ -273,8 +243,8 @@ test_expect_success 'complete tree filename with spaces' ' echo content >"name with spaces" && git add . && git commit -m spaces && - test_completion_long "git show HEAD:nam" <<-\EOF - name with spaces_ + test_completion "git show HEAD:nam" <<-\EOF + name with spaces Z EOF ' @@ -282,10 +252,15 @@ test_expect_failure 'complete tree filename with metacharacters' ' echo content >"name with \${meta}" && git add . && git commit -m meta && - test_completion_long "git show HEAD:nam" <<-\EOF - name with ${meta}_ - name with spaces_ + test_completion "git show HEAD:nam" <<-\EOF + name with ${meta} Z + name with spaces Z EOF ' +test_expect_success 'send-email' ' + test_completion "git send-email --cov" "--cover-letter " && + test_completion "git send-email ma" "master " +' + test_done diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh index 8889ba5..22a4f8f 100644 --- a/t/test-lib-functions.sh +++ b/t/test-lib-functions.sh @@ -275,6 +275,15 @@ test_have_prereq () { for prerequisite do + case "$prerequisite" in + !*) + negative_prereq=t + prerequisite=${prerequisite#!} + ;; + *) + negative_prereq= + esac + case " $lazily_tested_prereq " in *" $prerequisite "*) ;; @@ -294,10 +303,20 @@ test_have_prereq () { total_prereq=$(($total_prereq + 1)) case "$satisfied_prereq" in *" $prerequisite "*) + satisfied_this_prereq=t + ;; + *) + satisfied_this_prereq= + esac + + case "$satisfied_this_prereq,$negative_prereq" in + t,|,t) ok_prereq=$(($ok_prereq + 1)) ;; *) - # Keep a list of missing prerequisites + # Keep a list of missing prerequisites; restore + # the negative marker if necessary. + prerequisite=${negative_prereq:+!}$prerequisite if test -z "$missing_prereq" then missing_prereq=$prerequisite diff --git a/t/test-lib.sh b/t/test-lib.sh index 489bc80..8a12cbb 100644 --- a/t/test-lib.sh +++ b/t/test-lib.sh @@ -212,11 +212,13 @@ then error) tput bold; tput setaf 1;; # bold red skip) - tput bold; tput setaf 2;; # bold green + tput setaf 4;; # blue + warn) + tput setaf 3;; # brown/yellow pass) - tput setaf 2;; # green + tput setaf 2;; # green info) - tput setaf 3;; # brown + tput setaf 6;; # cyan *) test -n "$quiet" && return;; esac @@ -298,7 +300,7 @@ test_ok_ () { test_failure_ () { test_failure=$(($test_failure + 1)) - say_color error "not ok - $test_count $1" + say_color error "not ok $test_count - $1" shift echo "$@" | sed -e 's/^/# /' test "$immediate" = "" || { GIT_EXIT_OK=t; exit 1; } @@ -306,12 +308,12 @@ test_failure_ () { test_known_broken_ok_ () { test_fixed=$(($test_fixed+1)) - say_color "" "ok $test_count - $@ # TODO known breakage" + say_color error "ok $test_count - $@ # TODO known breakage vanished" } test_known_broken_failure_ () { test_broken=$(($test_broken+1)) - say_color skip "not ok $test_count - $@ # TODO known breakage" + say_color warn "not ok $test_count - $@ # TODO known breakage" } test_debug () { @@ -389,7 +391,8 @@ test_done () { then test_results_dir="$TEST_OUTPUT_DIRECTORY/test-results" mkdir -p "$test_results_dir" - test_results_path="$test_results_dir/${0%.sh}-$$.counts" + base=${0##*/} + test_results_path="$test_results_dir/${base%.sh}-$$.counts" cat >>"$test_results_path" <<-EOF total $test_count @@ -403,13 +406,18 @@ test_done () { if test "$test_fixed" != 0 then - say_color pass "# fixed $test_fixed known breakage(s)" + say_color error "# $test_fixed known breakage(s) vanished; please update test(s)" fi if test "$test_broken" != 0 then - say_color error "# still have $test_broken known breakage(s)" - msg="remaining $(($test_count-$test_broken)) test(s)" + say_color warn "# still have $test_broken known breakage(s)" + fi + if test "$test_broken" != 0 || test "$test_fixed" != 0 + then + test_remaining=$(( $test_count - $test_broken - $test_fixed )) + msg="remaining $test_remaining test(s)" else + test_remaining=$test_count msg="$test_count test(s)" fi case "$test_failure" in @@ -423,7 +431,7 @@ test_done () { if test $test_external_has_tap -eq 0 then - if test $test_count -gt 0 + if test $test_remaining -gt 0 then say_color pass "# passed all $msg" fi @@ -614,7 +622,7 @@ for skp in $GIT_SKIP_TESTS do case "$this_test" in $skp) - say_color skip >&3 "skipping test $this_test altogether" + say_color info >&3 "skipping test $this_test altogether" skip_all="skip all tests in $this_test" test_done esac @@ -738,6 +746,12 @@ test_lazy_prereq UTF8_NFD_TO_NFC ' esac ' +test_lazy_prereq AUTOIDENT ' + sane_unset GIT_AUTHOR_NAME && + sane_unset GIT_AUTHOR_EMAIL && + git var GIT_AUTHOR_IDENT +' + # When the tests are run as root, permission tests will report that # things are writable when they shouldn't be. test -w / || test_set_prereq SANITY diff --git a/test-path-utils.c b/test-path-utils.c index 3bc20e9..0092cbf 100644 --- a/test-path-utils.c +++ b/test-path-utils.c @@ -1,4 +1,32 @@ #include "cache.h" +#include "string-list.h" + +/* + * A "string_list_each_func_t" function that normalizes an entry from + * GIT_CEILING_DIRECTORIES. If the path is unusable for some reason, + * die with an explanation. + */ +static int normalize_ceiling_entry(struct string_list_item *item, void *unused) +{ + const char *ceil = item->string; + int len = strlen(ceil); + char buf[PATH_MAX+1]; + + if (len == 0) + die("Empty path is not supported"); + if (len > PATH_MAX) + die("Path \"%s\" is too long", ceil); + if (!is_absolute_path(ceil)) + die("Path \"%s\" is not absolute", ceil); + if (normalize_path_copy(buf, ceil) < 0) + die("Path \"%s\" could not be normalized", ceil); + len = strlen(buf); + if (len > 1 && buf[len-1] == '/') + die("Normalized path \"%s\" ended with slash", buf); + free(item->string); + item->string = xstrdup(buf); + return 1; +} int main(int argc, char **argv) { @@ -30,7 +58,28 @@ int main(int argc, char **argv) } if (argc == 4 && !strcmp(argv[1], "longest_ancestor_length")) { - int len = longest_ancestor_length(argv[2], argv[3]); + int len; + struct string_list ceiling_dirs = STRING_LIST_INIT_DUP; + char *path = xstrdup(argv[2]); + + /* + * We have to normalize the arguments because under + * Windows, bash mangles arguments that look like + * absolute POSIX paths or colon-separate lists of + * absolute POSIX paths into DOS paths (e.g., + * "/foo:/foo/bar" might be converted to + * "D:\Src\msysgit\foo;D:\Src\msysgit\foo\bar"), + * whereas longest_ancestor_length() requires paths + * that use forward slashes. + */ + if (normalize_path_copy(path, path)) + die("Path \"%s\" could not be normalized", argv[2]); + string_list_split(&ceiling_dirs, argv[3], PATH_SEP, -1); + filter_string_list(&ceiling_dirs, 0, + normalize_ceiling_entry, NULL); + len = longest_ancestor_length(path, &ceiling_dirs); + string_list_clear(&ceiling_dirs, 0); + free(path); printf("%d\n", len); return 0; } diff --git a/test-string-list.c b/test-string-list.c index 4693295..00ce6c9 100644 --- a/test-string-list.c +++ b/test-string-list.c @@ -97,26 +97,6 @@ int main(int argc, char **argv) return 0; } - if (argc == 4 && !strcmp(argv[1], "longest_prefix")) { - /* arguments: <colon-separated-prefixes>|- <string> */ - struct string_list prefixes = STRING_LIST_INIT_DUP; - int retval; - const char *prefix_string = argv[2]; - const char *string = argv[3]; - const char *match; - - parse_string_list(&prefixes, prefix_string); - match = string_list_longest_prefix(&prefixes, string); - if (match) { - printf("%s\n", match); - retval = 0; - } - else - retval = 1; - string_list_clear(&prefixes, 0); - return retval; - } - fprintf(stderr, "%s: unknown function name: %s\n", argv[0], argv[1] ? argv[1] : "(there was none)"); return 1; diff --git a/test-svn-fe.c b/test-svn-fe.c index 83633a2..0f2d9a4 100644 --- a/test-svn-fe.c +++ b/test-svn-fe.c @@ -40,7 +40,7 @@ int main(int argc, char *argv[]) if (argc == 2) { if (svndump_init(argv[1])) return 1; - svndump_read(NULL); + svndump_read(NULL, "refs/heads/master", "refs/notes/svn/revs"); svndump_deinit(); svndump_reset(); return 0; diff --git a/transport-helper.c b/transport-helper.c index cfe0988..965b778 100644 --- a/transport-helper.c +++ b/transport-helper.c @@ -10,6 +10,7 @@ #include "string-list.h" #include "thread-utils.h" #include "sigchain.h" +#include "argv-array.h" static int debug; @@ -19,6 +20,7 @@ struct helper_data { FILE *out; unsigned fetch : 1, import : 1, + bidi_import : 1, export : 1, option : 1, push : 1, @@ -101,6 +103,7 @@ static void do_take_over(struct transport *transport) static struct child_process *get_helper(struct transport *transport) { struct helper_data *data = transport->data; + struct argv_array argv = ARGV_ARRAY_INIT; struct strbuf buf = STRBUF_INIT; struct child_process *helper; const char **refspecs = NULL; @@ -122,11 +125,10 @@ static struct child_process *get_helper(struct transport *transport) helper->in = -1; helper->out = -1; helper->err = 0; - helper->argv = xcalloc(4, sizeof(*helper->argv)); - strbuf_addf(&buf, "git-remote-%s", data->name); - helper->argv[0] = strbuf_detach(&buf, NULL); - helper->argv[1] = transport->remote->name; - helper->argv[2] = remove_ext_force(transport->url); + argv_array_pushf(&argv, "git-remote-%s", data->name); + argv_array_push(&argv, transport->remote->name); + argv_array_push(&argv, remove_ext_force(transport->url)); + helper->argv = argv_array_detach(&argv, NULL); helper->git_cmd = 0; helper->silent_exec_failure = 1; @@ -178,6 +180,8 @@ static struct child_process *get_helper(struct transport *transport) data->push = 1; else if (!strcmp(capname, "import")) data->import = 1; + else if (!strcmp(capname, "bidi-import")) + data->bidi_import = 1; else if (!strcmp(capname, "export")) data->export = 1; else if (!data->refspecs && !prefixcmp(capname, "refspec ")) { @@ -241,8 +245,7 @@ static int disconnect_helper(struct transport *transport) close(data->helper->out); fclose(data->out); res = finish_command(data->helper); - free((char *)data->helper->argv[0]); - free(data->helper->argv); + argv_array_free_detached(data->helper->argv); free(data->helper); data->helper = NULL; } @@ -376,14 +379,23 @@ static int fetch_with_fetch(struct transport *transport, static int get_importer(struct transport *transport, struct child_process *fastimport) { struct child_process *helper = get_helper(transport); + struct helper_data *data = transport->data; + struct argv_array argv = ARGV_ARRAY_INIT; + int cat_blob_fd, code; memset(fastimport, 0, sizeof(*fastimport)); fastimport->in = helper->out; - fastimport->argv = xcalloc(5, sizeof(*fastimport->argv)); - fastimport->argv[0] = "fast-import"; - fastimport->argv[1] = "--quiet"; + argv_array_push(&argv, "fast-import"); + argv_array_push(&argv, debug ? "--stats" : "--quiet"); + if (data->bidi_import) { + cat_blob_fd = xdup(helper->in); + argv_array_pushf(&argv, "--cat-blob-fd=%d", cat_blob_fd); + } + fastimport->argv = argv.argv; fastimport->git_cmd = 1; - return start_command(fastimport); + + code = start_command(fastimport); + return code; } static int get_exporter(struct transport *transport, @@ -438,11 +450,17 @@ static int fetch_with_import(struct transport *transport, } write_constant(data->helper->in, "\n"); + /* + * remote-helpers that advertise the bidi-import capability are required to + * buffer the complete batch of import commands until this newline before + * sending data to fast-import. + * These helpers read back data from fast-import on their stdin, which could + * be mixed with import commands, otherwise. + */ if (finish_command(&fastimport)) die("Error while running fast-import"); - free(fastimport.argv); - fastimport.argv = NULL; + argv_array_free_detached(fastimport.argv); /* * The fast-import stream of a remote helper that advertises @@ -643,6 +661,11 @@ static void push_update_ref_status(struct strbuf *buf, free(msg); msg = NULL; } + else if (!strcmp(msg, "already exists")) { + status = REF_STATUS_REJECT_ALREADY_EXISTS; + free(msg); + msg = NULL; + } } if (*ref) @@ -702,6 +725,7 @@ static int push_refs_with_push(struct transport *transport, /* Check for statuses set by set_ref_status_for_push() */ switch (ref->status) { case REF_STATUS_REJECT_NONFASTFORWARD: + case REF_STATUS_REJECT_ALREADY_EXISTS: case REF_STATUS_UPTODATE: continue; default: diff --git a/transport.c b/transport.c index 9932f40..2673d27 100644 --- a/transport.c +++ b/transport.c @@ -659,7 +659,7 @@ static void print_ok_ref_status(struct ref *ref, int porcelain) const char *msg; strcpy(quickref, status_abbrev(ref->old_sha1)); - if (ref->nonfastforward) { + if (ref->requires_force) { strcat(quickref, "..."); type = '+'; msg = "forced update"; @@ -695,6 +695,10 @@ static int print_one_push_status(struct ref *ref, const char *dest, int count, i print_ref_status('!', "[rejected]", ref, ref->peer_ref, "non-fast-forward", porcelain); break; + case REF_STATUS_REJECT_ALREADY_EXISTS: + print_ref_status('!', "[rejected]", ref, ref->peer_ref, + "already exists", porcelain); + break; case REF_STATUS_REMOTE_REJECT: print_ref_status('!', "[remote rejected]", ref, ref->deletion ? NULL : ref->peer_ref, @@ -714,7 +718,7 @@ static int print_one_push_status(struct ref *ref, const char *dest, int count, i } void transport_print_push_status(const char *dest, struct ref *refs, - int verbose, int porcelain, int *nonfastforward) + int verbose, int porcelain, unsigned int *reject_reasons) { struct ref *ref; int n = 0; @@ -733,18 +737,19 @@ void transport_print_push_status(const char *dest, struct ref *refs, if (ref->status == REF_STATUS_OK) n += print_one_push_status(ref, dest, n, porcelain); - *nonfastforward = 0; + *reject_reasons = 0; for (ref = refs; ref; ref = ref->next) { if (ref->status != REF_STATUS_NONE && ref->status != REF_STATUS_UPTODATE && ref->status != REF_STATUS_OK) n += print_one_push_status(ref, dest, n, porcelain); - if (ref->status == REF_STATUS_REJECT_NONFASTFORWARD && - *nonfastforward != NON_FF_HEAD) { + if (ref->status == REF_STATUS_REJECT_NONFASTFORWARD) { if (!strcmp(head, ref->name)) - *nonfastforward = NON_FF_HEAD; + *reject_reasons |= REJECT_NON_FF_HEAD; else - *nonfastforward = NON_FF_OTHER; + *reject_reasons |= REJECT_NON_FF_OTHER; + } else if (ref->status == REF_STATUS_REJECT_ALREADY_EXISTS) { + *reject_reasons |= REJECT_ALREADY_EXISTS; } } } @@ -1031,9 +1036,9 @@ static void die_with_unpushed_submodules(struct string_list *needs_pushing) int transport_push(struct transport *transport, int refspec_nr, const char **refspec, int flags, - int *nonfastforward) + unsigned int *reject_reasons) { - *nonfastforward = 0; + *reject_reasons = 0; transport_verify_remote_names(refspec_nr, refspec); if (transport->push) { @@ -1099,7 +1104,7 @@ int transport_push(struct transport *transport, if (!quiet || err) transport_print_push_status(transport->url, remote_refs, verbose | porcelain, porcelain, - nonfastforward); + reject_reasons); if (flags & TRANSPORT_PUSH_SET_UPSTREAM) set_upstreams(transport, remote_refs, pretend); diff --git a/transport.h b/transport.h index 3b21c4a..bfd2df5 100644 --- a/transport.h +++ b/transport.h @@ -140,11 +140,13 @@ int transport_set_option(struct transport *transport, const char *name, void transport_set_verbosity(struct transport *transport, int verbosity, int force_progress); -#define NON_FF_HEAD 1 -#define NON_FF_OTHER 2 +#define REJECT_NON_FF_HEAD 0x01 +#define REJECT_NON_FF_OTHER 0x02 +#define REJECT_ALREADY_EXISTS 0x04 + int transport_push(struct transport *connection, int refspec_nr, const char **refspec, int flags, - int * nonfastforward); + unsigned int * reject_reasons); const struct ref *transport_get_remote_refs(struct transport *transport); @@ -170,9 +172,14 @@ void transport_update_tracking_ref(struct remote *remote, struct ref *ref, int v int transport_refs_pushed(struct ref *ref); void transport_print_push_status(const char *dest, struct ref *refs, - int verbose, int porcelain, int *nonfastforward); + int verbose, int porcelain, unsigned int *reject_reasons); typedef void alternate_ref_fn(const struct ref *, void *); extern void for_each_alternate_ref(alternate_ref_fn, void *); +struct send_pack_args; +extern int send_pack(struct send_pack_args *args, + int fd[], struct child_process *conn, + struct ref *remote_refs, + struct extra_have_objects *extra_have); #endif diff --git a/tree-walk.c b/tree-walk.c index 492c7cd..6e30ef9 100644 --- a/tree-walk.c +++ b/tree-walk.c @@ -490,11 +490,11 @@ int get_tree_entry(const unsigned char *tree_sha1, const char *name, unsigned ch static int match_entry(const struct name_entry *entry, int pathlen, const char *match, int matchlen, - int *never_interesting) + enum interesting *never_interesting) { int m = -1; /* signals that we haven't called strncmp() */ - if (*never_interesting) { + if (*never_interesting != entry_not_interesting) { /* * We have not seen any match that sorts later * than the current path. @@ -522,7 +522,7 @@ static int match_entry(const struct name_entry *entry, int pathlen, * the variable to -1 and that is what will be * returned, allowing the caller to terminate early. */ - *never_interesting = 0; + *never_interesting = entry_not_interesting; } if (pathlen > matchlen) @@ -573,6 +573,54 @@ static int match_dir_prefix(const char *base, } /* + * Perform matching on the leading non-wildcard part of + * pathspec. item->nowildcard_len must be greater than zero. Return + * non-zero if base is matched. + */ +static int match_wildcard_base(const struct pathspec_item *item, + const char *base, int baselen, + int *matched) +{ + const char *match = item->match; + /* the wildcard part is not considered in this function */ + int matchlen = item->nowildcard_len; + + if (baselen) { + int dirlen; + /* + * Return early if base is longer than the + * non-wildcard part but it does not match. + */ + if (baselen >= matchlen) { + *matched = matchlen; + return !strncmp(base, match, matchlen); + } + + dirlen = matchlen; + while (dirlen && match[dirlen - 1] != '/') + dirlen--; + + /* + * Return early if base is shorter than the + * non-wildcard part but it does not match. Note that + * base ends with '/' so we are sure it really matches + * directory + */ + if (strncmp(base, match, baselen)) + return 0; + *matched = baselen; + } else + *matched = 0; + /* + * we could have checked entry against the non-wildcard part + * that is not in base and does similar never_interesting + * optimization as in match_entry. For now just be happy with + * base comparison. + */ + return entry_interesting; +} + +/* * Is a tree entry interesting given the pathspec we have? * * Pre-condition: either baselen == base_offset (i.e. empty path) @@ -584,7 +632,7 @@ enum interesting tree_entry_interesting(const struct name_entry *entry, { int i; int pathlen, baselen = base->len - base_offset; - int never_interesting = ps->has_wildcard ? + enum interesting never_interesting = ps->has_wildcard ? entry_not_interesting : all_entries_not_interesting; if (!ps->nr) { @@ -602,7 +650,7 @@ enum interesting tree_entry_interesting(const struct name_entry *entry, const struct pathspec_item *item = ps->items+i; const char *match = item->match; const char *base_str = base->buf + base_offset; - int matchlen = item->len; + int matchlen = item->len, matched = 0; if (baselen >= matchlen) { /* If it doesn't match, move along... */ @@ -626,8 +674,10 @@ enum interesting tree_entry_interesting(const struct name_entry *entry, &never_interesting)) return entry_interesting; - if (item->use_wildcard) { - if (!fnmatch(match + baselen, entry->path, 0)) + if (item->nowildcard_len < item->len) { + if (!git_fnmatch(match + baselen, entry->path, + item->flags & PATHSPEC_ONESTAR ? GFNM_ONESTAR : 0, + item->nowildcard_len - baselen)) return entry_interesting; /* @@ -642,17 +692,34 @@ enum interesting tree_entry_interesting(const struct name_entry *entry, } match_wildcards: - if (!item->use_wildcard) + if (item->nowildcard_len == item->len) continue; + if (item->nowildcard_len && + !match_wildcard_base(item, base_str, baselen, &matched)) + return entry_not_interesting; + /* * Concatenate base and entry->path into one and do * fnmatch() on it. + * + * While we could avoid concatenation in certain cases + * [1], which saves a memcpy and potentially a + * realloc, it turns out not worth it. Measurement on + * linux-2.6 does not show any clear improvements, + * partly because of the nowildcard_len optimization + * in git_fnmatch(). Avoid micro-optimizations here. + * + * [1] if match_wildcard_base() says the base + * directory is already matched, we only need to match + * the rest, which is shorter so _in theory_ faster. */ strbuf_add(base, entry->path, pathlen); - if (!fnmatch(match, base->buf + base_offset, 0)) { + if (!git_fnmatch(match, base->buf + base_offset, + item->flags & PATHSPEC_ONESTAR ? GFNM_ONESTAR : 0, + item->nowildcard_len)) { strbuf_setlen(base, base_offset + baselen); return entry_interesting; } diff --git a/unpack-trees.c b/unpack-trees.c index 6d96366..61acc5e 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -1834,7 +1834,7 @@ int oneway_merge(struct cache_entry **src, struct unpack_trees_options *o) if (old && same(old, a)) { int update = 0; - if (o->reset && !ce_uptodate(old) && !ce_skip_worktree(old)) { + if (o->reset && o->update && !ce_uptodate(old) && !ce_skip_worktree(old)) { struct stat st; if (lstat(old->name, &st) || ie_match_stat(o->src_index, old, &st, CE_MATCH_IGNORE_VALID|CE_MATCH_IGNORE_SKIP_WORKTREE)) diff --git a/upload-pack.c b/upload-pack.c index 2e90ccb..6142421 100644 --- a/upload-pack.c +++ b/upload-pack.c @@ -727,12 +727,7 @@ static int send_ref(const char *refname, const unsigned char *sha1, int flag, vo " include-tag multi_ack_detailed"; struct object *o = lookup_unknown_object(sha1); const char *refname_nons = strip_namespace(refname); - - if (o->type == OBJ_NONE) { - o->type = sha1_object_info(sha1, NULL); - if (o->type < 0) - die("git upload-pack: cannot find object %s:", sha1_to_hex(sha1)); - } + unsigned char peeled[20]; if (capabilities) packet_write(1, "%s %s%c%s%s agent=%s\n", @@ -747,11 +742,8 @@ static int send_ref(const char *refname, const unsigned char *sha1, int flag, vo o->flags |= OUR_REF; nr_our_refs++; } - if (o->type == OBJ_TAG) { - o = deref_tag_noverify(o); - if (o) - packet_write(1, "%s %s^{}\n", sha1_to_hex(o->sha1), refname_nons); - } + if (!peel_ref(refname, peeled)) + packet_write(1, "%s %s^{}\n", sha1_to_hex(peeled), refname_nons); return 0; } @@ -6,6 +6,8 @@ #include "git-compat-util.h" #include "cache.h" +static int dying; + void vreportf(const char *prefix, const char *err, va_list params) { char msg[4096]; @@ -82,6 +84,12 @@ void NORETURN die(const char *err, ...) { va_list params; + if (dying) { + fputs("fatal: recursion detected in die handler\n", stderr); + exit(128); + } + dying = 1; + va_start(params, err); die_routine(err, params); va_end(params); @@ -94,6 +102,13 @@ void NORETURN die_errno(const char *fmt, ...) char str_error[256], *err; int i, j; + if (dying) { + fputs("fatal: recursion detected in die_errno handler\n", + stderr); + exit(128); + } + dying = 1; + err = strerror(errno); for (i = j = 0; err[i] && j < sizeof(str_error) - 1; ) { if ((str_error[j++] = err[i++]) != '%') @@ -115,6 +130,7 @@ void NORETURN die_errno(const char *fmt, ...) va_end(params); } +#undef error int error(const char *err, ...) { va_list params; @@ -323,7 +323,7 @@ static size_t display_mode_esc_sequence_len(const char *s) * If indent is negative, assume that already -indent columns have been * consumed (and no extra indent is necessary for the first line). */ -int strbuf_add_wrapped_text(struct strbuf *buf, +void strbuf_add_wrapped_text(struct strbuf *buf, const char *text, int indent1, int indent2, int width) { int indent, w, assume_utf8 = 1; @@ -332,7 +332,7 @@ int strbuf_add_wrapped_text(struct strbuf *buf, if (width <= 0) { strbuf_add_indented_text(buf, text, indent1, indent2); - return 1; + return; } retry: @@ -356,14 +356,14 @@ retry: if (w <= width || !space) { const char *start = bol; if (!c && text == start) - return w; + return; if (space) start = space; else strbuf_addchars(buf, ' ', indent); strbuf_add(buf, start, text - start); if (!c) - return w; + return; space = text; if (c == '\t') w |= 0x07; @@ -405,13 +405,12 @@ new_line: } } -int strbuf_add_wrapped_bytes(struct strbuf *buf, const char *data, int len, +void strbuf_add_wrapped_bytes(struct strbuf *buf, const char *data, int len, int indent, int indent2, int width) { char *tmp = xstrndup(data, len); - int r = strbuf_add_wrapped_text(buf, tmp, indent, indent2, width); + strbuf_add_wrapped_text(buf, tmp, indent, indent2, width); free(tmp); - return r; } int is_encoding_utf8(const char *name) @@ -9,9 +9,9 @@ int is_utf8(const char *text); int is_encoding_utf8(const char *name); int same_encoding(const char *, const char *); -int strbuf_add_wrapped_text(struct strbuf *buf, +void strbuf_add_wrapped_text(struct strbuf *buf, const char *text, int indent, int indent2, int width); -int strbuf_add_wrapped_bytes(struct strbuf *buf, const char *data, int len, +void strbuf_add_wrapped_bytes(struct strbuf *buf, const char *data, int len, int indent, int indent2, int width); #ifndef NO_ICONV diff --git a/vcs-svn/fast_export.c b/vcs-svn/fast_export.c index 1f04697..f2b23c8 100644 --- a/vcs-svn/fast_export.c +++ b/vcs-svn/fast_export.c @@ -3,8 +3,7 @@ * See LICENSE for details. */ -#include "git-compat-util.h" -#include "strbuf.h" +#include "cache.h" #include "quote.h" #include "fast_export.h" #include "repo_tree.h" @@ -68,11 +67,33 @@ void fast_export_modify(const char *path, uint32_t mode, const char *dataref) putchar('\n'); } +void fast_export_begin_note(uint32_t revision, const char *author, + const char *log, unsigned long timestamp, const char *note_ref) +{ + static int firstnote = 1; + size_t loglen = strlen(log); + printf("commit %s\n", note_ref); + printf("committer %s <%s@%s> %ld +0000\n", author, author, "local", timestamp); + printf("data %"PRIuMAX"\n", (uintmax_t)loglen); + fwrite(log, loglen, 1, stdout); + if (firstnote) { + if (revision > 1) + printf("from %s^0", note_ref); + firstnote = 0; + } + fputc('\n', stdout); +} + +void fast_export_note(const char *committish, const char *dataref) +{ + printf("N %s %s\n", dataref, committish); +} + static char gitsvnline[MAX_GITSVN_LINE_LEN]; void fast_export_begin_commit(uint32_t revision, const char *author, const struct strbuf *log, const char *uuid, const char *url, - unsigned long timestamp) + unsigned long timestamp, const char *local_ref) { static const struct strbuf empty = STRBUF_INIT; if (!log) @@ -84,7 +105,7 @@ void fast_export_begin_commit(uint32_t revision, const char *author, } else { *gitsvnline = '\0'; } - printf("commit refs/heads/master\n"); + printf("commit %s\n", local_ref); printf("mark :%"PRIu32"\n", revision); printf("committer %s <%s@%s> %ld +0000\n", *author ? author : "nobody", @@ -222,6 +243,13 @@ static long apply_delta(off_t len, struct line_buffer *input, return ret; } +void fast_export_buf_to_data(const struct strbuf *data) +{ + printf("data %"PRIuMAX"\n", (uintmax_t)data->len); + fwrite(data->buf, data->len, 1, stdout); + fputc('\n', stdout); +} + void fast_export_data(uint32_t mode, off_t len, struct line_buffer *input) { assert(len >= 0); diff --git a/vcs-svn/fast_export.h b/vcs-svn/fast_export.h index 8823aca..c8b5adb 100644 --- a/vcs-svn/fast_export.h +++ b/vcs-svn/fast_export.h @@ -9,11 +9,15 @@ void fast_export_deinit(void); void fast_export_delete(const char *path); void fast_export_modify(const char *path, uint32_t mode, const char *dataref); +void fast_export_note(const char *committish, const char *dataref); +void fast_export_begin_note(uint32_t revision, const char *author, + const char *log, unsigned long timestamp, const char *note_ref); void fast_export_begin_commit(uint32_t revision, const char *author, - const struct strbuf *log, const char *uuid, - const char *url, unsigned long timestamp); + const struct strbuf *log, const char *uuid,const char *url, + unsigned long timestamp, const char *local_ref); void fast_export_end_commit(uint32_t revision); void fast_export_data(uint32_t mode, off_t len, struct line_buffer *input); +void fast_export_buf_to_data(const struct strbuf *data); void fast_export_blob_delta(uint32_t mode, uint32_t old_mode, const char *old_data, off_t len, struct line_buffer *input); diff --git a/vcs-svn/svndump.c b/vcs-svn/svndump.c index 2b168ae..31d1d83 100644 --- a/vcs-svn/svndump.c +++ b/vcs-svn/svndump.c @@ -48,7 +48,7 @@ static struct { static struct { uint32_t revision; unsigned long timestamp; - struct strbuf log, author; + struct strbuf log, author, note; } rev_ctx; static struct { @@ -77,6 +77,7 @@ static void reset_rev_ctx(uint32_t revision) rev_ctx.timestamp = 0; strbuf_reset(&rev_ctx.log); strbuf_reset(&rev_ctx.author); + strbuf_reset(&rev_ctx.note); } static void reset_dump_ctx(const char *url) @@ -299,22 +300,29 @@ static void handle_node(void) node_ctx.text_length, &input); } -static void begin_revision(void) +static void begin_revision(const char *remote_ref) { if (!rev_ctx.revision) /* revision 0 gets no git commit. */ return; fast_export_begin_commit(rev_ctx.revision, rev_ctx.author.buf, &rev_ctx.log, dump_ctx.uuid.buf, dump_ctx.url.buf, - rev_ctx.timestamp); + rev_ctx.timestamp, remote_ref); } -static void end_revision(void) +static void end_revision(const char *note_ref) { - if (rev_ctx.revision) + struct strbuf mark = STRBUF_INIT; + if (rev_ctx.revision) { fast_export_end_commit(rev_ctx.revision); + fast_export_begin_note(rev_ctx.revision, "remote-svn", + "Note created by remote-svn.", rev_ctx.timestamp, note_ref); + strbuf_addf(&mark, ":%"PRIu32, rev_ctx.revision); + fast_export_note(mark.buf, "inline"); + fast_export_buf_to_data(&rev_ctx.note); + } } -void svndump_read(const char *url) +void svndump_read(const char *url, const char *local_ref, const char *notes_ref) { char *val; char *t; @@ -353,11 +361,12 @@ void svndump_read(const char *url) if (active_ctx == NODE_CTX) handle_node(); if (active_ctx == REV_CTX) - begin_revision(); + begin_revision(local_ref); if (active_ctx != DUMP_CTX) - end_revision(); + end_revision(notes_ref); active_ctx = REV_CTX; reset_rev_ctx(atoi(val)); + strbuf_addf(&rev_ctx.note, "%s\n", t); break; case sizeof("Node-path"): if (constcmp(t, "Node-")) @@ -366,13 +375,15 @@ void svndump_read(const char *url) if (active_ctx == NODE_CTX) handle_node(); if (active_ctx == REV_CTX) - begin_revision(); + begin_revision(local_ref); active_ctx = NODE_CTX; reset_node_ctx(val); + strbuf_addf(&rev_ctx.note, "%s\n", t); break; } if (constcmp(t + strlen("Node-"), "kind")) continue; + strbuf_addf(&rev_ctx.note, "%s\n", t); if (!strcmp(val, "dir")) node_ctx.type = REPO_MODE_DIR; else if (!strcmp(val, "file")) @@ -383,6 +394,7 @@ void svndump_read(const char *url) case sizeof("Node-action"): if (constcmp(t, "Node-action")) continue; + strbuf_addf(&rev_ctx.note, "%s\n", t); if (!strcmp(val, "delete")) { node_ctx.action = NODEACT_DELETE; } else if (!strcmp(val, "add")) { @@ -401,11 +413,13 @@ void svndump_read(const char *url) continue; strbuf_reset(&node_ctx.src); strbuf_addstr(&node_ctx.src, val); + strbuf_addf(&rev_ctx.note, "%s\n", t); break; case sizeof("Node-copyfrom-rev"): if (constcmp(t, "Node-copyfrom-rev")) continue; node_ctx.srcRev = atoi(val); + strbuf_addf(&rev_ctx.note, "%s\n", t); break; case sizeof("Text-content-length"): if (constcmp(t, "Text") && constcmp(t, "Prop")) @@ -463,25 +477,40 @@ void svndump_read(const char *url) if (active_ctx == NODE_CTX) handle_node(); if (active_ctx == REV_CTX) - begin_revision(); + begin_revision(local_ref); if (active_ctx != DUMP_CTX) - end_revision(); + end_revision(notes_ref); } -int svndump_init(const char *filename) +static void init(int report_fd) { - if (buffer_init(&input, filename)) - return error("cannot open %s: %s", filename, strerror(errno)); - fast_export_init(REPORT_FILENO); + fast_export_init(report_fd); strbuf_init(&dump_ctx.uuid, 4096); strbuf_init(&dump_ctx.url, 4096); strbuf_init(&rev_ctx.log, 4096); strbuf_init(&rev_ctx.author, 4096); + strbuf_init(&rev_ctx.note, 4096); strbuf_init(&node_ctx.src, 4096); strbuf_init(&node_ctx.dst, 4096); reset_dump_ctx(NULL); reset_rev_ctx(0); reset_node_ctx(NULL); + return; +} + +int svndump_init(const char *filename) +{ + if (buffer_init(&input, filename)) + return error("cannot open %s: %s", filename ? filename : "NULL", strerror(errno)); + init(REPORT_FILENO); + return 0; +} + +int svndump_init_fd(int in_fd, int back_fd) +{ + if(buffer_fdinit(&input, xdup(in_fd))) + return error("cannot open fd %d: %s", in_fd, strerror(errno)); + init(xdup(back_fd)); return 0; } @@ -492,6 +521,8 @@ void svndump_deinit(void) reset_rev_ctx(0); reset_node_ctx(NULL); strbuf_release(&rev_ctx.log); + strbuf_release(&rev_ctx.author); + strbuf_release(&rev_ctx.note); strbuf_release(&node_ctx.src); strbuf_release(&node_ctx.dst); if (buffer_deinit(&input)) diff --git a/vcs-svn/svndump.h b/vcs-svn/svndump.h index df9ceb0..b8eb129 100644 --- a/vcs-svn/svndump.h +++ b/vcs-svn/svndump.h @@ -2,7 +2,8 @@ #define SVNDUMP_H_ int svndump_init(const char *filename); -void svndump_read(const char *url); +int svndump_init_fd(int in_fd, int back_fd); +void svndump_read(const char *url, const char *local_ref, const char *notes_ref); void svndump_deinit(void); void svndump_reset(void); @@ -229,7 +229,7 @@ int xmkstemp(char *template) int saved_errno = errno; const char *nonrelative_template; - if (!template[0]) + if (strlen(template) != strlen(origtemplate)) template = origtemplate; nonrelative_template = absolute_path(template); @@ -411,11 +411,19 @@ void warn_on_inaccessible(const char *path) int access_or_warn(const char *path, int mode) { int ret = access(path, mode); - if (ret && errno != ENOENT) + if (ret && errno != ENOENT && errno != ENOTDIR) warn_on_inaccessible(path); return ret; } +int access_or_die(const char *path, int mode) +{ + int ret = access(path, mode); + if (ret && errno != ENOENT && errno != ENOTDIR) + die_errno(_("unable to access '%s'"), path); + return ret; +} + struct passwd *xgetpwuid_self(void) { struct passwd *pw; diff --git a/write_or_die.c b/write_or_die.c index d45b536..960f448 100644 --- a/write_or_die.c +++ b/write_or_die.c @@ -34,12 +34,7 @@ void maybe_flush_or_die(FILE *f, const char *desc) return; } if (fflush(f)) { - /* - * On Windows, EPIPE is returned only by the first write() - * after the reading end has closed its handle; subsequent - * write()s return EINVAL. - */ - if (errno == EPIPE || errno == EINVAL) + if (errno == EPIPE) exit(0); die_errno("write failure on '%s'", desc); } |