From: Junio C Hamano Date: Mon, 9 Sep 2013 21:50:37 +0000 (-0700) Subject: Merge branch 'jc/transport-do-not-use-connect-twice-in-fetch' X-Git-Tag: v1.8.5-rc0~162 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/20419de969b8ce0c49d133affdb1bb73eb62815e?hp=0f73f8bd7974fcf7f9e4608875323c96c6159829 Merge branch 'jc/transport-do-not-use-connect-twice-in-fetch' The auto-tag-following code in "git fetch" tries to reuse the same transport twice when the serving end does not cooperate and does not give tags that point to commits that are asked for as part of the primary transfer. Unfortunately, Git-aware transport helper interface is not designed to be used more than once, hence this does not work over smart-http transfer. * jc/transport-do-not-use-connect-twice-in-fetch: builtin/fetch.c: Fix a sparse warning fetch: work around "transport-take-over" hack fetch: refactor code that fetches leftover tags fetch: refactor code that prepares a transport fetch: rename file-scope global "transport" to "gtransport" t5802: add test for connect helper --- diff --git a/.gitignore b/.gitignore index 6b1fd1bfb0..66199edd4a 100644 --- a/.gitignore +++ b/.gitignore @@ -202,6 +202,7 @@ /test-string-list /test-subprocess /test-svn-fe +/test-urlmatch-normalization /test-wildmatch /common-cmds.h *.tar.gz diff --git a/.mailmap b/.mailmap index dfa2e65348..1c1f5ec6bf 100644 --- a/.mailmap +++ b/.mailmap @@ -14,13 +14,18 @@ Alex Riesen Alex Vandiver Alexander Gavrilov Alexey Shumkin +Alexey Shumkin Anders Kaseorg Anders Kaseorg Aneesh Kumar K.V +Amos Waterland +Amos Waterland Ben Walton +Benoit Sigoure Bernt Hansen Brandon Casey -Brian M. Carlson +brian m. carlson Brian M. Carlson +brian m. carlson Bryan Larsen Bryan Larsen Cheng Renquan @@ -31,7 +36,10 @@ Christian Stimming Csaba Henk Dan Johnson Dana L. How +Dana L. How Dana How Daniel Barkalow +Daniel Trstenjak +Daniel Trstenjak David Brown David D. Kilzer David KÃ¥gedal @@ -65,11 +73,18 @@ J. Bruce Fields J. Bruce Fields J. Bruce Fields Jakub Narębski +James Y Knight +# The 2 following authors are probably the same person, +# but both emails bounce. +Jason McMullan +Jason McMullan Jason Riedy Jason Riedy Jay Soffian Jeff King Jeff Muizelaar +Jens Axboe +Jens Axboe Jim Meyering Joachim Berdal Haga Johannes Schindelin @@ -92,8 +107,8 @@ Junio C Hamano Junio C Hamano Junio C Hamano Junio C Hamano -Karl Wiberg Karl Hasselström -Karl Wiberg Karl Hasselström +Karl Wiberg Karl Hasselström +Karl Wiberg Karsten Blees Karsten Blees Kay Sievers @@ -141,7 +156,7 @@ Michele Ballabio Miklos Vajna Namhyung Kim Namhyung Kim -Nanako Shiraishi +Nanako Shiraishi Nanako Shiraishi Nelson Elhage Nelson Elhage @@ -174,9 +189,12 @@ Robert Fitzsimons Robert Shearman Robert Zeh Robin Rosenberg +Rutger Nijlunsing +Rutger Nijlunsing Ryan Anderson Salikh Zakirov Sam Vilain +Sam Vilain sam@vilain.net Santi Béjar Sean Estabrooks Sebastian Schuberth @@ -191,6 +209,7 @@ Stefan Sperling Stephen Boyd Steven Drake Steven Grimm +Steven Grimm koreth@midwinter.com Steven Walter Steven Walter Sven Verdoolaege diff --git a/Documentation/CodingGuidelines b/Documentation/CodingGuidelines index 559d5f9ebf..e5ca3b75d3 100644 --- a/Documentation/CodingGuidelines +++ b/Documentation/CodingGuidelines @@ -242,6 +242,14 @@ Writing Documentation: processed into HTML and manpages (e.g. git.html and git.1 in the same directory). + The documentation liberally mixes US and UK English (en_US/UK) + norms for spelling and grammar, which is somewhat unfortunate. + In an ideal world, it would have been better if it consistently + used only one and not the other, and we would have picked en_US + (if you wish to correct the English of some of the existing + documentation, please see the documentation-related advice in the + Documentation/SubmittingPatches file). + Every user-visible change should be reflected in the documentation. The same general rule as for code applies -- imitate the existing conventions. A few commented examples follow to provide reference diff --git a/Documentation/RelNotes/1.8.4.txt b/Documentation/RelNotes/1.8.4.txt index b4f8737c5a..02f681b710 100644 --- a/Documentation/RelNotes/1.8.4.txt +++ b/Documentation/RelNotes/1.8.4.txt @@ -198,9 +198,6 @@ UI, Workflows & Features response was to stash them and re-run). This introduced a corner case breakage to "git am --abort" but it has been fixed. - * Instead of typing four capital letters "HEAD", you can say "@" now, - e.g. "git log @". - * "check-ignore" (new feature since 1.8.2) has been updated to work more like "check-attr" over bidi-pipes. @@ -242,6 +239,13 @@ UI, Workflows & Features Performance, Internal Implementation, etc. + * On Cygwin, we used to use our own lstat(2) emulation that is + allegedly faster than the platform one in codepaths where some of + the information it returns did not matter, but it started to bite + us in a few codepaths where the trick it uses to cheat does show + breakages. This emulation has been removed and we use the native + lstat(2) emulation supplied by Cygwin now. + * The function attributes extensions are used to catch mistakes in use of our own variadic functions that use NULL sentinel at the end (i.e. like execl(3)) and format strings (i.e. like printf(3)). @@ -263,7 +267,7 @@ Performance, Internal Implementation, etc. been susceptible to lossage of refs under right conditions, which has been tightened up. - * We read loose and packed rerferences in two steps, but after + * We read loose and packed references in two steps, but after deciding to read a loose ref but before actually opening it to read it, another process racing with us can unlink it, which would cause us to barf. The codepath has been updated to retry when such a @@ -365,12 +369,6 @@ details). the user to an unexpected place. (merge 3bed291 rr/rebase-checkout-reflog later to maint). - * "git stash save", when your local change turns a tracked file into - a directory, has to remove files in that directory in order to - revert your working tree to a pristine state. This will lose - untracked files in such a directory, and the command now requires - you to "--force" it. - * The configuration variable column.ui was poorly documented. (merge 5e62cc1 rr/column-doc later to maint). @@ -381,7 +379,7 @@ details). * "git apply" parsed patches that add new files, generated by programs other than Git, incorrectly. This is an old breakage in - v1.7.11 and will need to be merged down to the maintanance tracks. + v1.7.11 and will need to be merged down to the maintenance tracks. * Older cURL wanted piece of memory we call it with to be stable, but we updated the auth material after handing it to a call. diff --git a/Documentation/RelNotes/1.8.5.txt b/Documentation/RelNotes/1.8.5.txt new file mode 100644 index 0000000000..3b43a61d85 --- /dev/null +++ b/Documentation/RelNotes/1.8.5.txt @@ -0,0 +1,130 @@ +Git v1.8.5 Release Notes +======================== + +Backward compatibility notes (for Git 2.0) +------------------------------------------ + +When "git push [$there]" does not say what to push, we have used the +traditional "matching" semantics so far (all your branches were sent +to the remote as long as there already are branches of the same name +over there). In Git 2.0, the default will change to the "simple" +semantics that pushes: + + - only the current branch to the branch with the same name, and only + when the current branch is set to integrate with that remote + branch, if you are pushing to the same remote as you fetch from; or + + - only the current branch to the branch with the same name, if you + are pushing to a remote that is not where you usually fetch from. + +Use the user preference configuration variable "push.default" to +change this. If you are an old-timer who is used to the "matching" +semantics, you can set the variable to "matching" to keep the +traditional behaviour. If you want to live in the future early, you +can set it to "simple" today without waiting for Git 2.0. + +When "git add -u" (and "git add -A") is run inside a subdirectory and +does not specify which paths to add on the command line, it +will operate on the entire tree in Git 2.0 for consistency +with "git commit -a" and other commands. There will be no +mechanism to make plain "git add -u" behave like "git add -u .". +Current users of "git add -u" (without a pathspec) should start +training their fingers to explicitly say "git add -u ." +before Git 2.0 comes. A warning is issued when these commands are +run without a pathspec and when you have local changes outside the +current directory, because the behaviour in Git 2.0 will be different +from today's version in such a situation. + +In Git 2.0, "git add " will behave as "git add -A ", so +that "git add dir/" will notice paths you removed from the directory +and record the removal. Versions before Git 2.0, including this +release, will keep ignoring removals, but the users who rely on this +behaviour are encouraged to start using "git add --ignore-removal " +now before 2.0 is released. + + +Updates since v1.8.4 +-------------------- + +Foreign interfaces, subsystems and ports. + + * remote-hg remote helper misbehaved when interacting with a local Hg + repository relative to the home directory, e.g. "clone hg::~/there". + + * imap-send ported to OS X uses Apple's security framework instead of + OpenSSL one. + + * Subversion 1.8.0 that was recently released breaks older subversion + clients coming over http/https in various ways. + + * "git fast-import" treats an empty path given to "ls" as the root of + the tree. + + +UI, Workflows & Features + + * "git check-ignore -z" applied the NUL termination to both its input + (with --stdin) and its output, but "git check-attr -z" ignored the + option on the output side. Make both honor -z on the input and + output side the same way. + + * "git whatchanged" may still be used by old timers, but mention of + it in documents meant for new users will only waste readers' time + wonderig what the difference is between it and "git log". Make it + less prominent in the general part of the documentation and explain + that it is merely a "git log" with different default behaviour in + its own document. + + +Performance, Internal Implementation, etc. + + * Many commands use --dashed-option as a operation mode selector + (e.g. "git tag --delete") that the user can use at most one + (e.g. "git tag --delete --verify" is a nonsense) and you cannot + negate (e.g. "git tag --no-delete" is a nonsense). parse-options + API learned a new OPT_CMDMODE macro to make it easier to implement + such a set of options. + + * OPT_BOOLEAN() in parse-options API was misdesigned to be "counting + up" but many subcommands expect it to behave as "on/off". Update + them to use OPT_BOOL() which is a proper boolean. + + * "git gc" exits early without doing a double-work when it detects + that another instance of itself is already running. + + * Under memory pressure and/or file descriptor pressure, we used to + close pack windows that are not used and also closed filehandle to + an open but unused packfiles. These are now controlled separately + to better cope with the load. + +Also contains various documentation updates and code clean-ups. + + +Fixes since v1.8.4 +------------------ + +Unless otherwise noted, all the fixes since v1.8.4 in the maintenance +track are contained in this release (see release notes to them for +details). + + * Setting submodule.*.path configuration variable to true (without + giving "= value") caused Git to segfault. + (merge 4b05440 jl/some-submodule-config-are-not-boolean later to maint). + + * "git rebase -i" (there could be others, as the root cause is pretty + generic) fed a random, data dependeant string to 'echo' and + expects it to come out literally, corrupting its error message. + (merge 89b0230 mm/no-shell-escape-in-die-message later to maint). + + * Some people still use rather old versions of bash, which cannot + grok some constructs like 'printf -v varname' the prompt and + completion code started to use recently. + (merge a44aa69 bc/completion-for-bash-3.0 later to maint). + + * Code to read configuration from a blob object did not compile on + platforms with fgetc() etc. implemented as macros. + (merge 49d6cfa hv/config-from-blob later to maint-1.8.3). + + * The recent "short-cut clone connectivity check" topic broke a + shallow repository when a fetch operation tries to auto-follow tags. + (merge 6da8bdc nd/fetch-pack-shallow-fix later to maint-1.8.3). diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches index d0a4733e45..705557689d 100644 --- a/Documentation/SubmittingPatches +++ b/Documentation/SubmittingPatches @@ -65,7 +65,20 @@ feature does not trigger when it shouldn't. Also make sure that the test suite passes after your commit. Do not forget to update the documentation to describe the updated behaviour. -Oh, another thing. I am picky about whitespaces. Make sure your +Speaking of the documentation, it is currently a liberal mixture of US +and UK English norms for spelling and grammar, which is somewhat +unfortunate. A huge patch that touches the files all over the place +only to correct the inconsistency is not welcome, though. Potential +clashes with other changes that can result from such a patch are not +worth it. We prefer to gradually reconcile the inconsistencies in +favor of US English, with small and easily digestible patches, as a +side effect of doing some other real work in the vicinity (e.g. +rewriting a paragraph for clarity, while turning en_UK spelling to +en_US). Obvious typographical fixes are much more welcomed ("teh -> +"the"), preferably submitted as independent patches separate from +other documentation changes. + +Oh, another thing. We are picky about whitespaces. Make sure your changes do not trigger errors with the sample pre-commit hook shipped in templates/hooks--pre-commit. To help ensure this does not happen, run git diff --check on your changes before you commit. diff --git a/Documentation/blame-options.txt b/Documentation/blame-options.txt index 4e55b1564e..0cebc4f692 100644 --- a/Documentation/blame-options.txt +++ b/Documentation/blame-options.txt @@ -11,12 +11,12 @@ -L ,:: -L ::: - Annotate only the given line range. and are optional. - ``-L '' or ``-L ,'' spans from to end of file. - ``-L ,'' spans from start of file to . + Annotate only the given line range. May be specified multiple times. + Overlapping ranges are allowed. ++ + and are optional. ``-L '' or ``-L ,'' spans from + to end of file. ``-L ,'' spans from start of file to . + - and can take one of these forms: - include::line-range-format.txt[] -l:: diff --git a/Documentation/config.txt b/Documentation/config.txt index ec57a15ac5..00bde9dec5 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -1061,6 +1061,10 @@ fetch.unpackLimit:: especially on slow filesystems. If not set, the value of `transfer.unpackLimit` is used instead. +fetch.prune:: + If true, fetch will automatically behave as if the `--prune` + option was given on the command line. See also `remote..prune`. + format.attach:: Enable multipart/mixed attachments as the default for 'format-patch'. The value can also be a double quoted string @@ -1445,7 +1449,11 @@ http.cookiefile:: of the file to read cookies from should be plain HTTP headers or the Netscape/Mozilla cookie file format (see linkgit:curl[1]). NOTE that the file specified with http.cookiefile is only used as - input. No cookies will be stored in the file. + input unless http.saveCookies is set. + +http.savecookies:: + If set, store cookies received during requests to the file specified by + http.cookiefile. Has no effect if http.cookiefile is unset. http.sslVerify:: Whether to verify the SSL certificate when fetching or pushing @@ -1525,6 +1533,51 @@ http.useragent:: of common USER_AGENT strings (but not including those like git/1.7.1). Can be overridden by the 'GIT_HTTP_USER_AGENT' environment variable. +http..*:: + Any of the http.* options above can be applied selectively to some urls. + For a config key to match a URL, each element of the config key is + compared to that of the URL, in the following order: ++ +-- +. Scheme (e.g., `https` in `https://example.com/`). This field + must match exactly between the config key and the URL. + +. Host/domain name (e.g., `example.com` in `https://example.com/`). + This field must match exactly between the config key and the URL. + +. Port number (e.g., `8080` in `http://example.com:8080/`). + This field must match exactly between the config key and the URL. + Omitted port numbers are automatically converted to the correct + default for the scheme before matching. + +. Path (e.g., `repo.git` in `https://example.com/repo.git`). The + path field of the config key must match the path field of the URL + either exactly or as a prefix of slash-delimited path elements. This means + a config key with path `foo/` matches URL path `foo/bar`. A prefix can only + match on a slash (`/`) boundary. Longer matches take precedence (so a config + key with path `foo/bar` is a better match to URL path `foo/bar` than a config + key with just path `foo/`). + +. User name (e.g., `user` in `https://user@example.com/repo.git`). If + the config key has a user name it must match the user name in the + URL exactly. If the config key does not have a user name, that + config key will match a URL with any user name (including none), + but at a lower precedence than a config key with a user name. +-- ++ +The list above is ordered by decreasing precedence; a URL that matches +a config key's path is preferred to one that matches its user name. For example, +if the URL is `https://user@example.com/foo/bar` a config key match of +`https://example.com/foo` will be preferred over a config key match of +`https://user@example.com`. ++ +All URLs are normalized before attempting any matching (the password part, +if embedded in the URL, is always ignored for matching purposes) so that +equivalent urls that are simply spelled differently will match properly. +Environment variable settings always override any matches. The urls that are +matched against are those given directly to Git commands. This means any URLs +visited as a result of a redirection do not participate in matching. + i18n.commitEncoding:: Character encoding the commit messages are stored in; Git itself does not care per se, but this information is necessary e.g. when @@ -2024,6 +2077,12 @@ remote..vcs:: Setting this to a value will cause Git to interact with the remote with the git-remote- helper. +remote..prune:: + When set to true, fetching from this remote by default will also + remove any remote-tracking branches which no longer exist on the + remote (as if the `--prune` option was give on the command line). + Overrides `fetch.prune` settings, if any. + remotes.:: The list of remotes which are fetched by "git remote update ". See linkgit:git-remote[1]. diff --git a/Documentation/git-blame.txt b/Documentation/git-blame.txt index 6cea7f1ce1..f2c85cc633 100644 --- a/Documentation/git-blame.txt +++ b/Documentation/git-blame.txt @@ -9,7 +9,7 @@ SYNOPSIS -------- [verse] 'git blame' [-c] [-b] [-l] [--root] [-t] [-f] [-n] [-s] [-e] [-p] [-w] [--incremental] - [-L n,m | -L :fn] [-S ] [-M] [-C] [-C] [-C] [--since=] + [-L ] [-S ] [-M] [-C] [-C] [-C] [--since=] [--abbrev=] [ | --contents | --reverse ] [--] DESCRIPTION @@ -18,7 +18,8 @@ DESCRIPTION Annotates each line in the given file with information from the revision which last modified the line. Optionally, start annotating from the given revision. -The command can also limit the range of lines annotated. +When specified one or more times, `-L` restricts annotation to the requested +lines. The origin of lines is automatically followed across whole-file renames (currently there is no option to turn the rename-following @@ -130,7 +131,10 @@ SPECIFYING RANGES Unlike 'git blame' and 'git annotate' in older versions of git, the extent of the annotation can be limited to both line ranges and revision -ranges. When you are interested in finding the origin for +ranges. The `-L` option, which limits annotation to a range of lines, may be +specified multiple times. + +When you are interested in finding the origin for lines 40-60 for file `foo`, you can use the `-L` option like so (they mean the same thing -- both ask for 21 lines starting at line 40): diff --git a/Documentation/git-cat-file.txt b/Documentation/git-cat-file.txt index 10fbc6a373..21cffe2bcd 100644 --- a/Documentation/git-cat-file.txt +++ b/Documentation/git-cat-file.txt @@ -86,10 +86,9 @@ BATCH OUTPUT ------------ If `--batch` or `--batch-check` is given, `cat-file` will read objects -from stdin, one per line, and print information about them. - -Each line is considered as a whole object name, and is parsed as if -given to linkgit:git-rev-parse[1]. +from stdin, one per line, and print information about them. By default, +the whole line is considered as an object, as if it were fed to +linkgit:git-rev-parse[1]. You can specify the information shown for each object by using a custom ``. The `` is copied literally to stdout for each @@ -110,6 +109,13 @@ newline. The available atoms are: The size, in bytes, that the object takes up on disk. See the note about on-disk sizes in the `CAVEATS` section below. +`rest`:: + If this atom is used in the output string, input lines are split + at the first whitespace boundary. All characters before that + whitespace are considered to be the object name; characters + after that first run of whitespace (i.e., the "rest" of the + line) are output in place of the `%(rest)` atom. + If no format is specified, the default format is `%(objectname) %(objecttype) %(objectsize)`. diff --git a/Documentation/git-check-attr.txt b/Documentation/git-check-attr.txt index a7be80d48b..00e2aa2df2 100644 --- a/Documentation/git-check-attr.txt +++ b/Documentation/git-check-attr.txt @@ -31,8 +31,9 @@ OPTIONS Read file names from stdin instead of from the command-line. -z:: - Only meaningful with `--stdin`; paths are separated with a - NUL character instead of a linefeed character. + The output format is modified to be machine-parseable. + If `--stdin` is also given, input paths are separated + with a NUL character instead of a linefeed character. \--:: Interpret all preceding arguments as attributes and all following @@ -48,6 +49,10 @@ OUTPUT The output is of the form: COLON SP COLON SP LF +unless `-z` is in effect, in which case NUL is used as delimiter: + NUL NUL NUL + + is the path of a file being queried, is an attribute being queried and can be either: diff --git a/Documentation/git-check-ref-format.txt b/Documentation/git-check-ref-format.txt index fc02959ba4..a49be1bab4 100644 --- a/Documentation/git-check-ref-format.txt +++ b/Documentation/git-check-ref-format.txt @@ -54,8 +54,6 @@ Git imposes the following rules on how references are named: . They cannot contain a sequence `@{`. -. They cannot be the single character `@`. - . They cannot contain a `\`. These rules make it easy for shell script based tools to parse diff --git a/Documentation/git-config.txt b/Documentation/git-config.txt index 2dbe486eb1..e9917b89a9 100644 --- a/Documentation/git-config.txt +++ b/Documentation/git-config.txt @@ -15,6 +15,7 @@ SYNOPSIS 'git config' [] [type] [-z|--null] --get name [value_regex] 'git config' [] [type] [-z|--null] --get-all name [value_regex] 'git config' [] [type] [-z|--null] --get-regexp name_regex [value_regex] +'git config' [] [type] [-z|--null] --get-urlmatch name URL 'git config' [] --unset name [value_regex] 'git config' [] --unset-all name [value_regex] 'git config' [] --rename-section old_name new_name @@ -95,6 +96,14 @@ OPTIONS in which section and variable names are lowercased, but subsection names are not. +--get-urlmatch name URL:: + When given a two-part name section.key, the value for + section..key whose part matches the best to the + given URL is returned (if no such key exists, the value for + section.key is used as a fallback). When given just the + section as name, do so for all the keys in the section and + list them. + --global:: For writing options: write to global `~/.gitconfig` file rather than the repository `.git/config`, write to @@ -295,6 +304,13 @@ Given a .git/config like this: gitproxy=proxy-command for kernel.org gitproxy=default-proxy ; for all the rest + ; HTTP + [http] + sslVerify + [http "https://weak.example.com"] + sslVerify = false + cookieFile = /tmp/cookie.txt + you can set the filemode to true with ------------ @@ -380,6 +396,19 @@ RESET=$(git config --get-color "" "reset") echo "${WS}your whitespace color or blue reverse${RESET}" ------------ +For URLs in `https://weak.example.com`, `http.sslVerify` is set to +false, while it is set to `true` for all others: + +------------ +% git config --bool --get-urlmatch http.sslverify https://good.example.com +true +% git config --bool --get-urlmatch http.sslverify https://weak.example.com +false +% git config --get-urlmatch http https://weak.example.com +http.cookiefile /tmp/cookie.txt +http.sslverify false +------------ + include::config.txt[] GIT diff --git a/Documentation/git-fetch-pack.txt b/Documentation/git-fetch-pack.txt index 1e71754347..444b805d35 100644 --- a/Documentation/git-fetch-pack.txt +++ b/Documentation/git-fetch-pack.txt @@ -90,6 +90,10 @@ be in a separate packet, and the list must end with a flush packet. --no-progress:: Do not show the progress. +--check-self-contained-and-connected:: + Output "connectivity-ok" if the received pack is + self-contained and connected. + -v:: Run verbosely. diff --git a/Documentation/git-format-patch.txt b/Documentation/git-format-patch.txt index e394276b1a..9e0ef0eaf3 100644 --- a/Documentation/git-format-patch.txt +++ b/Documentation/git-format-patch.txt @@ -242,6 +242,7 @@ configuration options in linkgit:git-notes[1] to use this workflow). Note that the leading character does not have to be a dot; for example, you can use `--suffix=-patch` to get `0001-description-of-my-change-patch`. +-q:: --quiet:: Do not print the names of the generated files to standard output. diff --git a/Documentation/git-gc.txt b/Documentation/git-gc.txt index 2402ed6828..e158a3b31f 100644 --- a/Documentation/git-gc.txt +++ b/Documentation/git-gc.txt @@ -9,7 +9,7 @@ git-gc - Cleanup unnecessary files and optimize the local repository SYNOPSIS -------- [verse] -'git gc' [--aggressive] [--auto] [--quiet] [--prune= | --no-prune] +'git gc' [--aggressive] [--auto] [--quiet] [--prune= | --no-prune] [--force] DESCRIPTION ----------- @@ -72,6 +72,10 @@ automatic consolidation of packs. --quiet:: Suppress all progress reports. +--force:: + Force `git gc` to run even if there may be another `git gc` + instance running on this repository. + Configuration ------------- diff --git a/Documentation/git-log.txt b/Documentation/git-log.txt index ac2694d04c..34097efea7 100644 --- a/Documentation/git-log.txt +++ b/Documentation/git-log.txt @@ -62,7 +62,8 @@ produced by --stat etc. Note that only message is considered, if also a diff is shown its size is not included. --L ,:, -L :::: +-L ,::: +-L :::: Trace the evolution of the line range given by "," (or the funcname regex ) within the . You may @@ -71,8 +72,6 @@ produced by --stat etc. give zero or one positive revision arguments. You can specify this option more than once. + - and can take one of these forms: - include::line-range-format.txt[] :: diff --git a/Documentation/git-merge-file.txt b/Documentation/git-merge-file.txt index d7db2a3737..d2fc12ec77 100644 --- a/Documentation/git-merge-file.txt +++ b/Documentation/git-merge-file.txt @@ -11,7 +11,7 @@ SYNOPSIS [verse] 'git merge-file' [-L [-L [-L ]]] [--ours|--theirs|--union] [-p|--stdout] [-q|--quiet] [--marker-size=] - + [--[no-]diff3] DESCRIPTION @@ -66,6 +66,9 @@ OPTIONS -q:: Quiet; do not warn about conflicts. +--diff3:: + Show conflicts in "diff3" style. + --ours:: --theirs:: --union:: diff --git a/Documentation/git-merge.txt b/Documentation/git-merge.txt index 8c7f2f66d8..a74c3713c6 100644 --- a/Documentation/git-merge.txt +++ b/Documentation/git-merge.txt @@ -186,11 +186,11 @@ In such a case, you can "unwrap" the tag yourself before feeding it to `git merge`, or pass `--ff-only` when you do not have any work on your own. e.g. ---- +---- git fetch origin git merge v1.2.3^0 git merge --ff-only v1.2.3 ---- +---- HOW CONFLICTS ARE PRESENTED diff --git a/Documentation/git-mv.txt b/Documentation/git-mv.txt index e93fcb49fd..b1f79881ef 100644 --- a/Documentation/git-mv.txt +++ b/Documentation/git-mv.txt @@ -13,7 +13,7 @@ SYNOPSIS DESCRIPTION ----------- -This script is used to move or rename a file, directory or symlink. +Move or rename a file, directory or symlink. git mv [-v] [-f] [-n] [-k] git mv [-v] [-f] [-n] [-k] ... @@ -44,6 +44,14 @@ OPTIONS --verbose:: Report the names of files as they are moved. +SUBMODULES +---------- +Moving a submodule using a gitfile (which means they were cloned +with a Git version 1.7.8 or newer) will update the gitfile and +core.worktree setting to make the submodule work in the new location. +It also will attempt to update the submodule..path setting in +the linkgit:gitmodules[5] file and stage that file (unless -n is used). + GIT --- Part of the linkgit:git[1] suite diff --git a/Documentation/git-push.txt b/Documentation/git-push.txt index f7dfe48d28..e2992f17a0 100644 --- a/Documentation/git-push.txt +++ b/Documentation/git-push.txt @@ -11,6 +11,7 @@ SYNOPSIS [verse] 'git push' [--all | --mirror | --tags] [--follow-tags] [-n | --dry-run] [--receive-pack=] [--repo=] [-f | --force] [--prune] [-v | --verbose] [-u | --set-upstream] + [--force-with-lease[=[:]]] [--no-verify] [ [...]] DESCRIPTION @@ -130,21 +131,75 @@ already exists on the remote side. repository over ssh, and you do not have the program in a directory on the default $PATH. +--[no-]force-with-lease:: +--force-with-lease=:: +--force-with-lease=::: + Usually, "git push" refuses to update a remote ref that is + not an ancestor of the local ref used to overwrite it. ++ +This option bypasses the check, but instead requires that the +current value of the ref to be the expected value. "git push" +fails otherwise. ++ +Imagine that you have to rebase what you have already published. +You will have to bypass the "must fast-forward" rule in order to +replace the history you originally published with the rebased history. +If somebody else built on top of your original history while you are +rebasing, the tip of the branch at the remote may advance with her +commit, and blindly pushing with `--force` will lose her work. ++ +This option allows you to say that you expect the history you are +updating is what you rebased and want to replace. If the remote ref +still points at the commit you specified, you can be sure that no +other people did anything to the ref (it is like taking a "lease" on +the ref without explicitly locking it, and you update the ref while +making sure that your earlier "lease" is still valid). ++ +`--force-with-lease` alone, without specifying the details, will protect +all remote refs that are going to be updated by requiring their +current value to be the same as the remote-tracking branch we have +for them, unless specified with a `--force-with-lease=:` +option that explicitly states what the expected value is. ++ +`--force-with-lease=`, without specifying the expected value, will +protect the named ref (alone), if it is going to be updated, by +requiring its current value to be the same as the remote-tracking +branch we have for it. ++ +`--force-with-lease=:` will protect the named ref (alone), +if it is going to be updated, by requiring its current value to be +the same as the specified value (which is allowed to be +different from the remote-tracking branch we have for the refname, +or we do not even have to have such a remote-tracking branch when +this form is used). ++ +Note that all forms other than `--force-with-lease=:` +that specifies the expected current value of the ref explicitly are +still experimental and their semantics may change as we gain experience +with this feature. ++ +"--no-force-with-lease" will cancel all the previous --force-with-lease on the +command line. + -f:: --force:: Usually, the command refuses to update a remote ref that is not an ancestor of the local ref used to overwrite it. - This flag disables the check. This can cause the - remote repository to lose commits; use it with care. - Note that `--force` applies to all the refs that are pushed, - hence using it with `push.default` set to `matching` or with - multiple push destinations configured with `remote.*.push` - may overwrite refs other than the current branch (including - local refs that are strictly behind their remote counterpart). - To force a push to only one branch, use a `+` in front of the - refspec to push (e.g `git push origin +master` to force a push - to the `master` branch). See the `...` section above - for details. + Also, when `--force-with-lease` option is used, the command refuses + to update a remote ref whose current value does not match + what is expected. ++ +This flag disables these checks, and can cause the remote repository +to lose commits; use it with care. ++ +Note that `--force` applies to all the refs that are pushed, hence +using it with `push.default` set to `matching` or with multiple push +destinations configured with `remote.*.push` may overwrite refs +other than the current branch (including local refs that are +strictly behind their remote counterpart). To force a push to only +one branch, use a `+` in front of the refspec to push (e.g `git push +origin +master` to force a push to the `master` branch). See the +`...` section above for details. --repo=:: This option is only relevant if no argument is diff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt index 2b126c0a77..d068a65377 100644 --- a/Documentation/git-rev-parse.txt +++ b/Documentation/git-rev-parse.txt @@ -24,9 +24,23 @@ distinguish between them. OPTIONS ------- + +Operation Modes +~~~~~~~~~~~~~~~ + +Each of these options must appear first on the command line. + --parseopt:: Use 'git rev-parse' in option parsing mode (see PARSEOPT section below). +--sq-quote:: + Use 'git rev-parse' in shell quoting mode (see SQ-QUOTE + section below). In contrast to the `--sq` option below, this + mode does only quoting. Nothing else is done to command input. + +Options for --parseopt +~~~~~~~~~~~~~~~~~~~~~~ + --keep-dashdash:: Only meaningful in `--parseopt` mode. Tells the option parser to echo out the first `--` met instead of skipping it. @@ -36,10 +50,8 @@ OPTIONS the first non-option argument. This can be used to parse sub-commands that take options themselves. ---sq-quote:: - Use 'git rev-parse' in shell quoting mode (see SQ-QUOTE - section below). In contrast to the `--sq` option below, this - mode does only quoting. Nothing else is done to command input. +Options for Filtering +~~~~~~~~~~~~~~~~~~~~~ --revs-only:: Do not output flags and parameters not meant for @@ -55,6 +67,9 @@ OPTIONS --no-flags:: Do not output flag parameters. +Options for Output +~~~~~~~~~~~~~~~~~~ + --default :: If there is no parameter given by the user, use `` instead. @@ -110,6 +125,17 @@ can be used. strip '{caret}' prefix from the object names that already have one. +--abbrev-ref[=(strict|loose)]:: + A non-ambiguous short name of the objects name. + The option core.warnAmbiguousRefs is used to select the strict + abbreviation mode. + +--short:: +--short=number:: + Instead of outputting the full SHA-1 values of object names try to + abbreviate them to a shorter unique name. When no length is specified + 7 is used. The minimum length is 4. + --symbolic:: Usually the object names are output in SHA-1 form (with possible '{caret}' prefix); this option makes them output in a @@ -123,16 +149,8 @@ can be used. unfortunately named tag "master"), and show them as full refnames (e.g. "refs/heads/master"). ---abbrev-ref[=(strict|loose)]:: - A non-ambiguous short name of the objects name. - The option core.warnAmbiguousRefs is used to select the strict - abbreviation mode. - ---disambiguate=:: - Show every object whose name begins with the given prefix. - The must be at least 4 hexadecimal digits long to - avoid listing each and every object in the repository by - mistake. +Options for Objects +~~~~~~~~~~~~~~~~~~~ --all:: Show all refs found in `refs/`. @@ -155,18 +173,20 @@ shown. If the pattern does not contain a globbing character (`?`, character (`?`, `*`, or `[`), it is turned into a prefix match by appending `/*`. ---show-toplevel:: - Show the absolute path of the top-level directory. +--disambiguate=:: + Show every object whose name begins with the given prefix. + The must be at least 4 hexadecimal digits long to + avoid listing each and every object in the repository by + mistake. ---show-prefix:: - When the command is invoked from a subdirectory, show the - path of the current directory relative to the top-level - directory. +Options for Files +~~~~~~~~~~~~~~~~~ ---show-cdup:: - When the command is invoked from a subdirectory, show the - path of the top-level directory relative to the current - directory (typically a sequence of "../", or an empty string). +--local-env-vars:: + List the GIT_* environment variables that are local to the + repository (e.g. GIT_DIR or GIT_WORK_TREE, but not GIT_EDITOR). + Only the names of the variables are listed, not their value, + even if they are set. --git-dir:: Show `$GIT_DIR` if defined. Otherwise show the path to @@ -188,17 +208,27 @@ print a message to stderr and exit with nonzero status. --is-bare-repository:: When the repository is bare print "true", otherwise "false". ---local-env-vars:: - List the GIT_* environment variables that are local to the - repository (e.g. GIT_DIR or GIT_WORK_TREE, but not GIT_EDITOR). - Only the names of the variables are listed, not their value, - even if they are set. +--resolve-git-dir :: + Check if is a valid repository or a gitfile that + points at a valid repository, and print the location of the + repository. If is a gitfile then the resolved path + to the real repository is printed. ---short:: ---short=number:: - Instead of outputting the full SHA-1 values of object names try to - abbreviate them to a shorter unique name. When no length is specified - 7 is used. The minimum length is 4. +--show-cdup:: + When the command is invoked from a subdirectory, show the + path of the top-level directory relative to the current + directory (typically a sequence of "../", or an empty string). + +--show-prefix:: + When the command is invoked from a subdirectory, show the + path of the current directory relative to the top-level + directory. + +--show-toplevel:: + Show the absolute path of the top-level directory. + +Other Options +~~~~~~~~~~~~~ --since=datestring:: --after=datestring:: @@ -213,12 +243,6 @@ print a message to stderr and exit with nonzero status. ...:: Flags and parameters to be parsed. ---resolve-git-dir :: - Check if is a valid repository or a gitfile that - points at a valid repository, and print the location of the - repository. If is a gitfile then the resolved path - to the real repository is printed. - include::revisions.txt[] diff --git a/Documentation/git-rm.txt b/Documentation/git-rm.txt index 1d876c2619..9d731b453d 100644 --- a/Documentation/git-rm.txt +++ b/Documentation/git-rm.txt @@ -134,14 +134,16 @@ use the following command: git diff --name-only --diff-filter=D -z | xargs -0 git rm --cached ---------------- -Submodules -~~~~~~~~~~ +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. +or not - to protect the submodule's history. If it exists the +submodule. section in the linkgit:gitmodules[5] file will also +be removed and that file will be staged (unless --cached or -n are used). 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 diff --git a/Documentation/git-stash.txt b/Documentation/git-stash.txt index 7c8b648fbe..db7e803038 100644 --- a/Documentation/git-stash.txt +++ b/Documentation/git-stash.txt @@ -14,8 +14,7 @@ SYNOPSIS 'git stash' ( pop | apply ) [--index] [-q|--quiet] [] 'git stash' branch [] 'git stash' [save [-p|--patch] [-k|--[no-]keep-index] [-q|--quiet] - [-u|--include-untracked] [-a|--all] [-f|--force] - []] + [-u|--include-untracked] [-a|--all] []] 'git stash' clear 'git stash' create [] 'git stash' store [-m|--message ] [-q|--quiet] @@ -45,7 +44,7 @@ is also possible). OPTIONS ------- -save [-p|--patch] [--[no-]keep-index] [-u|--include-untracked] [-a|--all] [-q|--quiet] [-f|--force] []:: +save [-p|--patch] [--[no-]keep-index] [-u|--include-untracked] [-a|--all] [-q|--quiet] []:: Save your local modifications to a new 'stash', and run `git reset --hard` to revert them. The part is optional and gives @@ -72,13 +71,6 @@ linkgit:git-add[1] to learn how to operate the `--patch` mode. + The `--patch` option implies `--keep-index`. You can use `--no-keep-index` to override this. -+ -In some cases, saving a stash could mean irretrievably removing some -data - if a directory with untracked files replaces a tracked file of -the same name, the new untracked files are not saved (except in case -of `--include-untracked`) but the original tracked file shall be restored. -By default, `stash save` will abort in such a case; `--force` will allow -it to remove the untracked files. list []:: diff --git a/Documentation/git-whatchanged.txt b/Documentation/git-whatchanged.txt index c600b61e2b..8b63ceb00e 100644 --- a/Documentation/git-whatchanged.txt +++ b/Documentation/git-whatchanged.txt @@ -13,43 +13,17 @@ SYNOPSIS DESCRIPTION ----------- -Shows commit logs and diff output each commit introduces. The -command internally invokes 'git rev-list' piped to -'git diff-tree', and takes command line options for both of -these commands. -This manual page describes only the most frequently used options. +Shows commit logs and diff output each commit introduces. +New users are encouraged to use linkgit:git-log[1] instead. The +`whatchanged` command is essentially the same as linkgit:git-log[1] +but defaults to show the raw format diff output and to skip merges. -OPTIONS -------- --p:: - Show textual diffs, instead of the Git internal diff - output format that is useful only to tell the changed - paths and their nature of changes. +The command is kept primarily for historical reasons; fingers of +many people who learned Git long before `git log` was invented by +reading Linux kernel mailing list are trained to type it. --:: - Limit output to commits. - -..:: - Limit output to between the two named commits (bottom - exclusive, top inclusive). - --r:: - Show Git internal diff output, but for the whole tree, - not just the top level. - --m:: - By default, differences for merge commits are not shown. - With this flag, show differences to that commit from all - of its parents. -+ -However, it is not very useful in general, although it -*is* useful on a file-by-file basis. - -include::pretty-options.txt[] - -include::pretty-formats.txt[] Examples -------- diff --git a/Documentation/git.txt b/Documentation/git.txt index 3bdd56e8f4..c4f0ed5957 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.4/git.html[documentation for release 1.8.4] + +* release notes for + link:RelNotes/1.8.4.txt[1.8.4]. + * link:v1.8.3.4/git.html[documentation for release 1.8.3.4] * release notes for @@ -452,10 +457,25 @@ help ...`. 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 + Treat pathspecs literally (i.e. no globbing, no pathspec magic). + This is equivalent to setting the `GIT_LITERAL_PATHSPECS` environment variable to `1`. +--glob-pathspecs: + Add "glob" magic to all pathspec. This is equivalent to setting + the `GIT_GLOB_PATHSPECS` environment variable to `1`. Disabling + globbing on individual pathspecs can be done using pathspec + magic ":(literal)" + +--noglob-pathspecs: + Add "literal" magic to all pathspec. This is equivalent to setting + the `GIT_NOGLOB_PATHSPECS` environment variable to `1`. Enabling + globbing on individual pathspecs can be done using pathspec + magic ":(glob)" + +--icase-pathspecs: + Add "icase" magic to all pathspec. This is equivalent to setting + the `GIT_ICASE_PATHSPECS` environment variable to `1`. GIT COMMANDS ------------ @@ -818,7 +838,7 @@ for further details. 'GIT_FLUSH':: If this environment variable is set to "1", then commands such as 'git blame' (in incremental mode), 'git rev-list', 'git log', - 'git check-attr', 'git check-ignore', and 'git whatchanged' will + 'git check-attr' and 'git check-ignore' will force a flush of the output stream after each record have been flushed. If this variable is set to "0", the output of these commands will be done @@ -862,6 +882,18 @@ GIT_LITERAL_PATHSPECS:: literal paths to Git (e.g., paths previously given to you by `git ls-tree`, `--raw` diff output, etc). +GIT_GLOB_PATHSPECS:: + Setting this variable to `1` will cause Git to treat all + pathspecs as glob patterns (aka "glob" magic). + +GIT_NOGLOB_PATHSPECS:: + Setting this variable to `1` will cause Git to treat all + pathspecs as literal (aka "literal" magic). + +GIT_ICASE_PATHSPECS:: + Setting this variable to `1` will cause Git to treat all + pathspecs as case-insensitive. + Discussion[[Discussion]] ------------------------ diff --git a/Documentation/gitcore-tutorial.txt b/Documentation/gitcore-tutorial.txt index f538a870c7..058a352980 100644 --- a/Documentation/gitcore-tutorial.txt +++ b/Documentation/gitcore-tutorial.txt @@ -534,42 +534,9 @@ all, but just show the actual commit message. In fact, together with the 'git rev-list' program (which generates a list of revisions), 'git diff-tree' ends up being a veritable fount of -changes. A trivial (but very useful) script called 'git whatchanged' is -included with Git which does exactly this, and shows a log of recent -activities. - -To see the whole history of our pitiful little git-tutorial project, you -can do - ----------------- -$ git log ----------------- - -which shows just the log messages, or if we want to see the log together -with the associated patches use the more complex (and much more -powerful) - ----------------- -$ git whatchanged -p ----------------- - -and you will see exactly what has changed in the repository over its -short history. - -[NOTE] -When using the above two commands, the initial commit will be shown. -If this is a problem because it is huge, you can hide it by setting -the log.showroot configuration variable to false. Having this, you -can still show it for each command just adding the `--root` option, -which is a flag for 'git diff-tree' accepted by both commands. - -With that, you should now be having some inkling of what Git does, and -can explore on your own. - -[NOTE] -Most likely, you are not directly using the core -Git Plumbing commands, but using Porcelain such as 'git add', `git-rm' -and `git-commit'. +changes. You can emulate `git log`, `git log -p`, etc. with a trivial +script that pipes the output of `git rev-list` to `git diff-tree --stdin`, +which was exactly how early versions of `git log` were implemented. Tagging a version diff --git a/Documentation/gitremote-helpers.txt b/Documentation/gitremote-helpers.txt index 0827f69139..bc069c23df 100644 --- a/Documentation/gitremote-helpers.txt +++ b/Documentation/gitremote-helpers.txt @@ -143,6 +143,10 @@ Supported commands: 'list', 'fetch'. + Supported commands: 'list', 'import'. +'check-connectivity':: + Can guarantee that when a clone is requested, the received + pack is self contained and is connected. + 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). @@ -270,6 +274,9 @@ Optionally may output a 'lock ' line indicating a file under GIT_DIR/objects/pack which is keeping a pack until refs can be suitably updated. + +If option 'check-connectivity' is requested, the helper must output +'connectivity-ok' if the clone is self-contained and connected. ++ Supported if the helper has the "fetch" capability. 'push' +::: @@ -416,6 +423,9 @@ set by Git if the remote helper has the 'option' capability. must not rely on this option being set before connect request occurs. +'option check-connectivity' \{'true'|'false'\}:: + Request the helper to check connectivity of a clone. + SEE ALSO -------- linkgit:git-remote[1] diff --git a/Documentation/glossary-content.txt b/Documentation/glossary-content.txt index dba5062b37..13a64d3aac 100644 --- a/Documentation/glossary-content.txt +++ b/Documentation/glossary-content.txt @@ -322,10 +322,54 @@ and a close parentheses `)`, and the remainder is the pattern to match against the path. + The "magic signature" consists of an ASCII symbol that is not -alphanumeric. Currently only the slash `/` is recognized as a -"magic signature": it makes the pattern match from the root of -the working tree, even when you are running the command from -inside a subdirectory. +alphanumeric. ++ +-- +top `/`;; + The magic word `top` (mnemonic: `/`) makes the pattern match + from the root of the working tree, even when you are running + the command from inside a subdirectory. + +literal;; + Wildcards in the pattern such as `*` or `?` are treated + as literal characters. + +icase;; + Case insensitive match. + +glob;; + Git treats the pattern as a shell glob suitable for + consumption by fnmatch(3) with the FNM_PATHNAME flag: + wildcards in the pattern will not match a / in the pathname. + For example, "Documentation/{asterisk}.html" matches + "Documentation/git.html" but not "Documentation/ppc/ppc.html" + or "tools/perf/Documentation/perf.html". ++ +Two consecutive asterisks ("`**`") in patterns matched against +full pathname may have special meaning: + + - A leading "`**`" followed by a slash means match in all + directories. For example, "`**/foo`" matches file or directory + "`foo`" anywhere, the same as pattern "`foo`". "**/foo/bar" + matches file or directory "`bar`" anywhere that is directly + under directory "`foo`". + + - A trailing "/**" matches everything inside. For example, + "abc/**" matches all files inside directory "abc", relative + to the location of the `.gitignore` file, with infinite depth. + + - A slash followed by two consecutive asterisks then a slash + matches zero or more directories. For example, "`a/**/b`" + matches "`a/b`", "`a/x/b`", "`a/x/y/b`" and so on. + + - Other consecutive asterisks are considered invalid. ++ +Glob magic is incompatible with literal magic. +-- ++ +Currently only the slash `/` is recognized as the "magic signature", +but it is envisioned that we will support more types of magic in later +versions of Git. + A pathspec with only a colon means "there is no pathspec". This form should not be combined with other pathspec. diff --git a/Documentation/line-range-format.txt b/Documentation/line-range-format.txt index 3e7ce72daa..d7f26039ca 100644 --- a/Documentation/line-range-format.txt +++ b/Documentation/line-range-format.txt @@ -1,3 +1,5 @@ + and can take one of these forms: + - number + If or is a number, it specifies an @@ -7,7 +9,10 @@ absolute line number (lines count from 1). - /regex/ + This form will use the first line matching the given -POSIX regex. If is a regex, it will search +POSIX regex. If is a regex, it will search from the end of +the previous `-L` range, if any, otherwise from the start of file. +If is ``^/regex/'', it will search from the start of file. +If is a regex, it will search starting at the line given by . + @@ -15,11 +20,10 @@ starting at the line given by . + This is only valid for and will specify a number of lines before or after the line given by . -+ -- :regex + -If the option's argument is of the form :regex, it denotes the range +If ``:'' is given in place of and , it denotes the range from the first funcname line that matches , up to the next -funcname line. -+ +funcname line. ``:'' searches from the end of the previous `-L` range, +if any, otherwise from the start of file. +``^:'' searches from the start of file. diff --git a/Documentation/revisions.txt b/Documentation/revisions.txt index 09896a37b1..d477b3f6bc 100644 --- a/Documentation/revisions.txt +++ b/Documentation/revisions.txt @@ -58,9 +58,6 @@ the '$GIT_DIR/refs' directory or from the '$GIT_DIR/packed-refs' file. While the ref name encoding is unspecified, UTF-8 is preferred as some output processing may assume ref names in UTF-8. -'@':: - '@' alone is a shortcut for 'HEAD'. - '@\{\}', e.g. 'master@\{yesterday\}', 'HEAD@\{5 minutes ago\}':: A ref followed by the suffix '@' with a date specification enclosed in a brace diff --git a/Documentation/technical/api-setup.txt b/Documentation/technical/api-setup.txt index 4f63a04d7d..540e455689 100644 --- a/Documentation/technical/api-setup.txt +++ b/Documentation/technical/api-setup.txt @@ -8,6 +8,42 @@ Talk about * is_inside_git_dir() * is_inside_work_tree() * setup_work_tree() -* get_pathspec() (Dscho) + +Pathspec +-------- + +See glossary-context.txt for the syntax of pathspec. In memory, a +pathspec set is represented by "struct pathspec" and is prepared by +parse_pathspec(). This function takes several arguments: + +- magic_mask specifies what features that are NOT supported by the + following code. If a user attempts to use such a feature, + parse_pathspec() can reject it early. + +- flags specifies other things that the caller wants parse_pathspec to + perform. + +- prefix and args come from cmd_* functions + +get_pathspec() is obsolete and should never be used in new code. + +parse_pathspec() helps catch unsupported features and reject them +politely. At a lower level, different pathspec-related functions may +not support the same set of features. Such pathspec-sensitive +functions are guarded with GUARD_PATHSPEC(), which will die in an +unfriendly way when an unsupported feature is requested. + +The command designers are supposed to make sure that GUARD_PATHSPEC() +never dies. They have to make sure all unsupported features are caught +by parse_pathspec(), not by GUARD_PATHSPEC. grepping GUARD_PATHSPEC() +should give the designers all pathspec-sensitive codepaths and what +features they support. + +A similar process is applied when a new pathspec magic is added. The +designer lifts the GUARD_PATHSPEC restriction in the functions that +support the new magic. At the same time (s)he has to make sure this +new feature will be caught at parse_pathspec() in commands that cannot +handle the new magic in some cases. grepping parse_pathspec() should +help. diff --git a/Documentation/technical/http-protocol.txt b/Documentation/technical/http-protocol.txt new file mode 100644 index 0000000000..a1173ee266 --- /dev/null +++ b/Documentation/technical/http-protocol.txt @@ -0,0 +1,503 @@ +HTTP transfer protocols +======================= + +Git supports two HTTP based transfer protocols. A "dumb" protocol +which requires only a standard HTTP server on the server end of the +connection, and a "smart" protocol which requires a Git aware CGI +(or server module). This document describes both protocols. + +As a design feature smart clients can automatically upgrade "dumb" +protocol URLs to smart URLs. This permits all users to have the +same published URL, and the peers automatically select the most +efficient transport available to them. + + +URL Format +---------- + +URLs for Git repositories accessed by HTTP use the standard HTTP +URL syntax documented by RFC 1738, so they are of the form: + + http://:/? + +Within this documentation the placeholder $GIT_URL will stand for +the http:// repository URL entered by the end-user. + +Servers SHOULD handle all requests to locations matching $GIT_URL, as +both the "smart" and "dumb" HTTP protocols used by Git operate +by appending additional path components onto the end of the user +supplied $GIT_URL string. + +An example of a dumb client requesting for a loose object: + + $GIT_URL: http://example.com:8080/git/repo.git + URL request: http://example.com:8080/git/repo.git/objects/d0/49f6c27a2244e12041955e262a404c7faba355 + +An example of a smart request to a catch-all gateway: + + $GIT_URL: http://example.com/daemon.cgi?svc=git&q= + URL request: http://example.com/daemon.cgi?svc=git&q=/info/refs&service=git-receive-pack + +An example of a request to a submodule: + + $GIT_URL: http://example.com/git/repo.git/path/submodule.git + URL request: http://example.com/git/repo.git/path/submodule.git/info/refs + +Clients MUST strip a trailing '/', if present, from the user supplied +$GIT_URL string to prevent empty path tokens ('//') from appearing +in any URL sent to a server. Compatible clients MUST expand +'$GIT_URL/info/refs' as 'foo/info/refs' and not 'foo//info/refs'. + + +Authentication +-------------- + +Standard HTTP authentication is used if authentication is required +to access a repository, and MAY be configured and enforced by the +HTTP server software. + +Because Git repositories are accessed by standard path components +server administrators MAY use directory based permissions within +their HTTP server to control repository access. + +Clients SHOULD support Basic authentication as described by RFC 2616. +Servers SHOULD support Basic authentication by relying upon the +HTTP server placed in front of the Git server software. + +Servers SHOULD NOT require HTTP cookies for the purposes of +authentication or access control. + +Clients and servers MAY support other common forms of HTTP based +authentication, such as Digest authentication. + + +SSL +--- + +Clients and servers SHOULD support SSL, particularly to protect +passwords when relying on Basic HTTP authentication. + + +Session State +------------- + +The Git over HTTP protocol (much like HTTP itself) is stateless +from the perspective of the HTTP server side. All state MUST be +retained and managed by the client process. This permits simple +round-robin load-balancing on the server side, without needing to +worry about state management. + +Clients MUST NOT require state management on the server side in +order to function correctly. + +Servers MUST NOT require HTTP cookies in order to function correctly. +Clients MAY store and forward HTTP cookies during request processing +as described by RFC 2616 (HTTP/1.1). Servers SHOULD ignore any +cookies sent by a client. + + +General Request Processing +-------------------------- + +Except where noted, all standard HTTP behavior SHOULD be assumed +by both client and server. This includes (but is not necessarily +limited to): + +If there is no repository at $GIT_URL, or the resource pointed to by a +location matching $GIT_URL does not exist, the server MUST NOT respond +with '200 OK' response. A server SHOULD respond with +'404 Not Found', '410 Gone', or any other suitable HTTP status code +which does not imply the resource exists as requested. + +If there is a repository at $GIT_URL, but access is not currently +permitted, the server MUST respond with the '403 Forbidden' HTTP +status code. + +Servers SHOULD support both HTTP 1.0 and HTTP 1.1. +Servers SHOULD support chunked encoding for both request and response +bodies. + +Clients SHOULD support both HTTP 1.0 and HTTP 1.1. +Clients SHOULD support chunked encoding for both request and response +bodies. + +Servers MAY return ETag and/or Last-Modified headers. + +Clients MAY revalidate cached entities by including If-Modified-Since +and/or If-None-Match request headers. + +Servers MAY return '304 Not Modified' if the relevant headers appear +in the request and the entity has not changed. Clients MUST treat +'304 Not Modified' identical to '200 OK' by reusing the cached entity. + +Clients MAY reuse a cached entity without revalidation if the +Cache-Control and/or Expires header permits caching. Clients and +servers MUST follow RFC 2616 for cache controls. + + +Discovering References +---------------------- + +All HTTP clients MUST begin either a fetch or a push exchange by +discovering the references available on the remote repository. + +Dumb Clients +~~~~~~~~~~~~ + +HTTP clients that only support the "dumb" protocol MUST discover +references by making a request for the special info/refs file of +the repository. + +Dumb HTTP clients MUST make a GET request to $GIT_URL/info/refs, +without any search/query parameters. + + C: GET $GIT_URL/info/refs HTTP/1.0 + + S: 200 OK + S: + S: 95dcfa3633004da0049d3d0fa03f80589cbcaf31 refs/heads/maint + S: d049f6c27a2244e12041955e262a404c7faba355 refs/heads/master + S: 2cb58b79488a98d2721cea644875a8dd0026b115 refs/tags/v1.0 + S: a3c2e2402b99163d1d59756e5f207ae21cccba4c refs/tags/v1.0^{} + +The Content-Type of the returned info/refs entity SHOULD be +"text/plain; charset=utf-8", but MAY be any content type. +Clients MUST NOT attempt to validate the returned Content-Type. +Dumb servers MUST NOT return a return type starting with +"application/x-git-". + +Cache-Control headers MAY be returned to disable caching of the +returned entity. + +When examining the response clients SHOULD only examine the HTTP +status code. Valid responses are '200 OK', or '304 Not Modified'. + +The returned content is a UNIX formatted text file describing +each ref and its known value. The file SHOULD be sorted by name +according to the C locale ordering. The file SHOULD NOT include +the default ref named 'HEAD'. + + info_refs = *( ref_record ) + ref_record = any_ref / peeled_ref + + any_ref = obj-id HTAB refname LF + peeled_ref = obj-id HTAB refname LF + obj-id HTAB refname "^{}" LF + +Smart Clients +~~~~~~~~~~~~~ + +HTTP clients that support the "smart" protocol (or both the +"smart" and "dumb" protocols) MUST discover references by making +a parameterized request for the info/refs file of the repository. + +The request MUST contain exactly one query parameter, +'service=$servicename', where $servicename MUST be the service +name the client wishes to contact to complete the operation. +The request MUST NOT contain additional query parameters. + + C: GET $GIT_URL/info/refs?service=git-upload-pack HTTP/1.0 + + dumb server reply: + S: 200 OK + S: + S: 95dcfa3633004da0049d3d0fa03f80589cbcaf31 refs/heads/maint + S: d049f6c27a2244e12041955e262a404c7faba355 refs/heads/master + S: 2cb58b79488a98d2721cea644875a8dd0026b115 refs/tags/v1.0 + S: a3c2e2402b99163d1d59756e5f207ae21cccba4c refs/tags/v1.0^{} + + smart server reply: + S: 200 OK + S: Content-Type: application/x-git-upload-pack-advertisement + S: Cache-Control: no-cache + S: + S: 001e# service=git-upload-pack\n + S: 004895dcfa3633004da0049d3d0fa03f80589cbcaf31 refs/heads/maint\0multi_ack\n + S: 0042d049f6c27a2244e12041955e262a404c7faba355 refs/heads/master\n + S: 003c2cb58b79488a98d2721cea644875a8dd0026b115 refs/tags/v1.0\n + S: 003fa3c2e2402b99163d1d59756e5f207ae21cccba4c refs/tags/v1.0^{}\n + +Dumb Server Response +^^^^^^^^^^^^^^^^^^^^ +Dumb servers MUST respond with the dumb server reply format. + +See the prior section under dumb clients for a more detailed +description of the dumb server response. + +Smart Server Response +^^^^^^^^^^^^^^^^^^^^^ +If the server does not recognize the requested service name, or the +requested service name has been disabled by the server administrator, +the server MUST respond with the '403 Forbidden' HTTP status code. + +Otherwise, smart servers MUST respond with the smart server reply +format for the requested service name. + +Cache-Control headers SHOULD be used to disable caching of the +returned entity. + +The Content-Type MUST be 'application/x-$servicename-advertisement'. +Clients SHOULD fall back to the dumb protocol if another content +type is returned. When falling back to the dumb protocol clients +SHOULD NOT make an additional request to $GIT_URL/info/refs, but +instead SHOULD use the response already in hand. Clients MUST NOT +continue if they do not support the dumb protocol. + +Clients MUST validate the status code is either '200 OK' or +'304 Not Modified'. + +Clients MUST validate the first five bytes of the response entity +matches the regex "^[0-9a-f]{4}#". If this test fails, clients +MUST NOT continue. + +Clients MUST parse the entire response as a sequence of pkt-line +records. + +Clients MUST verify the first pkt-line is "# service=$servicename". +Servers MUST set $servicename to be the request parameter value. +Servers SHOULD include an LF at the end of this line. +Clients MUST ignore an LF at the end of the line. + +Servers MUST terminate the response with the magic "0000" end +pkt-line marker. + +The returned response is a pkt-line stream describing each ref and +its known value. The stream SHOULD be sorted by name according to +the C locale ordering. The stream SHOULD include the default ref +named 'HEAD' as the first ref. The stream MUST include capability +declarations behind a NUL on the first ref. + + smart_reply = PKT-LINE("# service=$servicename" LF) + ref_list + "0000" + ref_list = empty_list / non_empty_list + + empty_list = PKT-LINE(zero-id SP "capabilities^{}" NUL cap-list LF) + + non_empty_list = PKT-LINE(obj-id SP name NUL cap_list LF) + *ref_record + + cap-list = capability *(SP capability) + capability = 1*(LC_ALPHA / DIGIT / "-" / "_") + LC_ALPHA = %x61-7A + + ref_record = any_ref / peeled_ref + any_ref = PKT-LINE(obj-id SP name LF) + peeled_ref = PKT-LINE(obj-id SP name LF) + PKT-LINE(obj-id SP name "^{}" LF + +Smart Service git-upload-pack +------------------------------ +This service reads from the repository pointed to by $GIT_URL. + +Clients MUST first perform ref discovery with +'$GIT_URL/info/refs?service=git-upload-pack'. + + C: POST $GIT_URL/git-upload-pack HTTP/1.0 + C: Content-Type: application/x-git-upload-pack-request + C: + C: 0032want 0a53e9ddeaddad63ad106860237bbf53411d11a7\n + C: 0032have 441b40d833fdfa93eb2908e52742248faf0ee993\n + C: 0000 + + S: 200 OK + S: Content-Type: application/x-git-upload-pack-result + S: Cache-Control: no-cache + S: + S: ....ACK %s, continue + S: ....NAK + +Clients MUST NOT reuse or revalidate a cached reponse. +Servers MUST include sufficient Cache-Control headers +to prevent caching of the response. + +Servers SHOULD support all capabilities defined here. + +Clients MUST send at least one 'want' command in the request body. +Clients MUST NOT reference an id in a 'want' command which did not +appear in the response obtained through ref discovery unless the +server advertises capability "allow-tip-sha1-in-want". + + compute_request = want_list + have_list + request_end + request_end = "0000" / "done" + + want_list = PKT-LINE(want NUL cap_list LF) + *(want_pkt) + want_pkt = PKT-LINE(want LF) + want = "want" SP id + cap_list = *(SP capability) SP + + have_list = *PKT-LINE("have" SP id LF) + +TODO: Document this further. +TODO: Don't use uppercase for variable names below. + +The Negotiation Algorithm +~~~~~~~~~~~~~~~~~~~~~~~~~ +The computation to select the minimal pack proceeds as follows +(c = client, s = server): + + init step: + (c) Use ref discovery to obtain the advertised refs. + (c) Place any object seen into set ADVERTISED. + + (c) Build an empty set, COMMON, to hold the objects that are later + determined to be on both ends. + (c) Build a set, WANT, of the objects from ADVERTISED the client + wants to fetch, based on what it saw during ref discovery. + + (c) Start a queue, C_PENDING, ordered by commit time (popping newest + first). Add all client refs. When a commit is popped from + the queue its parents SHOULD be automatically inserted back. + Commits MUST only enter the queue once. + + one compute step: + (c) Send one $GIT_URL/git-upload-pack request: + + C: 0032want ............................... + C: 0032want ............................... + .... + C: 0032have ............................. + C: 0032have ............................. + .... + C: 0032have ............................... + C: 0032have ............................... + .... + C: 0000 + + The stream is organized into "commands", with each command + appearing by itself in a pkt-line. Within a command line + the text leading up to the first space is the command name, + and the remainder of the line to the first LF is the value. + Command lines are terminated with an LF as the last byte of + the pkt-line value. + + Commands MUST appear in the following order, if they appear + at all in the request stream: + + * want + * have + + The stream is terminated by a pkt-line flush ("0000"). + + A single "want" or "have" command MUST have one hex formatted + SHA-1 as its value. Multiple SHA-1s MUST be sent by sending + multiple commands. + + The HAVE list is created by popping the first 32 commits + from C_PENDING. Less can be supplied if C_PENDING empties. + + If the client has sent 256 HAVE commits and has not yet + received one of those back from S_COMMON, or the client has + emptied C_PENDING it SHOULD include a "done" command to let + the server know it won't proceed: + + C: 0009done + + (s) Parse the git-upload-pack request: + + Verify all objects in WANT are directly reachable from refs. + + The server MAY walk backwards through history or through + the reflog to permit slightly stale requests. + + If no WANT objects are received, send an error: + +TODO: Define error if no want lines are requested. + + If any WANT object is not reachable, send an error: + +TODO: Define error if an invalid want is requested. + + Create an empty list, S_COMMON. + + If 'have' was sent: + + Loop through the objects in the order supplied by the client. + For each object, if the server has the object reachable from + a ref, add it to S_COMMON. If a commit is added to S_COMMON, + do not add any ancestors, even if they also appear in HAVE. + + (s) Send the git-upload-pack response: + + If the server has found a closed set of objects to pack or the + request ends with "done", it replies with the pack. + +TODO: Document the pack based response + S: PACK... + + The returned stream is the side-band-64k protocol supported + by the git-upload-pack service, and the pack is embedded into + stream 1. Progress messages from the server side MAY appear + in stream 2. + + Here a "closed set of objects" is defined to have at least + one path from every WANT to at least one COMMON object. + + If the server needs more information, it replies with a + status continue response: + +TODO: Document the non-pack response + + (c) Parse the upload-pack response: + +TODO: Document parsing response + + Do another compute step. + + +Smart Service git-receive-pack +------------------------------ +This service reads from the repository pointed to by $GIT_URL. + +Clients MUST first perform ref discovery with +'$GIT_URL/info/refs?service=git-receive-pack'. + + C: POST $GIT_URL/git-receive-pack HTTP/1.0 + C: Content-Type: application/x-git-receive-pack-request + C: + C: ....0a53e9ddeaddad63ad106860237bbf53411d11a7 441b40d833fdfa93eb2908e52742248faf0ee993 refs/heads/maint\0 report-status + C: 0000 + C: PACK.... + + S: 200 OK + S: Content-Type: application/x-git-receive-pack-result + S: Cache-Control: no-cache + S: + S: .... + +Clients MUST NOT reuse or revalidate a cached reponse. +Servers MUST include sufficient Cache-Control headers +to prevent caching of the response. + +Servers SHOULD support all capabilities defined here. + +Clients MUST send at least one command in the request body. +Within the command portion of the request body clients SHOULD send +the id obtained through ref discovery as old_id. + + update_request = command_list + "PACK" + + command_list = PKT-LINE(command NUL cap_list LF) + *(command_pkt) + command_pkt = PKT-LINE(command LF) + cap_list = *(SP capability) SP + + command = create / delete / update + create = zero-id SP new_id SP name + delete = old_id SP zero-id SP name + update = old_id SP new_id SP name + +TODO: Document this further. + + +References +---------- + +link:http://www.ietf.org/rfc/rfc1738.txt[RFC 1738: Uniform Resource Locators (URL)] +link:http://www.ietf.org/rfc/rfc2616.txt[RFC 2616: Hypertext Transfer Protocol -- HTTP/1.1] +link:technical/pack-protocol.txt +link:technical/protocol-capabilities.txt diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index ede98a8c16..b444c18f17 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -1,7 +1,7 @@ #!/bin/sh GVF=GIT-VERSION-FILE -DEF_VER=v1.8.4-rc1 +DEF_VER=v1.8.4.GIT LF=' ' diff --git a/Makefile b/Makefile index 3588ca1b6a..9135cc9358 100644 --- a/Makefile +++ b/Makefile @@ -580,6 +580,7 @@ TEST_PROGRAMS_NEED_X += test-sigchain TEST_PROGRAMS_NEED_X += test-string-list TEST_PROGRAMS_NEED_X += test-subprocess TEST_PROGRAMS_NEED_X += test-svn-fe +TEST_PROGRAMS_NEED_X += test-urlmatch-normalization TEST_PROGRAMS_NEED_X += test-wildmatch TEST_PROGRAMS = $(patsubst %,%$X,$(TEST_PROGRAMS_NEED_X)) @@ -736,6 +737,7 @@ LIB_H += tree-walk.h LIB_H += tree.h LIB_H += unpack-trees.h LIB_H += url.h +LIB_H += urlmatch.h LIB_H += userdiff.h LIB_H += utf8.h LIB_H += varint.h @@ -886,6 +888,7 @@ LIB_OBJS += tree.o LIB_OBJS += tree-walk.o LIB_OBJS += unpack-trees.o LIB_OBJS += url.o +LIB_OBJS += urlmatch.o LIB_OBJS += usage.o LIB_OBJS += userdiff.o LIB_OBJS += utf8.o @@ -1182,6 +1185,9 @@ ifdef NEEDS_SSL_WITH_CRYPTO else LIB_4_CRYPTO = $(OPENSSL_LINK) -lcrypto endif +ifdef APPLE_COMMON_CRYPTO + LIB_4_CRYPTO += -framework Security -framework CoreFoundation +endif endif ifdef NEEDS_LIBICONV ifdef ICONVDIR diff --git a/RelNotes b/RelNotes index fce99fb79d..61c3b54134 120000 --- a/RelNotes +++ b/RelNotes @@ -1 +1 @@ -Documentation/RelNotes/1.8.4.txt \ No newline at end of file +Documentation/RelNotes/1.8.5.txt \ No newline at end of file diff --git a/archive.c b/archive.c index d254fa5d5c..99fadc88d0 100644 --- a/archive.c +++ b/archive.c @@ -151,7 +151,6 @@ int write_archive_entries(struct archiver_args *args, struct archiver_context context; struct unpack_trees_options opts; struct tree_desc t; - struct pathspec pathspec; int err; if (args->baselen > 0 && args->base[args->baselen - 1] == '/') { @@ -186,10 +185,8 @@ int write_archive_entries(struct archiver_args *args, git_attr_set_direction(GIT_ATTR_INDEX, &the_index); } - init_pathspec(&pathspec, args->pathspec); - err = read_tree_recursive(args->tree, "", 0, 0, &pathspec, + err = read_tree_recursive(args->tree, "", 0, 0, &args->pathspec, write_archive_entry, &context); - free_pathspec(&pathspec); if (err == READ_TREE_RECURSIVE) err = 0; return err; @@ -222,7 +219,7 @@ static int path_exists(struct tree *tree, const char *path) struct pathspec pathspec; int ret; - init_pathspec(&pathspec, paths); + parse_pathspec(&pathspec, 0, 0, "", paths); ret = read_tree_recursive(tree, "", 0, 0, &pathspec, reject_entry, NULL); free_pathspec(&pathspec); return ret != 0; @@ -231,11 +228,18 @@ static int path_exists(struct tree *tree, const char *path) static void parse_pathspec_arg(const char **pathspec, struct archiver_args *ar_args) { - ar_args->pathspec = pathspec = get_pathspec("", pathspec); + /* + * must be consistent with parse_pathspec in path_exists() + * Also if pathspec patterns are dependent, we're in big + * trouble as we test each one separately + */ + parse_pathspec(&ar_args->pathspec, 0, + PATHSPEC_PREFER_FULL, + "", pathspec); if (pathspec) { while (*pathspec) { if (**pathspec && !path_exists(ar_args->tree, *pathspec)) - die("path not found: %s", *pathspec); + die(_("pathspec '%s' did not match any files"), *pathspec); pathspec++; } } diff --git a/archive.h b/archive.h index 895afcdc7a..4a791e1fed 100644 --- a/archive.h +++ b/archive.h @@ -1,6 +1,8 @@ #ifndef ARCHIVE_H #define ARCHIVE_H +#include "pathspec.h" + struct archiver_args { const char *base; size_t baselen; @@ -8,7 +10,7 @@ struct archiver_args { const unsigned char *commit_sha1; const struct commit *commit; time_t time; - const char **pathspec; + struct pathspec pathspec; unsigned int verbose : 1; unsigned int worktree_attributes : 1; unsigned int convert : 1; diff --git a/builtin/add.c b/builtin/add.c index 8266a9cb70..ae0bdc78bb 100644 --- a/builtin/add.c +++ b/builtin/add.c @@ -166,14 +166,16 @@ static void update_callback(struct diff_queue_struct *q, } } -static void update_files_in_cache(const char *prefix, const char **pathspec, +static void update_files_in_cache(const char *prefix, + const struct pathspec *pathspec, struct update_callback_data *data) { struct rev_info rev; init_revisions(&rev, prefix); setup_revisions(0, NULL, &rev, NULL); - init_pathspec(&rev.prune_data, pathspec); + if (pathspec) + copy_pathspec(&rev.prune_data, pathspec); rev.diffopt.output_format = DIFF_FORMAT_CALLBACK; rev.diffopt.format_callback = update_callback; rev.diffopt.format_callback_data = data; @@ -181,7 +183,8 @@ static void update_files_in_cache(const char *prefix, const char **pathspec, run_diff_files(&rev, DIFF_RACY_IS_MODIFIED); } -int add_files_to_cache(const char *prefix, const char **pathspec, int flags) +int add_files_to_cache(const char *prefix, + const struct pathspec *pathspec, int flags) { struct update_callback_data data; @@ -192,23 +195,21 @@ int add_files_to_cache(const char *prefix, const char **pathspec, int flags) } #define WARN_IMPLICIT_DOT (1u << 0) -static char *prune_directory(struct dir_struct *dir, const char **pathspec, +static char *prune_directory(struct dir_struct *dir, struct pathspec *pathspec, int prefix, unsigned flag) { char *seen; - int i, specs; + int i; struct dir_entry **src, **dst; - for (specs = 0; pathspec[specs]; specs++) - /* nothing */; - seen = xcalloc(specs, 1); + seen = xcalloc(pathspec->nr, 1); src = dst = dir->entries; i = dir->nr; while (--i >= 0) { struct dir_entry *entry = *src++; - if (match_pathspec(pathspec, entry->name, entry->len, - prefix, seen)) + if (match_pathspec_depth(pathspec, entry->name, entry->len, + prefix, seen)) *dst++ = entry; else if (flag & WARN_IMPLICIT_DOT) /* @@ -222,72 +223,33 @@ static char *prune_directory(struct dir_struct *dir, const char **pathspec, warn_pathless_add(); } dir->nr = dst - dir->entries; - add_pathspec_matches_against_index(pathspec, seen, specs); + add_pathspec_matches_against_index(pathspec, seen); return seen; } -/* - * Checks the index to see whether any path in pathspec refers to - * something inside a submodule. If so, dies with an error message. - */ -static void treat_gitlinks(const char **pathspec) -{ - int i; - - if (!pathspec || !*pathspec) - return; - - for (i = 0; pathspec[i]; i++) - pathspec[i] = check_path_for_gitlink(pathspec[i]); -} - -static void refresh(int verbose, const char **pathspec) +static void refresh(int verbose, const struct pathspec *pathspec) { char *seen; - int i, specs; + int i; - for (specs = 0; pathspec[specs]; specs++) - /* nothing */; - seen = xcalloc(specs, 1); + seen = xcalloc(pathspec->nr, 1); refresh_index(&the_index, verbose ? REFRESH_IN_PORCELAIN : REFRESH_QUIET, pathspec, seen, _("Unstaged changes after refreshing the index:")); - for (i = 0; i < specs; i++) { + for (i = 0; i < pathspec->nr; i++) { if (!seen[i]) - die(_("pathspec '%s' did not match any files"), pathspec[i]); + die(_("pathspec '%s' did not match any files"), + pathspec->items[i].match); } free(seen); } -/* - * Normalizes argv relative to prefix, via get_pathspec(), and then - * runs die_if_path_beyond_symlink() on each path in the normalized - * list. - */ -static const char **validate_pathspec(const char **argv, const char *prefix) -{ - const char **pathspec = get_pathspec(prefix, argv); - - if (pathspec) { - const char **p; - for (p = pathspec; *p; p++) { - die_if_path_beyond_symlink(*p, prefix); - } - } - - return pathspec; -} - int run_add_interactive(const char *revision, const char *patch_mode, - const char **pathspec) + const struct pathspec *pathspec) { - int status, ac, pc = 0; + int status, ac, i; const char **args; - if (pathspec) - while (pathspec[pc]) - pc++; - - args = xcalloc(sizeof(const char *), (pc + 5)); + args = xcalloc(sizeof(const char *), (pathspec->nr + 6)); ac = 0; args[ac++] = "add--interactive"; if (patch_mode) @@ -295,11 +257,9 @@ int run_add_interactive(const char *revision, const char *patch_mode, if (revision) args[ac++] = revision; args[ac++] = "--"; - if (pc) { - memcpy(&(args[ac]), pathspec, sizeof(const char *) * pc); - ac += pc; - } - args[ac] = NULL; + for (i = 0; i < pathspec->nr; i++) + /* pass original pathspec, to be re-parsed */ + args[ac++] = pathspec->items[i].original; status = run_command_v_opt(args, RUN_GIT_CMD); free(args); @@ -308,17 +268,23 @@ int run_add_interactive(const char *revision, const char *patch_mode, int interactive_add(int argc, const char **argv, const char *prefix, int patch) { - const char **pathspec = NULL; + struct pathspec pathspec; - if (argc) { - pathspec = validate_pathspec(argv, prefix); - if (!pathspec) - return -1; - } + /* + * git-add--interactive itself does not parse pathspec. It + * simply passes the pathspec to other builtin commands. Let's + * hope all of them support all magic, or we'll need to limit + * the magic here. + */ + parse_pathspec(&pathspec, PATHSPEC_ALL_MAGIC & ~PATHSPEC_FROMTOP, + PATHSPEC_PREFER_FULL | + PATHSPEC_SYMLINK_LEADING_PATH | + PATHSPEC_PREFIX_ORIGIN, + prefix, argv); return run_add_interactive(NULL, patch ? "--patch" : NULL, - pathspec); + &pathspec); } static int edit_patch(int argc, const char **argv, const char *prefix) @@ -446,7 +412,7 @@ int cmd_add(int argc, const char **argv, const char *prefix) { int exit_status = 0; int newfd; - const char **pathspec; + struct pathspec pathspec; struct dir_struct dir; int flags; int add_new_files; @@ -527,14 +493,23 @@ int cmd_add(int argc, const char **argv, const char *prefix) fprintf(stderr, _("Maybe you wanted to say 'git add .'?\n")); return 0; } - pathspec = validate_pathspec(argv, prefix); if (read_cache() < 0) die(_("index file corrupt")); - treat_gitlinks(pathspec); + + /* + * Check the "pathspec '%s' did not match any files" block + * below before enabling new magic. + */ + parse_pathspec(&pathspec, 0, + PATHSPEC_PREFER_FULL | + PATHSPEC_SYMLINK_LEADING_PATH | + PATHSPEC_STRIP_SUBMODULE_SLASH_EXPENSIVE, + prefix, argv); if (add_new_files) { int baselen; + struct pathspec empty_pathspec; /* Set up the default git porcelain excludes */ memset(&dir, 0, sizeof(dir)); @@ -543,35 +518,49 @@ int cmd_add(int argc, const char **argv, const char *prefix) setup_standard_excludes(&dir); } + memset(&empty_pathspec, 0, sizeof(empty_pathspec)); /* This picks up the paths that are not tracked */ - baselen = fill_directory(&dir, implicit_dot ? NULL : pathspec); - if (pathspec) - seen = prune_directory(&dir, pathspec, baselen, + baselen = fill_directory(&dir, implicit_dot ? &empty_pathspec : &pathspec); + if (pathspec.nr) + seen = prune_directory(&dir, &pathspec, baselen, implicit_dot ? WARN_IMPLICIT_DOT : 0); } if (refresh_only) { - refresh(verbose, pathspec); + refresh(verbose, &pathspec); goto finish; } if (implicit_dot && prefix) refresh_cache(REFRESH_QUIET); - if (pathspec) { + if (pathspec.nr) { int i; if (!seen) - seen = find_pathspecs_matching_against_index(pathspec); - for (i = 0; pathspec[i]; i++) { - if (!seen[i] && pathspec[i][0] - && !file_exists(pathspec[i])) { + seen = find_pathspecs_matching_against_index(&pathspec); + + /* + * file_exists() assumes exact match + */ + GUARD_PATHSPEC(&pathspec, + PATHSPEC_FROMTOP | + PATHSPEC_LITERAL | + PATHSPEC_GLOB | + PATHSPEC_ICASE); + + for (i = 0; i < pathspec.nr; i++) { + const char *path = pathspec.items[i].match; + if (!seen[i] && + ((pathspec.items[i].magic & + (PATHSPEC_GLOB | PATHSPEC_ICASE)) || + !file_exists(path))) { if (ignore_missing) { int dtype = DT_UNKNOWN; - if (is_excluded(&dir, pathspec[i], &dtype)) - dir_add_ignored(&dir, pathspec[i], strlen(pathspec[i])); + if (is_excluded(&dir, path, &dtype)) + dir_add_ignored(&dir, path, pathspec.items[i].len); } else die(_("pathspec '%s' did not match any files"), - pathspec[i]); + pathspec.items[i].original); } } free(seen); @@ -587,10 +576,11 @@ int cmd_add(int argc, const char **argv, const char *prefix) */ update_data.implicit_dot = prefix; update_data.implicit_dot_len = strlen(prefix); - pathspec = NULL; + free_pathspec(&pathspec); + memset(&pathspec, 0, sizeof(pathspec)); } update_data.flags = flags & ~ADD_CACHE_IMPLICIT_DOT; - update_files_in_cache(prefix, pathspec, &update_data); + update_files_in_cache(prefix, &pathspec, &update_data); exit_status |= !!update_data.add_errors; if (add_new_files) diff --git a/builtin/apply.c b/builtin/apply.c index 50912c928f..ef32e4f624 100644 --- a/builtin/apply.c +++ b/builtin/apply.c @@ -4363,23 +4363,23 @@ int cmd_apply(int argc, const char **argv, const char *prefix_) { OPTION_CALLBACK, 'p', NULL, NULL, N_("num"), N_("remove leading slashes from traditional diff paths"), 0, option_parse_p }, - OPT_BOOLEAN(0, "no-add", &no_add, + OPT_BOOL(0, "no-add", &no_add, N_("ignore additions made by the patch")), - OPT_BOOLEAN(0, "stat", &diffstat, + OPT_BOOL(0, "stat", &diffstat, N_("instead of applying the patch, output diffstat for the input")), OPT_NOOP_NOARG(0, "allow-binary-replacement"), OPT_NOOP_NOARG(0, "binary"), - OPT_BOOLEAN(0, "numstat", &numstat, + OPT_BOOL(0, "numstat", &numstat, N_("show number of added and deleted lines in decimal notation")), - OPT_BOOLEAN(0, "summary", &summary, + OPT_BOOL(0, "summary", &summary, N_("instead of applying the patch, output a summary for the input")), - OPT_BOOLEAN(0, "check", &check, + OPT_BOOL(0, "check", &check, N_("instead of applying the patch, see if the patch is applicable")), - OPT_BOOLEAN(0, "index", &check_index, + OPT_BOOL(0, "index", &check_index, N_("make sure the patch is applicable to the current index")), - OPT_BOOLEAN(0, "cached", &cached, + OPT_BOOL(0, "cached", &cached, N_("apply a patch without touching the working tree")), - OPT_BOOLEAN(0, "apply", &force_apply, + OPT_BOOL(0, "apply", &force_apply, N_("also apply the patch (use with --stat/--summary/--check)")), OPT_BOOL('3', "3way", &threeway, N_( "attempt three-way merge if a patch does not apply")), @@ -4399,13 +4399,13 @@ int cmd_apply(int argc, const char **argv, const char *prefix_) { OPTION_CALLBACK, 0, "ignore-whitespace", NULL, NULL, N_("ignore changes in whitespace when finding context"), PARSE_OPT_NOARG, option_parse_space_change }, - OPT_BOOLEAN('R', "reverse", &apply_in_reverse, + OPT_BOOL('R', "reverse", &apply_in_reverse, N_("apply the patch in reverse")), - OPT_BOOLEAN(0, "unidiff-zero", &unidiff_zero, + OPT_BOOL(0, "unidiff-zero", &unidiff_zero, N_("don't expect at least one line of context")), - OPT_BOOLEAN(0, "reject", &apply_with_reject, + OPT_BOOL(0, "reject", &apply_with_reject, N_("leave the rejected hunks in corresponding *.rej files")), - OPT_BOOLEAN(0, "allow-overlap", &allow_overlap, + OPT_BOOL(0, "allow-overlap", &allow_overlap, N_("allow overlapping hunks")), OPT__VERBOSE(&apply_verbosely, N_("be verbose")), OPT_BIT(0, "inaccurate-eof", &options, diff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c index e3884e3bb6..3324229025 100644 --- a/builtin/bisect--helper.c +++ b/builtin/bisect--helper.c @@ -13,10 +13,10 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix) int next_all = 0; int no_checkout = 0; struct option options[] = { - OPT_BOOLEAN(0, "next-all", &next_all, - N_("perform 'git bisect next'")), - OPT_BOOLEAN(0, "no-checkout", &no_checkout, - N_("update BISECT_HEAD instead of checking out the current commit")), + OPT_BOOL(0, "next-all", &next_all, + N_("perform 'git bisect next'")), + OPT_BOOL(0, "no-checkout", &no_checkout, + N_("update BISECT_HEAD instead of checking out the current commit")), OPT_END() }; diff --git a/builtin/blame.c b/builtin/blame.c index 079dcd3407..6da7233968 100644 --- a/builtin/blame.c +++ b/builtin/blame.c @@ -22,6 +22,7 @@ #include "utf8.h" #include "userdiff.h" #include "line-range.h" +#include "line-log.h" static char blame_usage[] = N_("git blame [options] [rev-opts] [rev] [--] file"); @@ -408,7 +409,7 @@ static struct origin *find_origin(struct scoreboard *sb, paths[0] = origin->path; paths[1] = NULL; - diff_tree_setup_paths(paths, &diff_opts); + parse_pathspec(&diff_opts.pathspec, PATHSPEC_ALL_MAGIC, 0, "", paths); diff_setup_done(&diff_opts); if (is_null_sha1(origin->commit->object.sha1)) @@ -458,7 +459,7 @@ static struct origin *find_origin(struct scoreboard *sb, } } diff_flush(&diff_opts); - diff_tree_release_paths(&diff_opts); + free_pathspec(&diff_opts.pathspec); if (porigin) { /* * Create a freestanding copy that is not part of @@ -486,15 +487,12 @@ static struct origin *find_rename(struct scoreboard *sb, struct origin *porigin = NULL; struct diff_options diff_opts; int i; - const char *paths[2]; diff_setup(&diff_opts); DIFF_OPT_SET(&diff_opts, RECURSIVE); diff_opts.detect_rename = DIFF_DETECT_RENAME; diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT; diff_opts.single_follow = origin->path; - paths[0] = NULL; - diff_tree_setup_paths(paths, &diff_opts); diff_setup_done(&diff_opts); if (is_null_sha1(origin->commit->object.sha1)) @@ -516,7 +514,7 @@ static struct origin *find_rename(struct scoreboard *sb, } } diff_flush(&diff_opts); - diff_tree_release_paths(&diff_opts); + free_pathspec(&diff_opts.pathspec); return porigin; } @@ -1064,7 +1062,6 @@ static int find_copy_in_parent(struct scoreboard *sb, int opt) { struct diff_options diff_opts; - const char *paths[1]; int i, j; int retval; struct blame_list *blame_list; @@ -1078,8 +1075,6 @@ static int find_copy_in_parent(struct scoreboard *sb, DIFF_OPT_SET(&diff_opts, RECURSIVE); diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT; - paths[0] = NULL; - diff_tree_setup_paths(paths, &diff_opts); diff_setup_done(&diff_opts); /* Try "find copies harder" on new path if requested; @@ -1162,7 +1157,7 @@ static int find_copy_in_parent(struct scoreboard *sb, } reset_scanned_flag(sb); diff_flush(&diff_opts); - diff_tree_release_paths(&diff_opts); + free_pathspec(&diff_opts.pathspec); return retval; } @@ -1937,18 +1932,6 @@ static const char *add_prefix(const char *prefix, const char *path) return prefix_path(prefix, prefix ? strlen(prefix) : 0, path); } -/* - * Parsing of -L option - */ -static void prepare_blame_range(struct scoreboard *sb, - const char *bottomtop, - long lno, - long *bottom, long *top) -{ - if (parse_range_arg(bottomtop, nth_line_cb, sb, lno, bottom, top, sb->path)) - usage(blame_usage); -} - static int git_blame_config(const char *var, const char *value, void *cb) { if (!strcmp(var, "blame.showroot")) { @@ -2245,38 +2228,27 @@ static int blame_move_callback(const struct option *option, const char *arg, int return 0; } -static int blame_bottomtop_callback(const struct option *option, const char *arg, int unset) -{ - const char **bottomtop = option->value; - if (!arg) - return -1; - if (*bottomtop) - die("More than one '-L n,m' option given"); - *bottomtop = arg; - return 0; -} - int cmd_blame(int argc, const char **argv, const char *prefix) { struct rev_info revs; const char *path; struct scoreboard sb; struct origin *o; - struct blame_entry *ent; - long dashdash_pos, bottom, top, lno; + struct blame_entry *ent = NULL; + long dashdash_pos, lno; const char *final_commit_name = NULL; enum object_type type; - static const char *bottomtop = NULL; + static struct string_list range_list; static int output_option = 0, opt = 0; static int show_stats = 0; static const char *revs_file = NULL; static const char *contents_from = NULL; static const struct option options[] = { - OPT_BOOLEAN(0, "incremental", &incremental, N_("Show blame entries as we find them, incrementally")), - OPT_BOOLEAN('b', NULL, &blank_boundary, N_("Show blank SHA-1 for boundary commits (Default: off)")), - OPT_BOOLEAN(0, "root", &show_root, N_("Do not treat root commits as boundaries (Default: off)")), - OPT_BOOLEAN(0, "show-stats", &show_stats, N_("Show work cost statistics")), + OPT_BOOL(0, "incremental", &incremental, N_("Show blame entries as we find them, incrementally")), + OPT_BOOL('b', NULL, &blank_boundary, N_("Show blank SHA-1 for boundary commits (Default: off)")), + OPT_BOOL(0, "root", &show_root, N_("Do not treat root commits as boundaries (Default: off)")), + OPT_BOOL(0, "show-stats", &show_stats, N_("Show work cost statistics")), OPT_BIT(0, "score-debug", &output_option, N_("Show output score for blame entries"), OUTPUT_SHOW_SCORE), OPT_BIT('f', "show-name", &output_option, N_("Show original filename (Default: auto)"), OUTPUT_SHOW_NAME), OPT_BIT('n', "show-number", &output_option, N_("Show original linenumber (Default: off)"), OUTPUT_SHOW_NUMBER), @@ -2293,13 +2265,16 @@ int cmd_blame(int argc, const char **argv, const char *prefix) OPT_STRING(0, "contents", &contents_from, N_("file"), N_("Use 's contents as the final image")), { OPTION_CALLBACK, 'C', NULL, &opt, N_("score"), N_("Find line copies within and across files"), PARSE_OPT_OPTARG, blame_copy_callback }, { OPTION_CALLBACK, 'M', NULL, &opt, N_("score"), N_("Find line movements within and across files"), PARSE_OPT_OPTARG, blame_move_callback }, - OPT_CALLBACK('L', NULL, &bottomtop, N_("n,m"), N_("Process only line range n,m, counting from 1"), blame_bottomtop_callback), + OPT_STRING_LIST('L', NULL, &range_list, N_("n,m"), N_("Process only line range n,m, counting from 1")), OPT__ABBREV(&abbrev), OPT_END() }; struct parse_opt_ctx_t ctx; int cmd_is_annotate = !strcmp(argv[0], "annotate"); + struct range_set ranges; + unsigned int range_i; + long anchor; git_config(git_blame_config, NULL); init_revisions(&revs, NULL); @@ -2492,22 +2467,48 @@ int cmd_blame(int argc, const char **argv, const char *prefix) num_read_blob++; lno = prepare_lines(&sb); - bottom = top = 0; - if (bottomtop) - prepare_blame_range(&sb, bottomtop, lno, &bottom, &top); - if (bottom < 1) - bottom = 1; - if (top < 1) - top = lno; - bottom--; - if (lno < top || lno < bottom) - die("file %s has only %lu lines", path, lno); - - ent = xcalloc(1, sizeof(*ent)); - ent->lno = bottom; - ent->num_lines = top - bottom; - ent->suspect = o; - ent->s_lno = bottom; + if (lno && !range_list.nr) + string_list_append(&range_list, xstrdup("1")); + + anchor = 1; + range_set_init(&ranges, range_list.nr); + for (range_i = 0; range_i < range_list.nr; ++range_i) { + long bottom, top; + if (parse_range_arg(range_list.items[range_i].string, + nth_line_cb, &sb, lno, anchor, + &bottom, &top, sb.path)) + usage(blame_usage); + if (lno < top || ((lno || bottom) && lno < bottom)) + die("file %s has only %lu lines", path, lno); + if (bottom < 1) + bottom = 1; + if (top < 1) + top = lno; + bottom--; + range_set_append_unsafe(&ranges, bottom, top); + anchor = top + 1; + } + sort_and_merge_range_set(&ranges); + + for (range_i = ranges.nr; range_i > 0; --range_i) { + const struct range *r = &ranges.ranges[range_i - 1]; + long bottom = r->start; + long top = r->end; + struct blame_entry *next = ent; + ent = xcalloc(1, sizeof(*ent)); + ent->lno = bottom; + ent->num_lines = top - bottom; + ent->suspect = o; + ent->s_lno = bottom; + ent->next = next; + if (next) + next->prev = ent; + origin_incref(o); + } + origin_decref(o); + + range_set_release(&ranges); + string_list_clear(&range_list, 0); sb.ent = ent; sb.path = path; diff --git a/builtin/branch.c b/builtin/branch.c index 083689063f..0903763702 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -797,7 +797,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix) OPT_SET_INT( 0, "set-upstream", &track, N_("change upstream info"), BRANCH_TRACK_OVERRIDE), OPT_STRING('u', "set-upstream-to", &new_upstream, "upstream", "change the upstream info"), - OPT_BOOLEAN(0, "unset-upstream", &unset_upstream, "Unset the upstream info"), + OPT_BOOL(0, "unset-upstream", &unset_upstream, "Unset the upstream info"), OPT__COLOR(&branch_use_color, N_("use colored output")), OPT_SET_INT('r', "remotes", &kinds, N_("act on remote-tracking branches"), REF_REMOTE_BRANCH), @@ -822,10 +822,10 @@ int cmd_branch(int argc, const char **argv, const char *prefix) OPT_BIT('D', NULL, &delete, N_("delete branch (even if not merged)"), 2), OPT_BIT('m', "move", &rename, N_("move/rename a branch and its reflog"), 1), OPT_BIT('M', NULL, &rename, N_("move/rename a branch, even if target exists"), 2), - OPT_BOOLEAN(0, "list", &list, N_("list branch names")), - OPT_BOOLEAN('l', "create-reflog", &reflog, N_("create the branch's reflog")), - OPT_BOOLEAN(0, "edit-description", &edit_description, - N_("edit the description for the branch")), + OPT_BOOL(0, "list", &list, N_("list branch names")), + OPT_BOOL('l', "create-reflog", &reflog, N_("create the branch's reflog")), + OPT_BOOL(0, "edit-description", &edit_description, + N_("edit the description for the branch")), OPT__FORCE(&force_create, N_("force creation (when already exists)")), { OPTION_CALLBACK, 0, "no-merged", &merge_filter_ref, @@ -872,7 +872,8 @@ int cmd_branch(int argc, const char **argv, const char *prefix) if (with_commit || merge_filter != NO_FILTER) list = 1; - if (!!delete + !!rename + !!force_create + !!list + !!new_upstream + !!unset_upstream > 1) + if (!!delete + !!rename + !!force_create + !!new_upstream + + list + unset_upstream > 1) usage_with_options(builtin_branch_usage, options); if (abbrev == -1) diff --git a/builtin/cat-file.c b/builtin/cat-file.c index 425346048b..41afaa534b 100644 --- a/builtin/cat-file.c +++ b/builtin/cat-file.c @@ -119,6 +119,7 @@ struct expand_data { enum object_type type; unsigned long size; unsigned long disk_size; + const char *rest; /* * If mark_query is true, we do not expand anything, but rather @@ -126,6 +127,13 @@ struct expand_data { */ int mark_query; + /* + * Whether to split the input on whitespace before feeding it to + * get_sha1; this is decided during the mark_query phase based on + * whether we have a %(rest) token in our format. + */ + int split_on_whitespace; + /* * After a mark_query run, this object_info is set up to be * passed to sha1_object_info_extended. It will point to the data @@ -163,6 +171,11 @@ static void expand_atom(struct strbuf *sb, const char *atom, int len, data->info.disk_sizep = &data->disk_size; else strbuf_addf(sb, "%lu", data->disk_size); + } else if (is_atom("rest", atom, len)) { + if (data->mark_query) + data->split_on_whitespace = 1; + else if (data->rest) + strbuf_addstr(sb, data->rest); } else die("unknown format element: %.*s", len, atom); } @@ -273,7 +286,23 @@ static int batch_objects(struct batch_options *opt) warn_on_object_refname_ambiguity = 0; while (strbuf_getline(&buf, stdin, '\n') != EOF) { - int error = batch_one_object(buf.buf, opt, &data); + int error; + + if (data.split_on_whitespace) { + /* + * Split at first whitespace, tying off the beginning + * of the string and saving the remainder (or NULL) in + * data.rest. + */ + char *p = strpbrk(buf.buf, " \t"); + if (p) { + while (*p && strchr(" \t", *p)) + *p++ = '\0'; + } + data.rest = p; + } + + error = batch_one_object(buf.buf, opt, &data); if (error) return error; } diff --git a/builtin/check-attr.c b/builtin/check-attr.c index 075d01d30c..e9af7b2bfb 100644 --- a/builtin/check-attr.c +++ b/builtin/check-attr.c @@ -13,14 +13,14 @@ N_("git check-attr --stdin [-z] [-a | --all | attr...] < "), NULL }; -static int null_term_line; +static int nul_term_line; static const struct option check_attr_options[] = { - OPT_BOOLEAN('a', "all", &all_attrs, N_("report all attributes set on file")), - OPT_BOOLEAN(0, "cached", &cached_attrs, N_("use .gitattributes only from the index")), - OPT_BOOLEAN(0 , "stdin", &stdin_paths, N_("read file names from stdin")), - OPT_BOOLEAN('z', NULL, &null_term_line, - N_("input paths are terminated by a null character")), + OPT_BOOL('a', "all", &all_attrs, N_("report all attributes set on file")), + OPT_BOOL(0, "cached", &cached_attrs, N_("use .gitattributes only from the index")), + OPT_BOOL(0 , "stdin", &stdin_paths, N_("read file names from stdin")), + OPT_BOOL('z', NULL, &nul_term_line, + N_("terminate input and output records by a NUL character")), OPT_END() }; @@ -38,8 +38,16 @@ static void output_attr(int cnt, struct git_attr_check *check, else if (ATTR_UNSET(value)) value = "unspecified"; - quote_c_style(file, NULL, stdout, 0); - printf(": %s: %s\n", git_attr_name(check[j].attr), value); + if (nul_term_line) { + printf("%s%c" /* path */ + "%s%c" /* attrname */ + "%s%c" /* attrvalue */, + file, 0, git_attr_name(check[j].attr), 0, value, 0); + } else { + quote_c_style(file, NULL, stdout, 0); + printf(": %s: %s\n", git_attr_name(check[j].attr), value); + } + } } @@ -65,7 +73,7 @@ static void check_attr_stdin_paths(const char *prefix, int cnt, struct git_attr_check *check) { struct strbuf buf, nbuf; - int line_termination = null_term_line ? 0 : '\n'; + int line_termination = nul_term_line ? 0 : '\n'; strbuf_init(&buf, 0); strbuf_init(&nbuf, 0); diff --git a/builtin/check-ignore.c b/builtin/check-ignore.c index 4a8fc707c7..e2a1cef684 100644 --- a/builtin/check-ignore.c +++ b/builtin/check-ignore.c @@ -12,18 +12,18 @@ static const char * const check_ignore_usage[] = { NULL }; -static int null_term_line; +static int nul_term_line; static const struct option check_ignore_options[] = { OPT__QUIET(&quiet, N_("suppress progress reporting")), OPT__VERBOSE(&verbose, N_("be verbose")), OPT_GROUP(""), - OPT_BOOLEAN(0, "stdin", &stdin_paths, - N_("read file names from stdin")), - OPT_BOOLEAN('z', NULL, &null_term_line, - N_("input paths are terminated by a null character")), - OPT_BOOLEAN('n', "non-matching", &show_non_matching, - N_("show non-matching input paths")), + OPT_BOOL(0, "stdin", &stdin_paths, + N_("read file names from stdin")), + OPT_BOOL('z', NULL, &nul_term_line, + N_("terminate input and output records by a NUL character")), + OPT_BOOL('n', "non-matching", &show_non_matching, + N_("show non-matching input paths")), OPT_END() }; @@ -31,7 +31,7 @@ static void output_exclude(const char *path, struct exclude *exclude) { char *bang = (exclude && exclude->flags & EXC_FLAG_NEGATIVE) ? "!" : ""; char *slash = (exclude && exclude->flags & EXC_FLAG_MUSTBEDIR) ? "/" : ""; - if (!null_term_line) { + if (!nul_term_line) { if (!verbose) { write_name_quoted(path, stdout, '\n'); } else { @@ -64,37 +64,45 @@ static void output_exclude(const char *path, struct exclude *exclude) } static int check_ignore(struct dir_struct *dir, - const char *prefix, const char **pathspec) + const char *prefix, int argc, const char **argv) { - const char *path, *full_path; + const char *full_path; char *seen; int num_ignored = 0, dtype = DT_UNKNOWN, i; struct exclude *exclude; + struct pathspec pathspec; - if (!pathspec || !*pathspec) { + if (!argc) { if (!quiet) fprintf(stderr, "no pathspec given.\n"); return 0; } + /* + * check-ignore just needs paths. Magic beyond :/ is really + * irrelevant. + */ + parse_pathspec(&pathspec, + PATHSPEC_ALL_MAGIC & ~PATHSPEC_FROMTOP, + PATHSPEC_SYMLINK_LEADING_PATH | + PATHSPEC_STRIP_SUBMODULE_SLASH_EXPENSIVE | + PATHSPEC_KEEP_ORDER, + prefix, argv); + /* * look for pathspecs matching entries in the index, since these * should not be ignored, in order to be consistent with * 'git status', 'git add' etc. */ - seen = find_pathspecs_matching_against_index(pathspec); - for (i = 0; pathspec[i]; i++) { - path = pathspec[i]; - full_path = prefix_path(prefix, prefix - ? strlen(prefix) : 0, path); - full_path = check_path_for_gitlink(full_path); - die_if_path_beyond_symlink(full_path, prefix); + seen = find_pathspecs_matching_against_index(&pathspec); + for (i = 0; i < pathspec.nr; i++) { + full_path = pathspec.items[i].match; exclude = NULL; if (!seen[i]) { exclude = last_exclude_matching(dir, full_path, &dtype); } if (!quiet && (exclude || show_non_matching)) - output_exclude(path, exclude); + output_exclude(pathspec.items[i].original, exclude); if (exclude) num_ignored++; } @@ -107,7 +115,7 @@ static int check_ignore_stdin_paths(struct dir_struct *dir, const char *prefix) { struct strbuf buf, nbuf; char *pathspec[2] = { NULL, NULL }; - int line_termination = null_term_line ? 0 : '\n'; + int line_termination = nul_term_line ? 0 : '\n'; int num_ignored = 0; strbuf_init(&buf, 0); @@ -120,7 +128,8 @@ static int check_ignore_stdin_paths(struct dir_struct *dir, const char *prefix) strbuf_swap(&buf, &nbuf); } pathspec[0] = buf.buf; - num_ignored += check_ignore(dir, prefix, (const char **)pathspec); + num_ignored += check_ignore(dir, prefix, + 1, (const char **)pathspec); maybe_flush_or_die(stdout, "check-ignore to stdout"); } strbuf_release(&buf); @@ -142,7 +151,7 @@ int cmd_check_ignore(int argc, const char **argv, const char *prefix) if (argc > 0) die(_("cannot specify pathnames with --stdin")); } else { - if (null_term_line) + if (nul_term_line) die(_("-z only makes sense with --stdin")); if (argc == 0) die(_("no path specified")); @@ -166,7 +175,7 @@ int cmd_check_ignore(int argc, const char **argv, const char *prefix) if (stdin_paths) { num_ignored = check_ignore_stdin_paths(&dir, prefix); } else { - num_ignored = check_ignore(&dir, prefix, argv); + num_ignored = check_ignore(&dir, prefix, argc, argv); maybe_flush_or_die(stdout, "ignore to stdout"); } diff --git a/builtin/checkout-index.c b/builtin/checkout-index.c index b1feda7d5e..69e167b16c 100644 --- a/builtin/checkout-index.c +++ b/builtin/checkout-index.c @@ -183,12 +183,12 @@ int cmd_checkout_index(int argc, const char **argv, const char *prefix) int prefix_length; int force = 0, quiet = 0, not_new = 0; struct option builtin_checkout_index_options[] = { - OPT_BOOLEAN('a', "all", &all, + OPT_BOOL('a', "all", &all, N_("check out all files in the index")), OPT__FORCE(&force, N_("force overwrite of existing files")), OPT__QUIET(&quiet, N_("no warning for existing files and files not in index")), - OPT_BOOLEAN('n', "no-create", ¬_new, + OPT_BOOL('n', "no-create", ¬_new, N_("don't checkout new files")), { OPTION_CALLBACK, 'u', "index", &newfd, NULL, N_("update stat information in the index file"), @@ -196,9 +196,9 @@ int cmd_checkout_index(int argc, const char **argv, const char *prefix) { OPTION_CALLBACK, 'z', NULL, NULL, NULL, N_("paths are separated with NUL character"), PARSE_OPT_NOARG, option_parse_z }, - OPT_BOOLEAN(0, "stdin", &read_from_stdin, + OPT_BOOL(0, "stdin", &read_from_stdin, N_("read list of paths from the standard input")), - OPT_BOOLEAN(0, "temp", &to_tempfile, + OPT_BOOL(0, "temp", &to_tempfile, N_("write the content to temporary files")), OPT_CALLBACK(0, "prefix", NULL, N_("string"), N_("when creating files, prepend "), diff --git a/builtin/checkout.c b/builtin/checkout.c index 7025938ae3..62a96a7e2f 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -46,7 +46,7 @@ struct checkout_opts { int branch_exists; const char *prefix; - const char **pathspec; + struct pathspec pathspec; struct tree *source_tree; }; @@ -83,12 +83,9 @@ static int update_some(const unsigned char *sha1, const char *base, int baselen, return 0; } -static int read_tree_some(struct tree *tree, const char **pathspec) +static int read_tree_some(struct tree *tree, const struct pathspec *pathspec) { - struct pathspec ps; - init_pathspec(&ps, pathspec); - read_tree_recursive(tree, "", 0, 0, &ps, update_some, NULL); - free_pathspec(&ps); + read_tree_recursive(tree, "", 0, 0, pathspec, update_some, NULL); /* update the index with the given tree's info * for all args, expanding wildcards, and exit @@ -228,8 +225,6 @@ static int checkout_paths(const struct checkout_opts *opts, int flag; struct commit *head; int errs = 0; - int stage = opts->writeout_stage; - int merge = opts->merge; int newfd; struct lock_file *lock_file; @@ -257,20 +252,18 @@ static int checkout_paths(const struct checkout_opts *opts, if (opts->patch_mode) return run_add_interactive(revision, "--patch=checkout", - opts->pathspec); + &opts->pathspec); lock_file = xcalloc(1, sizeof(struct lock_file)); newfd = hold_locked_index(lock_file, 1); - if (read_cache_preload(opts->pathspec) < 0) + if (read_cache_preload(&opts->pathspec) < 0) return error(_("corrupt index file")); if (opts->source_tree) - read_tree_some(opts->source_tree, opts->pathspec); + read_tree_some(opts->source_tree, &opts->pathspec); - for (pos = 0; opts->pathspec[pos]; pos++) - ; - ps_matched = xcalloc(1, pos); + ps_matched = xcalloc(1, opts->pathspec.nr); /* * Make sure all pathspecs participated in locating the paths @@ -304,12 +297,12 @@ static int checkout_paths(const struct checkout_opts *opts, * match_pathspec() for _all_ entries when * opts->source_tree != NULL. */ - if (match_pathspec(opts->pathspec, ce->name, ce_namelen(ce), + if (match_pathspec_depth(&opts->pathspec, ce->name, ce_namelen(ce), 0, ps_matched)) ce->ce_flags |= CE_MATCHED; } - if (report_path_error(ps_matched, opts->pathspec, opts->prefix)) { + if (report_path_error(ps_matched, &opts->pathspec, opts->prefix)) { free(ps_matched); return 1; } @@ -327,8 +320,8 @@ static int checkout_paths(const struct checkout_opts *opts, continue; if (opts->force) { warning(_("path '%s' is unmerged"), ce->name); - } else if (stage) { - errs |= check_stage(stage, ce, pos); + } else if (opts->writeout_stage) { + errs |= check_stage(opts->writeout_stage, ce, pos); } else if (opts->merge) { errs |= check_stages((1<<2) | (1<<3), ce, pos); } else { @@ -352,9 +345,9 @@ static int checkout_paths(const struct checkout_opts *opts, errs |= checkout_entry(ce, &state, NULL); continue; } - if (stage) - errs |= checkout_stage(stage, ce, pos, &state); - else if (merge) + if (opts->writeout_stage) + errs |= checkout_stage(opts->writeout_stage, ce, pos, &state); + else if (opts->merge) errs |= checkout_merged(pos, &state); pos = skip_same_name(ce, pos) - 1; } @@ -1002,7 +995,7 @@ static int switch_unborn_to_new_branch(const struct checkout_opts *opts) static int checkout_branch(struct checkout_opts *opts, struct branch_info *new) { - if (opts->pathspec) + if (opts->pathspec.nr) die(_("paths cannot be used with switching branches")); if (opts->patch_mode) @@ -1056,8 +1049,8 @@ int cmd_checkout(int argc, const char **argv, const char *prefix) N_("create and checkout a new branch")), OPT_STRING('B', NULL, &opts.new_branch_force, N_("branch"), N_("create/reset and checkout a branch")), - OPT_BOOLEAN('l', NULL, &opts.new_branch_log, N_("create reflog for new branch")), - OPT_BOOLEAN(0, "detach", &opts.force_detach, N_("detach the HEAD at named commit")), + OPT_BOOL('l', NULL, &opts.new_branch_log, N_("create reflog for new branch")), + OPT_BOOL(0, "detach", &opts.force_detach, N_("detach the HEAD at named commit")), OPT_SET_INT('t', "track", &opts.track, N_("set upstream info for new branch"), BRANCH_TRACK_EXPLICIT), OPT_STRING(0, "orphan", &opts.new_orphan_branch, N_("new branch"), N_("new unparented branch")), @@ -1066,16 +1059,15 @@ int cmd_checkout(int argc, const char **argv, const char *prefix) OPT_SET_INT('3', "theirs", &opts.writeout_stage, N_("checkout their version for unmerged files"), 3), OPT__FORCE(&opts.force, N_("force checkout (throw away local modifications)")), - OPT_BOOLEAN('m', "merge", &opts.merge, N_("perform a 3-way merge with the new branch")), - OPT_BOOLEAN(0, "overwrite-ignore", &opts.overwrite_ignore, N_("update ignored files (default)")), + OPT_BOOL('m', "merge", &opts.merge, N_("perform a 3-way merge with the new branch")), + OPT_BOOL(0, "overwrite-ignore", &opts.overwrite_ignore, N_("update ignored files (default)")), OPT_STRING(0, "conflict", &conflict_style, N_("style"), N_("conflict style (merge or diff3)")), - OPT_BOOLEAN('p', "patch", &opts.patch_mode, N_("select hunks interactively")), + OPT_BOOL('p', "patch", &opts.patch_mode, N_("select hunks interactively")), OPT_BOOL(0, "ignore-skip-worktree-bits", &opts.ignore_skipworktree, N_("do not limit pathspecs to sparse entries only")), - { OPTION_BOOLEAN, 0, "guess", &dwim_new_local_branch, NULL, - N_("second guess 'git checkout no-such-branch'"), - PARSE_OPT_NOARG | PARSE_OPT_HIDDEN }, + OPT_HIDDEN_BOOL(0, "guess", &dwim_new_local_branch, + N_("second guess 'git checkout no-such-branch'")), OPT_END(), }; @@ -1154,9 +1146,18 @@ int cmd_checkout(int argc, const char **argv, const char *prefix) } if (argc) { - opts.pathspec = get_pathspec(prefix, argv); + /* + * In patch mode (opts.patch_mode != 0), we pass the + * pathspec to an external program, git-add--interactive. + * Do not accept any kind of magic that that program + * cannot handle. Magic mask is pretty safe to be + * lifted for new magic when opts.patch_mode == 0. + */ + parse_pathspec(&opts.pathspec, 0, + opts.patch_mode ? PATHSPEC_PREFIX_ORIGIN : 0, + prefix, argv); - if (!opts.pathspec) + if (!opts.pathspec.nr) die(_("invalid path specification")); /* @@ -1188,7 +1189,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix) strbuf_release(&buf); } - if (opts.patch_mode || opts.pathspec) + if (opts.patch_mode || opts.pathspec.nr) return checkout_paths(&opts, new.name); else return checkout_branch(&opts, &new); diff --git a/builtin/clean.c b/builtin/clean.c index 3c85e152e1..615cd57caf 100644 --- a/builtin/clean.c +++ b/builtin/clean.c @@ -15,6 +15,7 @@ #include "quote.h" #include "column.h" #include "color.h" +#include "pathspec.h" static int force = -1; /* unset */ static int interactive; @@ -863,24 +864,23 @@ int cmd_clean(int argc, const char **argv, const char *prefix) int rm_flags = REMOVE_DIR_KEEP_NESTED_GIT; struct strbuf abs_path = STRBUF_INIT; struct dir_struct dir; - static const char **pathspec; + struct pathspec pathspec; struct strbuf buf = STRBUF_INIT; struct string_list exclude_list = STRING_LIST_INIT_NODUP; struct exclude_list *el; struct string_list_item *item; const char *qname; - char *seen = NULL; struct option options[] = { OPT__QUIET(&quiet, N_("do not print names of files removed")), OPT__DRY_RUN(&dry_run, N_("dry run")), OPT__FORCE(&force, N_("force")), OPT_BOOL('i', "interactive", &interactive, N_("interactive cleaning")), - OPT_BOOLEAN('d', NULL, &remove_directories, + OPT_BOOL('d', NULL, &remove_directories, N_("remove whole directories")), { OPTION_CALLBACK, 'e', "exclude", &exclude_list, N_("pattern"), N_("add to ignore rules"), PARSE_OPT_NONEG, exclude_cb }, - OPT_BOOLEAN('x', NULL, &ignored, N_("remove ignored files, too")), - OPT_BOOLEAN('X', NULL, &ignored_only, + OPT_BOOL('x', NULL, &ignored, N_("remove ignored files, too")), + OPT_BOOL('X', NULL, &ignored_only, N_("remove only ignored files")), OPT_END() }; @@ -925,12 +925,11 @@ int cmd_clean(int argc, const char **argv, const char *prefix) for (i = 0; i < exclude_list.nr; i++) add_exclude(exclude_list.items[i].string, "", 0, el, -(i+1)); - pathspec = get_pathspec(prefix, argv); + parse_pathspec(&pathspec, 0, + PATHSPEC_PREFER_CWD, + prefix, argv); - fill_directory(&dir, pathspec); - - if (pathspec) - seen = xmalloc(argc > 0 ? argc : 1); + fill_directory(&dir, &pathspec); for (i = 0; i < dir.nr; i++) { struct dir_entry *ent = dir.entries[i]; @@ -961,11 +960,9 @@ int cmd_clean(int argc, const char **argv, const char *prefix) if (lstat(ent->name, &st)) die_errno("Cannot lstat '%s'", ent->name); - if (pathspec) { - memset(seen, 0, argc > 0 ? argc : 1); - matches = match_pathspec(pathspec, ent->name, len, - 0, seen); - } + if (pathspec.nr) + matches = match_pathspec_depth(&pathspec, ent->name, + len, 0, NULL); if (S_ISDIR(st.st_mode)) { if (remove_directories || (matches == MATCHED_EXACTLY)) { @@ -973,7 +970,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix) string_list_append(&del_list, rel); } } else { - if (pathspec && !matches) + if (pathspec.nr && !matches) continue; rel = relative_path(ent->name, prefix, &buf); string_list_append(&del_list, rel); @@ -1019,7 +1016,6 @@ int cmd_clean(int argc, const char **argv, const char *prefix) } strbuf_reset(&abs_path); } - free(seen); strbuf_release(&abs_path); strbuf_release(&buf); diff --git a/builtin/clone.c b/builtin/clone.c index 430307b298..ca3eb68d72 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -62,23 +62,22 @@ static struct option builtin_clone_options[] = { OPT__VERBOSITY(&option_verbosity), OPT_BOOL(0, "progress", &option_progress, N_("force progress reporting")), - OPT_BOOLEAN('n', "no-checkout", &option_no_checkout, - N_("don't create a checkout")), - OPT_BOOLEAN(0, "bare", &option_bare, N_("create a bare repository")), - { OPTION_BOOLEAN, 0, "naked", &option_bare, NULL, - N_("create a bare repository"), - PARSE_OPT_NOARG | PARSE_OPT_HIDDEN }, - OPT_BOOLEAN(0, "mirror", &option_mirror, - N_("create a mirror repository (implies bare)")), + OPT_BOOL('n', "no-checkout", &option_no_checkout, + N_("don't create a checkout")), + OPT_BOOL(0, "bare", &option_bare, N_("create a bare repository")), + OPT_HIDDEN_BOOL(0, "naked", &option_bare, + N_("create a bare repository")), + OPT_BOOL(0, "mirror", &option_mirror, + N_("create a mirror repository (implies bare)")), OPT_BOOL('l', "local", &option_local, N_("to clone from a local repository")), - OPT_BOOLEAN(0, "no-hardlinks", &option_no_hardlinks, + OPT_BOOL(0, "no-hardlinks", &option_no_hardlinks, N_("don't use local hardlinks, always copy")), - OPT_BOOLEAN('s', "shared", &option_shared, + OPT_BOOL('s', "shared", &option_shared, N_("setup as shared repository")), - OPT_BOOLEAN(0, "recursive", &option_recursive, + OPT_BOOL(0, "recursive", &option_recursive, N_("initialize submodules in the clone")), - OPT_BOOLEAN(0, "recurse-submodules", &option_recursive, + OPT_BOOL(0, "recurse-submodules", &option_recursive, N_("initialize submodules in the clone")), OPT_STRING(0, "template", &option_template, N_("template-directory"), N_("directory from which templates will be used")), diff --git a/builtin/commit.c b/builtin/commit.c index 10acc53f80..80d886ab3a 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -202,17 +202,15 @@ static int commit_index_files(void) * and return the paths that match the given pattern in list. */ static int list_paths(struct string_list *list, const char *with_tree, - const char *prefix, const char **pattern) + const char *prefix, const struct pathspec *pattern) { int i; char *m; - if (!pattern) + if (!pattern->nr) return 0; - for (i = 0; pattern[i]; i++) - ; - m = xcalloc(1, i); + m = xcalloc(1, pattern->nr); if (with_tree) { char *max_prefix = common_prefix(pattern); @@ -226,7 +224,7 @@ static int list_paths(struct string_list *list, const char *with_tree, if (ce->ce_flags & CE_UPDATE) continue; - if (!match_pathspec(pattern, ce->name, ce_namelen(ce), 0, m)) + if (!match_pathspec_depth(pattern, ce->name, ce_namelen(ce), 0, m)) continue; item = string_list_insert(list, ce->name); if (ce_skip_worktree(ce)) @@ -298,17 +296,17 @@ static char *prepare_index(int argc, const char **argv, const char *prefix, { int fd; struct string_list partial; - const char **pathspec = NULL; + struct pathspec pathspec; char *old_index_env = NULL; int refresh_flags = REFRESH_QUIET; if (is_status) refresh_flags |= REFRESH_UNMERGED; + parse_pathspec(&pathspec, 0, + PATHSPEC_PREFER_FULL, + prefix, argv); - if (*argv) - pathspec = get_pathspec(prefix, argv); - - if (read_cache_preload(pathspec) < 0) + if (read_cache_preload(&pathspec) < 0) die(_("index file corrupt")); if (interactive) { @@ -350,9 +348,9 @@ static char *prepare_index(int argc, const char **argv, const char *prefix, * (A) if all goes well, commit the real index; * (B) on failure, rollback the real index. */ - if (all || (also && pathspec && *pathspec)) { + if (all || (also && pathspec.nr)) { fd = hold_locked_index(&index_lock, 1); - add_files_to_cache(also ? prefix : NULL, pathspec, 0); + add_files_to_cache(also ? prefix : NULL, &pathspec, 0); refresh_cache_or_die(refresh_flags); update_main_cache_tree(WRITE_TREE_SILENT); if (write_cache(fd, active_cache, active_nr) || @@ -371,7 +369,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix, * and create commit from the_index. * We still need to refresh the index here. */ - if (!only && (!pathspec || !*pathspec)) { + if (!only && !pathspec.nr) { fd = hold_locked_index(&index_lock, 1); refresh_cache_or_die(refresh_flags); if (active_cache_changed) { @@ -416,7 +414,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix, memset(&partial, 0, sizeof(partial)); partial.strdup_strings = 1; - if (list_paths(&partial, !current_head ? NULL : "HEAD", prefix, pathspec)) + if (list_paths(&partial, !current_head ? NULL : "HEAD", prefix, &pathspec)) exit(1); discard_cache(); @@ -1091,7 +1089,7 @@ static int parse_and_validate_options(int argc, const char *argv[], if (patch_interactive) interactive = 1; - if (!!also + !!only + !!all + !!interactive > 1) + if (also + only + all + interactive > 1) die(_("Only one of --include/--only/--all/--interactive/--patch can be used.")); if (argc == 0 && (also || (only && !amend))) die(_("No paths with --include/--only does not make sense.")); @@ -1228,14 +1226,14 @@ int cmd_status(int argc, const char **argv, const char *prefix) 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_BOOL('z', "null", &s.null_termination, + N_("terminate entries with NUL")), { OPTION_STRING, 'u', "untracked-files", &untracked_files_arg, N_("mode"), N_("show untracked files, optional modes: all, normal, no. (Default: all)"), PARSE_OPT_OPTARG, NULL, (intptr_t)"all" }, - OPT_BOOLEAN(0, "ignored", &show_ignored_in_status, - N_("show ignored files")), + OPT_BOOL(0, "ignored", &show_ignored_in_status, + N_("show ignored files")), { OPTION_STRING, 0, "ignore-submodules", &ignore_submodule_arg, N_("when"), N_("ignore changes to submodules, optional when: all, dirty, untracked. (Default: all)"), PARSE_OPT_OPTARG, NULL, (intptr_t)"all" }, @@ -1259,11 +1257,12 @@ int cmd_status(int argc, const char **argv, const char *prefix) handle_untracked_files_arg(&s); if (show_ignored_in_status) s.show_ignored_files = 1; - if (*argv) - s.pathspec = get_pathspec(prefix, argv); + parse_pathspec(&s.pathspec, 0, + PATHSPEC_PREFER_FULL, + prefix, argv); - read_cache_preload(s.pathspec); - refresh_index(&the_index, REFRESH_QUIET|REFRESH_UNMERGED, s.pathspec, NULL, NULL); + read_cache_preload(&s.pathspec); + refresh_index(&the_index, REFRESH_QUIET|REFRESH_UNMERGED, &s.pathspec, NULL, NULL); fd = hold_locked_index(&index_lock, 0); if (0 <= fd) @@ -1434,24 +1433,24 @@ int cmd_commit(int argc, const char **argv, const char *prefix) OPT_STRING('C', "reuse-message", &use_message, N_("commit"), N_("reuse message from specified commit")), OPT_STRING(0, "fixup", &fixup_message, N_("commit"), N_("use autosquash formatted message to fixup specified commit")), OPT_STRING(0, "squash", &squash_message, N_("commit"), N_("use autosquash formatted message to squash specified commit")), - OPT_BOOLEAN(0, "reset-author", &renew_authorship, N_("the commit is authored by me now (used with -C/-c/--amend)")), - OPT_BOOLEAN('s', "signoff", &signoff, N_("add Signed-off-by:")), + OPT_BOOL(0, "reset-author", &renew_authorship, N_("the commit is authored by me now (used with -C/-c/--amend)")), + OPT_BOOL('s', "signoff", &signoff, N_("add Signed-off-by:")), OPT_FILENAME('t', "template", &template_file, N_("use specified template file")), OPT_BOOL('e', "edit", &edit_flag, N_("force edit of commit")), OPT_STRING(0, "cleanup", &cleanup_arg, N_("default"), N_("how to strip spaces and #comments from message")), - OPT_BOOLEAN(0, "status", &include_status, N_("include status in commit message template")), + OPT_BOOL(0, "status", &include_status, N_("include status in commit message template")), { OPTION_STRING, 'S', "gpg-sign", &sign_commit, N_("key id"), N_("GPG sign commit"), PARSE_OPT_OPTARG, NULL, (intptr_t) "" }, /* end commit message options */ OPT_GROUP(N_("Commit contents options")), - OPT_BOOLEAN('a', "all", &all, N_("commit all changed files")), - OPT_BOOLEAN('i', "include", &also, N_("add specified files to index for commit")), - OPT_BOOLEAN(0, "interactive", &interactive, N_("interactively add files")), - OPT_BOOLEAN('p', "patch", &patch_interactive, N_("interactively add changes")), - OPT_BOOLEAN('o', "only", &only, N_("commit only specified files")), - OPT_BOOLEAN('n', "no-verify", &no_verify, N_("bypass pre-commit hook")), - OPT_BOOLEAN(0, "dry-run", &dry_run, N_("show what would be committed")), + OPT_BOOL('a', "all", &all, N_("commit all changed files")), + OPT_BOOL('i', "include", &also, N_("add specified files to index for commit")), + OPT_BOOL(0, "interactive", &interactive, N_("interactively add files")), + OPT_BOOL('p', "patch", &patch_interactive, N_("interactively add changes")), + OPT_BOOL('o', "only", &only, N_("commit only specified files")), + OPT_BOOL('n', "no-verify", &no_verify, N_("bypass pre-commit hook")), + OPT_BOOL(0, "dry-run", &dry_run, N_("show what would be committed")), OPT_SET_INT(0, "short", &status_format, N_("show status concisely"), STATUS_FORMAT_SHORT), OPT_BOOL(0, "branch", &s.show_branch, N_("show branch information")), @@ -1460,19 +1459,17 @@ int cmd_commit(int argc, const char **argv, const char *prefix) 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")), - OPT_BOOLEAN(0, "no-post-rewrite", &no_post_rewrite, N_("bypass post-rewrite hook")), + OPT_BOOL('z', "null", &s.null_termination, + N_("terminate entries with NUL")), + OPT_BOOL(0, "amend", &amend, N_("amend previous commit")), + OPT_BOOL(0, "no-post-rewrite", &no_post_rewrite, N_("bypass post-rewrite hook")), { OPTION_STRING, 'u', "untracked-files", &untracked_files_arg, N_("mode"), N_("show untracked files, optional modes: all, normal, no. (Default: all)"), PARSE_OPT_OPTARG, NULL, (intptr_t)"all" }, /* end commit contents options */ - { OPTION_BOOLEAN, 0, "allow-empty", &allow_empty, NULL, - N_("ok to record an empty change"), - PARSE_OPT_NOARG | PARSE_OPT_HIDDEN }, - { OPTION_BOOLEAN, 0, "allow-empty-message", &allow_empty_message, NULL, - N_("ok to record a change with an empty message"), - PARSE_OPT_NOARG | PARSE_OPT_HIDDEN }, + OPT_HIDDEN_BOOL(0, "allow-empty", &allow_empty, + N_("ok to record an empty change")), + OPT_HIDDEN_BOOL(0, "allow-empty-message", &allow_empty_message, + N_("ok to record a change with an empty message")), OPT_END() }; diff --git a/builtin/config.c b/builtin/config.c index 4010c4320a..fc8d8820cb 100644 --- a/builtin/config.c +++ b/builtin/config.c @@ -2,6 +2,7 @@ #include "cache.h" #include "color.h" #include "parse-options.h" +#include "urlmatch.h" static const char *const builtin_config_usage[] = { N_("git config [options]"), @@ -42,6 +43,7 @@ static int respect_includes = -1; #define ACTION_SET_ALL (1<<12) #define ACTION_GET_COLOR (1<<13) #define ACTION_GET_COLORBOOL (1<<14) +#define ACTION_GET_URLMATCH (1<<15) #define TYPE_BOOL (1<<0) #define TYPE_INT (1<<1) @@ -50,15 +52,16 @@ static int respect_includes = -1; static struct option builtin_config_options[] = { OPT_GROUP(N_("Config file location")), - OPT_BOOLEAN(0, "global", &use_global_config, N_("use global config file")), - OPT_BOOLEAN(0, "system", &use_system_config, N_("use system config file")), - OPT_BOOLEAN(0, "local", &use_local_config, N_("use repository config file")), + OPT_BOOL(0, "global", &use_global_config, N_("use global config file")), + OPT_BOOL(0, "system", &use_system_config, N_("use system config file")), + OPT_BOOL(0, "local", &use_local_config, N_("use repository config file")), OPT_STRING('f', "file", &given_config_file, N_("file"), N_("use given config file")), OPT_STRING(0, "blob", &given_config_blob, N_("blob-id"), N_("read config from given blob object")), OPT_GROUP(N_("Action")), OPT_BIT(0, "get", &actions, N_("get value: name [value-regex]"), ACTION_GET), OPT_BIT(0, "get-all", &actions, N_("get all values: key [value-regex]"), ACTION_GET_ALL), OPT_BIT(0, "get-regexp", &actions, N_("get values for regexp: name-regex [value-regex]"), ACTION_GET_REGEXP), + OPT_BIT(0, "get-urlmatch", &actions, N_("get value specific for the URL: section[.var] URL"), ACTION_GET_URLMATCH), OPT_BIT(0, "replace-all", &actions, N_("replace all matching variables: name value [value_regex]"), ACTION_REPLACE_ALL), OPT_BIT(0, "add", &actions, N_("add a new variable: name value"), ACTION_ADD), OPT_BIT(0, "unset", &actions, N_("remove a variable: name [value-regex]"), ACTION_UNSET), @@ -75,7 +78,7 @@ static struct option builtin_config_options[] = { OPT_BIT(0, "bool-or-int", &types, N_("value is --bool or --int"), TYPE_BOOL_OR_INT), OPT_BIT(0, "path", &types, N_("value is a path (file or directory name)"), TYPE_PATH), OPT_GROUP(N_("Other")), - OPT_BOOLEAN('z', "null", &end_null, N_("terminate values with NUL byte")), + OPT_BOOL('z', "null", &end_null, N_("terminate values with NUL byte")), OPT_BOOL(0, "includes", &respect_includes, N_("respect include directives on lookup")), OPT_END(), }; @@ -102,25 +105,13 @@ struct strbuf_list { int alloc; }; -static int collect_config(const char *key_, const char *value_, void *cb) +static int format_config(struct strbuf *buf, const char *key_, const char *value_) { - struct strbuf_list *values = cb; - struct strbuf *buf; - char value[256]; - const char *vptr = value; int must_free_vptr = 0; int must_print_delim = 0; + char value[256]; + const char *vptr = value; - if (!use_key_regexp && strcmp(key_, key)) - return 0; - if (use_key_regexp && regexec(key_regexp, key_, 0, NULL, 0)) - return 0; - if (regexp != NULL && - (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) { @@ -128,7 +119,7 @@ static int collect_config(const char *key_, const char *value_, void *cb) must_print_delim = 1; } if (types == TYPE_INT) - sprintf(value, "%d", git_config_int(key_, value_?value_:"")); + sprintf(value, "%d", git_config_int(key_, value_ ? value_ : "")); else if (types == TYPE_BOOL) vptr = git_config_bool(key_, value_) ? "true" : "false"; else if (types == TYPE_BOOL_OR_INT) { @@ -156,15 +147,27 @@ static int collect_config(const char *key_, const char *value_, void *cb) 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 - * const. - */ free((char *)vptr); - return 0; } +static int collect_config(const char *key_, const char *value_, void *cb) +{ + struct strbuf_list *values = cb; + + if (!use_key_regexp && strcmp(key_, key)) + return 0; + if (use_key_regexp && regexec(key_regexp, key_, 0, NULL, 0)) + return 0; + if (regexp != NULL && + (do_not_match ^ !!regexec(regexp, (value_?value_:""), 0, NULL, 0))) + return 0; + + ALLOC_GROW(values->items, values->nr + 1, values->alloc); + + return format_config(&values->items[values->nr++], key_, value_); +} + static int get_value(const char *key_, const char *regex_) { int ret = CONFIG_GENERIC_ERROR; @@ -364,6 +367,97 @@ static void check_blob_write(void) die("writing config blobs is not supported"); } +struct urlmatch_current_candidate_value { + char value_is_null; + struct strbuf value; +}; + +static int urlmatch_collect_fn(const char *var, const char *value, void *cb) +{ + struct string_list *values = cb; + struct string_list_item *item = string_list_insert(values, var); + struct urlmatch_current_candidate_value *matched = item->util; + + if (!matched) { + matched = xmalloc(sizeof(*matched)); + strbuf_init(&matched->value, 0); + item->util = matched; + } else { + strbuf_reset(&matched->value); + } + + if (value) { + strbuf_addstr(&matched->value, value); + matched->value_is_null = 0; + } else { + matched->value_is_null = 1; + } + return 0; +} + +static char *dup_downcase(const char *string) +{ + char *result; + size_t len, i; + + len = strlen(string); + result = xmalloc(len + 1); + for (i = 0; i < len; i++) + result[i] = tolower(string[i]); + result[i] = '\0'; + return result; +} + +static int get_urlmatch(const char *var, const char *url) +{ + char *section_tail; + struct string_list_item *item; + struct urlmatch_config config = { STRING_LIST_INIT_DUP }; + struct string_list values = STRING_LIST_INIT_DUP; + + config.collect_fn = urlmatch_collect_fn; + config.cascade_fn = NULL; + config.cb = &values; + + if (!url_normalize(url, &config.url)) + die("%s", config.url.err); + + config.section = dup_downcase(var); + section_tail = strchr(config.section, '.'); + if (section_tail) { + *section_tail = '\0'; + config.key = section_tail + 1; + show_keys = 0; + } else { + config.key = NULL; + show_keys = 1; + } + + git_config_with_options(urlmatch_config_entry, &config, + given_config_file, NULL, respect_includes); + + for_each_string_list_item(item, &values) { + struct urlmatch_current_candidate_value *matched = item->util; + struct strbuf key = STRBUF_INIT; + struct strbuf buf = STRBUF_INIT; + + strbuf_addstr(&key, item->string); + format_config(&buf, key.buf, + matched->value_is_null ? NULL : matched->value.buf); + fwrite(buf.buf, 1, buf.len, stdout); + strbuf_release(&key); + strbuf_release(&buf); + + strbuf_release(&matched->value); + } + string_list_clear(&config.vars, 1); + string_list_clear(&values, 1); + free(config.url.url); + + free((void *)config.section); + return 0; +} + int cmd_config(int argc, const char **argv, const char *prefix) { int nongit = !startup_info->have_repository; @@ -523,6 +617,10 @@ int cmd_config(int argc, const char **argv, const char *prefix) check_argc(argc, 1, 2); return get_value(argv[0], argv[1]); } + else if (actions == ACTION_GET_URLMATCH) { + check_argc(argc, 2, 2); + return get_urlmatch(argv[0], argv[1]); + } else if (actions == ACTION_UNSET) { check_blob_write(); check_argc(argc, 1, 2); diff --git a/builtin/describe.c b/builtin/describe.c index 7d73722f59..c94e5c30d0 100644 --- a/builtin/describe.c +++ b/builtin/describe.c @@ -406,12 +406,12 @@ int cmd_describe(int argc, const char **argv, const char *prefix) { int contains = 0; struct option options[] = { - OPT_BOOLEAN(0, "contains", &contains, N_("find the tag that comes after the commit")), - OPT_BOOLEAN(0, "debug", &debug, N_("debug search strategy on stderr")), - OPT_BOOLEAN(0, "all", &all, N_("use any ref")), - OPT_BOOLEAN(0, "tags", &tags, N_("use any tag, even unannotated")), - OPT_BOOLEAN(0, "long", &longformat, N_("always use long format")), - OPT_BOOLEAN(0, "first-parent", &first_parent, N_("only follow first parent")), + OPT_BOOL(0, "contains", &contains, N_("find the tag that comes after the commit")), + OPT_BOOL(0, "debug", &debug, N_("debug search strategy on stderr")), + OPT_BOOL(0, "all", &all, N_("use any ref")), + OPT_BOOL(0, "tags", &tags, N_("use any tag, even unannotated")), + OPT_BOOL(0, "long", &longformat, N_("always use long format")), + OPT_BOOL(0, "first-parent", &first_parent, N_("only follow first parent")), OPT__ABBREV(&abbrev), OPT_SET_INT(0, "exact-match", &max_candidates, N_("only output exact matches"), 0), @@ -419,11 +419,11 @@ int cmd_describe(int argc, const char **argv, const char *prefix) N_("consider most recent tags (default: 10)")), OPT_STRING(0, "match", &pattern, N_("pattern"), N_("only consider tags matching ")), - OPT_BOOLEAN(0, "always", &always, - N_("show abbreviated commit object as fallback")), + OPT_BOOL(0, "always", &always, + N_("show abbreviated commit object as fallback")), {OPTION_STRING, 0, "dirty", &dirty, N_("mark"), - N_("append on dirty working tree (default: \"-dirty\")"), - PARSE_OPT_OPTARG, NULL, (intptr_t) "-dirty"}, + N_("append on dirty working tree (default: \"-dirty\")"), + PARSE_OPT_OPTARG, NULL, (intptr_t) "-dirty"}, OPT_END(), }; diff --git a/builtin/diff-files.c b/builtin/diff-files.c index 46085f862f..9200069363 100644 --- a/builtin/diff-files.c +++ b/builtin/diff-files.c @@ -61,7 +61,7 @@ int cmd_diff_files(int argc, const char **argv, const char *prefix) (rev.diffopt.output_format & DIFF_FORMAT_PATCH)) rev.combine_merges = rev.dense_combined_merges = 1; - if (read_cache_preload(rev.diffopt.pathspec.raw) < 0) { + if (read_cache_preload(&rev.diffopt.pathspec) < 0) { perror("read_cache_preload"); return -1; } diff --git a/builtin/diff-index.c b/builtin/diff-index.c index 1c737f7921..ce15b23042 100644 --- a/builtin/diff-index.c +++ b/builtin/diff-index.c @@ -43,7 +43,7 @@ int cmd_diff_index(int argc, const char **argv, const char *prefix) usage(diff_cache_usage); if (!cached) { setup_work_tree(); - if (read_cache_preload(rev.diffopt.pathspec.raw) < 0) { + if (read_cache_preload(&rev.diffopt.pathspec) < 0) { perror("read_cache_preload"); return -1; } diff --git a/builtin/diff.c b/builtin/diff.c index 9fc273d8cd..2fb8c5dc0b 100644 --- a/builtin/diff.c +++ b/builtin/diff.c @@ -140,7 +140,7 @@ static int builtin_diff_index(struct rev_info *revs, usage(builtin_diff_usage); if (!cached) { setup_work_tree(); - if (read_cache_preload(revs->diffopt.pathspec.raw) < 0) { + if (read_cache_preload(&revs->diffopt.pathspec) < 0) { perror("read_cache_preload"); return -1; } @@ -242,7 +242,7 @@ static int builtin_diff_files(struct rev_info *revs, int argc, const char **argv revs->combine_merges = revs->dense_combined_merges = 1; setup_work_tree(); - if (read_cache_preload(revs->diffopt.pathspec.raw) < 0) { + if (read_cache_preload(&revs->diffopt.pathspec) < 0) { perror("read_cache_preload"); return -1; } @@ -367,6 +367,8 @@ int cmd_diff(int argc, const char **argv, const char *prefix) } } if (rev.prune_data.nr) { + /* builtin_diff_b_f() */ + GUARD_PATHSPEC(&rev.prune_data, PATHSPEC_FROMTOP | PATHSPEC_LITERAL); if (!path) path = rev.prune_data.items[0].match; paths += rev.prune_data.nr; diff --git a/builtin/fast-export.c b/builtin/fast-export.c index 8e19058744..b1b9b5e52a 100644 --- a/builtin/fast-export.c +++ b/builtin/fast-export.c @@ -674,11 +674,11 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix) N_("Dump marks to this file")), OPT_STRING(0, "import-marks", &import_filename, N_("file"), N_("Import marks from this file")), - OPT_BOOLEAN(0, "fake-missing-tagger", &fake_missing_tagger, - N_("Fake a tagger when tags lack one")), - OPT_BOOLEAN(0, "full-tree", &full_tree, - N_("Output full tree for each commit")), - OPT_BOOLEAN(0, "use-done-feature", &use_done_feature, + OPT_BOOL(0, "fake-missing-tagger", &fake_missing_tagger, + N_("Fake a tagger when tags lack one")), + OPT_BOOL(0, "full-tree", &full_tree, + N_("Output full tree for each commit")), + OPT_BOOL(0, "use-done-feature", &use_done_feature, N_("Use the done feature to terminate the stream")), OPT_BOOL(0, "no-data", &no_data, N_("Skip output of blob data")), OPT_END() diff --git a/builtin/fetch-pack.c b/builtin/fetch-pack.c index aba4465552..c8e858232a 100644 --- a/builtin/fetch-pack.c +++ b/builtin/fetch-pack.c @@ -1,6 +1,8 @@ #include "builtin.h" #include "pkt-line.h" #include "fetch-pack.h" +#include "remote.h" +#include "connect.h" static const char fetch_pack_usage[] = "git fetch-pack [--all] [--stdin] [--quiet|-q] [--keep|-k] [--thin] " @@ -100,6 +102,10 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix) pack_lockfile_ptr = &pack_lockfile; continue; } + if (!strcmp("--check-self-contained-and-connected", arg)) { + args.check_self_contained_and_connected = 1; + continue; + } usage(fetch_pack_usage); } @@ -152,6 +158,11 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix) printf("lock %s\n", pack_lockfile); fflush(stdout); } + if (args.check_self_contained_and_connected && + args.self_contained_and_connected) { + printf("connectivity-ok\n"); + fflush(stdout); + } close(fd[0]); close(fd[1]); if (finish_connect(conn)) diff --git a/builtin/fetch.c b/builtin/fetch.c index 564705555b..9e654efa3b 100644 --- a/builtin/fetch.c +++ b/builtin/fetch.c @@ -30,7 +30,11 @@ enum { TAGS_SET = 2 }; -static int all, append, dry_run, force, keep, multiple, prune, update_head_ok, verbosity; +static int fetch_prune_config = -1; /* unspecified */ +static int prune = -1; /* unspecified */ +#define PRUNE_BY_DEFAULT 0 /* do we prune by default? */ + +static int all, append, dry_run, force, keep, multiple, update_head_ok, verbosity; static int progress = -1, recurse_submodules = RECURSE_SUBMODULES_DEFAULT; static int tags = TAGS_DEFAULT, unshallow; static const char *depth; @@ -55,30 +59,39 @@ static int option_parse_recurse_submodules(const struct option *opt, return 0; } +static int git_fetch_config(const char *k, const char *v, void *cb) +{ + if (!strcmp(k, "fetch.prune")) { + fetch_prune_config = git_config_bool(k, v); + return 0; + } + return 0; +} + static struct option builtin_fetch_options[] = { OPT__VERBOSITY(&verbosity), - OPT_BOOLEAN(0, "all", &all, - N_("fetch from all remotes")), - OPT_BOOLEAN('a', "append", &append, - N_("append to .git/FETCH_HEAD instead of overwriting")), + OPT_BOOL(0, "all", &all, + N_("fetch from all remotes")), + OPT_BOOL('a', "append", &append, + N_("append to .git/FETCH_HEAD instead of overwriting")), OPT_STRING(0, "upload-pack", &upload_pack, N_("path"), N_("path to upload pack on remote end")), OPT__FORCE(&force, N_("force overwrite of local branch")), - OPT_BOOLEAN('m', "multiple", &multiple, - N_("fetch from multiple remotes")), + OPT_BOOL('m', "multiple", &multiple, + N_("fetch from multiple remotes")), OPT_SET_INT('t', "tags", &tags, N_("fetch all tags and associated objects"), TAGS_SET), OPT_SET_INT('n', NULL, &tags, N_("do not fetch all tags (--no-tags)"), TAGS_UNSET), - OPT_BOOLEAN('p', "prune", &prune, - N_("prune remote-tracking branches no longer on remote")), + OPT_BOOL('p', "prune", &prune, + N_("prune remote-tracking branches no longer on remote")), { OPTION_CALLBACK, 0, "recurse-submodules", NULL, N_("on-demand"), N_("control recursive fetching of submodules"), PARSE_OPT_OPTARG, option_parse_recurse_submodules }, - OPT_BOOLEAN(0, "dry-run", &dry_run, - N_("dry run")), - OPT_BOOLEAN('k', "keep", &keep, N_("keep downloaded pack")), - OPT_BOOLEAN('u', "update-head-ok", &update_head_ok, + OPT_BOOL(0, "dry-run", &dry_run, + N_("dry run")), + OPT_BOOL('k', "keep", &keep, N_("keep downloaded pack")), + OPT_BOOL('u', "update-head-ok", &update_head_ok, N_("allow updating of HEAD ref")), OPT_BOOL(0, "progress", &progress, N_("force progress reporting")), OPT_STRING(0, "depth", &depth, N_("depth"), @@ -816,7 +829,10 @@ static int do_fetch(struct transport *transport, goto cleanup; } if (prune) { - /* If --tags was specified, pretend the user gave us the canonical tags refspec */ + /* + * If --tags was specified, pretend that the user gave us + * the canonical tags refspec + */ if (tags == TAGS_SET) { const char *tags_str = "refs/tags/*:refs/tags/*"; struct refspec *tags_refspec, *refspec; @@ -913,7 +929,7 @@ static void add_options_to_argv(struct argv_array *argv) { if (dry_run) argv_array_push(argv, "--dry-run"); - if (prune) + if (prune > 0) argv_array_push(argv, "--prune"); if (update_head_ok) argv_array_push(argv, "--update-head-ok"); @@ -981,6 +997,17 @@ static int fetch_one(struct remote *remote, int argc, const char **argv) "remote name from which new revisions should be fetched.")); gtransport = prepare_transport(remote); + + if (prune < 0) { + /* no command line request */ + if (0 <= gtransport->remote->prune) + prune = gtransport->remote->prune; + else if (0 <= fetch_prune_config) + prune = fetch_prune_config; + else + prune = PRUNE_BY_DEFAULT; + } + if (argc > 0) { int j = 0; refs = xcalloc(argc + 1, sizeof(const char *)); @@ -1030,6 +1057,8 @@ int cmd_fetch(int argc, const char **argv, const char *prefix) for (i = 1; i < argc; i++) strbuf_addf(&default_rla, " %s", argv[i]); + git_config(git_fetch_config, NULL); + argc = parse_options(argc, argv, prefix, builtin_fetch_options, builtin_fetch_usage, 0); diff --git a/builtin/for-each-ref.c b/builtin/for-each-ref.c index 7f059c31df..1d4083c2dd 100644 --- a/builtin/for-each-ref.c +++ b/builtin/for-each-ref.c @@ -867,24 +867,29 @@ static void sort_refs(struct ref_sort *sort, struct refinfo **refs, int num_refs static void print_value(struct refinfo *ref, int atom, int quote_style) { struct atom_value *v; + struct strbuf sb = STRBUF_INIT; get_value(ref, atom, &v); switch (quote_style) { case QUOTE_NONE: fputs(v->s, stdout); break; case QUOTE_SHELL: - sq_quote_print(stdout, v->s); + sq_quote_buf(&sb, v->s); break; case QUOTE_PERL: - perl_quote_print(stdout, v->s); + perl_quote_buf(&sb, v->s); break; case QUOTE_PYTHON: - python_quote_print(stdout, v->s); + python_quote_buf(&sb, v->s); break; case QUOTE_TCL: - tcl_quote_print(stdout, v->s); + tcl_quote_buf(&sb, v->s); break; } + if (quote_style != QUOTE_NONE) { + fputs(sb.buf, stdout); + strbuf_release(&sb); + } } static int hex1(char ch) diff --git a/builtin/fsck.c b/builtin/fsck.c index 9909b6d519..39fa5e86d4 100644 --- a/builtin/fsck.c +++ b/builtin/fsck.c @@ -611,15 +611,15 @@ static char const * const fsck_usage[] = { static struct option fsck_opts[] = { OPT__VERBOSE(&verbose, N_("be verbose")), - OPT_BOOLEAN(0, "unreachable", &show_unreachable, N_("show unreachable objects")), + OPT_BOOL(0, "unreachable", &show_unreachable, N_("show unreachable objects")), OPT_BOOL(0, "dangling", &show_dangling, N_("show dangling objects")), - OPT_BOOLEAN(0, "tags", &show_tags, N_("report tags")), - OPT_BOOLEAN(0, "root", &show_root, N_("report root nodes")), - OPT_BOOLEAN(0, "cache", &keep_cache_objects, N_("make index objects head nodes")), - OPT_BOOLEAN(0, "reflogs", &include_reflogs, N_("make reflogs head nodes (default)")), - OPT_BOOLEAN(0, "full", &check_full, N_("also consider packs and alternate objects")), - OPT_BOOLEAN(0, "strict", &check_strict, N_("enable more strict checking")), - OPT_BOOLEAN(0, "lost-found", &write_lost_and_found, + OPT_BOOL(0, "tags", &show_tags, N_("report tags")), + OPT_BOOL(0, "root", &show_root, N_("report root nodes")), + OPT_BOOL(0, "cache", &keep_cache_objects, N_("make index objects head nodes")), + OPT_BOOL(0, "reflogs", &include_reflogs, N_("make reflogs head nodes (default)")), + OPT_BOOL(0, "full", &check_full, N_("also consider packs and alternate objects")), + OPT_BOOL(0, "strict", &check_strict, N_("enable more strict checking")), + OPT_BOOL(0, "lost-found", &write_lost_and_found, N_("write dangling objects in .git/lost-found")), OPT_BOOL(0, "progress", &show_progress, N_("show progress")), OPT_END(), diff --git a/builtin/gc.c b/builtin/gc.c index 6be6c8d65b..891a2c2ecb 100644 --- a/builtin/gc.c +++ b/builtin/gc.c @@ -167,19 +167,78 @@ static int need_to_gc(void) return 1; } +/* return NULL on success, else hostname running the gc */ +static const char *lock_repo_for_gc(int force, pid_t* ret_pid) +{ + static struct lock_file lock; + static char locking_host[128]; + char my_host[128]; + struct strbuf sb = STRBUF_INIT; + struct stat st; + uintmax_t pid; + FILE *fp; + int fd, should_exit; + + if (gethostname(my_host, sizeof(my_host))) + strcpy(my_host, "unknown"); + + fd = hold_lock_file_for_update(&lock, git_path("gc.pid"), + LOCK_DIE_ON_ERROR); + if (!force) { + fp = fopen(git_path("gc.pid"), "r"); + memset(locking_host, 0, sizeof(locking_host)); + should_exit = + fp != NULL && + !fstat(fileno(fp), &st) && + /* + * 12 hour limit is very generous as gc should + * never take that long. On the other hand we + * don't really need a strict limit here, + * running gc --auto one day late is not a big + * problem. --force can be used in manual gc + * after the user verifies that no gc is + * running. + */ + time(NULL) - st.st_mtime <= 12 * 3600 && + fscanf(fp, "%"PRIuMAX" %127c", &pid, locking_host) == 2 && + /* be gentle to concurrent "gc" on remote hosts */ + (strcmp(locking_host, my_host) || !kill(pid, 0)); + if (fp != NULL) + fclose(fp); + if (should_exit) { + if (fd >= 0) + rollback_lock_file(&lock); + *ret_pid = pid; + return locking_host; + } + } + + strbuf_addf(&sb, "%"PRIuMAX" %s", + (uintmax_t) getpid(), my_host); + write_in_full(fd, sb.buf, sb.len); + strbuf_release(&sb); + commit_lock_file(&lock); + + return NULL; +} + int cmd_gc(int argc, const char **argv, const char *prefix) { int aggressive = 0; int auto_gc = 0; int quiet = 0; + int force = 0; + const char *name; + pid_t pid; struct option builtin_gc_options[] = { OPT__QUIET(&quiet, N_("suppress progress reporting")), { OPTION_STRING, 0, "prune", &prune_expire, N_("date"), N_("prune unreferenced objects"), PARSE_OPT_OPTARG, NULL, (intptr_t)prune_expire }, - OPT_BOOLEAN(0, "aggressive", &aggressive, N_("be more thorough (increased runtime)")), - OPT_BOOLEAN(0, "auto", &auto_gc, N_("enable auto-gc mode")), + OPT_BOOL(0, "aggressive", &aggressive, N_("be more thorough (increased runtime)")), + OPT_BOOL(0, "auto", &auto_gc, N_("enable auto-gc mode")), + OPT_BOOL(0, "force", &force, N_("force running gc even if there may be another gc running")), OPT_END() }; @@ -225,6 +284,14 @@ int cmd_gc(int argc, const char **argv, const char *prefix) } else add_repack_all_option(); + name = lock_repo_for_gc(force, &pid); + if (name) { + if (auto_gc) + return 0; /* be quiet on --auto */ + die(_("gc is already running on machine '%s' pid %"PRIuMAX" (use --force if not)"), + name, (uintmax_t)pid); + } + if (pack_refs && run_command_v_opt(pack_refs_cmd.argv, RUN_GIT_CMD)) return error(FAILED_RUN, pack_refs_cmd.argv[0]); diff --git a/builtin/grep.c b/builtin/grep.c index d3b3b1db11..03bc442e3f 100644 --- a/builtin/grep.c +++ b/builtin/grep.c @@ -17,6 +17,7 @@ #include "grep.h" #include "quote.h" #include "dir.h" +#include "pathspec.h" static char const * const grep_usage[] = { N_("git grep [options] [-e] [...] [[--] ...]"), @@ -521,7 +522,7 @@ static int grep_directory(struct grep_opt *opt, const struct pathspec *pathspec, if (exc_std) setup_standard_excludes(&dir); - fill_directory(&dir, pathspec->raw); + fill_directory(&dir, pathspec); for (i = 0; i < dir.nr; i++) { const char *name = dir.entries[i]->name; int namelen = strlen(name); @@ -629,7 +630,6 @@ int cmd_grep(int argc, const char **argv, const char *prefix) const char *show_in_pager = NULL, *default_pager = "dummy"; struct grep_opt opt; struct object_array list = OBJECT_ARRAY_INIT; - const char **paths = NULL; struct pathspec pathspec; struct string_list path_list = STRING_LIST_INIT_NODUP; int i; @@ -638,20 +638,20 @@ int cmd_grep(int argc, const char **argv, const char *prefix) int pattern_type_arg = GREP_PATTERN_TYPE_UNSPECIFIED; struct option options[] = { - OPT_BOOLEAN(0, "cached", &cached, + OPT_BOOL(0, "cached", &cached, N_("search in index instead of in the work tree")), OPT_NEGBIT(0, "no-index", &use_index, N_("find in contents not managed by git"), 1), - OPT_BOOLEAN(0, "untracked", &untracked, + OPT_BOOL(0, "untracked", &untracked, N_("search in both tracked and untracked files")), OPT_SET_INT(0, "exclude-standard", &opt_exclude, N_("search also in ignored files"), 1), OPT_GROUP(""), - OPT_BOOLEAN('v', "invert-match", &opt.invert, + OPT_BOOL('v', "invert-match", &opt.invert, N_("show non-matching lines")), - OPT_BOOLEAN('i', "ignore-case", &opt.ignore_case, + OPT_BOOL('i', "ignore-case", &opt.ignore_case, N_("case insensitive matching")), - OPT_BOOLEAN('w', "word-regexp", &opt.word_regexp, + OPT_BOOL('w', "word-regexp", &opt.word_regexp, N_("match patterns only at word boundaries")), OPT_SET_INT('a', "text", &opt.binary, N_("process binary files as text"), GREP_BINARY_TEXT), @@ -675,26 +675,26 @@ int cmd_grep(int argc, const char **argv, const char *prefix) N_("use Perl-compatible regular expressions"), GREP_PATTERN_TYPE_PCRE), OPT_GROUP(""), - OPT_BOOLEAN('n', "line-number", &opt.linenum, N_("show line numbers")), + OPT_BOOL('n', "line-number", &opt.linenum, N_("show line numbers")), OPT_NEGBIT('h', NULL, &opt.pathname, N_("don't show filenames"), 1), OPT_BIT('H', NULL, &opt.pathname, N_("show filenames"), 1), OPT_NEGBIT(0, "full-name", &opt.relative, N_("show filenames relative to top directory"), 1), - OPT_BOOLEAN('l', "files-with-matches", &opt.name_only, + OPT_BOOL('l', "files-with-matches", &opt.name_only, N_("show only filenames instead of matching lines")), - OPT_BOOLEAN(0, "name-only", &opt.name_only, + OPT_BOOL(0, "name-only", &opt.name_only, N_("synonym for --files-with-matches")), - OPT_BOOLEAN('L', "files-without-match", + OPT_BOOL('L', "files-without-match", &opt.unmatch_name_only, N_("show only the names of files without match")), - OPT_BOOLEAN('z', "null", &opt.null_following_name, + OPT_BOOL('z', "null", &opt.null_following_name, N_("print NUL after filenames")), - OPT_BOOLEAN('c', "count", &opt.count, + OPT_BOOL('c', "count", &opt.count, N_("show the number of matches instead of matching lines")), OPT__COLOR(&opt.color, N_("highlight matches")), - OPT_BOOLEAN(0, "break", &opt.file_break, + OPT_BOOL(0, "break", &opt.file_break, N_("print empty line between matches from different files")), - OPT_BOOLEAN(0, "heading", &opt.heading, + OPT_BOOL(0, "heading", &opt.heading, N_("show filename only once above matches from same file")), OPT_GROUP(""), OPT_CALLBACK('C', "context", &opt, N_("n"), @@ -706,9 +706,9 @@ int cmd_grep(int argc, const char **argv, const char *prefix) N_("show context lines after matches")), OPT_NUMBER_CALLBACK(&opt, N_("shortcut for -C NUM"), context_callback), - OPT_BOOLEAN('p', "show-function", &opt.funcname, + OPT_BOOL('p', "show-function", &opt.funcname, N_("show a line with the function name before matches")), - OPT_BOOLEAN('W', "function-context", &opt.funcbody, + OPT_BOOL('W', "function-context", &opt.funcbody, N_("show the surrounding function")), OPT_GROUP(""), OPT_CALLBACK('f', NULL, &opt, N_("file"), @@ -718,7 +718,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix) { OPTION_CALLBACK, 0, "and", &opt, NULL, N_("combine patterns specified with -e"), PARSE_OPT_NOARG | PARSE_OPT_NONEG, and_callback }, - OPT_BOOLEAN(0, "or", &dummy, ""), + OPT_BOOL(0, "or", &dummy, ""), { OPTION_CALLBACK, 0, "not", &opt, NULL, "", PARSE_OPT_NOARG | PARSE_OPT_NONEG, not_callback }, { OPTION_CALLBACK, '(', NULL, &opt, NULL, "", @@ -729,7 +729,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix) close_callback }, OPT__QUIET(&opt.status_only, N_("indicate hit with exit status without output")), - OPT_BOOLEAN(0, "all-match", &opt.all_match, + OPT_BOOL(0, "all-match", &opt.all_match, N_("show only matches from files that match all patterns")), { OPTION_SET_INT, 0, "debug", &opt.debug, NULL, N_("show parse tree for grep expression"), @@ -738,8 +738,8 @@ int cmd_grep(int argc, const char **argv, const char *prefix) { OPTION_STRING, 'O', "open-files-in-pager", &show_in_pager, N_("pager"), N_("show matching files in the pager"), PARSE_OPT_OPTARG, NULL, (intptr_t)default_pager }, - OPT_BOOLEAN(0, "ext-grep", &external_grep_allowed__ignored, - N_("allow calling of grep(1) (ignored by this build)")), + OPT_BOOL(0, "ext-grep", &external_grep_allowed__ignored, + N_("allow calling of grep(1) (ignored by this build)")), { OPTION_CALLBACK, 0, "help-all", &options, NULL, N_("show usage"), PARSE_OPT_HIDDEN | PARSE_OPT_NOARG, help_callback }, OPT_END() @@ -856,8 +856,10 @@ int cmd_grep(int argc, const char **argv, const char *prefix) verify_filename(prefix, argv[j], j == i); } - paths = get_pathspec(prefix, argv + i); - init_pathspec(&pathspec, paths); + parse_pathspec(&pathspec, 0, + PATHSPEC_PREFER_CWD | + (opt.max_depth != -1 ? PATHSPEC_MAXDEPTH_VALID : 0), + prefix, argv + i); pathspec.max_depth = opt.max_depth; pathspec.recursive = 1; diff --git a/builtin/hash-object.c b/builtin/hash-object.c index 8d184f1a99..d7fcf4c13c 100644 --- a/builtin/hash-object.c +++ b/builtin/hash-object.c @@ -70,10 +70,10 @@ static const char *vpath; static const struct option hash_object_options[] = { OPT_STRING('t', NULL, &type, N_("type"), N_("object type")), - OPT_BOOLEAN('w', NULL, &write_object, N_("write the object into the object database")), - OPT_BOOLEAN( 0 , "stdin", &hashstdin, N_("read the object from stdin")), - OPT_BOOLEAN( 0 , "stdin-paths", &stdin_paths, N_("read file names from stdin")), - OPT_BOOLEAN( 0 , "no-filters", &no_filters, N_("store file as is without filters")), + OPT_BOOL('w', NULL, &write_object, N_("write the object into the object database")), + OPT_COUNTUP( 0 , "stdin", &hashstdin, N_("read the object from stdin")), + OPT_BOOL( 0 , "stdin-paths", &stdin_paths, N_("read file names from stdin")), + OPT_BOOL( 0 , "no-filters", &no_filters, N_("store file as is without filters")), OPT_STRING( 0 , "path", &vpath, N_("file"), N_("process file as it were from this path")), OPT_END() }; diff --git a/builtin/log.c b/builtin/log.c index 2625f9881a..77d0f5f3fd 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -121,7 +121,7 @@ static void cmd_log_init_finish(int argc, const char **argv, const char *prefix, static struct line_opt_callback_data line_cb = {NULL, NULL, STRING_LIST_INIT_DUP}; const struct option builtin_log_options[] = { - OPT_BOOL(0, "quiet", &quiet, N_("suppress diff output")), + OPT__QUIET(&quiet, N_("suppress diff output")), OPT_BOOL(0, "source", &source, N_("show source")), OPT_BOOL(0, "use-mailmap", &mailmap, N_("Use mail map file")), { OPTION_CALLBACK, 0, "decorate", NULL, NULL, N_("decorate options"), @@ -503,7 +503,7 @@ int cmd_show(int argc, const char **argv, const char *prefix) init_grep_defaults(); git_config(git_log_config, NULL); - init_pathspec(&match_all, NULL); + memset(&match_all, 0, sizeof(match_all)); init_revisions(&rev, prefix); rev.diff = 1; rev.always_show_header = 1; @@ -1179,13 +1179,13 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) { OPTION_CALLBACK, 'k', "keep-subject", &rev, NULL, N_("don't strip/add [PATCH]"), PARSE_OPT_NOARG | PARSE_OPT_NONEG, keep_callback }, - OPT_BOOLEAN(0, "no-binary", &no_binary_diff, - N_("don't output binary diffs")), - OPT_BOOLEAN(0, "ignore-if-in-upstream", &ignore_if_in_upstream, - N_("don't include a patch matching a commit upstream")), - { OPTION_BOOLEAN, 'p', "no-stat", &use_patch_format, NULL, + OPT_BOOL(0, "no-binary", &no_binary_diff, + N_("don't output binary diffs")), + OPT_BOOL(0, "ignore-if-in-upstream", &ignore_if_in_upstream, + N_("don't include a patch matching a commit upstream")), + { OPTION_SET_INT, 'p', "no-stat", &use_patch_format, NULL, N_("show patch format instead of default (patch + stat)"), - PARSE_OPT_NONEG | PARSE_OPT_NOARG }, + PARSE_OPT_NONEG | PARSE_OPT_NOARG, NULL, 1}, OPT_GROUP(N_("Messaging")), { OPTION_CALLBACK, 0, "add-header", NULL, N_("header"), N_("add email header"), 0, header_callback }, @@ -1210,8 +1210,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) PARSE_OPT_OPTARG, thread_callback }, OPT_STRING(0, "signature", &signature, N_("signature"), N_("add a signature")), - OPT_BOOLEAN(0, "quiet", &quiet, - N_("don't print the patch filenames")), + OPT__QUIET(&quiet, N_("don't print the patch filenames")), OPT_END() }; diff --git a/builtin/ls-files.c b/builtin/ls-files.c index 5cf3e31370..d4823c9d38 100644 --- a/builtin/ls-files.c +++ b/builtin/ls-files.c @@ -13,6 +13,7 @@ #include "parse-options.h" #include "resolve-undo.h" #include "string-list.h" +#include "pathspec.h" static int abbrev; static int show_deleted; @@ -30,7 +31,7 @@ static int debug_mode; static const char *prefix; static int max_prefix_len; static int prefix_len; -static const char **pathspec; +static struct pathspec pathspec; static int error_unmatch; static char *ps_matched; static const char *with_tree; @@ -63,7 +64,7 @@ static void show_dir_entry(const char *tag, struct dir_entry *ent) if (len >= ent->len) die("git ls-files: internal error - directory entry not superset of prefix"); - if (!match_pathspec(pathspec, ent->name, ent->len, len, ps_matched)) + if (!match_pathspec_depth(&pathspec, ent->name, ent->len, len, ps_matched)) return; fputs(tag, stdout); @@ -138,7 +139,7 @@ static void show_ce_entry(const char *tag, const struct cache_entry *ce) if (len >= ce_namelen(ce)) die("git ls-files: internal error - cache entry not superset of prefix"); - if (!match_pathspec(pathspec, ce->name, ce_namelen(ce), len, ps_matched)) + if (!match_pathspec_depth(&pathspec, ce->name, ce_namelen(ce), len, ps_matched)) return; if (tag && *tag && show_valid_bit && @@ -194,7 +195,7 @@ static void show_ru_info(void) len = strlen(path); if (len < max_prefix_len) continue; /* outside of the prefix */ - if (!match_pathspec(pathspec, path, len, max_prefix_len, ps_matched)) + if (!match_pathspec_depth(&pathspec, path, len, max_prefix_len, ps_matched)) continue; /* uninterested */ for (i = 0; i < 3; i++) { if (!ui->mode[i]) @@ -219,7 +220,7 @@ static void show_files(struct dir_struct *dir) /* For cached/deleted files we don't need to even do the readdir */ if (show_others || show_killed) { - fill_directory(dir, pathspec); + fill_directory(dir, &pathspec); if (show_others) show_other_files(dir); if (show_killed) @@ -287,21 +288,6 @@ static void prune_cache(const char *prefix) active_nr = last; } -static void strip_trailing_slash_from_submodules(void) -{ - const char **p; - - for (p = pathspec; *p != NULL; p++) { - int len = strlen(*p), pos; - - if (len < 1 || (*p)[len - 1] != '/') - continue; - pos = cache_name_pos(*p, len - 1); - if (pos >= 0 && S_ISGITLINK(active_cache[pos]->ce_mode)) - *p = xstrndup(*p, len - 1); - } -} - /* * Read the tree specified with --with-tree option * (typically, HEAD) into stage #1 and then @@ -333,13 +319,12 @@ void overlay_tree_on_cache(const char *tree_name, const char *prefix) } if (prefix) { - static const char *(matchbuf[2]); - matchbuf[0] = prefix; - matchbuf[1] = NULL; - init_pathspec(&pathspec, matchbuf); - pathspec.items[0].nowildcard_len = pathspec.items[0].len; + static const char *(matchbuf[1]); + matchbuf[0] = NULL; + parse_pathspec(&pathspec, PATHSPEC_ALL_MAGIC, + PATHSPEC_PREFER_CWD, prefix, matchbuf); } else - init_pathspec(&pathspec, NULL); + memset(&pathspec, 0, sizeof(pathspec)); if (read_tree(tree, 1, &pathspec)) die("unable to read tree entries %s", tree_name); @@ -364,15 +349,16 @@ void overlay_tree_on_cache(const char *tree_name, const char *prefix) } } -int report_path_error(const char *ps_matched, const char **pathspec, const char *prefix) +int report_path_error(const char *ps_matched, + const struct pathspec *pathspec, + const char *prefix) { /* * Make sure all pathspec matched; otherwise it is an error. */ struct strbuf sb = STRBUF_INIT; - const char *name; int num, errors = 0; - for (num = 0; pathspec[num]; num++) { + for (num = 0; num < pathspec->nr; num++) { int other, found_dup; if (ps_matched[num]) @@ -380,13 +366,16 @@ int report_path_error(const char *ps_matched, const char **pathspec, const char /* * The caller might have fed identical pathspec * twice. Do not barf on such a mistake. + * FIXME: parse_pathspec should have eliminated + * duplicate pathspec. */ for (found_dup = other = 0; - !found_dup && pathspec[other]; + !found_dup && other < pathspec->nr; other++) { if (other == num || !ps_matched[other]) continue; - if (!strcmp(pathspec[other], pathspec[num])) + if (!strcmp(pathspec->items[other].original, + pathspec->items[num].original)) /* * Ok, we have a match already. */ @@ -395,9 +384,8 @@ int report_path_error(const char *ps_matched, const char **pathspec, const char if (found_dup) continue; - name = quote_path_relative(pathspec[num], prefix, &sb); error("pathspec '%s' did not match any file(s) known to git.", - name); + pathspec->items[num].original); errors++; } strbuf_release(&sb); @@ -461,24 +449,24 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix) { OPTION_CALLBACK, 'z', NULL, NULL, NULL, N_("paths are separated with NUL character"), PARSE_OPT_NOARG, option_parse_z }, - OPT_BOOLEAN('t', NULL, &show_tag, + OPT_BOOL('t', NULL, &show_tag, N_("identify the file status with tags")), - OPT_BOOLEAN('v', NULL, &show_valid_bit, + OPT_BOOL('v', NULL, &show_valid_bit, N_("use lowercase letters for 'assume unchanged' files")), - OPT_BOOLEAN('c', "cached", &show_cached, + OPT_BOOL('c', "cached", &show_cached, N_("show cached files in the output (default)")), - OPT_BOOLEAN('d', "deleted", &show_deleted, + OPT_BOOL('d', "deleted", &show_deleted, N_("show deleted files in the output")), - OPT_BOOLEAN('m', "modified", &show_modified, + OPT_BOOL('m', "modified", &show_modified, N_("show modified files in the output")), - OPT_BOOLEAN('o', "others", &show_others, + OPT_BOOL('o', "others", &show_others, N_("show other files in the output")), OPT_BIT('i', "ignored", &dir.flags, N_("show ignored files in the output"), DIR_SHOW_IGNORED), - OPT_BOOLEAN('s', "stage", &show_stage, + OPT_BOOL('s', "stage", &show_stage, N_("show staged contents' object name in the output")), - OPT_BOOLEAN('k', "killed", &show_killed, + OPT_BOOL('k', "killed", &show_killed, N_("show files on the filesystem that need to be removed")), OPT_BIT(0, "directory", &dir.flags, N_("show 'other' directories' name only"), @@ -486,9 +474,9 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix) OPT_NEGBIT(0, "empty-directory", &dir.flags, N_("don't show empty directories"), DIR_HIDE_EMPTY_DIRECTORIES), - OPT_BOOLEAN('u', "unmerged", &show_unmerged, + OPT_BOOL('u', "unmerged", &show_unmerged, N_("show unmerged files in the output")), - OPT_BOOLEAN(0, "resolve-undo", &show_resolve_undo, + OPT_BOOL(0, "resolve-undo", &show_resolve_undo, N_("show resolve-undo information")), { OPTION_CALLBACK, 'x', "exclude", &exclude_list, N_("pattern"), N_("skip files matching pattern"), @@ -504,12 +492,12 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix) { OPTION_SET_INT, 0, "full-name", &prefix_len, NULL, N_("make the output relative to the project top directory"), PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL }, - OPT_BOOLEAN(0, "error-unmatch", &error_unmatch, + OPT_BOOL(0, "error-unmatch", &error_unmatch, N_("if any is not in the index, treat this as an error")), OPT_STRING(0, "with-tree", &with_tree, N_("tree-ish"), N_("pretend that paths removed since are still present")), OPT__ABBREV(&abbrev), - OPT_BOOLEAN(0, "debug", &debug_mode, N_("show debugging data")), + OPT_BOOL(0, "debug", &debug_mode, N_("show debugging data")), OPT_END() }; @@ -555,23 +543,18 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix) if (require_work_tree && !is_inside_work_tree()) setup_work_tree(); - pathspec = get_pathspec(prefix, argv); - - /* be nice with submodule paths ending in a slash */ - if (pathspec) - strip_trailing_slash_from_submodules(); + parse_pathspec(&pathspec, 0, + PATHSPEC_PREFER_CWD | + PATHSPEC_STRIP_SUBMODULE_SLASH_CHEAP, + prefix, argv); /* Find common prefix for all pathspec's */ - max_prefix = common_prefix(pathspec); + max_prefix = common_prefix(&pathspec); max_prefix_len = max_prefix ? strlen(max_prefix) : 0; /* Treat unmatching pathspec elements as errors */ - if (pathspec && error_unmatch) { - int num; - for (num = 0; pathspec[num]; num++) - ; - ps_matched = xcalloc(1, num); - } + if (pathspec.nr && error_unmatch) + ps_matched = xcalloc(1, pathspec.nr); if ((dir.flags & DIR_SHOW_IGNORED) && !exc_given) die("ls-files --ignored needs some exclude pattern"); @@ -598,7 +581,7 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix) if (ps_matched) { int bad; - bad = report_path_error(ps_matched, pathspec, prefix); + bad = report_path_error(ps_matched, &pathspec, prefix); if (bad) fprintf(stderr, "Did you forget to 'git add'?\n"); diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c index fb76e38d84..65ec931846 100644 --- a/builtin/ls-tree.c +++ b/builtin/ls-tree.c @@ -10,6 +10,7 @@ #include "quote.h" #include "builtin.h" #include "parse-options.h" +#include "pathspec.h" static int line_termination = '\n'; #define LS_RECURSIVE 1 @@ -35,7 +36,7 @@ static int show_recursive(const char *base, int baselen, const char *pathname) if (ls_options & LS_RECURSIVE) return 1; - s = pathspec.raw; + s = pathspec._raw; if (!s) return 0; @@ -138,9 +139,9 @@ int cmd_ls_tree(int argc, const char **argv, const char *prefix) LS_NAME_ONLY), OPT_SET_INT(0, "full-name", &chomp_prefix, N_("use full path names"), 0), - OPT_BOOLEAN(0, "full-tree", &full_tree, - N_("list entire tree; not just current directory " - "(implies --full-name)")), + OPT_BOOL(0, "full-tree", &full_tree, + N_("list entire tree; not just current directory " + "(implies --full-name)")), OPT__ABBREV(&abbrev), OPT_END() }; @@ -166,7 +167,15 @@ int cmd_ls_tree(int argc, const char **argv, const char *prefix) if (get_sha1(argv[0], sha1)) die("Not a valid object name %s", argv[0]); - init_pathspec(&pathspec, get_pathspec(prefix, argv + 1)); + /* + * show_recursive() rolls its own matching code and is + * generally ignorant of 'struct pathspec'. The magic mask + * cannot be lifted until it is converted to use + * match_pathspec_depth() or tree_entry_interesting() + */ + parse_pathspec(&pathspec, PATHSPEC_GLOB | PATHSPEC_ICASE, + PATHSPEC_PREFER_CWD, + prefix, argv + 1); for (i = 0; i < pathspec.nr; i++) pathspec.items[i].nowildcard_len = pathspec.items[i].len; pathspec.has_wildcard = 0; diff --git a/builtin/merge-base.c b/builtin/merge-base.c index 0c4cd2f9f7..e88eb93f14 100644 --- a/builtin/merge-base.c +++ b/builtin/merge-base.c @@ -95,11 +95,11 @@ int cmd_merge_base(int argc, const char **argv, const char *prefix) int is_ancestor = 0; struct option options[] = { - OPT_BOOLEAN('a', "all", &show_all, N_("output all common ancestors")), - OPT_BOOLEAN(0, "octopus", &octopus, N_("find ancestors for a single n-way merge")), - OPT_BOOLEAN(0, "independent", &reduce, N_("list revs not reachable from others")), - OPT_BOOLEAN(0, "is-ancestor", &is_ancestor, - N_("is the first one ancestor of the other?")), + OPT_BOOL('a', "all", &show_all, N_("output all common ancestors")), + OPT_BOOL(0, "octopus", &octopus, N_("find ancestors for a single n-way merge")), + OPT_BOOL(0, "independent", &reduce, N_("list revs not reachable from others")), + OPT_BOOL(0, "is-ancestor", &is_ancestor, + N_("is the first one ancestor of the other?")), OPT_END() }; diff --git a/builtin/merge-file.c b/builtin/merge-file.c index c0570f2407..844f84f40b 100644 --- a/builtin/merge-file.c +++ b/builtin/merge-file.c @@ -30,7 +30,7 @@ int cmd_merge_file(int argc, const char **argv, const char *prefix) int quiet = 0; int prefixlen = 0; struct option options[] = { - OPT_BOOLEAN('p', "stdout", &to_stdout, N_("send results to standard output")), + OPT_BOOL('p', "stdout", &to_stdout, N_("send results to standard output")), OPT_SET_INT(0, "diff3", &xmp.style, N_("use a diff3 based merge"), XDL_MERGE_DIFF3), OPT_SET_INT(0, "ours", &xmp.favor, N_("for conflicts, use our version"), XDL_MERGE_FAVOR_OURS), diff --git a/builtin/merge.c b/builtin/merge.c index 34a6166b52..a8cf4a2484 100644 --- a/builtin/merge.c +++ b/builtin/merge.c @@ -197,15 +197,15 @@ static struct option builtin_merge_options[] = { { OPTION_CALLBACK, 'n', NULL, NULL, NULL, N_("do not show a diffstat at the end of the merge"), PARSE_OPT_NOARG, option_parse_n }, - OPT_BOOLEAN(0, "stat", &show_diffstat, + OPT_BOOL(0, "stat", &show_diffstat, N_("show a diffstat at the end of the merge")), - OPT_BOOLEAN(0, "summary", &show_diffstat, N_("(synonym to --stat)")), + OPT_BOOL(0, "summary", &show_diffstat, N_("(synonym to --stat)")), { OPTION_INTEGER, 0, "log", &shortlog_len, N_("n"), N_("add (at most ) entries from shortlog to merge commit message"), PARSE_OPT_OPTARG, NULL, DEFAULT_MERGE_LOG_LEN }, - OPT_BOOLEAN(0, "squash", &squash, + OPT_BOOL(0, "squash", &squash, N_("create a single commit instead of doing a merge")), - OPT_BOOLEAN(0, "commit", &option_commit, + OPT_BOOL(0, "commit", &option_commit, N_("perform a commit if the merge succeeds (default)")), OPT_BOOL('e', "edit", &option_edit, N_("edit message before committing")), @@ -224,12 +224,12 @@ static struct option builtin_merge_options[] = { N_("merge commit message (for a non-fast-forward merge)"), option_parse_message), OPT__VERBOSITY(&verbosity), - OPT_BOOLEAN(0, "abort", &abort_current_merge, + OPT_BOOL(0, "abort", &abort_current_merge, N_("abort the current in-progress merge")), OPT_SET_INT(0, "progress", &show_progress, N_("force progress reporting"), 1), { OPTION_STRING, 'S', "gpg-sign", &sign_commit, N_("key id"), N_("GPG sign commit"), PARSE_OPT_OPTARG, NULL, (intptr_t) "" }, - OPT_BOOLEAN(0, "overwrite-ignore", &overwrite_ignore, N_("update ignored files (default)")), + OPT_BOOL(0, "overwrite-ignore", &overwrite_ignore, N_("update ignored files (default)")), OPT_END() }; diff --git a/builtin/mv.c b/builtin/mv.c index 034fec92a1..aec79d1838 100644 --- a/builtin/mv.c +++ b/builtin/mv.c @@ -9,14 +9,16 @@ #include "cache-tree.h" #include "string-list.h" #include "parse-options.h" +#include "submodule.h" static const char * const builtin_mv_usage[] = { N_("git mv [options] ... "), NULL }; -static const char **copy_pathspec(const char *prefix, const char **pathspec, - int count, int base_name) +static const char **internal_copy_pathspec(const char *prefix, + const char **pathspec, + int count, int base_name) { int i; const char **result = xmalloc((count + 1) * sizeof(const char *)); @@ -56,20 +58,21 @@ static struct lock_file lock_file; int cmd_mv(int argc, const char **argv, const char *prefix) { - int i, newfd; + int i, newfd, gitmodules_modified = 0; int verbose = 0, show_only = 0, force = 0, ignore_errors = 0; struct option builtin_mv_options[] = { OPT__VERBOSE(&verbose, N_("be verbose")), OPT__DRY_RUN(&show_only, N_("dry run")), OPT__FORCE(&force, N_("force move/rename even if target exists")), - OPT_BOOLEAN('k', NULL, &ignore_errors, N_("skip move/rename errors")), + OPT_BOOL('k', NULL, &ignore_errors, N_("skip move/rename errors")), OPT_END(), }; - const char **source, **destination, **dest_path; + const char **source, **destination, **dest_path, **submodule_gitfile; enum update_mode { BOTH = 0, WORKING_DIRECTORY, INDEX } *modes; struct stat st; struct string_list src_for_dst = STRING_LIST_INIT_NODUP; + gitmodules_config(); git_config(git_default_config, NULL); argc = parse_options(argc, argv, prefix, builtin_mv_options, @@ -81,17 +84,18 @@ int cmd_mv(int argc, const char **argv, const char *prefix) if (read_cache() < 0) die(_("index file corrupt")); - source = copy_pathspec(prefix, argv, argc, 0); + source = internal_copy_pathspec(prefix, argv, argc, 0); modes = xcalloc(argc, sizeof(enum update_mode)); - dest_path = copy_pathspec(prefix, argv + argc, 1, 0); + dest_path = internal_copy_pathspec(prefix, argv + argc, 1, 0); + submodule_gitfile = xcalloc(argc, sizeof(char *)); if (dest_path[0][0] == '\0') /* special case: "." was normalized to "" */ - destination = copy_pathspec(dest_path[0], argv, argc, 1); + destination = internal_copy_pathspec(dest_path[0], argv, argc, 1); else if (!lstat(dest_path[0], &st) && S_ISDIR(st.st_mode)) { dest_path[0] = add_slash(dest_path[0]); - destination = copy_pathspec(dest_path[0], argv, argc, 1); + destination = internal_copy_pathspec(dest_path[0], argv, argc, 1); } else { if (argc != 1) die("destination '%s' is not a directory", dest_path[0]); @@ -117,55 +121,68 @@ int cmd_mv(int argc, const char **argv, const char *prefix) && lstat(dst, &st) == 0) bad = _("cannot move directory over file"); else if (src_is_dir) { - const char *src_w_slash = add_slash(src); - int len_w_slash = length + 1; - int first, last; - - modes[i] = WORKING_DIRECTORY; - - first = cache_name_pos(src_w_slash, len_w_slash); - if (first >= 0) - die (_("Huh? %.*s is in index?"), - len_w_slash, src_w_slash); - - first = -1 - first; - for (last = first; last < active_nr; last++) { - const char *path = active_cache[last]->name; - if (strncmp(path, src_w_slash, len_w_slash)) - break; - } - free((char *)src_w_slash); - - if (last - first < 1) - bad = _("source directory is empty"); - else { - int j, dst_len; - - if (last - first > 0) { - source = xrealloc(source, - (argc + last - first) - * sizeof(char *)); - destination = xrealloc(destination, - (argc + last - first) - * sizeof(char *)); - modes = xrealloc(modes, - (argc + last - first) - * sizeof(enum update_mode)); + int first = cache_name_pos(src, length); + if (first >= 0) { + struct strbuf submodule_dotgit = STRBUF_INIT; + if (!S_ISGITLINK(active_cache[first]->ce_mode)) + die (_("Huh? Directory %s is in index and no submodule?"), src); + if (!is_staging_gitmodules_ok()) + die (_("Please, stage your changes to .gitmodules or stash them to proceed")); + strbuf_addf(&submodule_dotgit, "%s/.git", src); + submodule_gitfile[i] = read_gitfile(submodule_dotgit.buf); + if (submodule_gitfile[i]) + submodule_gitfile[i] = xstrdup(submodule_gitfile[i]); + strbuf_release(&submodule_dotgit); + } else { + const char *src_w_slash = add_slash(src); + int last, len_w_slash = length + 1; + + modes[i] = WORKING_DIRECTORY; + + first = cache_name_pos(src_w_slash, len_w_slash); + if (first >= 0) + die (_("Huh? %.*s is in index?"), + len_w_slash, src_w_slash); + + first = -1 - first; + for (last = first; last < active_nr; last++) { + const char *path = active_cache[last]->name; + if (strncmp(path, src_w_slash, len_w_slash)) + break; } + free((char *)src_w_slash); + + if (last - first < 1) + bad = _("source directory is empty"); + else { + int j, dst_len; - dst = add_slash(dst); - dst_len = strlen(dst); - - for (j = 0; j < last - first; j++) { - const char *path = - active_cache[first + j]->name; - source[argc + j] = path; - destination[argc + j] = - prefix_path(dst, dst_len, - path + length + 1); - modes[argc + j] = INDEX; + if (last - first > 0) { + source = xrealloc(source, + (argc + last - first) + * sizeof(char *)); + destination = xrealloc(destination, + (argc + last - first) + * sizeof(char *)); + modes = xrealloc(modes, + (argc + last - first) + * sizeof(enum update_mode)); + } + + dst = add_slash(dst); + dst_len = strlen(dst); + + for (j = 0; j < last - first; j++) { + const char *path = + active_cache[first + j]->name; + source[argc + j] = path; + destination[argc + j] = + prefix_path(dst, dst_len, + path + length + 1); + modes[argc + j] = INDEX; + } + argc += last - first; } - argc += last - first; } } else if (cache_name_pos(src, length) < 0) bad = _("not under version control"); @@ -210,9 +227,14 @@ int cmd_mv(int argc, const char **argv, const char *prefix) int pos; if (show_only || verbose) printf(_("Renaming %s to %s\n"), src, dst); - if (!show_only && mode != INDEX && - rename(src, dst) < 0 && !ignore_errors) - die_errno (_("renaming '%s' failed"), src); + if (!show_only && mode != INDEX) { + if (rename(src, dst) < 0 && !ignore_errors) + die_errno (_("renaming '%s' failed"), src); + if (submodule_gitfile[i]) + connect_work_tree_and_git_dir(dst, submodule_gitfile[i]); + if (!update_path_in_gitmodules(src, dst)) + gitmodules_modified = 1; + } if (mode == WORKING_DIRECTORY) continue; @@ -223,6 +245,9 @@ int cmd_mv(int argc, const char **argv, const char *prefix) rename_cache_entry_at(pos, dst); } + if (gitmodules_modified) + stage_updated_gitmodules(); + if (active_cache_changed) { if (write_cache(newfd, active_cache, active_nr) || commit_locked_index(&lock_file)) diff --git a/builtin/name-rev.c b/builtin/name-rev.c index 0aaa19e4ab..20fcf8c696 100644 --- a/builtin/name-rev.c +++ b/builtin/name-rev.c @@ -310,15 +310,15 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix) int all = 0, transform_stdin = 0, allow_undefined = 1, always = 0, peel_tag = 0; struct name_ref_data data = { 0, 0, NULL }; struct option opts[] = { - OPT_BOOLEAN(0, "name-only", &data.name_only, N_("print only names (no SHA-1)")), - OPT_BOOLEAN(0, "tags", &data.tags_only, N_("only use tags to name the commits")), + OPT_BOOL(0, "name-only", &data.name_only, N_("print only names (no SHA-1)")), + OPT_BOOL(0, "tags", &data.tags_only, N_("only use tags to name the commits")), OPT_STRING(0, "refs", &data.ref_filter, N_("pattern"), N_("only use refs matching ")), OPT_GROUP(""), - OPT_BOOLEAN(0, "all", &all, N_("list all commits reachable from all refs")), - OPT_BOOLEAN(0, "stdin", &transform_stdin, N_("read from stdin")), - OPT_BOOLEAN(0, "undefined", &allow_undefined, N_("allow to print `undefined` names")), - OPT_BOOLEAN(0, "always", &always, + OPT_BOOL(0, "all", &all, N_("list all commits reachable from all refs")), + OPT_BOOL(0, "stdin", &transform_stdin, N_("read from stdin")), + OPT_BOOL(0, "undefined", &allow_undefined, N_("allow to print `undefined` names (default)")), + OPT_BOOL(0, "always", &always, N_("show abbreviated commit object as fallback")), { /* A Hidden OPT_BOOL */ @@ -331,7 +331,7 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix) git_config(git_default_config, NULL); argc = parse_options(argc, argv, prefix, opts, name_rev_usage, 0); - if (!!all + !!transform_stdin + !!argc > 1) { + if (all + transform_stdin + !!argc > 1) { error("Specify either a list, or --all, not both!"); usage_with_options(name_rev_usage, opts); } diff --git a/builtin/notes.c b/builtin/notes.c index e4100c4982..d459e23c42 100644 --- a/builtin/notes.c +++ b/builtin/notes.c @@ -483,7 +483,7 @@ static int copy(int argc, const char **argv, const char *prefix) const char *rewrite_cmd = NULL; struct option options[] = { OPT__FORCE(&force, N_("replace existing notes")), - OPT_BOOLEAN(0, "stdin", &from_stdin, N_("read objects from stdin")), + OPT_BOOL(0, "stdin", &from_stdin, N_("read objects from stdin")), OPT_STRING(0, "for-rewrite", &rewrite_cmd, N_("command"), N_("load rewriting config for (implies " "--stdin)")), @@ -739,13 +739,13 @@ static int merge(int argc, const char **argv, const char *prefix) N_("resolve notes conflicts using the given strategy " "(manual/ours/theirs/union/cat_sort_uniq)")), OPT_GROUP(N_("Committing unmerged notes")), - { OPTION_BOOLEAN, 0, "commit", &do_commit, NULL, + { OPTION_SET_INT, 0, "commit", &do_commit, NULL, N_("finalize notes merge by committing unmerged notes"), - PARSE_OPT_NOARG | PARSE_OPT_NONEG }, + PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, 1}, OPT_GROUP(N_("Aborting notes merge resolution")), - { OPTION_BOOLEAN, 0, "abort", &do_abort, NULL, + { OPTION_SET_INT, 0, "abort", &do_abort, NULL, N_("abort notes merge"), - PARSE_OPT_NOARG | PARSE_OPT_NONEG }, + PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, 1}, OPT_END() }; @@ -853,7 +853,7 @@ static int remove_cmd(int argc, const char **argv, const char *prefix) OPT_BIT(0, "ignore-missing", &flag, N_("attempt to remove non-existent note is not an error"), IGNORE_MISSING), - OPT_BOOLEAN(0, "stdin", &from_stdin, + OPT_BOOL(0, "stdin", &from_stdin, N_("read object names from the standard input")), OPT_END() }; diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c index f069462cb0..4eb0521c81 100644 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@ -1809,7 +1809,7 @@ static void find_deltas(struct object_entry **list, unsigned *list_size, static void try_to_free_from_threads(size_t size) { read_lock(); - release_pack_memory(size, -1); + release_pack_memory(size); read_unlock(); } diff --git a/builtin/push.c b/builtin/push.c index 04f0eaf179..50bbfd62b1 100644 --- a/builtin/push.c +++ b/builtin/push.c @@ -21,6 +21,8 @@ static const char *receivepack; static int verbosity; static int progress = -1; +static struct push_cas_option cas; + static const char **refspec; static int refspec_nr; static int refspec_alloc; @@ -316,6 +318,13 @@ static int push_with_options(struct transport *transport, int flags) if (thin) transport_set_option(transport, TRANS_OPT_THIN, "yes"); + if (!is_empty_cas(&cas)) { + if (!transport->smart_options) + die("underlying transport does not support --%s option", + CAS_OPT_NAME); + transport->smart_options->cas = &cas; + } + if (verbosity > 0) fprintf(stderr, _("Pushing to %s\n"), transport->url); err = transport_push(transport, refspec_nr, refspec, flags, @@ -446,15 +455,19 @@ int cmd_push(int argc, const char **argv, const char *prefix) OPT_BIT( 0 , "all", &flags, N_("push all refs"), TRANSPORT_PUSH_ALL), OPT_BIT( 0 , "mirror", &flags, N_("mirror all refs"), (TRANSPORT_PUSH_MIRROR|TRANSPORT_PUSH_FORCE)), - OPT_BOOLEAN( 0, "delete", &deleterefs, N_("delete refs")), - OPT_BOOLEAN( 0 , "tags", &tags, N_("push tags (can't be used with --all or --mirror)")), + OPT_BOOL( 0, "delete", &deleterefs, N_("delete refs")), + OPT_BOOL( 0 , "tags", &tags, N_("push tags (can't be used with --all or --mirror)")), OPT_BIT('n' , "dry-run", &flags, N_("dry run"), TRANSPORT_PUSH_DRY_RUN), OPT_BIT( 0, "porcelain", &flags, N_("machine-readable output"), TRANSPORT_PUSH_PORCELAIN), OPT_BIT('f', "force", &flags, N_("force updates"), TRANSPORT_PUSH_FORCE), + { OPTION_CALLBACK, + 0, CAS_OPT_NAME, &cas, N_("refname>:/HEAD according to remote")), - OPT_BOOLEAN('d', "delete", &opt_d, - N_("delete refs/remotes//HEAD")), + OPT_BOOL('a', "auto", &opt_a, + N_("set refs/remotes//HEAD according to remote")), + OPT_BOOL('d', "delete", &opt_d, + N_("delete refs/remotes//HEAD")), OPT_END() }; argc = parse_options(argc, argv, NULL, options, builtin_remote_sethead_usage, @@ -1317,8 +1317,8 @@ static int update(int argc, const char **argv) { int i, prune = 0; struct option options[] = { - OPT_BOOLEAN('p', "prune", &prune, - N_("prune remotes after fetching")), + OPT_BOOL('p', "prune", &prune, + N_("prune remotes after fetching")), OPT_END() }; const char **fetch_argv; @@ -1404,7 +1404,7 @@ static int set_branches(int argc, const char **argv) { int add_mode = 0; struct option options[] = { - OPT_BOOLEAN('\0', "add", &add_mode, N_("add branch")), + OPT_BOOL('\0', "add", &add_mode, N_("add branch")), OPT_END() }; @@ -1432,11 +1432,11 @@ static int set_url(int argc, const char **argv) int urlset_nr; struct strbuf name_buf = STRBUF_INIT; struct option options[] = { - OPT_BOOLEAN('\0', "push", &push_mode, - N_("manipulate push URLs")), - OPT_BOOLEAN('\0', "add", &add_mode, - N_("add URL")), - OPT_BOOLEAN('\0', "delete", &delete_mode, + OPT_BOOL('\0', "push", &push_mode, + N_("manipulate push URLs")), + OPT_BOOL('\0', "add", &add_mode, + N_("add URL")), + OPT_BOOL('\0', "delete", &delete_mode, N_("delete URLs")), OPT_END() }; diff --git a/builtin/replace.c b/builtin/replace.c index 59d31152d0..11b0a55ae7 100644 --- a/builtin/replace.c +++ b/builtin/replace.c @@ -118,9 +118,9 @@ int cmd_replace(int argc, const char **argv, const char *prefix) { int list = 0, delete = 0, force = 0; struct option options[] = { - OPT_BOOLEAN('l', NULL, &list, N_("list replace refs")), - OPT_BOOLEAN('d', NULL, &delete, N_("delete replace refs")), - OPT_BOOLEAN('f', NULL, &force, N_("replace the ref if it exists")), + OPT_BOOL('l', NULL, &list, N_("list replace refs")), + OPT_BOOL('d', NULL, &delete, N_("delete replace refs")), + OPT_BOOL('f', NULL, &force, N_("replace the ref if it exists")), OPT_END() }; diff --git a/builtin/rerere.c b/builtin/rerere.c index dc1708e6d6..4e51addb3e 100644 --- a/builtin/rerere.c +++ b/builtin/rerere.c @@ -6,6 +6,7 @@ #include "rerere.h" #include "xdiff/xdiff.h" #include "xdiff-interface.h" +#include "pathspec.h" static const char * const rerere_usage[] = { N_("git rerere [clear | forget path... | status | remaining | diff | gc]"), @@ -68,11 +69,12 @@ int cmd_rerere(int argc, const char **argv, const char *prefix) return rerere(flags); if (!strcmp(argv[0], "forget")) { - const char **pathspec; + struct pathspec pathspec; if (argc < 2) warning("'git rerere forget' without paths is deprecated"); - pathspec = get_pathspec(prefix, argv + 1); - return rerere_forget(pathspec); + parse_pathspec(&pathspec, 0, PATHSPEC_PREFER_CWD, + prefix, argv + 1); + return rerere_forget(&pathspec); } fd = setup_rerere(&merge_rr, flags); diff --git a/builtin/reset.c b/builtin/reset.c index afa6e020e8..5e4c551531 100644 --- a/builtin/reset.c +++ b/builtin/reset.c @@ -133,12 +133,13 @@ static void update_index_from_diff(struct diff_queue_struct *q, } } -static int read_from_tree(const char **pathspec, unsigned char *tree_sha1) +static int read_from_tree(const struct pathspec *pathspec, + unsigned char *tree_sha1) { struct diff_options opt; memset(&opt, 0, sizeof(opt)); - diff_tree_setup_paths(pathspec, &opt); + copy_pathspec(&opt.pathspec, pathspec); opt.output_format = DIFF_FORMAT_CALLBACK; opt.format_callback = update_index_from_diff; @@ -147,7 +148,7 @@ static int read_from_tree(const char **pathspec, unsigned char *tree_sha1) return 1; diffcore_std(&opt); diff_flush(&opt); - diff_tree_release_paths(&opt); + free_pathspec(&opt.pathspec); return 0; } @@ -174,7 +175,10 @@ static void die_if_unmerged_cache(int reset_type) } -static const char **parse_args(const char **argv, const char *prefix, const char **rev_ret) +static void parse_args(struct pathspec *pathspec, + const char **argv, const char *prefix, + int patch_mode, + const char **rev_ret) { const char *rev = "HEAD"; unsigned char unused[20]; @@ -216,7 +220,10 @@ static const char **parse_args(const char **argv, const char *prefix, const char } } *rev_ret = rev; - return argv[0] ? get_pathspec(prefix, argv) : NULL; + parse_pathspec(pathspec, 0, + PATHSPEC_PREFER_FULL | + (patch_mode ? PATHSPEC_PREFIX_ORIGIN : 0), + prefix, argv); } static int update_refs(const char *rev, const unsigned char *sha1) @@ -246,7 +253,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix) int patch_mode = 0, unborn; const char *rev; unsigned char sha1[20]; - const char **pathspec = NULL; + struct pathspec pathspec; const struct option options[] = { OPT__QUIET(&quiet, N_("be quiet, only report errors")), OPT_SET_INT(0, "mixed", &reset_type, @@ -258,7 +265,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix) N_("reset HEAD, index and working tree"), MERGE), OPT_SET_INT(0, "keep", &reset_type, N_("reset HEAD but keep local changes"), KEEP), - OPT_BOOLEAN('p', "patch", &patch_mode, N_("select hunks interactively")), + OPT_BOOL('p', "patch", &patch_mode, N_("select hunks interactively")), OPT_END() }; @@ -266,13 +273,13 @@ int cmd_reset(int argc, const char **argv, const char *prefix) argc = parse_options(argc, argv, prefix, options, git_reset_usage, PARSE_OPT_KEEP_DASHDASH); - pathspec = parse_args(argv, prefix, &rev); + parse_args(&pathspec, argv, prefix, patch_mode, &rev); unborn = !strcmp(rev, "HEAD") && get_sha1("HEAD", sha1); if (unborn) { /* reset on unborn branch: treat as reset to empty tree */ hashcpy(sha1, EMPTY_TREE_SHA1_BIN); - } else if (!pathspec) { + } else if (!pathspec.nr) { struct commit *commit; if (get_sha1_committish(rev, sha1)) die(_("Failed to resolve '%s' as a valid revision."), rev); @@ -293,13 +300,13 @@ int cmd_reset(int argc, const char **argv, const char *prefix) if (patch_mode) { if (reset_type != NONE) die(_("--patch is incompatible with --{hard,mixed,soft}")); - return run_add_interactive(sha1_to_hex(sha1), "--patch=reset", pathspec); + return run_add_interactive(sha1_to_hex(sha1), "--patch=reset", &pathspec); } /* git reset tree [--] paths... can be used to * load chosen paths from the tree into the index without * affecting the working tree nor HEAD. */ - if (pathspec) { + if (pathspec.nr) { if (reset_type == MIXED) warning(_("--mixed with paths is deprecated; use 'git reset -- ' instead.")); else if (reset_type != NONE) @@ -326,7 +333,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix) struct lock_file *lock = xcalloc(1, sizeof(struct lock_file)); int newfd = hold_locked_index(lock, 1); if (reset_type == MIXED) { - if (read_from_tree(pathspec, sha1)) + if (read_from_tree(&pathspec, sha1)) return 1; } else { int err = reset_index(sha1, reset_type, quiet); @@ -347,7 +354,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix) die(_("Could not write new index file.")); } - if (!pathspec && !unborn) { + if (!pathspec.nr && !unborn) { /* Any resets without paths update HEAD to the head being * switched to, saving the previous head in ORIG_HEAD before. */ update_ref_status = update_refs(rev, sha1); @@ -355,7 +362,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix) if (reset_type == HARD && !update_ref_status && !quiet) print_new_head_line(lookup_commit_reference(sha1)); } - if (!pathspec) + if (!pathspec.nr) remove_branch_state(); return update_ref_status; diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c index de894c7577..c76b89dc5b 100644 --- a/builtin/rev-parse.c +++ b/builtin/rev-parse.c @@ -346,9 +346,9 @@ static int cmd_parseopt(int argc, const char **argv, const char *prefix) NULL }; static struct option parseopt_opts[] = { - OPT_BOOLEAN(0, "keep-dashdash", &keep_dashdash, + OPT_BOOL(0, "keep-dashdash", &keep_dashdash, N_("keep the `--` passed as an arg")), - OPT_BOOLEAN(0, "stop-at-non-option", &stop_at_non_option, + OPT_BOOL(0, "stop-at-non-option", &stop_at_non_option, N_("stop parsing after the " "first non-option argument")), OPT_END(), @@ -486,21 +486,6 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix) if (argc > 1 && !strcmp("--sq-quote", argv[1])) return cmd_sq_quote(argc - 2, argv + 2); - if (argc == 2 && !strcmp("--local-env-vars", argv[1])) { - int i; - for (i = 0; local_repo_env[i]; i++) - printf("%s\n", local_repo_env[i]); - return 0; - } - - if (argc > 2 && !strcmp(argv[1], "--resolve-git-dir")) { - const char *gitdir = resolve_gitdir(argv[2]); - if (!gitdir) - die("not a gitdir '%s'", argv[2]); - puts(gitdir); - return 0; - } - if (argc > 1 && !strcmp("-h", argv[1])) usage(builtin_rev_parse_usage); @@ -661,6 +646,12 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix) for_each_remote_ref(show_reference, NULL); continue; } + if (!strcmp(arg, "--local-env-vars")) { + int i; + for (i = 0; local_repo_env[i]; i++) + printf("%s\n", local_repo_env[i]); + continue; + } if (!strcmp(arg, "--show-toplevel")) { const char *work_tree = get_git_work_tree(); if (work_tree) @@ -711,6 +702,13 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix) printf("%s%s.git\n", cwd, len && cwd[len-1] != '/' ? "/" : ""); continue; } + if (!strcmp(arg, "--resolve-git-dir")) { + const char *gitdir = resolve_gitdir(argv[i+1]); + if (!gitdir) + die("not a gitdir '%s'", argv[i+1]); + puts(gitdir); + continue; + } if (!strcmp(arg, "--is-inside-git-dir")) { printf("%s\n", is_inside_git_dir() ? "true" : "false"); diff --git a/builtin/revert.c b/builtin/revert.c index 1d2648b756..8e87acd12e 100644 --- a/builtin/revert.c +++ b/builtin/revert.c @@ -71,44 +71,19 @@ static void verify_opt_compatible(const char *me, const char *base_opt, ...) die(_("%s: %s cannot be used with %s"), me, this_opt, base_opt); } -LAST_ARG_MUST_BE_NULL -static void verify_opt_mutually_compatible(const char *me, ...) -{ - const char *opt1, *opt2 = NULL; - va_list ap; - - va_start(ap, me); - while ((opt1 = va_arg(ap, const char *))) { - if (va_arg(ap, int)) - break; - } - if (opt1) { - while ((opt2 = va_arg(ap, const char *))) { - if (va_arg(ap, int)) - break; - } - } - va_end(ap); - - if (opt1 && opt2) - die(_("%s: %s cannot be used with %s"), me, opt1, opt2); -} - static void parse_args(int argc, const char **argv, struct replay_opts *opts) { const char * const * usage_str = revert_or_cherry_pick_usage(opts); const char *me = action_name(opts); - int remove_state = 0; - int contin = 0; - int rollback = 0; + int cmd = 0; struct option options[] = { - OPT_BOOLEAN(0, "quit", &remove_state, N_("end revert or cherry-pick sequence")), - OPT_BOOLEAN(0, "continue", &contin, N_("resume revert or cherry-pick sequence")), - OPT_BOOLEAN(0, "abort", &rollback, N_("cancel revert or cherry-pick sequence")), - OPT_BOOLEAN('n', "no-commit", &opts->no_commit, N_("don't automatically commit")), - OPT_BOOLEAN('e', "edit", &opts->edit, N_("edit the commit message")), + OPT_CMDMODE(0, "quit", &cmd, N_("end revert or cherry-pick sequence"), 'q'), + OPT_CMDMODE(0, "continue", &cmd, N_("resume revert or cherry-pick sequence"), 'c'), + OPT_CMDMODE(0, "abort", &cmd, N_("cancel revert or cherry-pick sequence"), 'a'), + OPT_BOOL('n', "no-commit", &opts->no_commit, N_("don't automatically commit")), + OPT_BOOL('e', "edit", &opts->edit, N_("edit the commit message")), OPT_NOOP_NOARG('r', NULL), - OPT_BOOLEAN('s', "signoff", &opts->signoff, N_("add Signed-off-by:")), + OPT_BOOL('s', "signoff", &opts->signoff, N_("add Signed-off-by:")), OPT_INTEGER('m', "mainline", &opts->mainline, N_("parent number")), OPT_RERERE_AUTOUPDATE(&opts->allow_rerere_auto), OPT_STRING(0, "strategy", &opts->strategy, N_("strategy"), N_("merge strategy")), @@ -124,11 +99,11 @@ static void parse_args(int argc, const char **argv, struct replay_opts *opts) if (opts->action == REPLAY_PICK) { struct option cp_extra[] = { - OPT_BOOLEAN('x', NULL, &opts->record_origin, N_("append commit name")), - OPT_BOOLEAN(0, "ff", &opts->allow_ff, N_("allow fast-forward")), - OPT_BOOLEAN(0, "allow-empty", &opts->allow_empty, N_("preserve initially empty commits")), - OPT_BOOLEAN(0, "allow-empty-message", &opts->allow_empty_message, N_("allow commits with empty messages")), - OPT_BOOLEAN(0, "keep-redundant-commits", &opts->keep_redundant_commits, N_("keep redundant, empty commits")), + OPT_BOOL('x', NULL, &opts->record_origin, N_("append commit name")), + OPT_BOOL(0, "ff", &opts->allow_ff, N_("allow fast-forward")), + OPT_BOOL(0, "allow-empty", &opts->allow_empty, N_("preserve initially empty commits")), + OPT_BOOL(0, "allow-empty-message", &opts->allow_empty_message, N_("allow commits with empty messages")), + OPT_BOOL(0, "keep-redundant-commits", &opts->keep_redundant_commits, N_("keep redundant, empty commits")), OPT_END(), }; if (parse_options_concat(options, ARRAY_SIZE(options), cp_extra)) @@ -139,23 +114,16 @@ static void parse_args(int argc, const char **argv, struct replay_opts *opts) PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN); - /* Check for incompatible subcommands */ - verify_opt_mutually_compatible(me, - "--quit", remove_state, - "--continue", contin, - "--abort", rollback, - NULL); - /* implies allow_empty */ if (opts->keep_redundant_commits) opts->allow_empty = 1; /* Set the subcommand */ - if (remove_state) + if (cmd == 'q') opts->subcommand = REPLAY_REMOVE_STATE; - else if (contin) + else if (cmd == 'c') opts->subcommand = REPLAY_CONTINUE; - else if (rollback) + else if (cmd == 'a') opts->subcommand = REPLAY_ROLLBACK; else opts->subcommand = REPLAY_NONE; diff --git a/builtin/rm.c b/builtin/rm.c index 0df0b4d942..9b59ab3a64 100644 --- a/builtin/rm.c +++ b/builtin/rm.c @@ -11,6 +11,7 @@ #include "parse-options.h" #include "string-list.h" #include "submodule.h" +#include "pathspec.h" static const char * const builtin_rm_usage[] = { N_("git rm [options] [--] ..."), @@ -267,10 +268,10 @@ static int ignore_unmatch = 0; static struct option builtin_rm_options[] = { OPT__DRY_RUN(&show_only, N_("dry run")), OPT__QUIET(&quiet, N_("do not list removed files")), - OPT_BOOLEAN( 0 , "cached", &index_only, N_("only remove from the index")), + OPT_BOOL( 0 , "cached", &index_only, N_("only remove from the index")), OPT__FORCE(&force, N_("override the up-to-date check")), - OPT_BOOLEAN('r', NULL, &recursive, N_("allow recursive removal")), - OPT_BOOLEAN( 0 , "ignore-unmatch", &ignore_unmatch, + OPT_BOOL('r', NULL, &recursive, N_("allow recursive removal")), + OPT_BOOL( 0 , "ignore-unmatch", &ignore_unmatch, N_("exit with a zero status even if nothing matched")), OPT_END(), }; @@ -278,9 +279,10 @@ static struct option builtin_rm_options[] = { int cmd_rm(int argc, const char **argv, const char *prefix) { int i, newfd; - const char **pathspec; + struct pathspec pathspec; char *seen; + gitmodules_config(); git_config(git_default_config, NULL); argc = parse_options(argc, argv, prefix, builtin_rm_options, @@ -311,31 +313,32 @@ int cmd_rm(int argc, const char **argv, const char *prefix) } } - pathspec = get_pathspec(prefix, argv); - refresh_index(&the_index, REFRESH_QUIET, pathspec, NULL, NULL); + parse_pathspec(&pathspec, 0, PATHSPEC_PREFER_CWD, prefix, argv); + refresh_index(&the_index, REFRESH_QUIET, &pathspec, NULL, NULL); - seen = NULL; - for (i = 0; pathspec[i] ; i++) - /* nothing */; - seen = xcalloc(i, 1); + seen = xcalloc(pathspec.nr, 1); for (i = 0; i < active_nr; i++) { const struct cache_entry *ce = active_cache[i]; - if (!match_pathspec(pathspec, ce->name, ce_namelen(ce), 0, seen)) + if (!match_pathspec_depth(&pathspec, ce->name, ce_namelen(ce), 0, seen)) continue; 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); + list.entry[list.nr].is_submodule = S_ISGITLINK(ce->ce_mode); + if (list.entry[list.nr++].is_submodule && + !is_staging_gitmodules_ok()) + die (_("Please, stage your changes to .gitmodules or stash them to proceed")); } - if (pathspec) { - const char *match; + if (pathspec.nr) { + const char *original; int seen_any = 0; - for (i = 0; (match = pathspec[i]) != NULL ; i++) { + for (i = 0; i < pathspec.nr; i++) { + original = pathspec.items[i].original; if (!seen[i]) { if (!ignore_unmatch) { die(_("pathspec '%s' did not match any files"), - match); + original); } } else { @@ -343,10 +346,10 @@ int cmd_rm(int argc, const char **argv, const char *prefix) } if (!recursive && seen[i] == MATCHED_RECURSIVELY) die(_("not removing '%s' recursively without -r"), - *match ? match : "."); + *original ? original : "."); } - if (! seen_any) + if (!seen_any) exit(0); } @@ -396,13 +399,15 @@ int cmd_rm(int argc, const char **argv, const char *prefix) * in the middle) */ if (!index_only) { - int removed = 0; + int removed = 0, gitmodules_modified = 0; for (i = 0; i < list.nr; i++) { const char *path = list.entry[i].name; if (list.entry[i].is_submodule) { if (is_empty_dir(path)) { if (!rmdir(path)) { removed = 1; + if (!remove_path_from_gitmodules(path)) + gitmodules_modified = 1; continue; } } else { @@ -410,9 +415,14 @@ int cmd_rm(int argc, const char **argv, const char *prefix) strbuf_addstr(&buf, path); if (!remove_dir_recursively(&buf, 0)) { removed = 1; + if (!remove_path_from_gitmodules(path)) + gitmodules_modified = 1; strbuf_release(&buf); continue; - } + } else if (!file_exists(path)) + /* Submodule was removed by user */ + if (!remove_path_from_gitmodules(path)) + gitmodules_modified = 1; strbuf_release(&buf); /* Fallthrough and let remove_path() fail. */ } @@ -424,6 +434,8 @@ int cmd_rm(int argc, const char **argv, const char *prefix) if (!removed) die_errno("git rm: '%s'", path); } + if (gitmodules_modified) + stage_updated_gitmodules(); } if (active_cache_changed) { diff --git a/builtin/send-pack.c b/builtin/send-pack.c index 152c4ea092..4482f16efb 100644 --- a/builtin/send-pack.c +++ b/builtin/send-pack.c @@ -5,6 +5,7 @@ #include "sideband.h" #include "run-command.h" #include "remote.h" +#include "connect.h" #include "send-pack.h" #include "quote.h" #include "transport.h" @@ -54,6 +55,11 @@ static void print_helper_status(struct ref *ref) msg = "needs force"; break; + case REF_STATUS_REJECT_STALE: + res = "error"; + msg = "stale info"; + break; + case REF_STATUS_REJECT_ALREADY_EXISTS: res = "error"; msg = "already exists"; @@ -102,6 +108,7 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix) int flags; unsigned int reject_reasons; int progress = -1; + struct push_cas_option cas = {0}; argv++; for (i = 1; i < argc; i++, argv++) { @@ -164,6 +171,22 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix) helper_status = 1; continue; } + if (!strcmp(arg, "--" CAS_OPT_NAME)) { + if (parse_push_cas_option(&cas, NULL, 0) < 0) + exit(1); + continue; + } + if (!strcmp(arg, "--no-" CAS_OPT_NAME)) { + if (parse_push_cas_option(&cas, NULL, 1) < 0) + exit(1); + continue; + } + if (!prefixcmp(arg, "--" CAS_OPT_NAME "=")) { + if (parse_push_cas_option(&cas, + strchr(arg, '=') + 1, 0) < 0) + exit(1); + continue; + } usage(send_pack_usage); } if (!dest) { @@ -224,6 +247,9 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix) if (match_push_refs(local_refs, &remote_refs, nr_refspecs, refspecs, flags)) return -1; + if (!is_empty_cas(&cas)) + apply_push_cas(&cas, remote, remote_refs); + set_ref_status_for_push(remote_refs, args.send_mirror, args.force_update); diff --git a/builtin/shortlog.c b/builtin/shortlog.c index 1434f8fee4..ae73d17b6c 100644 --- a/builtin/shortlog.c +++ b/builtin/shortlog.c @@ -224,12 +224,12 @@ int cmd_shortlog(int argc, const char **argv, const char *prefix) int nongit = !startup_info->have_repository; static const struct option options[] = { - OPT_BOOLEAN('n', "numbered", &log.sort_by_number, - N_("sort output according to the number of commits per author")), - OPT_BOOLEAN('s', "summary", &log.summary, - N_("Suppress commit descriptions, only provides commit count")), - OPT_BOOLEAN('e', "email", &log.email, - N_("Show the email address of each author")), + OPT_BOOL('n', "numbered", &log.sort_by_number, + N_("sort output according to the number of commits per author")), + OPT_BOOL('s', "summary", &log.summary, + N_("Suppress commit descriptions, only provides commit count")), + OPT_BOOL('e', "email", &log.email, + N_("Show the email address of each author")), { OPTION_CALLBACK, 'w', NULL, &log, N_("w[,i1[,i2]]"), N_("Linewrap output"), PARSE_OPT_OPTARG, &parse_wrap_args }, OPT_END(), diff --git a/builtin/show-branch.c b/builtin/show-branch.c index 9788eb115b..001f29ca1b 100644 --- a/builtin/show-branch.c +++ b/builtin/show-branch.c @@ -646,30 +646,30 @@ int cmd_show_branch(int ac, const char **av, const char *prefix) int dense = 1; const char *reflog_base = NULL; struct option builtin_show_branch_options[] = { - OPT_BOOLEAN('a', "all", &all_heads, - N_("show remote-tracking and local branches")), - OPT_BOOLEAN('r', "remotes", &all_remotes, - N_("show remote-tracking branches")), + OPT_BOOL('a', "all", &all_heads, + N_("show remote-tracking and local branches")), + OPT_BOOL('r', "remotes", &all_remotes, + N_("show remote-tracking branches")), OPT__COLOR(&showbranch_use_color, N_("color '*!+-' corresponding to the branch")), { OPTION_INTEGER, 0, "more", &extra, N_("n"), N_("show more commits after the common ancestor"), PARSE_OPT_OPTARG, NULL, (intptr_t)1 }, OPT_SET_INT(0, "list", &extra, N_("synonym to more=-1"), -1), - OPT_BOOLEAN(0, "no-name", &no_name, N_("suppress naming strings")), - OPT_BOOLEAN(0, "current", &with_current_branch, - N_("include the current branch")), - OPT_BOOLEAN(0, "sha1-name", &sha1_name, - N_("name commits with their object names")), - OPT_BOOLEAN(0, "merge-base", &merge_base, - N_("show possible merge bases")), - OPT_BOOLEAN(0, "independent", &independent, + OPT_BOOL(0, "no-name", &no_name, N_("suppress naming strings")), + OPT_BOOL(0, "current", &with_current_branch, + N_("include the current branch")), + OPT_BOOL(0, "sha1-name", &sha1_name, + N_("name commits with their object names")), + OPT_BOOL(0, "merge-base", &merge_base, + N_("show possible merge bases")), + OPT_BOOL(0, "independent", &independent, N_("show refs unreachable from any other ref")), OPT_SET_INT(0, "topo-order", &sort_order, N_("show commits in topological order"), REV_SORT_IN_GRAPH_ORDER), - OPT_BOOLEAN(0, "topics", &topics, - N_("show only commits not on the first branch")), + OPT_BOOL(0, "topics", &topics, + N_("show only commits not on the first branch")), OPT_SET_INT(0, "sparse", &dense, N_("show merges reachable from only one tip"), 0), OPT_SET_INT(0, "date-order", &sort_order, diff --git a/builtin/show-ref.c b/builtin/show-ref.c index 87806ad5b0..9f3f5e370b 100644 --- a/builtin/show-ref.c +++ b/builtin/show-ref.c @@ -165,16 +165,15 @@ static int help_callback(const struct option *opt, const char *arg, int unset) } static const struct option show_ref_options[] = { - OPT_BOOLEAN(0, "tags", &tags_only, N_("only show tags (can be combined with heads)")), - OPT_BOOLEAN(0, "heads", &heads_only, N_("only show heads (can be combined with tags)")), - OPT_BOOLEAN(0, "verify", &verify, N_("stricter reference checking, " + OPT_BOOL(0, "tags", &tags_only, N_("only show tags (can be combined with heads)")), + OPT_BOOL(0, "heads", &heads_only, N_("only show heads (can be combined with tags)")), + OPT_BOOL(0, "verify", &verify, N_("stricter reference checking, " "requires exact ref path")), - { OPTION_BOOLEAN, 'h', NULL, &show_head, NULL, - N_("show the HEAD reference, even if it would be filtered out"), - PARSE_OPT_NOARG | PARSE_OPT_HIDDEN }, - OPT_BOOLEAN(0, "head", &show_head, + OPT_HIDDEN_BOOL('h', NULL, &show_head, + N_("show the HEAD reference, even if it would be filtered out")), + OPT_BOOL(0, "head", &show_head, N_("show the HEAD reference, even if it would be filtered out")), - OPT_BOOLEAN('d', "dereference", &deref_tags, + OPT_BOOL('d', "dereference", &deref_tags, N_("dereference tags into object IDs")), { OPTION_CALLBACK, 's', "hash", &abbrev, N_("n"), N_("only show SHA1 hash using digits"), diff --git a/builtin/tag.c b/builtin/tag.c index af3af3f649..b577af562a 100644 --- a/builtin/tag.c +++ b/builtin/tag.c @@ -436,26 +436,26 @@ int cmd_tag(int argc, const char **argv, const char *prefix) struct ref_lock *lock; struct create_tag_options opt; char *cleanup_arg = NULL; - int annotate = 0, force = 0, lines = -1, list = 0, - delete = 0, verify = 0; + int annotate = 0, force = 0, lines = -1; + int cmdmode = 0; const char *msgfile = NULL, *keyid = NULL; struct msg_arg msg = { 0, STRBUF_INIT }; struct commit_list *with_commit = NULL; struct option options[] = { - OPT_BOOLEAN('l', "list", &list, N_("list tag names")), + OPT_CMDMODE('l', "list", &cmdmode, N_("list tag names"), 'l'), { OPTION_INTEGER, 'n', NULL, &lines, N_("n"), N_("print lines of each tag message"), PARSE_OPT_OPTARG, NULL, 1 }, - OPT_BOOLEAN('d', "delete", &delete, N_("delete tags")), - OPT_BOOLEAN('v', "verify", &verify, N_("verify tags")), + OPT_CMDMODE('d', "delete", &cmdmode, N_("delete tags"), 'd'), + OPT_CMDMODE('v', "verify", &cmdmode, N_("verify tags"), 'v'), OPT_GROUP(N_("Tag creation options")), - OPT_BOOLEAN('a', "annotate", &annotate, + OPT_BOOL('a', "annotate", &annotate, N_("annotated tag, needs a message")), OPT_CALLBACK('m', "message", &msg, N_("message"), N_("tag message"), parse_msg_arg), OPT_FILENAME('F', "file", &msgfile, N_("read message from file")), - OPT_BOOLEAN('s', "sign", &opt.sign, N_("annotated and GPG-signed tag")), + OPT_BOOL('s', "sign", &opt.sign, N_("annotated and GPG-signed tag")), OPT_STRING(0, "cleanup", &cleanup_arg, N_("mode"), N_("how to strip spaces and #comments from message")), OPT_STRING('u', "local-user", &keyid, N_("key id"), @@ -489,22 +489,19 @@ int cmd_tag(int argc, const char **argv, const char *prefix) } if (opt.sign) annotate = 1; - if (argc == 0 && !(delete || verify)) - list = 1; + if (argc == 0 && !cmdmode) + cmdmode = 'l'; - if ((annotate || msg.given || msgfile || force) && - (list || delete || verify)) + if ((annotate || msg.given || msgfile || force) && (cmdmode != 0)) usage_with_options(git_tag_usage, options); - if (list + delete + verify > 1) - usage_with_options(git_tag_usage, options); finalize_colopts(&colopts, -1); - if (list && lines != -1) { + if (cmdmode == 'l' && lines != -1) { if (explicitly_enable_column(colopts)) die(_("--column and -n are incompatible")); colopts = 0; } - if (list) { + if (cmdmode == 'l') { int ret; if (column_active(colopts)) { struct column_options copts; @@ -523,9 +520,9 @@ int cmd_tag(int argc, const char **argv, const char *prefix) die(_("--contains option is only allowed with -l.")); if (points_at.nr) die(_("--points-at option is only allowed with -l.")); - if (delete) + if (cmdmode == 'd') return for_each_tag_name(argv, delete_tag); - if (verify) + if (cmdmode == 'v') return for_each_tag_name(argv, verify_tag); if (msg.given || msgfile) { diff --git a/builtin/tar-tree.c b/builtin/tar-tree.c index 3f1e7012db..ba3ffe69a9 100644 --- a/builtin/tar-tree.c +++ b/builtin/tar-tree.c @@ -26,8 +26,8 @@ int cmd_tar_tree(int argc, const char **argv, const char *prefix) * $0 tree-ish basedir ==> * git archive --format-tar --prefix=basedir tree-ish */ - int i; const char **nargv = xcalloc(sizeof(*nargv), argc + 3); + struct strbuf sb = STRBUF_INIT; char *basedir_arg; int nargc = 0; @@ -65,11 +65,10 @@ int cmd_tar_tree(int argc, const char **argv, const char *prefix) fprintf(stderr, "*** \"git tar-tree\" is now deprecated.\n" "*** Running \"git archive\" instead.\n***"); - for (i = 0; i < nargc; i++) { - fputc(' ', stderr); - sq_quote_print(stderr, nargv[i]); - } - fputc('\n', stderr); + sq_quote_argv(&sb, nargv, 0); + strbuf_addch(&sb, '\n'); + fputs(sb.buf, stderr); + strbuf_release(&sb); return cmd_archive(nargc, nargv, prefix); } diff --git a/builtin/update-index.c b/builtin/update-index.c index c317981516..e3a10d706d 100644 --- a/builtin/update-index.c +++ b/builtin/update-index.c @@ -11,6 +11,7 @@ #include "refs.h" #include "resolve-undo.h" #include "parse-options.h" +#include "pathspec.h" /* * Default to not allowing changes to the list of files. The @@ -546,10 +547,11 @@ static int do_reupdate(int ac, const char **av, */ int pos; int has_head = 1; - const char **paths = get_pathspec(prefix, av + 1); struct pathspec pathspec; - init_pathspec(&pathspec, paths); + parse_pathspec(&pathspec, 0, + PATHSPEC_PREFER_CWD, + prefix, av + 1); if (read_ref("HEAD", head_sha1)) /* If there is no HEAD, that means it is an initial diff --git a/builtin/update-ref.c b/builtin/update-ref.c index 51d2684859..7484d36a65 100644 --- a/builtin/update-ref.c +++ b/builtin/update-ref.c @@ -16,8 +16,8 @@ int cmd_update_ref(int argc, const char **argv, const char *prefix) int delete = 0, no_deref = 0, flags = 0; struct option options[] = { OPT_STRING( 'm', NULL, &msg, N_("reason"), N_("reason of the update")), - OPT_BOOLEAN('d', NULL, &delete, N_("delete the reference")), - OPT_BOOLEAN( 0 , "no-deref", &no_deref, + OPT_BOOL('d', NULL, &delete, N_("delete the reference")), + OPT_BOOL( 0 , "no-deref", &no_deref, N_("update not the one it points to")), OPT_END(), }; diff --git a/cache.h b/cache.h index 85b544f38d..bd6fb9f664 100644 --- a/cache.h +++ b/cache.h @@ -189,6 +189,8 @@ struct cache_entry { #error "CE_EXTENDED_FLAGS out of range" #endif +struct pathspec; + /* * Copy the sha1 and stat state of a cache entry from one to * another. But we never change the name, or the hash state! @@ -365,6 +367,9 @@ static inline enum object_type object_type(unsigned int mode) #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" +#define GIT_GLOB_PATHSPECS_ENVIRONMENT "GIT_GLOB_PATHSPECS" +#define GIT_NOGLOB_PATHSPECS_ENVIRONMENT "GIT_NOGLOB_PATHSPECS" +#define GIT_ICASE_PATHSPECS_ENVIRONMENT "GIT_ICASE_PATHSPECS" /* * This environment variable is expected to contain a boolean indicating @@ -412,6 +417,7 @@ extern void setup_work_tree(void); extern const char *setup_git_directory_gently(int *); extern const char *setup_git_directory(void); extern char *prefix_path(const char *prefix, int len, const char *path); +extern char *prefix_path_gently(const char *prefix, int len, int *remaining, const char *path); extern const char *prefix_filename(const char *prefix, int len, const char *path); extern int check_filename(const char *prefix, const char *name); extern void verify_filename(const char *prefix, @@ -449,7 +455,7 @@ extern void sanitize_stdfds(void); /* Initialize and use the cache information */ extern int read_index(struct index_state *); -extern int read_index_preload(struct index_state *, const char **pathspec); +extern int read_index_preload(struct index_state *, const struct pathspec *pathspec); extern int read_index_from(struct index_state *, const char *path); extern int is_index_unborn(struct index_state *); extern int read_index_unmerged(struct index_state *); @@ -491,28 +497,8 @@ extern void *read_blob_data_from_index(struct index_state *, const char *, unsig extern int ie_match_stat(const struct index_state *, const struct cache_entry *, struct stat *, unsigned int); extern int ie_modified(const struct index_state *, const struct cache_entry *, struct stat *, unsigned int); -#define PATHSPEC_ONESTAR 1 /* the pathspec pattern satisfies GFNM_ONESTAR */ - -struct pathspec { - const char **raw; /* get_pathspec() result, not freed by free_pathspec() */ - int nr; - unsigned int has_wildcard:1; - unsigned int recursive:1; - int max_depth; - struct pathspec_item { - const char *match; - int len; - int nowildcard_len; - int flags; - } *items; -}; - -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); @@ -540,7 +526,7 @@ extern void fill_stat_cache_info(struct cache_entry *ce, struct stat *st); #define REFRESH_IGNORE_MISSING 0x0008 /* ignore non-existent */ #define REFRESH_IGNORE_SUBMODULES 0x0010 /* ignore submodules */ #define REFRESH_IN_PORCELAIN 0x0020 /* user friendly output, not "needs update" */ -extern int refresh_index(struct index_state *, unsigned int flags, const char **pathspec, char *seen, const char *header_msg); +extern int refresh_index(struct index_state *, unsigned int flags, const struct pathspec *pathspec, char *seen, const char *header_msg); struct lock_file { struct lock_file *next; @@ -762,6 +748,7 @@ 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 *in, const char *prefix, struct strbuf *sb); +int normalize_path_copy_len(char *dst, const char *src, int *prefix_len); int normalize_path_copy(char *dst, const char *src); int longest_ancestor_length(const char *path, struct string_list *prefixes); char *strip_path_suffix(const char *path, const char *suffix); @@ -1038,68 +1025,6 @@ struct pack_entry { struct packed_git *p; }; -struct ref { - struct ref *next; - unsigned char old_sha1[20]; - unsigned char new_sha1[20]; - char *symref; - unsigned int - force:1, - forced_update:1, - deletion:1, - matched:1; - - /* - * Order is important here, as we write to FETCH_HEAD - * in numeric order. And the default NOT_FOR_MERGE - * should be 0, so that xcalloc'd structures get it - * by default. - */ - enum { - FETCH_HEAD_MERGE = -1, - FETCH_HEAD_NOT_FOR_MERGE = 0, - FETCH_HEAD_IGNORE = 1 - } fetch_head_status; - - enum { - REF_STATUS_NONE = 0, - REF_STATUS_OK, - REF_STATUS_REJECT_NONFASTFORWARD, - REF_STATUS_REJECT_ALREADY_EXISTS, - REF_STATUS_REJECT_NODELETE, - REF_STATUS_REJECT_FETCH_FIRST, - REF_STATUS_REJECT_NEEDS_FORCE, - REF_STATUS_UPTODATE, - REF_STATUS_REMOTE_REJECT, - REF_STATUS_EXPECTING_REPORT - } status; - char *remote_status; - struct ref *peer_ref; /* when renaming */ - char name[FLEX_ARRAY]; /* more */ -}; - -#define REF_NORMAL (1u << 0) -#define REF_HEADS (1u << 1) -#define REF_TAGS (1u << 2) - -extern struct ref *find_ref_by_name(const struct ref *list, const char *name); - -#define CONNECT_VERBOSE (1u << 0) -extern struct child_process *git_connect(int fd[2], const char *url, const char *prog, int flags); -extern int finish_connect(struct child_process *conn); -extern int git_connection_is_socket(struct child_process *conn); -struct extra_have_objects { - int nr, alloc; - unsigned char (*array)[20]; -}; -extern struct ref **get_remote_heads(int in, char *src_buf, size_t src_len, - struct ref **list, unsigned int flags, - struct extra_have_objects *); -extern int server_supports(const char *feature); -extern int parse_feature_request(const char *features, const char *feature); -extern const char *server_feature_value(const char *feature, int *len_ret); -extern const char *parse_feature_value(const char *feature_list, const char *feature, int *len_ret); - extern struct packed_git *parse_pack_index(unsigned char *sha1, const char *idx_path); /* A hook for count-objects to report invalid files in pack directory */ @@ -1305,7 +1230,7 @@ void packet_trace_identity(const char *prog); * return 0 if success, 1 - if addition of a file failed and * ADD_FILES_IGNORE_ERRORS was specified in flags */ -int add_files_to_cache(const char *prefix, const char **pathspec, int flags); +int add_files_to_cache(const char *prefix, const struct pathspec *pathspec, int flags); /* diff.c */ extern int diff_auto_refresh_index; @@ -1339,7 +1264,7 @@ extern int ws_blank_line(const char *line, int len, unsigned ws_rule); #define ws_tab_width(rule) ((rule) & WS_TAB_WIDTH_MASK) /* ls-files */ -int report_path_error(const char *ps_matched, const char **pathspec, const char *prefix); +int report_path_error(const char *ps_matched, const struct pathspec *pathspec, const char *prefix); void overlay_tree_on_cache(const char *tree_name, const char *prefix); char *alias_lookup(const char *alias); diff --git a/combine-diff.c b/combine-diff.c index 88525b37cf..3b92c44880 100644 --- a/combine-diff.c +++ b/combine-diff.c @@ -10,6 +10,7 @@ #include "refs.h" #include "userdiff.h" #include "sha1-array.h" +#include "revision.h" static struct combine_diff_path *intersect_paths(struct combine_diff_path *curr, int n, int num_parent) { @@ -1305,7 +1306,7 @@ void diff_tree_combined(const unsigned char *sha1, int i, num_paths, needsep, show_log_first, num_parent = parents->nr; diffopts = *opt; - diff_tree_setup_paths(diffopts.pathspec.raw, &diffopts); + copy_pathspec(&diffopts.pathspec, &opt->pathspec); diffopts.output_format = DIFF_FORMAT_NO_OUTPUT; DIFF_OPT_SET(&diffopts, RECURSIVE); DIFF_OPT_CLR(&diffopts, ALLOW_EXTERNAL); @@ -1377,13 +1378,13 @@ void diff_tree_combined(const unsigned char *sha1, free(tmp); } - diff_tree_release_paths(&diffopts); + free_pathspec(&diffopts.pathspec); } void diff_tree_combined_merge(const struct commit *commit, int dense, struct rev_info *rev) { - struct commit_list *parent = commit->parents; + struct commit_list *parent = get_saved_parents(rev, commit); struct sha1_array parents = SHA1_ARRAY_INIT; while (parent) { diff --git a/commit.c b/commit.c index a575564a15..de16a3c0a2 100644 --- a/commit.c +++ b/commit.c @@ -377,6 +377,22 @@ unsigned commit_list_count(const struct commit_list *l) return c; } +struct commit_list *copy_commit_list(struct commit_list *list) +{ + struct commit_list *head = NULL; + struct commit_list **pp = &head; + while (list) { + struct commit_list *new; + new = xmalloc(sizeof(struct commit_list)); + new->item = list->item; + new->next = NULL; + *pp = new; + pp = &new->next; + list = list->next; + } + return head; +} + void free_commit_list(struct commit_list *list) { while (list) { diff --git a/commit.h b/commit.h index d912a9d4ac..90a5a3c361 100644 --- a/commit.h +++ b/commit.h @@ -62,6 +62,9 @@ struct commit_list *commit_list_insert_by_date(struct commit *item, struct commit_list **list); void commit_list_sort_by_date(struct commit_list **list); +/* Shallow copy of the input list */ +struct commit_list *copy_commit_list(struct commit_list *list); + void free_commit_list(struct commit_list *list); /* Commit formats */ @@ -205,7 +208,7 @@ int in_merge_bases_many(struct commit *, int, struct commit **); extern int interactive_add(int argc, const char **argv, const char *prefix, int patch); extern int run_add_interactive(const char *revision, const char *patch_mode, - const char **pathspec); + const struct pathspec *pathspec); static inline int single_parent(struct commit *commit) { diff --git a/compat/apple-common-crypto.h b/compat/apple-common-crypto.h new file mode 100644 index 0000000000..c8b9b0e1a6 --- /dev/null +++ b/compat/apple-common-crypto.h @@ -0,0 +1,86 @@ +/* suppress inclusion of conflicting openssl functions */ +#define OPENSSL_NO_MD5 +#define HEADER_HMAC_H +#define HEADER_SHA_H +#include +#define HMAC_CTX CCHmacContext +#define HMAC_Init(hmac, key, len, algo) CCHmacInit(hmac, algo, key, len) +#define HMAC_Update CCHmacUpdate +#define HMAC_Final(hmac, hash, ptr) CCHmacFinal(hmac, hash) +#define HMAC_CTX_cleanup(ignore) +#define EVP_md5(...) kCCHmacAlgMD5 +#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 +#define APPLE_LION_OR_NEWER +#include +/* Apple's TYPE_BOOL conflicts with config.c */ +#undef TYPE_BOOL +#endif + +#ifdef APPLE_LION_OR_NEWER +#define git_CC_error_check(pattern, err) \ + do { \ + if (err) { \ + die(pattern, (long)CFErrorGetCode(err)); \ + } \ + } while(0) + +#define EVP_EncodeBlock git_CC_EVP_EncodeBlock +static inline int git_CC_EVP_EncodeBlock(unsigned char *out, + const unsigned char *in, int inlen) +{ + CFErrorRef err; + SecTransformRef encoder; + CFDataRef input, output; + CFIndex length; + + encoder = SecEncodeTransformCreate(kSecBase64Encoding, &err); + git_CC_error_check("SecEncodeTransformCreate failed: %ld", err); + + input = CFDataCreate(kCFAllocatorDefault, in, inlen); + SecTransformSetAttribute(encoder, kSecTransformInputAttributeName, + input, &err); + git_CC_error_check("SecTransformSetAttribute failed: %ld", err); + + output = SecTransformExecute(encoder, &err); + git_CC_error_check("SecTransformExecute failed: %ld", err); + + length = CFDataGetLength(output); + CFDataGetBytes(output, CFRangeMake(0, length), out); + + CFRelease(output); + CFRelease(input); + CFRelease(encoder); + + return (int)strlen((const char *)out); +} + +#define EVP_DecodeBlock git_CC_EVP_DecodeBlock +static int inline git_CC_EVP_DecodeBlock(unsigned char *out, + const unsigned char *in, int inlen) +{ + CFErrorRef err; + SecTransformRef decoder; + CFDataRef input, output; + CFIndex length; + + decoder = SecDecodeTransformCreate(kSecBase64Encoding, &err); + git_CC_error_check("SecEncodeTransformCreate failed: %ld", err); + + input = CFDataCreate(kCFAllocatorDefault, in, inlen); + SecTransformSetAttribute(decoder, kSecTransformInputAttributeName, + input, &err); + git_CC_error_check("SecTransformSetAttribute failed: %ld", err); + + output = SecTransformExecute(decoder, &err); + git_CC_error_check("SecTransformExecute failed: %ld", err); + + length = CFDataGetLength(output); + CFDataGetBytes(output, CFRangeMake(0, length), out); + + CFRelease(output); + CFRelease(input); + CFRelease(decoder); + + return (int)strlen((const char *)out); +} +#endif /* APPLE_LION_OR_NEWER */ diff --git a/compat/mingw.c b/compat/mingw.c index bb92c436f7..22ee9ef1cf 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -1086,6 +1086,12 @@ int mingw_kill(pid_t pid, int sig) errno = err_win_to_posix(GetLastError()); CloseHandle(h); return -1; + } else if (pid > 0 && sig == 0) { + HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid); + if (h) { + CloseHandle(h); + return 0; + } } errno = EINVAL; diff --git a/config.c b/config.c index e13a7b65e7..9f9bf0cc9a 100644 --- a/config.c +++ b/config.c @@ -27,9 +27,9 @@ struct config_source { struct strbuf value; struct strbuf var; - int (*fgetc)(struct config_source *c); - int (*ungetc)(int c, struct config_source *conf); - long (*ftell)(struct config_source *c); + int (*do_fgetc)(struct config_source *c); + int (*do_ungetc)(int c, struct config_source *conf); + long (*do_ftell)(struct config_source *c); }; static struct config_source *cf; @@ -217,13 +217,13 @@ int git_config_from_parameters(config_fn_t fn, void *data) static int get_next_char(void) { - int c = cf->fgetc(cf); + int c = cf->do_fgetc(cf); if (c == '\r') { /* DOS like systems */ - c = cf->fgetc(cf); + c = cf->do_fgetc(cf); if (c != '\n') { - cf->ungetc(c, cf); + cf->do_ungetc(c, cf); c = '\r'; } } @@ -992,9 +992,9 @@ int git_config_from_file(config_fn_t fn, const char *filename, void *data) top.u.file = f; top.name = filename; top.die_on_error = 1; - top.fgetc = config_file_fgetc; - top.ungetc = config_file_ungetc; - top.ftell = config_file_ftell; + top.do_fgetc = config_file_fgetc; + top.do_ungetc = config_file_ungetc; + top.do_ftell = config_file_ftell; ret = do_config_from(&top, fn, data); @@ -1013,9 +1013,9 @@ int git_config_from_buf(config_fn_t fn, const char *name, const char *buf, top.u.buf.pos = 0; top.name = name; top.die_on_error = 0; - top.fgetc = config_buf_fgetc; - top.ungetc = config_buf_ungetc; - top.ftell = config_buf_ftell; + top.do_fgetc = config_buf_fgetc; + top.do_ungetc = config_buf_ungetc; + top.do_ftell = config_buf_ftell; return do_config_from(&top, fn, data); } @@ -1196,7 +1196,7 @@ static int store_aux(const char *key, const char *value, void *cb) return 1; } - store.offset[store.seen] = cf->ftell(cf); + store.offset[store.seen] = cf->do_ftell(cf); store.seen++; } break; @@ -1223,19 +1223,19 @@ static int store_aux(const char *key, const char *value, void *cb) * Do not increment matches: this is no match, but we * just made sure we are in the desired section. */ - store.offset[store.seen] = cf->ftell(cf); + store.offset[store.seen] = cf->do_ftell(cf); /* fallthru */ case SECTION_END_SEEN: case START: if (matches(key, value)) { - store.offset[store.seen] = cf->ftell(cf); + store.offset[store.seen] = cf->do_ftell(cf); store.state = KEY_SEEN; store.seen++; } else { if (strrchr(key, '.') - key == store.baselen && !strncmp(key, store.key, store.baselen)) { store.state = SECTION_SEEN; - store.offset[store.seen] = cf->ftell(cf); + store.offset[store.seen] = cf->do_ftell(cf); } } } diff --git a/connect.c b/connect.c index a0783d4867..a80ebd316c 100644 --- a/connect.c +++ b/connect.c @@ -5,6 +5,7 @@ #include "refs.h" #include "run-command.h" #include "remote.h" +#include "connect.h" #include "url.h" static char *server_capabilities; diff --git a/connect.h b/connect.h new file mode 100644 index 0000000000..9dff25cad4 --- /dev/null +++ b/connect.h @@ -0,0 +1,13 @@ +#ifndef CONNECT_H +#define CONNECT_H + +#define CONNECT_VERBOSE (1u << 0) +extern struct child_process *git_connect(int fd[2], const char *url, const char *prog, int flags); +extern int finish_connect(struct child_process *conn); +extern int git_connection_is_socket(struct child_process *conn); +extern int server_supports(const char *feature); +extern int parse_feature_request(const char *features, const char *feature); +extern const char *server_feature_value(const char *feature, int *len_ret); +extern const char *parse_feature_value(const char *feature_list, const char *feature, int *len_ret); + +#endif diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index 5da920ecd9..e1b7313072 100644 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -2580,7 +2580,7 @@ if [[ -n ${ZSH_VERSION-} ]]; then --*=*|*.) ;; *) c="$c " ;; esac - array[$#array+1]="$c" + array[${#array[@]}+1]="$c" done compset -P '*[=:]' compadd -Q -S '' -p "${2-}" -a -- array && _ret=0 diff --git a/contrib/completion/git-prompt.sh b/contrib/completion/git-prompt.sh index a81ef5a482..d6c61b2bde 100644 --- a/contrib/completion/git-prompt.sh +++ b/contrib/completion/git-prompt.sh @@ -84,6 +84,10 @@ # the colored output of "git status -sb" and are available only when # using __git_ps1 for PROMPT_COMMAND or precmd. +# check whether printf supports -v +__git_printf_supports_v= +printf -v __git_printf_supports_v -- '%s' yes >/dev/null 2>&1 + # stores the divergence from upstream in $p # used by GIT_PS1_SHOWUPSTREAM __git_ps1_show_upstream () @@ -433,7 +437,7 @@ __git_ps1 () local gitstring="$c${b##refs/heads/}${f:+$z$f}$r$p" if [ $pcmode = yes ]; then - if [[ -n ${ZSH_VERSION-} ]]; then + if [ "${__git_printf_supports_v-}" != yes ]; then gitstring=$(printf -- "$printf_format" "$gitstring") else printf -v gitstring -- "$printf_format" "$gitstring" diff --git a/contrib/contacts/git-contacts b/contrib/contacts/git-contacts index d80f7d1b6e..fb6429b64b 100755 --- a/contrib/contacts/git-contacts +++ b/contrib/contacts/git-contacts @@ -59,11 +59,11 @@ sub import_commits { } sub get_blame { - my ($commits, $source, $start, $len, $from) = @_; - $len = 1 unless defined($len); - return if $len == 0; + my ($commits, $source, $from, $ranges) = @_; + return unless @$ranges; open my $f, '-|', - qw(git blame --porcelain -C), '-L', "$start,+$len", + qw(git blame --porcelain -C), + map({"-L$_->[0],+$_->[1]"} @$ranges), '--since', $since, "$from^", '--', $source or die; while (<$f>) { if (/^([0-9a-f]{40}) \d+ \d+ \d+$/) { @@ -76,8 +76,17 @@ sub get_blame { close $f; } +sub blame_sources { + my ($sources, $commits) = @_; + for my $s (keys %$sources) { + for my $id (keys %{$sources->{$s}}) { + get_blame($commits, $s, $id, $sources->{$s}{$id}); + } + } +} + sub scan_patches { - my ($commits, $id, $f) = @_; + my ($sources, $id, $f) = @_; my $source; while (<$f>) { if (/^From ([0-9a-f]{40}) Mon Sep 17 00:00:00 2001$/) { @@ -90,7 +99,8 @@ sub scan_patches { } elsif (/^--- /) { die "Cannot parse hunk source: $_\n"; } elsif (/^@@ -(\d+)(?:,(\d+))?/ && $source) { - get_blame($commits, $source, $1, $2, $id); + my $len = defined($2) ? $2 : 1; + push @{$sources->{$source}{$id}}, [$1, $len] if $len; } } } @@ -163,13 +173,16 @@ for (@ARGV) { } } -my %commits; +my %sources; for (@files) { - scan_patch_file(\%commits, $_); + scan_patch_file(\%sources, $_); } if (@rev_args) { - scan_rev_args(\%commits, \@rev_args) + scan_rev_args(\%sources, \@rev_args) } + +my %commits; +blame_sources(\%sources, \%commits); import_commits(\%commits); my $contacts = {}; diff --git a/contrib/examples/git-log.sh b/contrib/examples/git-log.sh new file mode 100755 index 0000000000..c2ea71cf14 --- /dev/null +++ b/contrib/examples/git-log.sh @@ -0,0 +1,15 @@ +#!/bin/sh +# +# Copyright (c) 2005 Linus Torvalds +# + +USAGE='[--max-count=] [..] [--pretty=] [git-rev-list options]' +SUBDIRECTORY_OK='Yes' +. git-sh-setup + +revs=$(git-rev-parse --revs-only --no-flags --default HEAD "$@") || exit +[ "$revs" ] || { + die "No HEAD ref" +} +git-rev-list --pretty $(git-rev-parse --default HEAD "$@") | +LESS=-S ${PAGER:-less} diff --git a/contrib/examples/git-whatchanged.sh b/contrib/examples/git-whatchanged.sh new file mode 100755 index 0000000000..1fb9feb348 --- /dev/null +++ b/contrib/examples/git-whatchanged.sh @@ -0,0 +1,28 @@ +#!/bin/sh + +USAGE='[-p] [--max-count=] [..] [--pretty=] [-m] [git-diff-tree options] [git-rev-list options]' +SUBDIRECTORY_OK='Yes' +. git-sh-setup + +diff_tree_flags=$(git-rev-parse --sq --no-revs --flags "$@") || exit +case "$0" in +*whatchanged) + count= + test -z "$diff_tree_flags" && + diff_tree_flags=$(git-repo-config --get whatchanged.difftree) + diff_tree_default_flags='-c -M --abbrev' ;; +*show) + count=-n1 + test -z "$diff_tree_flags" && + diff_tree_flags=$(git-repo-config --get show.difftree) + diff_tree_default_flags='--cc --always' ;; +esac +test -z "$diff_tree_flags" && + diff_tree_flags="$diff_tree_default_flags" + +rev_list_args=$(git-rev-parse --sq --default HEAD --revs-only "$@") && +diff_tree_args=$(git-rev-parse --sq --no-revs --no-flags "$@") && + +eval "git-rev-list $count $rev_list_args" | +eval "git-diff-tree --stdin --pretty -r $diff_tree_flags $diff_tree_args" | +LESS="$LESS -S" ${PAGER:-less} diff --git a/contrib/mw-to-git/.gitignore b/contrib/mw-to-git/.gitignore index b9196555e5..ae545b013d 100644 --- a/contrib/mw-to-git/.gitignore +++ b/contrib/mw-to-git/.gitignore @@ -1 +1,2 @@ git-remote-mediawiki +git-mw diff --git a/contrib/remote-helpers/git-remote-bzr b/contrib/remote-helpers/git-remote-bzr index c3a3cac77b..1e0044b69f 100755 --- a/contrib/remote-helpers/git-remote-bzr +++ b/contrib/remote-helpers/git-remote-bzr @@ -674,7 +674,7 @@ def parse_reset(parser): parsed_refs[ref] = mark_to_rev(from_mark) def do_export(parser): - global parsed_refs, dirname + global parsed_refs, dirname, transports parser.next() @@ -699,7 +699,8 @@ def do_export(parser): branch.generate_revision_history(revid, marks.get_tip(name)) if name in peers: - peer = bzrlib.branch.Branch.open(peers[name]) + peer = bzrlib.branch.Branch.open(peers[name], + possible_transports=transports) try: peer.bzrdir.push_branch(branch, revision_id=revid) except bzrlib.errors.DivergedBranches: @@ -769,25 +770,28 @@ def do_list(parser): print def clone(path, remote_branch): + global transports try: - bdir = bzrlib.bzrdir.BzrDir.create(path) + bdir = bzrlib.bzrdir.BzrDir.create(path, possible_transports=transports) except bzrlib.errors.AlreadyControlDirError: - bdir = bzrlib.bzrdir.BzrDir.open(path) + bdir = bzrlib.bzrdir.BzrDir.open(path, possible_transports=transports) repo = bdir.find_repository() repo.fetch(remote_branch.repository) return remote_branch.sprout(bdir, repository=repo) def get_remote_branch(name): - global dirname, branches + global dirname, branches, transports - remote_branch = bzrlib.branch.Branch.open(branches[name]) + remote_branch = bzrlib.branch.Branch.open(branches[name], + possible_transports=transports) if isinstance(remote_branch.user_transport, bzrlib.transport.local.LocalTransport): return remote_branch branch_path = os.path.join(dirname, 'clone', name) try: - branch = bzrlib.branch.Branch.open(branch_path) + branch = bzrlib.branch.Branch.open(branch_path, + possible_transports=transports) except bzrlib.errors.NotBranchError: # clone branch = clone(branch_path, remote_branch) @@ -821,17 +825,19 @@ def find_branches(repo): yield name, branch.base def get_repo(url, alias): - global dirname, peer, branches + global dirname, peer, branches, transports normal_url = bzrlib.urlutils.normalize_url(url) - origin = bzrlib.bzrdir.BzrDir.open(url) + origin = bzrlib.bzrdir.BzrDir.open(url, possible_transports=transports) is_local = isinstance(origin.transport, bzrlib.transport.local.LocalTransport) shared_path = os.path.join(gitdir, 'bzr') try: - shared_dir = bzrlib.bzrdir.BzrDir.open(shared_path) + shared_dir = bzrlib.bzrdir.BzrDir.open(shared_path, + possible_transports=transports) except bzrlib.errors.NotBranchError: - shared_dir = bzrlib.bzrdir.BzrDir.create(shared_path) + shared_dir = bzrlib.bzrdir.BzrDir.create(shared_path, + possible_transports=transports) try: shared_repo = shared_dir.open_repository() except bzrlib.errors.NoRepositoryPresent: @@ -844,7 +850,8 @@ def get_repo(url, alias): else: # check and remove old organization try: - bdir = bzrlib.bzrdir.BzrDir.open(clone_path) + bdir = bzrlib.bzrdir.BzrDir.open(clone_path, + possible_transports=transports) bdir.destroy_repository() except bzrlib.errors.NotBranchError: pass @@ -897,6 +904,7 @@ def main(args): global files_cache global is_tmp global branches, peers + global transports alias = args[1] url = args[2] @@ -909,6 +917,7 @@ def main(args): marks = None branches = {} peers = {} + transports = [] if alias[5:] == url: is_tmp = True diff --git a/contrib/remote-helpers/git-remote-hg b/contrib/remote-helpers/git-remote-hg index 0194c67fb1..c27603965a 100755 --- a/contrib/remote-helpers/git-remote-hg +++ b/contrib/remote-helpers/git-remote-hg @@ -391,11 +391,24 @@ def get_repo(url, alias): os.makedirs(dirname) else: shared_path = os.path.join(gitdir, 'hg') - if not os.path.exists(shared_path): - try: - hg.clone(myui, {}, url, shared_path, update=False, pull=True) - except: - die('Repository error') + + # check and upgrade old organization + hg_path = os.path.join(shared_path, '.hg') + if os.path.exists(shared_path) and not os.path.exists(hg_path): + repos = os.listdir(shared_path) + for x in repos: + local_hg = os.path.join(shared_path, x, 'clone', '.hg') + if not os.path.exists(local_hg): + continue + if not os.path.exists(hg_path): + shutil.move(local_hg, hg_path) + shutil.rmtree(os.path.join(shared_path, x, 'clone')) + + # setup shared repo (if not there) + try: + hg.peer(myui, {}, shared_path, create=True) + except error.RepoError: + pass if not os.path.exists(dirname): os.makedirs(dirname) @@ -1124,7 +1137,7 @@ def do_option(parser): def fix_path(alias, repo, orig_url): url = urlparse.urlparse(orig_url, 'file') - if url.scheme != 'file' or os.path.isabs(url.path): + if url.scheme != 'file' or os.path.isabs(os.path.expanduser(url.path)): return abs_url = urlparse.urljoin("%s/" % os.getcwd(), orig_url) cmd = ['git', 'config', 'remote.%s.url' % alias, "hg::%s" % abs_url] diff --git a/diff-delta.c b/diff-delta.c index 93385e12ba..3797ce6041 100644 --- a/diff-delta.c +++ b/diff-delta.c @@ -155,7 +155,7 @@ struct delta_index * create_delta_index(const void *buf, unsigned long bufsize) entries = 0xfffffffeU / RABIN_WINDOW; } hsize = entries / 4; - for (i = 4; (1u << i) < hsize && i < 31; i++); + for (i = 4; (1u << i) < hsize; i++); hsize = 1 << i; hmask = hsize - 1; diff --git a/diff-lib.c b/diff-lib.c index b6f4b21637..346cac651d 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -87,10 +87,12 @@ int run_diff_files(struct rev_info *revs, unsigned int option) { int entries, i; int diff_unmerged_stage = revs->max_count; - int silent_on_removed = option & DIFF_SILENT_ON_REMOVED; unsigned ce_option = ((option & DIFF_RACY_IS_MODIFIED) ? CE_MATCH_RACY_IS_DIRTY : 0); + if (option & DIFF_SILENT_ON_REMOVED) + handle_deprecated_show_diff_q(&revs->diffopt); + diff_set_mnemonic_prefix(&revs->diffopt, "i/", "w/"); if (diff_unmerged_stage < 0) @@ -137,8 +139,6 @@ int run_diff_files(struct rev_info *revs, unsigned int option) perror(ce->name); continue; } - if (silent_on_removed) - continue; wt_mode = 0; } dpath->mode = wt_mode; @@ -204,8 +204,6 @@ int run_diff_files(struct rev_info *revs, unsigned int option) perror(ce->name); continue; } - if (silent_on_removed) - continue; diff_addremove(&revs->diffopt, '-', ce->ce_mode, ce->sha1, !is_null_sha1(ce->sha1), ce->name, 0); @@ -476,7 +474,6 @@ static int diff_cache(struct rev_info *revs, opts.dst_index = NULL; opts.pathspec = &revs->diffopt.pathspec; opts.pathspec->recursive = 1; - opts.pathspec->max_depth = -1; init_tree_desc(&t, tree->buffer, tree->size); return unpack_trees(1, &t, &opts); @@ -502,7 +499,7 @@ int do_diff_cache(const unsigned char *tree_sha1, struct diff_options *opt) struct rev_info revs; init_revisions(&revs, NULL); - init_pathspec(&revs.prune_data, opt->pathspec.raw); + copy_pathspec(&revs.prune_data, &opt->pathspec); revs.diffopt = *opt; if (diff_cache(&revs, tree_sha1, NULL, 1)) diff --git a/diff-no-index.c b/diff-no-index.c index e66fdf33da..e301aafff9 100644 --- a/diff-no-index.c +++ b/diff-no-index.c @@ -187,7 +187,7 @@ void diff_no_index(struct rev_info *revs, { int i, prefixlen; int no_index = 0; - unsigned options = 0; + unsigned deprecated_show_diff_q_option_used = 0; const char *paths[2]; /* Were we asked to do --no-index explicitly? */ @@ -225,7 +225,7 @@ void diff_no_index(struct rev_info *revs, if (!strcmp(argv[i], "--no-index")) i++; else if (!strcmp(argv[i], "-q")) { - options |= DIFF_SILENT_ON_REMOVED; + deprecated_show_diff_q_option_used = 1; i++; } else if (!strcmp(argv[i], "--")) @@ -260,6 +260,9 @@ void diff_no_index(struct rev_info *revs, revs->max_count = -2; diff_setup_done(&revs->diffopt); + if (deprecated_show_diff_q_option_used) + handle_deprecated_show_diff_q(&revs->diffopt); + setup_diff_pager(&revs->diffopt); DIFF_OPT_SET(&revs->diffopt, EXIT_WITH_STATUS); diff --git a/diff.c b/diff.c index 266112ca61..a04a34d048 100644 --- a/diff.c +++ b/diff.c @@ -669,7 +669,7 @@ static void emit_rewrite_diff(const char *name_a, memset(&ecbdata, 0, sizeof(ecbdata)); ecbdata.color_diff = want_color(o->use_color); ecbdata.found_changesp = &o->found_changes; - ecbdata.ws_rule = whitespace_rule(name_b ? name_b : name_a); + ecbdata.ws_rule = whitespace_rule(name_b); ecbdata.opt = o; if (ecbdata.ws_rule & WS_BLANK_AT_EOF) { mmfile_t mf1, mf2; @@ -2252,7 +2252,7 @@ static void builtin_diff(const char *name_a, (!two->mode || S_ISGITLINK(two->mode))) { const char *del = diff_get_color_opt(o, DIFF_FILE_OLD); const char *add = diff_get_color_opt(o, DIFF_FILE_NEW); - show_submodule_summary(o->file, one ? one->path : two->path, + show_submodule_summary(o->file, one->path ? one->path : two->path, line_prefix, one->sha1, two->sha1, two->dirty_submodule, meta, del, add, reset); @@ -2372,7 +2372,7 @@ static void builtin_diff(const char *name_a, ecbdata.label_path = lbl; ecbdata.color_diff = want_color(o->use_color); ecbdata.found_changesp = &o->found_changes; - ecbdata.ws_rule = whitespace_rule(name_b ? name_b : name_a); + ecbdata.ws_rule = whitespace_rule(name_b); if (ecbdata.ws_rule & WS_BLANK_AT_EOF) check_blank_at_eof(&mf1, &mf2, &ecbdata); ecbdata.opt = o; @@ -3503,6 +3503,88 @@ static int parse_submodule_opt(struct diff_options *options, const char *value) return 1; } +static const char diff_status_letters[] = { + DIFF_STATUS_ADDED, + DIFF_STATUS_COPIED, + DIFF_STATUS_DELETED, + DIFF_STATUS_MODIFIED, + DIFF_STATUS_RENAMED, + DIFF_STATUS_TYPE_CHANGED, + DIFF_STATUS_UNKNOWN, + DIFF_STATUS_UNMERGED, + DIFF_STATUS_FILTER_AON, + DIFF_STATUS_FILTER_BROKEN, + '\0', +}; + +static unsigned int filter_bit['Z' + 1]; + +static void prepare_filter_bits(void) +{ + int i; + + if (!filter_bit[DIFF_STATUS_ADDED]) { + for (i = 0; diff_status_letters[i]; i++) + filter_bit[(int) diff_status_letters[i]] = (1 << i); + } +} + +static unsigned filter_bit_tst(char status, const struct diff_options *opt) +{ + return opt->filter & filter_bit[(int) status]; +} + +static int parse_diff_filter_opt(const char *optarg, struct diff_options *opt) +{ + int i, optch; + + prepare_filter_bits(); + + /* + * If there is a negation e.g. 'd' in the input, and we haven't + * initialized the filter field with another --diff-filter, start + * from full set of bits, except for AON. + */ + if (!opt->filter) { + for (i = 0; (optch = optarg[i]) != '\0'; i++) { + if (optch < 'a' || 'z' < optch) + continue; + opt->filter = (1 << (ARRAY_SIZE(diff_status_letters) - 1)) - 1; + opt->filter &= ~filter_bit[DIFF_STATUS_FILTER_AON]; + break; + } + } + + for (i = 0; (optch = optarg[i]) != '\0'; i++) { + unsigned int bit; + int negate; + + if ('a' <= optch && optch <= 'z') { + negate = 1; + optch = toupper(optch); + } else { + negate = 0; + } + + bit = (0 <= optch && optch <= 'Z') ? filter_bit[optch] : 0; + if (!bit) + return optarg[i]; + if (negate) + opt->filter &= ~bit; + else + opt->filter |= bit; + } + return 0; +} + +/* Used only by "diff-files" and "diff --no-index" */ +void handle_deprecated_show_diff_q(struct diff_options *opt) +{ + warning("'diff -q' and 'diff-files -q' are deprecated."); + warning("Use 'diff --diff-filter=d' instead to ignore deleted filepairs."); + parse_diff_filter_opt("d", opt); +} + static void enable_patch_output(int *fmt) { *fmt &= ~DIFF_FORMAT_NO_OUTPUT; *fmt |= DIFF_FORMAT_PATCH; @@ -3732,7 +3814,10 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac) return argcount; } else if ((argcount = parse_long_opt("diff-filter", av, &optarg))) { - options->filter = optarg; + int offending = parse_diff_filter_opt(optarg, options); + if (offending) + die("unknown change class '%c' in --diff-filter=%s", + offending, optarg); return argcount; } else if (!strcmp(arg, "--abbrev")) @@ -4524,27 +4609,32 @@ void diff_flush(struct diff_options *options) } } -static void diffcore_apply_filter(const char *filter) +static int match_filter(const struct diff_options *options, const struct diff_filepair *p) +{ + return (((p->status == DIFF_STATUS_MODIFIED) && + ((p->score && + filter_bit_tst(DIFF_STATUS_FILTER_BROKEN, options)) || + (!p->score && + filter_bit_tst(DIFF_STATUS_MODIFIED, options)))) || + ((p->status != DIFF_STATUS_MODIFIED) && + filter_bit_tst(p->status, options))); +} + +static void diffcore_apply_filter(struct diff_options *options) { int i; struct diff_queue_struct *q = &diff_queued_diff; struct diff_queue_struct outq; + DIFF_QUEUE_CLEAR(&outq); - if (!filter) + if (!options->filter) return; - if (strchr(filter, DIFF_STATUS_FILTER_AON)) { + if (filter_bit_tst(DIFF_STATUS_FILTER_AON, options)) { int found; for (i = found = 0; !found && i < q->nr; i++) { - struct diff_filepair *p = q->queue[i]; - if (((p->status == DIFF_STATUS_MODIFIED) && - ((p->score && - strchr(filter, DIFF_STATUS_FILTER_BROKEN)) || - (!p->score && - strchr(filter, DIFF_STATUS_MODIFIED)))) || - ((p->status != DIFF_STATUS_MODIFIED) && - strchr(filter, p->status))) + if (match_filter(options, q->queue[i])) found++; } if (found) @@ -4562,14 +4652,7 @@ static void diffcore_apply_filter(const char *filter) /* Only the matching ones */ for (i = 0; i < q->nr; i++) { struct diff_filepair *p = q->queue[i]; - - if (((p->status == DIFF_STATUS_MODIFIED) && - ((p->score && - strchr(filter, DIFF_STATUS_FILTER_BROKEN)) || - (!p->score && - strchr(filter, DIFF_STATUS_MODIFIED)))) || - ((p->status != DIFF_STATUS_MODIFIED) && - strchr(filter, p->status))) + if (match_filter(options, p)) diff_q(&outq, p); else diff_free_filepair(p); @@ -4676,7 +4759,7 @@ void diffcore_std(struct diff_options *options) if (!options->found_follow) /* See try_to_follow_renames() in tree-diff.c */ diff_resolve_rename_copy(); - diffcore_apply_filter(options->filter); + diffcore_apply_filter(options); if (diff_queued_diff.nr && !DIFF_OPT_TST(options, DIFF_FROM_CONTENTS)) DIFF_OPT_SET(options, HAS_CHANGES); diff --git a/diff.h b/diff.h index 78b4091dd5..44092c2176 100644 --- a/diff.h +++ b/diff.h @@ -5,6 +5,7 @@ #define DIFF_H #include "tree-walk.h" +#include "pathspec.h" struct rev_info; struct diff_options; @@ -103,12 +104,15 @@ enum diff_words_type { }; struct diff_options { - const char *filter; const char *orderfile; const char *pickaxe; const char *single_follow; const char *a_prefix, *b_prefix; unsigned flags; + + /* diff-filter bits */ + unsigned int filter; + int use_color; int context; int interhunkcontext; @@ -179,8 +183,6 @@ const char *diff_line_prefix(struct diff_options *); extern const char mime_boundary_leader[]; -extern void diff_tree_setup_paths(const char **paths, struct diff_options *); -extern void diff_tree_release_paths(struct diff_options *); extern int diff_tree(struct tree_desc *t1, struct tree_desc *t2, const char *base, struct diff_options *opt); extern int diff_tree_sha1(const unsigned char *old, const unsigned char *new, @@ -338,6 +340,8 @@ extern int parse_rename_score(const char **cp_p); extern long parse_algorithm_value(const char *value); +extern void handle_deprecated_show_diff_q(struct diff_options *); + extern int print_stat_summary(FILE *fp, int files, int insertions, int deletions); extern void setup_diff_pager(struct diff_options *); diff --git a/dir.c b/dir.c index 910bfcde4e..1128110a44 100644 --- a/dir.c +++ b/dir.c @@ -11,6 +11,7 @@ #include "dir.h" #include "refs.h" #include "wildmatch.h" +#include "pathspec.h" struct path_simplify { int len; @@ -51,26 +52,32 @@ 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) +inline int git_fnmatch(const struct pathspec_item *item, + const char *pattern, const char *string, + int prefix) { - int fnm_flags = 0; - if (flags & GFNM_PATHNAME) - fnm_flags |= FNM_PATHNAME; if (prefix > 0) { - if (strncmp(pattern, string, prefix)) + if (ps_strncmp(item, pattern, string, prefix)) return FNM_NOMATCH; pattern += prefix; string += prefix; } - if (flags & GFNM_ONESTAR) { + if (item->flags & PATHSPEC_ONESTAR) { int pattern_len = strlen(++pattern); int string_len = strlen(string); return string_len < pattern_len || - strcmp(pattern, - string + string_len - pattern_len); + ps_strcmp(item, pattern, + string + string_len - pattern_len); } - return fnmatch(pattern, string, fnm_flags); + if (item->magic & PATHSPEC_GLOB) + return wildmatch(pattern, string, + WM_PATHNAME | + (item->magic & PATHSPEC_ICASE ? WM_CASEFOLD : 0), + NULL); + else + /* wildmatch has not learned no FNM_PATHNAME mode yet */ + return fnmatch(pattern, string, + item->magic & PATHSPEC_ICASE ? FNM_CASEFOLD : 0); } static int fnmatch_icase_mem(const char *pattern, int patternlen, @@ -102,26 +109,40 @@ static int fnmatch_icase_mem(const char *pattern, int patternlen, return match_status; } -static size_t common_prefix_len(const char **pathspec) +static size_t common_prefix_len(const struct pathspec *pathspec) { - const char *n, *first; + int n; size_t max = 0; - int literal = limit_pathspec_to_literal(); - if (!pathspec) - return max; - - first = *pathspec; - while ((n = *pathspec++)) { - size_t i, len = 0; - for (i = 0; first == n || i < max; i++) { - char c = n[i]; - if (!c || c != first[i] || (!literal && is_glob_special(c))) + /* + * ":(icase)path" is treated as a pathspec full of + * wildcard. In other words, only prefix is considered common + * prefix. If the pathspec is abc/foo abc/bar, running in + * subdir xyz, the common prefix is still xyz, not xuz/abc as + * in non-:(icase). + */ + GUARD_PATHSPEC(pathspec, + PATHSPEC_FROMTOP | + PATHSPEC_MAXDEPTH | + PATHSPEC_LITERAL | + PATHSPEC_GLOB | + PATHSPEC_ICASE); + + for (n = 0; n < pathspec->nr; n++) { + size_t i = 0, len = 0, item_len; + if (pathspec->items[n].magic & PATHSPEC_ICASE) + item_len = pathspec->items[n].prefix; + else + item_len = pathspec->items[n].nowildcard_len; + while (i < item_len && (n == 0 || i < max)) { + char c = pathspec->items[n].match[i]; + if (c != pathspec->items[0].match[i]) break; if (c == '/') len = i + 1; + i++; } - if (first == n || len < max) { + if (n == 0 || len < max) { max = len; if (!max) break; @@ -134,14 +155,14 @@ static size_t common_prefix_len(const char **pathspec) * Returns a copy of the longest leading path common among all * pathspecs. */ -char *common_prefix(const char **pathspec) +char *common_prefix(const struct pathspec *pathspec) { unsigned long len = common_prefix_len(pathspec); - return len ? xmemdupz(*pathspec, len) : NULL; + return len ? xmemdupz(pathspec->items[0].match, len) : NULL; } -int fill_directory(struct dir_struct *dir, const char **pathspec) +int fill_directory(struct dir_struct *dir, const struct pathspec *pathspec) { size_t len; @@ -152,7 +173,7 @@ int fill_directory(struct dir_struct *dir, const char **pathspec) len = common_prefix_len(pathspec); /* Read the directory and prune it */ - read_directory(dir, pathspec ? *pathspec : "", len, pathspec); + read_directory(dir, pathspec->nr ? pathspec->_raw[0] : "", len, pathspec); return len; } @@ -171,113 +192,6 @@ int within_depth(const char *name, int namelen, return 1; } -/* - * Does 'match' match the given name? - * A match is found if - * - * (1) the 'match' string is leading directory of 'name', or - * (2) the 'match' string is a wildcard and matches 'name', or - * (3) the 'match' string is exactly the same as 'name'. - * - * and the return value tells which case it was. - * - * It returns 0 when there is no match. - */ -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) - return MATCHED_RECURSIVELY; - - if (ignore_case) { - for (;;) { - unsigned char c1 = tolower(*match); - unsigned char c2 = tolower(*name); - if (c1 == '\0' || (!literal && is_glob_special(c1))) - break; - if (c1 != c2) - return 0; - match++; - name++; - namelen--; - } - } else { - for (;;) { - unsigned char c1 = *match; - unsigned char c2 = *name; - if (c1 == '\0' || (!literal && is_glob_special(c1))) - break; - if (c1 != c2) - return 0; - match++; - name++; - 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 (literal) - return 0; - return !fnmatch_icase(match, name, 0) ? MATCHED_FNMATCH : 0; - } - - if (namelen == matchlen) - return MATCHED_EXACTLY; - if (match[matchlen-1] == '/' || name[matchlen] == '/') - return MATCHED_RECURSIVELY; - return 0; -} - -/* - * Given a name and a list of pathspecs, returns the nature of the - * closest (i.e. most specific) match of the name to any of the - * pathspecs. - * - * The caller typically calls this multiple times with the same - * pathspec and seen[] array but with different name/namelen - * (e.g. entries from the index) and is interested in seeing if and - * how each pathspec matches all the names it calls this function - * with. A mark is left in the seen[] array for each pathspec element - * indicating the closest type of match that element achieved, so if - * seen[n] remains zero after multiple invocations, that means the nth - * pathspec did not match any names, which could indicate that the - * user mistyped the nth pathspec. - */ -int match_pathspec(const char **pathspec, const char *name, int namelen, - int prefix, char *seen) -{ - int i, retval = 0; - - if (!pathspec) - return 1; - - name += prefix; - namelen -= prefix; - - for (i = 0; pathspec[i] != NULL; i++) { - int how; - const char *match = pathspec[i] + prefix; - if (seen && seen[i] == MATCHED_EXACTLY) - continue; - how = match_one(match, name, namelen); - if (how) { - if (retval < how) - retval = how; - if (seen && seen[i] < how) - seen[i] = how; - } - } - return retval; -} - /* * Does 'match' match the given name? * A match is found if @@ -297,11 +211,44 @@ static int match_pathspec_item(const struct pathspec_item *item, int prefix, const char *match = item->match + prefix; int matchlen = item->len - prefix; + /* + * The normal call pattern is: + * 1. prefix = common_prefix_len(ps); + * 2. prune something, or fill_directory + * 3. match_pathspec_depth() + * + * 'prefix' at #1 may be shorter than the command's prefix and + * it's ok for #2 to match extra files. Those extras will be + * trimmed at #3. + * + * Suppose the pathspec is 'foo' and '../bar' running from + * subdir 'xyz'. The common prefix at #1 will be empty, thanks + * to "../". We may have xyz/foo _and_ XYZ/foo after #2. The + * user does not want XYZ/foo, only the "foo" part should be + * case-insensitive. We need to filter out XYZ/foo here. In + * other words, we do not trust the caller on comparing the + * prefix part when :(icase) is involved. We do exact + * comparison ourselves. + * + * Normally the caller (common_prefix_len() in fact) does + * _exact_ matching on name[-prefix+1..-1] and we do not need + * to check that part. Be defensive and check it anyway, in + * case common_prefix_len is changed, or a new caller is + * introduced that does not use common_prefix_len. + * + * If the penalty turns out too high when prefix is really + * long, maybe change it to + * strncmp(match, name, item->prefix - prefix) + */ + if (item->prefix && (item->magic & PATHSPEC_ICASE) && + strncmp(item->match, name - prefix, item->prefix)) + return 0; + /* If the match was just the prefix, we matched */ if (!*match) return MATCHED_RECURSIVELY; - if (matchlen <= namelen && !strncmp(match, name, matchlen)) { + if (matchlen <= namelen && !ps_strncmp(item, match, name, matchlen)) { if (matchlen == namelen) return MATCHED_EXACTLY; @@ -310,8 +257,7 @@ static int match_pathspec_item(const struct pathspec_item *item, int prefix, } if (item->nowildcard_len < item->len && - !git_fnmatch(match, name, - item->flags & PATHSPEC_ONESTAR ? GFNM_ONESTAR : 0, + !git_fnmatch(item, match, name, item->nowildcard_len - prefix)) return MATCHED_FNMATCH; @@ -339,8 +285,17 @@ int match_pathspec_depth(const struct pathspec *ps, { int i, retval = 0; + GUARD_PATHSPEC(ps, + PATHSPEC_FROMTOP | + PATHSPEC_MAXDEPTH | + PATHSPEC_LITERAL | + PATHSPEC_GLOB | + PATHSPEC_ICASE); + if (!ps->nr) { - if (!ps->recursive || ps->max_depth == -1) + if (!ps->recursive || + !(ps->magic & PATHSPEC_MAXDEPTH) || + ps->max_depth == -1) return MATCHED_RECURSIVELY; if (within_depth(name, namelen, 0, ps->max_depth)) @@ -357,7 +312,9 @@ int match_pathspec_depth(const struct pathspec *ps, if (seen && seen[i] == MATCHED_EXACTLY) continue; how = match_pathspec_item(ps->items+i, prefix, name, namelen); - if (ps->recursive && ps->max_depth != -1 && + if (ps->recursive && + (ps->magic & PATHSPEC_MAXDEPTH) && + ps->max_depth != -1 && how && how != MATCHED_FNMATCH) { int len = ps->items[i].len; if (name[len] == '/') @@ -380,7 +337,7 @@ int match_pathspec_depth(const struct pathspec *ps, /* * Return the length of the "simple" part of a path match limiter. */ -static int simple_length(const char *match) +int simple_length(const char *match) { int len = -1; @@ -392,7 +349,7 @@ static int simple_length(const char *match) } } -static int no_wildcard(const char *string) +int no_wildcard(const char *string) { return string[simple_length(string)] == '\0'; } @@ -1381,14 +1338,25 @@ static int treat_leading_path(struct dir_struct *dir, return rc; } -int read_directory(struct dir_struct *dir, const char *path, int len, const char **pathspec) +int read_directory(struct dir_struct *dir, const char *path, int len, const struct pathspec *pathspec) { struct path_simplify *simplify; + /* + * Check out create_simplify() + */ + if (pathspec) + GUARD_PATHSPEC(pathspec, + PATHSPEC_FROMTOP | + PATHSPEC_MAXDEPTH | + PATHSPEC_LITERAL | + PATHSPEC_GLOB | + PATHSPEC_ICASE); + if (has_symlink_leading_path(path, len)) return dir->nr; - simplify = create_simplify(pathspec); + simplify = create_simplify(pathspec ? pathspec->_raw : NULL); if (!len || treat_leading_path(dir, path, len, simplify)) read_directory_recursive(dir, path, len, 0, simplify); free_simplify(simplify); @@ -1568,71 +1536,6 @@ int remove_path(const char *name) return 0; } -static int pathspec_item_cmp(const void *a_, const void *b_) -{ - struct pathspec_item *a, *b; - - a = (struct pathspec_item *)a_; - b = (struct pathspec_item *)b_; - return strcmp(a->match, b->match); -} - -int init_pathspec(struct pathspec *pathspec, const char **paths) -{ - const char **p = paths; - int i; - - memset(pathspec, 0, sizeof(*pathspec)); - if (!p) - return 0; - while (*p) - p++; - pathspec->raw = paths; - pathspec->nr = p - paths; - if (!pathspec->nr) - return 0; - - pathspec->items = xmalloc(sizeof(struct pathspec_item)*pathspec->nr); - for (i = 0; i < pathspec->nr; i++) { - struct pathspec_item *item = pathspec->items+i; - const char *path = paths[i]; - - item->match = path; - item->len = strlen(path); - 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, - sizeof(struct pathspec_item), pathspec_item_cmp); - - return 0; -} - -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; -} - /* * Frees memory within dir which was allocated for exclude lists and * the exclude_stack. Does not free dir itself. diff --git a/dir.h b/dir.h index 3d6b80c933..343ec7aa31 100644 --- a/dir.h +++ b/dir.h @@ -128,15 +128,16 @@ struct dir_struct { #define MATCHED_RECURSIVELY 1 #define MATCHED_FNMATCH 2 #define MATCHED_EXACTLY 3 -extern char *common_prefix(const char **pathspec); -extern int match_pathspec(const char **pathspec, const char *name, int namelen, int prefix, char *seen); +extern int simple_length(const char *match); +extern int no_wildcard(const char *string); +extern char *common_prefix(const struct pathspec *pathspec); extern int match_pathspec_depth(const struct pathspec *pathspec, const char *name, int namelen, int prefix, char *seen); extern int within_depth(const char *name, int namelen, int depth, int max_depth); -extern int fill_directory(struct dir_struct *dir, const char **pathspec); -extern int read_directory(struct dir_struct *, const char *path, int len, const char **pathspec); +extern int fill_directory(struct dir_struct *dir, const struct pathspec *pathspec); +extern int read_directory(struct dir_struct *, const char *path, int len, const struct pathspec *pathspec); extern int is_excluded_from_list(const char *pathname, int pathlen, const char *basename, int *dtype, struct exclude_list *el); @@ -198,10 +199,9 @@ 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); +struct pathspec_item; +extern int git_fnmatch(const struct pathspec_item *item, + const char *pattern, const char *string, + int prefix); #endif diff --git a/editor.c b/editor.c index 27bdecdaf3..0abbd8dc3a 100644 --- a/editor.c +++ b/editor.c @@ -37,7 +37,7 @@ int launch_editor(const char *path, struct strbuf *buffer, const char *const *en return error("Terminal is dumb, but EDITOR unset"); if (strcmp(editor, ":")) { - const char *args[] = { editor, path, NULL }; + const char *args[] = { editor, real_path(path), NULL }; struct child_process p; int ret, sig; diff --git a/fast-import.c b/fast-import.c index 23f625f561..21db3fc46d 100644 --- a/fast-import.c +++ b/fast-import.c @@ -1568,7 +1568,8 @@ static int tree_content_set( static int tree_content_remove( struct tree_entry *root, const char *p, - struct tree_entry *backup_leaf) + struct tree_entry *backup_leaf, + int allow_root) { struct tree_content *t; const char *slash1; @@ -1583,6 +1584,12 @@ static int tree_content_remove( if (!root->tree) load_tree(root); + + if (!*p && allow_root) { + e = root; + goto del_entry; + } + t = root->tree; for (i = 0; i < t->entry_count; i++) { e = t->entries[i]; @@ -1599,7 +1606,7 @@ static int tree_content_remove( goto del_entry; if (!e->tree) load_tree(e); - if (tree_content_remove(e, slash1 + 1, backup_leaf)) { + if (tree_content_remove(e, slash1 + 1, backup_leaf, 0)) { for (n = 0; n < e->tree->entry_count; n++) { if (e->tree->entries[n]->versions[1].mode) { hashclr(root->versions[1].sha1); @@ -1629,7 +1636,8 @@ static int tree_content_remove( static int tree_content_get( struct tree_entry *root, const char *p, - struct tree_entry *leaf) + struct tree_entry *leaf, + int allow_root) { struct tree_content *t; const char *slash1; @@ -1641,31 +1649,39 @@ static int tree_content_get( n = slash1 - p; else n = strlen(p); - if (!n) + if (!n && !allow_root) die("Empty path component found in input"); if (!root->tree) load_tree(root); + + if (!n) { + e = root; + goto found_entry; + } + t = root->tree; for (i = 0; i < t->entry_count; i++) { e = t->entries[i]; if (e->name->str_len == n && !strncmp_icase(p, e->name->str_dat, n)) { - if (!slash1) { - memcpy(leaf, e, sizeof(*leaf)); - if (e->tree && is_null_sha1(e->versions[1].sha1)) - leaf->tree = dup_tree_content(e->tree); - else - leaf->tree = NULL; - return 1; - } + if (!slash1) + goto found_entry; if (!S_ISDIR(e->versions[1].mode)) return 0; if (!e->tree) load_tree(e); - return tree_content_get(e, slash1 + 1, leaf); + return tree_content_get(e, slash1 + 1, leaf, 0); } } return 0; + +found_entry: + memcpy(leaf, e, sizeof(*leaf)); + if (e->tree && is_null_sha1(e->versions[1].sha1)) + leaf->tree = dup_tree_content(e->tree); + else + leaf->tree = NULL; + return 1; } static int update_branch(struct branch *b) @@ -2179,7 +2195,7 @@ static uintmax_t do_change_note_fanout( } /* Rename fullpath to realpath */ - if (!tree_content_remove(orig_root, fullpath, &leaf)) + if (!tree_content_remove(orig_root, fullpath, &leaf, 0)) die("Failed to remove path %s", fullpath); tree_content_set(orig_root, realpath, leaf.versions[1].sha1, @@ -2314,7 +2330,7 @@ static void file_change_m(struct branch *b) /* Git does not track empty, non-toplevel directories. */ if (S_ISDIR(mode) && !memcmp(sha1, EMPTY_TREE_SHA1_BIN, 20) && *p) { - tree_content_remove(&b->branch_tree, p, NULL); + tree_content_remove(&b->branch_tree, p, NULL, 0); return; } @@ -2375,7 +2391,7 @@ static void file_change_d(struct branch *b) die("Garbage after path in: %s", command_buf.buf); p = uq.buf; } - tree_content_remove(&b->branch_tree, p, NULL); + tree_content_remove(&b->branch_tree, p, NULL, 1); } static void file_change_cr(struct branch *b, int rename) @@ -2413,9 +2429,9 @@ static void file_change_cr(struct branch *b, int rename) memset(&leaf, 0, sizeof(leaf)); if (rename) - tree_content_remove(&b->branch_tree, s, &leaf); + tree_content_remove(&b->branch_tree, s, &leaf, 1); else - tree_content_get(&b->branch_tree, s, &leaf); + tree_content_get(&b->branch_tree, s, &leaf, 1); if (!leaf.versions[1].mode) die("Path %s not in branch", s); if (!*d) { /* C "path/to/subdir" "" */ @@ -2521,7 +2537,7 @@ static void note_change_n(struct branch *b, unsigned char *old_fanout) } construct_path_with_fanout(sha1_to_hex(commit_sha1), *old_fanout, path); - if (tree_content_remove(&b->branch_tree, path, NULL)) + if (tree_content_remove(&b->branch_tree, path, NULL, 0)) b->num_notes--; if (is_null_sha1(sha1)) @@ -3051,6 +3067,8 @@ static void parse_ls(struct branch *b) struct object_entry *e = parse_treeish_dataref(&p); root = new_tree_entry(); hashcpy(root->versions[1].sha1, e->idx.sha1); + if (!is_null_sha1(root->versions[1].sha1)) + root->versions[1].mode = S_IFDIR; load_tree(root); if (*p++ != ' ') die("Missing space after tree-ish: %s", command_buf.buf); @@ -3065,7 +3083,7 @@ static void parse_ls(struct branch *b) die("Garbage after path in: %s", command_buf.buf); p = uq.buf; } - tree_content_get(root, p, &leaf); + tree_content_get(root, p, &leaf, 1); /* * A directory in preparation would have a sha1 of zero * until it is saved. Save, for simplicity. diff --git a/fetch-pack.c b/fetch-pack.c index 6684348c0e..094267fd80 100644 --- a/fetch-pack.c +++ b/fetch-pack.c @@ -9,6 +9,7 @@ #include "fetch-pack.h" #include "remote.h" #include "run-command.h" +#include "connect.h" #include "transport.h" #include "version.h" #include "prio-queue.h" @@ -897,6 +898,8 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args, packet_flush(fd[1]); if (args->depth > 0) setup_alternate_shallow(); + else + alternate_shallow_file = NULL; if (get_pack(args, fd, pack_lockfile)) die("git fetch-pack: fetch failed."); @@ -987,7 +990,7 @@ struct ref *fetch_pack(struct fetch_pack_args *args, } ref_cpy = do_fetch_pack(args, fd, ref, sought, nr_sought, pack_lockfile); - if (alternate_shallow_file) { + if (args->depth > 0 && alternate_shallow_file) { if (*alternate_shallow_file == '\0') { /* --unshallow */ unlink_or_warn(git_path("shallow")); rollback_lock_file(&shallow_lock); diff --git a/fetch-pack.h b/fetch-pack.h index 40f08bab24..461cbf39b2 100644 --- a/fetch-pack.h +++ b/fetch-pack.h @@ -2,6 +2,7 @@ #define FETCH_PACK_H #include "string-list.h" +#include "run-command.h" struct fetch_pack_args { const char *uploadpack; diff --git a/git-compat-util.h b/git-compat-util.h index 115cb1da42..8752317fe9 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -330,6 +330,16 @@ 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))); +#ifndef NO_OPENSSL +#ifdef APPLE_COMMON_CRYPTO +#include "compat/apple-common-crypto.h" +#else +#include +#include +#endif /* APPLE_COMMON_CRYPTO */ +#include +#endif /* NO_OPENSSL */ + /* * Let callers be aware of the constant return value; this can help * gcc with -Wuninitialized analysis. We restrict this trick to gcc, though, @@ -514,7 +524,7 @@ int inet_pton(int af, const char *src, void *dst); const char *inet_ntop(int af, const void *src, char *dst, size_t size); #endif -extern void release_pack_memory(size_t, int); +extern void release_pack_memory(size_t); typedef void (*try_to_free_t)(size_t); extern try_to_free_t set_try_to_free_routine(try_to_free_t); diff --git a/git-p4.py b/git-p4.py index 31e71ff8b2..a53a6dc406 100755 --- a/git-p4.py +++ b/git-p4.py @@ -2180,9 +2180,13 @@ def streamOneP4File(self, file, contents): git_mode = "100755" if type_base == "symlink": git_mode = "120000" - # p4 print on a symlink contains "target\n"; remove the newline + # p4 print on a symlink sometimes contains "target\n"; + # if it does, remove the newline data = ''.join(contents) - contents = [data[:-1]] + if data[-1] == '\n': + contents = [data[:-1]] + else: + contents = [data] if type_base == "utf16": # p4 delivers different text in the python output to -G diff --git a/git-sh-setup.sh b/git-sh-setup.sh index 7a964ad2ff..e15be51636 100644 --- a/git-sh-setup.sh +++ b/git-sh-setup.sh @@ -53,7 +53,7 @@ die () { die_with_status () { status=$1 shift - echo >&2 "$*" + printf >&2 '%s\n' "$*" exit "$status" } diff --git a/git-stash.sh b/git-stash.sh index 85c9e2c081..1e541a2125 100755 --- a/git-stash.sh +++ b/git-stash.sh @@ -195,7 +195,6 @@ save_stash () { keep_index= patch_mode= untracked= - force= while test $# != 0 do case "$1" in @@ -216,9 +215,6 @@ save_stash () { -u|--include-untracked) untracked=untracked ;; - -f|--force) - force=t - ;; -a|--all) untracked=all ;; @@ -262,14 +258,6 @@ save_stash () { say "$(gettext "No local changes to save")" exit 0 fi - if test -z "$untracked$force" && - test -n "$(git ls-files --killed | head -n 1)" - then - say "$(gettext "The following untracked files would NOT be saved but need to be removed by stash save:")" - test -n "$GIT_QUIET" || git ls-files --killed | sed 's/^/\t/' - say "$(gettext "Aborting. Consider using either the --force or --include-untracked option.")" >&2 - exit 1 - fi test -f "$GIT_DIR/logs/$ref_stash" || clear_stash || die "$(gettext "Cannot initialize stash")" diff --git a/git.c b/git.c index 2025f77d01..b3893e73c9 100644 --- a/git.c +++ b/git.c @@ -147,6 +147,18 @@ static int handle_options(const char ***argv, int *argc, int *envchanged) setenv(GIT_LITERAL_PATHSPECS_ENVIRONMENT, "0", 1); if (envchanged) *envchanged = 1; + } else if (!strcmp(cmd, "--glob-pathspecs")) { + setenv(GIT_GLOB_PATHSPECS_ENVIRONMENT, "1", 1); + if (envchanged) + *envchanged = 1; + } else if (!strcmp(cmd, "--noglob-pathspecs")) { + setenv(GIT_NOGLOB_PATHSPECS_ENVIRONMENT, "1", 1); + if (envchanged) + *envchanged = 1; + } else if (!strcmp(cmd, "--icase-pathspecs")) { + setenv(GIT_ICASE_PATHSPECS_ENVIRONMENT, "1", 1); + if (envchanged) + *envchanged = 1; } else if (!strcmp(cmd, "--shallow-file")) { (*argv)++; (*argc)--; diff --git a/http.c b/http.c index 2d086aedfa..f3e1439d58 100644 --- a/http.c +++ b/http.c @@ -3,6 +3,7 @@ #include "sideband.h" #include "run-command.h" #include "url.h" +#include "urlmatch.h" #include "credential.h" #include "version.h" #include "pkt-line.h" @@ -45,6 +46,7 @@ static long curl_low_speed_time = -1; static int curl_ftp_no_epsv; static const char *curl_http_proxy; static const char *curl_cookie_file; +static int curl_save_cookies; static struct credential http_auth = CREDENTIAL_INIT; static int http_proactive_auth; static const char *user_agent; @@ -160,8 +162,7 @@ static int http_options(const char *var, const char *value, void *cb) if (!strcmp("http.sslcainfo", var)) return git_config_string(&ssl_cainfo, var, value); if (!strcmp("http.sslcertpasswordprotected", var)) { - if (git_config_bool(var, value)) - ssl_cert_password_required = 1; + ssl_cert_password_required = git_config_bool(var, value); return 0; } if (!strcmp("http.ssltry", var)) { @@ -200,6 +201,10 @@ static int http_options(const char *var, const char *value, void *cb) if (!strcmp("http.cookiefile", var)) return git_config_string(&curl_cookie_file, var, value); + if (!strcmp("http.savecookies", var)) { + curl_save_cookies = git_config_bool(var, value); + return 0; + } if (!strcmp("http.postbuffer", var)) { http_post_buffer = git_config_int(var, value); @@ -341,10 +346,20 @@ void http_init(struct remote *remote, const char *url, int proactive_auth) { char *low_speed_limit; char *low_speed_time; + char *normalized_url; + struct urlmatch_config config = { STRING_LIST_INIT_DUP }; + + config.section = "http"; + config.key = NULL; + config.collect_fn = http_options; + config.cascade_fn = git_default_config; + config.cb = NULL; http_is_verbose = 0; + normalized_url = url_normalize(url, &config.url); - git_config(http_options, NULL); + git_config(urlmatch_config_entry, &config); + free(normalized_url); curl_global_init(CURL_GLOBAL_ALL); @@ -513,6 +528,8 @@ struct active_request_slot *get_active_slot(void) slot->callback_data = NULL; slot->callback_func = NULL; curl_easy_setopt(slot->curl, CURLOPT_COOKIEFILE, curl_cookie_file); + if (curl_save_cookies) + curl_easy_setopt(slot->curl, CURLOPT_COOKIEJAR, curl_cookie_file); curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, pragma_header); curl_easy_setopt(slot->curl, CURLOPT_ERRORBUFFER, curl_errorstr); curl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, NULL); diff --git a/imap-send.c b/imap-send.c index d6b65e204c..6f5cc4f782 100644 --- a/imap-send.c +++ b/imap-send.c @@ -28,20 +28,6 @@ #include "prompt.h" #ifdef NO_OPENSSL typedef void *SSL; -#else -#ifdef APPLE_COMMON_CRYPTO -#include -#define HMAC_CTX CCHmacContext -#define HMAC_Init(hmac, key, len, algo) CCHmacInit(hmac, algo, key, len) -#define HMAC_Update CCHmacUpdate -#define HMAC_Final(hmac, hash, ptr) CCHmacFinal(hmac, hash) -#define HMAC_CTX_cleanup(ignore) -#define EVP_md5() kCCHmacAlgMD5 -#else -#include -#include -#endif -#include #endif static const char imap_send_usage[] = "git imap-send < "; diff --git a/line-log.c b/line-log.c index c2d01dccc2..8b6e497b3f 100644 --- a/line-log.c +++ b/line-log.c @@ -23,7 +23,7 @@ static void range_set_grow(struct range_set *rs, size_t extra) /* Either initialization would be fine */ #define RANGE_SET_INIT {0} -static void range_set_init(struct range_set *rs, size_t prealloc) +void range_set_init(struct range_set *rs, size_t prealloc) { rs->alloc = rs->nr = 0; rs->ranges = NULL; @@ -31,7 +31,7 @@ static void range_set_init(struct range_set *rs, size_t prealloc) range_set_grow(rs, prealloc); } -static void range_set_release(struct range_set *rs) +void range_set_release(struct range_set *rs) { free(rs->ranges); rs->alloc = rs->nr = 0; @@ -56,7 +56,7 @@ static void range_set_move(struct range_set *dst, struct range_set *src) } /* tack on a _new_ range _at the end_ */ -static void range_set_append_unsafe(struct range_set *rs, long a, long b) +void range_set_append_unsafe(struct range_set *rs, long a, long b) { assert(a <= b); range_set_grow(rs, 1); @@ -65,7 +65,7 @@ static void range_set_append_unsafe(struct range_set *rs, long a, long b) rs->nr++; } -static void range_set_append(struct range_set *rs, long a, long b) +void range_set_append(struct range_set *rs, long a, long b) { assert(rs->nr == 0 || rs->ranges[rs->nr-1].end <= a); range_set_append_unsafe(rs, a, b); @@ -107,7 +107,7 @@ static void range_set_check_invariants(struct range_set *rs) * In-place pass of sorting and merging the ranges in the range set, * to establish the invariants when we get the ranges from the user */ -static void sort_and_merge_range_set(struct range_set *rs) +void sort_and_merge_range_set(struct range_set *rs) { int i; int o = 0; /* output cursor */ @@ -291,7 +291,6 @@ static void line_log_data_insert(struct line_log_data **list, if (p) { range_set_append_unsafe(&p->ranges, begin, end); - sort_and_merge_range_set(&p->ranges); free(path); return; } @@ -299,7 +298,6 @@ static void line_log_data_insert(struct line_log_data **list, p = xcalloc(1, sizeof(struct line_log_data)); p->path = path; range_set_append(&p->ranges, begin, end); - sort_and_merge_range_set(&p->ranges); if (ip) { p->next = ip->next; ip->next = p; @@ -566,12 +564,14 @@ parse_lines(struct commit *commit, const char *prefix, struct string_list *args) struct nth_line_cb cb_data; struct string_list_item *item; struct line_log_data *ranges = NULL; + struct line_log_data *p; for_each_string_list_item(item, args) { const char *name_part, *range_part; char *full_name; struct diff_filespec *spec; long begin = 0, end = 0; + long anchor; name_part = skip_range_arg(item->string); if (!name_part || *name_part != ':' || !name_part[1]) @@ -590,17 +590,23 @@ parse_lines(struct commit *commit, const char *prefix, struct string_list *args) cb_data.lines = lines; cb_data.line_ends = ends; + p = search_line_log_data(ranges, full_name, NULL); + if (p && p->ranges.nr) + anchor = p->ranges.ranges[p->ranges.nr - 1].end + 1; + else + anchor = 1; + if (parse_range_arg(range_part, nth_line, &cb_data, - lines, &begin, &end, + lines, anchor, &begin, &end, full_name)) die("malformed -L argument '%s'", range_part); + if (lines < end || ((lines || begin) && lines < begin)) + die("file %s has only %lu lines", name_part, lines); if (begin < 1) begin = 1; if (end < 1) end = lines; begin--; - if (lines < end || lines < begin) - die("file %s has only %ld lines", name_part, lines); line_log_data_insert(&ranges, full_name, begin, end); free_filespec(spec); @@ -608,6 +614,9 @@ parse_lines(struct commit *commit, const char *prefix, struct string_list *args) ends = NULL; } + for (p = ranges; p; p = p->next) + sort_and_merge_range_set(&p->ranges); + return ranges; } @@ -751,7 +760,7 @@ void line_log_init(struct rev_info *rev, const char *prefix, struct string_list r = r->next; } paths[count] = NULL; - init_pathspec(&rev->diffopt.pathspec, paths); + parse_pathspec(&rev->diffopt.pathspec, 0, 0, "", paths); free(paths); } } diff --git a/line-log.h b/line-log.h index 8bea45fd78..a9212d84e4 100644 --- a/line-log.h +++ b/line-log.h @@ -25,6 +25,18 @@ struct diff_ranges { struct range_set target; }; +extern void range_set_init(struct range_set *, size_t prealloc); +extern void range_set_release(struct range_set *); +/* Range includes start; excludes end */ +extern void range_set_append_unsafe(struct range_set *, long start, long end); +/* New range must begin at or after end of last added range */ +extern void range_set_append(struct range_set *, long start, long end); +/* + * In-place pass of sorting and merging the ranges in the range set, + * to sort and make the ranges disjoint. + */ +extern void sort_and_merge_range_set(struct range_set *); + /* Linked list of interesting files and their associated ranges. The * list must be kept sorted by path. * diff --git a/line-range.c b/line-range.c index 3942475c2f..de4e32f942 100644 --- a/line-range.c +++ b/line-range.c @@ -6,6 +6,18 @@ /* * Parse one item in the -L option + * + * 'begin' is applicable only to relative range anchors. Absolute anchors + * ignore this value. + * + * When parsing "-L A,B", parse_loc() is called once for A and once for B. + * + * When parsing A, 'begin' must be a negative number, the absolute value of + * which is the line at which relative start-of-range anchors should be + * based. Beginning of file is represented by -1. + * + * When parsing B, 'begin' must be the positive line number immediately + * following the line computed for 'A'. */ static const char *parse_loc(const char *spec, nth_line_fn_t nth_line, void *data, long lines, long begin, long *ret) @@ -21,11 +33,13 @@ static const char *parse_loc(const char *spec, nth_line_fn_t nth_line, * for 20 lines, or "-L ,-5" for 5 lines ending at * . */ - if (1 < begin && (spec[0] == '+' || spec[0] == '-')) { + if (1 <= begin && (spec[0] == '+' || spec[0] == '-')) { num = strtol(spec + 1, &term, 10); if (term != spec + 1) { if (!ret) return term; + if (num == 0) + die("-L invalid empty range"); if (spec[0] == '-') num = 0 - num; if (0 < num) @@ -40,10 +54,23 @@ static const char *parse_loc(const char *spec, nth_line_fn_t nth_line, } num = strtol(spec, &term, 10); if (term != spec) { - if (ret) + if (ret) { + if (num <= 0) + die("-L invalid line number: %ld", num); *ret = num; + } return term; } + + if (begin < 0) { + if (spec[0] != '^') + begin = -begin; + else { + begin = 1; + spec++; + } + } + if (spec[0] != '/') return spec; @@ -83,7 +110,8 @@ static const char *parse_loc(const char *spec, nth_line_fn_t nth_line, else { char errbuf[1024]; regerror(reg_error, ®exp, errbuf, 1024); - die("-L parameter '%s': %s", spec + 1, errbuf); + die("-L parameter '%s' starting at line %ld: %s", + spec + 1, begin + 1, errbuf); } } @@ -136,7 +164,7 @@ static const char *find_funcname_matching_regexp(xdemitconf_t *xecfg, const char } static const char *parse_range_funcname(const char *arg, nth_line_fn_t nth_line_cb, - void *cb_data, long lines, long *begin, long *end, + void *cb_data, long lines, long anchor, long *begin, long *end, const char *path) { char *pattern; @@ -148,6 +176,11 @@ static const char *parse_range_funcname(const char *arg, nth_line_fn_t nth_line_ int reg_error; regex_t regexp; + if (*arg == '^') { + anchor = 1; + arg++; + } + assert(*arg == ':'); term = arg+1; while (*term && *term != ':') { @@ -162,7 +195,8 @@ static const char *parse_range_funcname(const char *arg, nth_line_fn_t nth_line_ pattern = xstrndup(arg+1, term-(arg+1)); - start = nth_line_cb(cb_data, 0); + anchor--; /* input is in human terms */ + start = nth_line_cb(cb_data, anchor); drv = userdiff_find_by_path(path); if (drv && drv->funcname.pattern) { @@ -180,7 +214,8 @@ static const char *parse_range_funcname(const char *arg, nth_line_fn_t nth_line_ p = find_funcname_matching_regexp(xecfg, (char*) start, ®exp); if (!p) - die("-L parameter '%s': no match", pattern); + die("-L parameter '%s' starting at line %ld: no match", + pattern, anchor + 1); *begin = 0; while (p > nth_line_cb(cb_data, *begin)) (*begin)++; @@ -208,19 +243,24 @@ static const char *parse_range_funcname(const char *arg, nth_line_fn_t nth_line_ } int parse_range_arg(const char *arg, nth_line_fn_t nth_line_cb, - void *cb_data, long lines, long *begin, long *end, - const char *path) + void *cb_data, long lines, long anchor, + long *begin, long *end, const char *path) { *begin = *end = 0; - if (*arg == ':') { - arg = parse_range_funcname(arg, nth_line_cb, cb_data, lines, begin, end, path); + if (anchor < 1) + anchor = 1; + if (anchor > lines) + anchor = lines + 1; + + if (*arg == ':' || (*arg == '^' && *(arg + 1) == ':')) { + arg = parse_range_funcname(arg, nth_line_cb, cb_data, lines, anchor, begin, end, path); if (!arg || *arg) return -1; return 0; } - arg = parse_loc(arg, nth_line_cb, cb_data, lines, 1, begin); + arg = parse_loc(arg, nth_line_cb, cb_data, lines, -anchor, begin); if (*arg == ',') arg = parse_loc(arg + 1, nth_line_cb, cb_data, lines, *begin + 1, end); @@ -238,8 +278,8 @@ int parse_range_arg(const char *arg, nth_line_fn_t nth_line_cb, const char *skip_range_arg(const char *arg) { - if (*arg == ':') - return parse_range_funcname(arg, NULL, NULL, 0, NULL, NULL, NULL); + if (*arg == ':' || (*arg == '^' && *(arg + 1) == ':')) + return parse_range_funcname(arg, NULL, NULL, 0, 0, NULL, NULL, NULL); arg = parse_loc(arg, NULL, NULL, 0, -1, NULL); diff --git a/line-range.h b/line-range.h index ae3d0123b4..83ba3c25e8 100644 --- a/line-range.h +++ b/line-range.h @@ -9,6 +9,9 @@ * line 'lno' inside the 'cb_data'. The caller is expected to already * have a suitable map at hand to make this a constant-time lookup. * + * 'anchor' is the 1-based line at which relative range specifications + * should be anchored. Absolute ranges are unaffected by this value. + * * Returns 0 in case of success and -1 if there was an error. The * actual range is stored in *begin and *end. The counting starts * at 1! In case of error, the caller should show usage message. @@ -18,7 +21,7 @@ typedef const char *(*nth_line_fn_t)(void *data, long lno); extern int parse_range_arg(const char *arg, nth_line_fn_t nth_line_cb, - void *cb_data, long lines, + void *cb_data, long lines, long anchor, long *begin, long *end, const char *path); diff --git a/log-tree.c b/log-tree.c index a49d8e895d..8534d91826 100644 --- a/log-tree.c +++ b/log-tree.c @@ -738,7 +738,7 @@ static int log_tree_diff(struct rev_info *opt, struct commit *commit, struct log sha1 = commit->tree->object.sha1; /* Root commit? */ - parents = commit->parents; + parents = get_saved_parents(opt, commit); if (!parents) { if (opt->show_root_diff) { diff_root_tree_sha1(sha1, "", &opt->diffopt); diff --git a/merge-recursive.c b/merge-recursive.c index f95933b0aa..40eb840a52 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -298,7 +298,7 @@ static int get_files_dirs(struct merge_options *o, struct tree *tree) { int n; struct pathspec match_all; - init_pathspec(&match_all, NULL); + memset(&match_all, 0, sizeof(match_all)); if (read_tree_recursive(tree, "", 0, 0, &match_all, save_files_dirs, o)) return 0; n = o->current_file_set.nr + o->current_directory_set.nr; diff --git a/notes-merge.c b/notes-merge.c index ab18857074..94a1a8ae46 100644 --- a/notes-merge.c +++ b/notes-merge.c @@ -170,7 +170,7 @@ static struct notes_merge_pair *diff_tree_remote(struct notes_merge_options *o, sha1_to_hex(mp->remote)); } diff_flush(&opt); - diff_tree_release_paths(&opt); + free_pathspec(&opt.pathspec); *num_changes = len; return changes; @@ -256,7 +256,7 @@ static void diff_tree_local(struct notes_merge_options *o, sha1_to_hex(mp->local)); } diff_flush(&opt); - diff_tree_release_paths(&opt); + free_pathspec(&opt.pathspec); } static void check_notes_merge_worktree(struct notes_merge_options *o) diff --git a/parse-options.c b/parse-options.c index c2cbca25cc..62e9b1cc68 100644 --- a/parse-options.c +++ b/parse-options.c @@ -43,8 +43,42 @@ static void fix_filename(const char *prefix, const char **file) *file = xstrdup(prefix_filename(prefix, strlen(prefix), *file)); } +static int opt_command_mode_error(const struct option *opt, + const struct option *all_opts, + int flags) +{ + const struct option *that; + struct strbuf message = STRBUF_INIT; + struct strbuf that_name = STRBUF_INIT; + + /* + * Find the other option that was used to set the variable + * already, and report that this is not compatible with it. + */ + for (that = all_opts; that->type != OPTION_END; that++) { + if (that == opt || + that->type != OPTION_CMDMODE || + that->value != opt->value || + that->defval != *(int *)opt->value) + continue; + + if (that->long_name) + strbuf_addf(&that_name, "--%s", that->long_name); + else + strbuf_addf(&that_name, "-%c", that->short_name); + strbuf_addf(&message, ": incompatible with %s", that_name.buf); + strbuf_release(&that_name); + opterror(opt, message.buf, flags); + strbuf_release(&message); + return -1; + } + return opterror(opt, ": incompatible with something else", flags); +} + static int get_value(struct parse_opt_ctx_t *p, - const struct option *opt, int flags) + const struct option *opt, + const struct option *all_opts, + int flags) { const char *s, *arg; const int unset = flags & OPT_UNSET; @@ -83,6 +117,16 @@ static int get_value(struct parse_opt_ctx_t *p, *(int *)opt->value = unset ? 0 : opt->defval; return 0; + case OPTION_CMDMODE: + /* + * Giving the same mode option twice, although is unnecessary, + * is not a grave error, so let it pass. + */ + if (*(int *)opt->value && *(int *)opt->value != opt->defval) + return opt_command_mode_error(opt, all_opts, flags); + *(int *)opt->value = opt->defval; + return 0; + case OPTION_SET_PTR: *(void **)opt->value = unset ? NULL : (void *)opt->defval; return 0; @@ -143,12 +187,13 @@ static int get_value(struct parse_opt_ctx_t *p, static int parse_short_opt(struct parse_opt_ctx_t *p, const struct option *options) { + const struct option *all_opts = options; const struct option *numopt = NULL; for (; options->type != OPTION_END; options++) { if (options->short_name == *p->opt) { p->opt = p->opt[1] ? p->opt + 1 : NULL; - return get_value(p, options, OPT_SHORT); + return get_value(p, options, all_opts, OPT_SHORT); } /* @@ -177,6 +222,7 @@ static int parse_short_opt(struct parse_opt_ctx_t *p, const struct option *optio static int parse_long_opt(struct parse_opt_ctx_t *p, const char *arg, const struct option *options) { + const struct option *all_opts = options; const char *arg_end = strchr(arg, '='); const struct option *abbrev_option = NULL, *ambiguous_option = NULL; int abbrev_flags = 0, ambiguous_flags = 0; @@ -253,7 +299,7 @@ static int parse_long_opt(struct parse_opt_ctx_t *p, const char *arg, continue; p->opt = rest + 1; } - return get_value(p, options, flags ^ opt_flags); + return get_value(p, options, all_opts, flags ^ opt_flags); } if (ambiguous_option) @@ -265,18 +311,20 @@ static int parse_long_opt(struct parse_opt_ctx_t *p, const char *arg, (abbrev_flags & OPT_UNSET) ? "no-" : "", abbrev_option->long_name); if (abbrev_option) - return get_value(p, abbrev_option, abbrev_flags); + return get_value(p, abbrev_option, all_opts, abbrev_flags); return -2; } static int parse_nodash_opt(struct parse_opt_ctx_t *p, const char *arg, const struct option *options) { + const struct option *all_opts = options; + for (; options->type != OPTION_END; options++) { if (!(options->flags & PARSE_OPT_NODASH)) continue; if (options->short_name == arg[0] && arg[1] == '\0') - return get_value(p, options, OPT_SHORT); + return get_value(p, options, all_opts, OPT_SHORT); } return -2; } diff --git a/parse-options.h b/parse-options.h index c378b75b13..8736006ed7 100644 --- a/parse-options.h +++ b/parse-options.h @@ -13,6 +13,7 @@ enum parse_opt_type { OPTION_COUNTUP, OPTION_SET_INT, OPTION_SET_PTR, + OPTION_CMDMODE, /* options with arguments (usually) */ OPTION_STRING, OPTION_INTEGER, @@ -21,9 +22,6 @@ enum parse_opt_type { OPTION_FILENAME }; -/* Deprecated synonym */ -#define OPTION_BOOLEAN OPTION_COUNTUP - enum parse_opt_flags { PARSE_OPT_KEEP_DASHDASH = 1, PARSE_OPT_STOP_AT_NON_OPTION = 2, @@ -128,8 +126,12 @@ struct option { #define OPT_SET_INT(s, l, v, h, i) { OPTION_SET_INT, (s), (l), (v), NULL, \ (h), PARSE_OPT_NOARG, NULL, (i) } #define OPT_BOOL(s, l, v, h) OPT_SET_INT(s, l, v, h, 1) +#define OPT_HIDDEN_BOOL(s, l, v, h) { OPTION_SET_INT, (s), (l), (v), NULL, \ + (h), PARSE_OPT_NOARG | PARSE_OPT_HIDDEN, NULL, 1} #define OPT_SET_PTR(s, l, v, h, p) { OPTION_SET_PTR, (s), (l), (v), NULL, \ (h), PARSE_OPT_NOARG, NULL, (p) } +#define OPT_CMDMODE(s, l, v, h, i) { OPTION_CMDMODE, (s), (l), (v), NULL, \ + (h), PARSE_OPT_NOARG|PARSE_OPT_NONEG, NULL, (i) } #define OPT_INTEGER(s, l, v, h) { OPTION_INTEGER, (s), (l), (v), N_("n"), (h) } #define OPT_STRING(s, l, v, a, h) { OPTION_STRING, (s), (l), (v), (a), (h) } #define OPT_STRING_LIST(s, l, v, a, h) \ @@ -180,7 +182,7 @@ 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); -#if defined(__GNUC__) && ! defined(clang) +#if defined(__GNUC__) && ! defined(__clang__) #define opterror(o,r,f) (opterror((o),(r),(f)), -1) #endif diff --git a/path.c b/path.c index 3d244d3e03..9fd28bcd08 100644 --- a/path.c +++ b/path.c @@ -543,8 +543,14 @@ const char *relative_path(const char *in, const char *prefix, * * Note that this function is purely textual. It does not follow symlinks, * verify the existence of the path, or make any system calls. + * + * prefix_len != NULL is for a specific case of prefix_pathspec(): + * assume that src == dst and src[0..prefix_len-1] is already + * normalized, any time "../" eats up to the prefix_len part, + * prefix_len is reduced. In the end prefix_len is the remaining + * prefix that has not been overridden by user pathspec. */ -int normalize_path_copy(char *dst, const char *src) +int normalize_path_copy_len(char *dst, const char *src, int *prefix_len) { char *dst0; @@ -619,11 +625,18 @@ int normalize_path_copy(char *dst, const char *src) /* Windows: dst[-1] cannot be backslash anymore */ while (dst0 < dst && dst[-1] != '/') dst--; + if (prefix_len && *prefix_len > dst - dst0) + *prefix_len = dst - dst0; } *dst = '\0'; return 0; } +int normalize_path_copy(char *dst, const char *src) +{ + return normalize_path_copy_len(dst, src, NULL); +} + /* * path = Canonical absolute path * prefixes = string_list containing normalized, absolute paths without diff --git a/pathspec.c b/pathspec.c index 6ea0867493..4b32cc32cb 100644 --- a/pathspec.c +++ b/pathspec.c @@ -15,8 +15,8 @@ * If seen[] has not already been written to, it may make sense * to use find_pathspecs_matching_against_index() instead. */ -void add_pathspec_matches_against_index(const char **pathspec, - char *seen, int specs) +void add_pathspec_matches_against_index(const struct pathspec *pathspec, + char *seen) { int num_unmatched = 0, i; @@ -26,14 +26,14 @@ void add_pathspec_matches_against_index(const char **pathspec, * mistakenly think that the user gave a pathspec that did not match * anything. */ - for (i = 0; i < specs; i++) + for (i = 0; i < pathspec->nr; i++) if (!seen[i]) num_unmatched++; if (!num_unmatched) return; for (i = 0; i < active_nr; i++) { const struct cache_entry *ce = active_cache[i]; - match_pathspec(pathspec, ce->name, ce_namelen(ce), 0, seen); + match_pathspec_depth(pathspec, ce->name, ce_namelen(ce), 0, seen); } } @@ -45,57 +45,428 @@ void add_pathspec_matches_against_index(const char **pathspec, * nature of the "closest" (i.e. most specific) matches which each of the * given pathspecs achieves against all items in the index. */ -char *find_pathspecs_matching_against_index(const char **pathspec) +char *find_pathspecs_matching_against_index(const struct pathspec *pathspec) { - char *seen; - int i; - - for (i = 0; pathspec[i]; i++) - ; /* just counting */ - seen = xcalloc(i, 1); - add_pathspec_matches_against_index(pathspec, seen, i); + char *seen = xcalloc(pathspec->nr, 1); + add_pathspec_matches_against_index(pathspec, seen); return seen; } /* - * Check the index to see whether path refers to a submodule, or - * something inside a submodule. If the former, returns the path with - * any trailing slash stripped. If the latter, dies with an error - * message. + * Magic pathspec + * + * Possible future magic semantics include stuff like: + * + * { PATHSPEC_RECURSIVE, '*', "recursive" }, + * { PATHSPEC_REGEXP, '\0', "regexp" }, + * + */ + +static struct pathspec_magic { + unsigned bit; + char mnemonic; /* this cannot be ':'! */ + const char *name; +} pathspec_magic[] = { + { PATHSPEC_FROMTOP, '/', "top" }, + { PATHSPEC_LITERAL, 0, "literal" }, + { PATHSPEC_GLOB, '\0', "glob" }, + { PATHSPEC_ICASE, '\0', "icase" }, +}; + +/* + * Take an element of a pathspec and check for magic signatures. + * Append the result to the prefix. Return the magic bitmap. + * + * For now, we only parse the syntax and throw out anything other than + * "top" magic. + * + * NEEDSWORK: This needs to be rewritten when we start migrating + * get_pathspec() users to use the "struct pathspec" interface. For + * example, a pathspec element may be marked as case-insensitive, but + * the prefix part must always match literally, and a single stupid + * string cannot express such a case. */ -const char *check_path_for_gitlink(const char *path) +static unsigned prefix_pathspec(struct pathspec_item *item, + unsigned *p_short_magic, + const char **raw, unsigned flags, + const char *prefix, int prefixlen, + const char *elt) { - int i, path_len = strlen(path); - for (i = 0; i < active_nr; i++) { - const struct cache_entry *ce = active_cache[i]; - if (S_ISGITLINK(ce->ce_mode)) { - int ce_len = ce_namelen(ce); - if (path_len <= ce_len || path[ce_len] != '/' || - memcmp(ce->name, path, ce_len)) - /* path does not refer to this - * submodule or anything inside it */ + static int literal_global = -1; + static int glob_global = -1; + static int noglob_global = -1; + static int icase_global = -1; + unsigned magic = 0, short_magic = 0, global_magic = 0; + const char *copyfrom = elt, *long_magic_end = NULL; + char *match; + int i, pathspec_prefix = -1; + + if (literal_global < 0) + literal_global = git_env_bool(GIT_LITERAL_PATHSPECS_ENVIRONMENT, 0); + if (literal_global) + global_magic |= PATHSPEC_LITERAL; + + if (glob_global < 0) + glob_global = git_env_bool(GIT_GLOB_PATHSPECS_ENVIRONMENT, 0); + if (glob_global) + global_magic |= PATHSPEC_GLOB; + + if (noglob_global < 0) + noglob_global = git_env_bool(GIT_NOGLOB_PATHSPECS_ENVIRONMENT, 0); + + if (glob_global && noglob_global) + die(_("global 'glob' and 'noglob' pathspec settings are incompatible")); + + + if (icase_global < 0) + icase_global = git_env_bool(GIT_ICASE_PATHSPECS_ENVIRONMENT, 0); + if (icase_global) + global_magic |= PATHSPEC_ICASE; + + if ((global_magic & PATHSPEC_LITERAL) && + (global_magic & ~PATHSPEC_LITERAL)) + die(_("global 'literal' pathspec setting is incompatible " + "with all other global pathspec settings")); + + if (elt[0] != ':' || literal_global) { + ; /* nothing to do */ + } else if (elt[1] == '(') { + /* longhand */ + const char *nextat; + for (copyfrom = elt + 2; + *copyfrom && *copyfrom != ')'; + copyfrom = nextat) { + size_t len = strcspn(copyfrom, ",)"); + if (copyfrom[len] == ',') + nextat = copyfrom + len + 1; + else + /* handle ')' and '\0' */ + nextat = copyfrom + len; + if (!len) continue; - if (path_len == ce_len + 1) { - /* path refers to submodule; - * strip trailing slash */ - return xstrndup(ce->name, ce_len); + for (i = 0; i < ARRAY_SIZE(pathspec_magic); i++) { + if (strlen(pathspec_magic[i].name) == len && + !strncmp(pathspec_magic[i].name, copyfrom, len)) { + magic |= pathspec_magic[i].bit; + break; + } + if (!prefixcmp(copyfrom, "prefix:")) { + char *endptr; + pathspec_prefix = strtol(copyfrom + 7, + &endptr, 10); + if (endptr - copyfrom != len) + die(_("invalid parameter for pathspec magic 'prefix'")); + /* "i" would be wrong, but it does not matter */ + break; + } + } + if (ARRAY_SIZE(pathspec_magic) <= i) + die(_("Invalid pathspec magic '%.*s' in '%s'"), + (int) len, copyfrom, elt); + } + if (*copyfrom != ')') + die(_("Missing ')' at the end of pathspec magic in '%s'"), elt); + long_magic_end = copyfrom; + copyfrom++; + } else { + /* shorthand */ + for (copyfrom = elt + 1; + *copyfrom && *copyfrom != ':'; + copyfrom++) { + char ch = *copyfrom; + + if (!is_pathspec_magic(ch)) + break; + for (i = 0; i < ARRAY_SIZE(pathspec_magic); i++) + if (pathspec_magic[i].mnemonic == ch) { + short_magic |= pathspec_magic[i].bit; + break; + } + if (ARRAY_SIZE(pathspec_magic) <= i) + die(_("Unimplemented pathspec magic '%c' in '%s'"), + ch, elt); + } + if (*copyfrom == ':') + copyfrom++; + } + + magic |= short_magic; + *p_short_magic = short_magic; + + /* --noglob-pathspec adds :(literal) _unless_ :(glob) is specifed */ + if (noglob_global && !(magic & PATHSPEC_GLOB)) + global_magic |= PATHSPEC_LITERAL; + + /* --glob-pathspec is overriden by :(literal) */ + if ((global_magic & PATHSPEC_GLOB) && (magic & PATHSPEC_LITERAL)) + global_magic &= ~PATHSPEC_GLOB; + + magic |= global_magic; + + if (pathspec_prefix >= 0 && + (prefixlen || (prefix && *prefix))) + die("BUG: 'prefix' magic is supposed to be used at worktree's root"); + + if ((magic & PATHSPEC_LITERAL) && (magic & PATHSPEC_GLOB)) + die(_("%s: 'literal' and 'glob' are incompatible"), elt); + + if (pathspec_prefix >= 0) { + match = xstrdup(copyfrom); + prefixlen = pathspec_prefix; + } else if (magic & PATHSPEC_FROMTOP) { + match = xstrdup(copyfrom); + prefixlen = 0; + } else { + match = prefix_path_gently(prefix, prefixlen, &prefixlen, copyfrom); + if (!match) + die(_("%s: '%s' is outside repository"), elt, copyfrom); + } + *raw = item->match = match; + /* + * Prefix the pathspec (keep all magic) and assign to + * original. Useful for passing to another command. + */ + if (flags & PATHSPEC_PREFIX_ORIGIN) { + struct strbuf sb = STRBUF_INIT; + const char *start = elt; + if (prefixlen && !literal_global) { + /* Preserve the actual prefix length of each pattern */ + if (long_magic_end) { + strbuf_add(&sb, start, long_magic_end - start); + strbuf_addf(&sb, ",prefix:%d", prefixlen); + start = long_magic_end; } else { - die (_("Path '%s' is in submodule '%.*s'"), - path, ce_len, ce->name); + if (*start == ':') + start++; + strbuf_addf(&sb, ":(prefix:%d)", prefixlen); } } + strbuf_add(&sb, start, copyfrom - start); + strbuf_addstr(&sb, match); + item->original = strbuf_detach(&sb, NULL); + } else + item->original = elt; + item->len = strlen(item->match); + item->prefix = prefixlen; + + if ((flags & PATHSPEC_STRIP_SUBMODULE_SLASH_CHEAP) && + (item->len >= 1 && item->match[item->len - 1] == '/') && + (i = cache_name_pos(item->match, item->len - 1)) >= 0 && + S_ISGITLINK(active_cache[i]->ce_mode)) { + item->len--; + match[item->len] = '\0'; + } + + if (flags & PATHSPEC_STRIP_SUBMODULE_SLASH_EXPENSIVE) + for (i = 0; i < active_nr; i++) { + struct cache_entry *ce = active_cache[i]; + int ce_len = ce_namelen(ce); + + if (!S_ISGITLINK(ce->ce_mode)) + continue; + + if (item->len <= ce_len || match[ce_len] != '/' || + memcmp(ce->name, match, ce_len)) + continue; + if (item->len == ce_len + 1) { + /* strip trailing slash */ + item->len--; + match[item->len] = '\0'; + } else + die (_("Pathspec '%s' is in submodule '%.*s'"), + elt, ce_len, ce->name); + } + + if (magic & PATHSPEC_LITERAL) + item->nowildcard_len = item->len; + else { + item->nowildcard_len = simple_length(item->match); + if (item->nowildcard_len < prefixlen) + item->nowildcard_len = prefixlen; + } + item->flags = 0; + if (magic & PATHSPEC_GLOB) { + /* + * FIXME: should we enable ONESTAR in _GLOB for + * pattern "* * / * . c"? + */ + } else { + if (item->nowildcard_len < item->len && + item->match[item->nowildcard_len] == '*' && + no_wildcard(item->match + item->nowildcard_len + 1)) + item->flags |= PATHSPEC_ONESTAR; } - return path; + + /* sanity checks, pathspec matchers assume these are sane */ + assert(item->nowildcard_len <= item->len && + item->prefix <= item->len); + return magic; +} + +static int pathspec_item_cmp(const void *a_, const void *b_) +{ + struct pathspec_item *a, *b; + + a = (struct pathspec_item *)a_; + b = (struct pathspec_item *)b_; + return strcmp(a->match, b->match); +} + +static void NORETURN unsupported_magic(const char *pattern, + unsigned magic, + unsigned short_magic) +{ + struct strbuf sb = STRBUF_INIT; + int i, n; + for (n = i = 0; i < ARRAY_SIZE(pathspec_magic); i++) { + const struct pathspec_magic *m = pathspec_magic + i; + if (!(magic & m->bit)) + continue; + if (sb.len) + strbuf_addstr(&sb, " "); + if (short_magic & m->bit) + strbuf_addf(&sb, "'%c'", m->mnemonic); + else + strbuf_addf(&sb, "'%s'", m->name); + n++; + } + /* + * We may want to substitute "this command" with a command + * name. E.g. when add--interactive dies when running + * "checkout -p" + */ + die(_("%s: pathspec magic not supported by this command: %s"), + pattern, sb.buf); } /* - * Dies if the given path refers to a file inside a symlinked - * directory in the index. + * Given command line arguments and a prefix, convert the input to + * pathspec. die() if any magic in magic_mask is used. */ -void die_if_path_beyond_symlink(const char *path, const char *prefix) +void parse_pathspec(struct pathspec *pathspec, + unsigned magic_mask, unsigned flags, + const char *prefix, const char **argv) { - if (has_symlink_leading_path(path, strlen(path))) { - int len = prefix ? strlen(prefix) : 0; - die(_("'%s' is beyond a symbolic link"), path + len); + struct pathspec_item *item; + const char *entry = argv ? *argv : NULL; + int i, n, prefixlen; + + memset(pathspec, 0, sizeof(*pathspec)); + + if (flags & PATHSPEC_MAXDEPTH_VALID) + pathspec->magic |= PATHSPEC_MAXDEPTH; + + /* No arguments, no prefix -> no pathspec */ + if (!entry && !prefix) + return; + + if ((flags & PATHSPEC_PREFER_CWD) && + (flags & PATHSPEC_PREFER_FULL)) + die("BUG: PATHSPEC_PREFER_CWD and PATHSPEC_PREFER_FULL are incompatible"); + + /* No arguments with prefix -> prefix pathspec */ + if (!entry) { + static const char *raw[2]; + + if (flags & PATHSPEC_PREFER_FULL) + return; + + if (!(flags & PATHSPEC_PREFER_CWD)) + die("BUG: PATHSPEC_PREFER_CWD requires arguments"); + + pathspec->items = item = xmalloc(sizeof(*item)); + memset(item, 0, sizeof(*item)); + item->match = prefix; + item->original = prefix; + item->nowildcard_len = item->len = strlen(prefix); + item->prefix = item->len; + raw[0] = prefix; + raw[1] = NULL; + pathspec->nr = 1; + pathspec->_raw = raw; + return; } + + n = 0; + while (argv[n]) + n++; + + pathspec->nr = n; + pathspec->items = item = xmalloc(sizeof(*item) * n); + pathspec->_raw = argv; + prefixlen = prefix ? strlen(prefix) : 0; + + for (i = 0; i < n; i++) { + unsigned short_magic; + entry = argv[i]; + + item[i].magic = prefix_pathspec(item + i, &short_magic, + argv + i, flags, + prefix, prefixlen, entry); + if (item[i].magic & magic_mask) + unsupported_magic(entry, + item[i].magic & magic_mask, + short_magic); + + if ((flags & PATHSPEC_SYMLINK_LEADING_PATH) && + has_symlink_leading_path(item[i].match, item[i].len)) { + die(_("pathspec '%s' is beyond a symbolic link"), entry); + } + + if (item[i].nowildcard_len < item[i].len) + pathspec->has_wildcard = 1; + pathspec->magic |= item[i].magic; + } + + + if (pathspec->magic & PATHSPEC_MAXDEPTH) { + if (flags & PATHSPEC_KEEP_ORDER) + die("BUG: PATHSPEC_MAXDEPTH_VALID and PATHSPEC_KEEP_ORDER are incompatible"); + qsort(pathspec->items, pathspec->nr, + sizeof(struct pathspec_item), pathspec_item_cmp); + } +} + +/* + * N.B. get_pathspec() is deprecated in favor of the "struct pathspec" + * based interface - see pathspec.c:parse_pathspec(). + * + * Arguments: + * - prefix - a path relative to the root of the working tree + * - pathspec - a list of paths underneath the prefix path + * + * Iterates over pathspec, prepending each path with prefix, + * and return the resulting list. + * + * If pathspec is empty, return a singleton list containing prefix. + * + * If pathspec and prefix are both empty, return an empty list. + * + * This is typically used by built-in commands such as add.c, in order + * to normalize argv arguments provided to the built-in into a list of + * paths to process, all relative to the root of the working tree. + */ +const char **get_pathspec(const char *prefix, const char **pathspec) +{ + struct pathspec ps; + parse_pathspec(&ps, + PATHSPEC_ALL_MAGIC & + ~(PATHSPEC_FROMTOP | PATHSPEC_LITERAL), + PATHSPEC_PREFER_CWD, + prefix, pathspec); + return ps._raw; +} + +void copy_pathspec(struct pathspec *dst, const struct pathspec *src) +{ + *dst = *src; + dst->items = xmalloc(sizeof(struct pathspec_item) * dst->nr); + memcpy(dst->items, src->items, + sizeof(struct pathspec_item) * dst->nr); +} + +void free_pathspec(struct pathspec *pathspec) +{ + free(pathspec->items); + pathspec->items = NULL; } diff --git a/pathspec.h b/pathspec.h index db0184a1ac..04b632fa33 100644 --- a/pathspec.h +++ b/pathspec.h @@ -1,8 +1,92 @@ #ifndef PATHSPEC_H #define PATHSPEC_H -extern char *find_pathspecs_matching_against_index(const char **pathspec); -extern void add_pathspec_matches_against_index(const char **pathspec, char *seen, int specs); +/* Pathspec magic */ +#define PATHSPEC_FROMTOP (1<<0) +#define PATHSPEC_MAXDEPTH (1<<1) +#define PATHSPEC_LITERAL (1<<2) +#define PATHSPEC_GLOB (1<<3) +#define PATHSPEC_ICASE (1<<4) +#define PATHSPEC_ALL_MAGIC \ + (PATHSPEC_FROMTOP | \ + PATHSPEC_MAXDEPTH | \ + PATHSPEC_LITERAL | \ + PATHSPEC_GLOB | \ + PATHSPEC_ICASE) + +#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; + unsigned int has_wildcard:1; + unsigned int recursive:1; + unsigned magic; + int max_depth; + struct pathspec_item { + const char *match; + const char *original; + unsigned magic; + int len, prefix; + int nowildcard_len; + int flags; + } *items; +}; + +#define GUARD_PATHSPEC(ps, mask) \ + do { \ + if ((ps)->magic & ~(mask)) \ + die("BUG:%s:%d: unsupported magic %x", \ + __FILE__, __LINE__, (ps)->magic & ~(mask)); \ + } while (0) + +/* parse_pathspec flags */ +#define PATHSPEC_PREFER_CWD (1<<0) /* No args means match cwd */ +#define PATHSPEC_PREFER_FULL (1<<1) /* No args means match everything */ +#define PATHSPEC_MAXDEPTH_VALID (1<<2) /* max_depth field is valid */ +/* strip the trailing slash if the given path is a gitlink */ +#define PATHSPEC_STRIP_SUBMODULE_SLASH_CHEAP (1<<3) +/* die if a symlink is part of the given path's directory */ +#define PATHSPEC_SYMLINK_LEADING_PATH (1<<4) +/* + * This is like a combination of ..LEADING_PATH and .._SLASH_CHEAP + * (but not the same): it strips the trailing slash if the given path + * is a gitlink but also checks and dies if gitlink is part of the + * leading path (i.e. the given path goes beyond a submodule). It's + * safer than _SLASH_CHEAP and also more expensive. + */ +#define PATHSPEC_STRIP_SUBMODULE_SLASH_EXPENSIVE (1<<5) +#define PATHSPEC_PREFIX_ORIGIN (1<<6) +#define PATHSPEC_KEEP_ORDER (1<<7) + +extern void parse_pathspec(struct pathspec *pathspec, + unsigned magic_mask, + unsigned flags, + const char *prefix, + const char **args); +extern void copy_pathspec(struct pathspec *dst, const struct pathspec *src); +extern void free_pathspec(struct pathspec *); + +static inline int ps_strncmp(const struct pathspec_item *item, + const char *s1, const char *s2, size_t n) +{ + if (item->magic & PATHSPEC_ICASE) + return strncasecmp(s1, s2, n); + else + return strncmp(s1, s2, n); +} + +static inline int ps_strcmp(const struct pathspec_item *item, + const char *s1, const char *s2) +{ + if (item->magic & PATHSPEC_ICASE) + return strcasecmp(s1, s2); + else + return strcmp(s1, s2); +} + +extern char *find_pathspecs_matching_against_index(const struct pathspec *pathspec); +extern void add_pathspec_matches_against_index(const struct pathspec *pathspec, char *seen); extern const char *check_path_for_gitlink(const char *path); extern void die_if_path_beyond_symlink(const char *path, const char *prefix); diff --git a/perl/Git.pm b/perl/Git.pm index 7a252ef872..204fdc6737 100644 --- a/perl/Git.pm +++ b/perl/Git.pm @@ -61,7 +61,7 @@ =head1 SYNOPSIS remote_refs prompt get_tz_offset credential credential_read credential_write - temp_acquire temp_release temp_reset temp_path); + temp_acquire temp_is_locked temp_release temp_reset temp_path); =head1 DESCRIPTION @@ -1206,6 +1206,35 @@ sub temp_acquire { $temp_fd; } +=item temp_is_locked ( NAME ) + +Returns true if the internal lock created by a previous C +call with C is still in effect. + +When temp_acquire is called on a C, it internally locks the temporary +file mapped to C. That lock will not be released until C +is called with either the original C or the L that was +returned from the original call to temp_acquire. + +Subsequent attempts to call C with the same C will fail +unless there has been an intervening C call for that C +(or its corresponding L that was returned by the original +C call). + +If true is returned by C for a C, an attempt to +C the same C will cause an error unless +C is first called on that C (or its corresponding +L that was returned by the original C call). + +=cut + +sub temp_is_locked { + my ($self, $name) = _maybe_self(@_); + my $temp_fd = \$TEMP_FILEMAP{$name}; + + defined $$temp_fd && $$temp_fd->opened && $TEMP_FILES{$$temp_fd}{locked}; +} + =item temp_release ( NAME ) =item temp_release ( FILEHANDLE ) diff --git a/perl/Git/SVN/Fetcher.pm b/perl/Git/SVN/Fetcher.pm index bd174189b9..10edb27732 100644 --- a/perl/Git/SVN/Fetcher.pm +++ b/perl/Git/SVN/Fetcher.pm @@ -315,11 +315,13 @@ sub change_file_prop { sub apply_textdelta { my ($self, $fb, $exp) = @_; return undef if $self->is_path_ignored($fb->{path}); - my $fh = $::_repository->temp_acquire('svn_delta'); + my $suffix = 0; + ++$suffix while $::_repository->temp_is_locked("svn_delta_${$}_$suffix"); + my $fh = $::_repository->temp_acquire("svn_delta_${$}_$suffix"); # $fh gets auto-closed() by SVN::TxDelta::apply(), # (but $base does not,) so dup() it for reading in close_file open my $dup, '<&', $fh or croak $!; - my $base = $::_repository->temp_acquire('git_blob'); + my $base = $::_repository->temp_acquire("git_blob_${$}_$suffix"); if ($fb->{blob}) { my ($base_is_link, $size); diff --git a/po/TEAMS b/po/TEAMS index 5eb5aadb3a..107aa5917c 100644 --- a/po/TEAMS +++ b/po/TEAMS @@ -12,6 +12,11 @@ Members: Thomas Rast Jan Krüger Christian Stimming +Language: fr (French) +Repository: https://github.com/jnavila/git +Leader: Jean-Noël Avila +Members: Sébastien Helleu + Language: is (Icelandic) Leader: Ævar Arnfjörð Bjarmason diff --git a/po/de.po b/po/de.po index 4901488cbb..11dde114f3 100644 --- a/po/de.po +++ b/po/de.po @@ -5,10 +5,10 @@ # msgid "" msgstr "" -"Project-Id-Version: git 1.8.3\n" +"Project-Id-Version: git 1.8.4\n" "Report-Msgid-Bugs-To: Git Mailing List \n" -"POT-Creation-Date: 2013-04-30 08:25+0800\n" -"PO-Revision-Date: 2012-10-02 19:35+0200\n" +"POT-Creation-Date: 2013-08-06 14:10+0800\n" +"PO-Revision-Date: 2013-07-28 18:42+0200\n" "Last-Translator: Ralf Thielow \n" "Language-Team: German <>\n" "Language: de\n" @@ -17,7 +17,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n!=1);\n" -#: advice.c:53 +#: advice.c:57 #, c-format msgid "hint: %.*s\n" msgstr "Hinweis: %.*s\n" @@ -26,21 +26,21 @@ msgstr "Hinweis: %.*s\n" #. * Message used both when 'git commit' fails and when #. * other commands doing a merge do. #. -#: advice.c:83 +#: advice.c:87 msgid "" "Fix them up in the work tree,\n" "and then use 'git add/rm ' as\n" "appropriate to mark resolution and make a commit,\n" "or use 'git commit -a'." msgstr "" -"Korrigieren Sie dies im Arbeitsbaum,\n" +"Korrigieren Sie dies im Arbeitsverzeichnis,\n" "und benutzen Sie dann 'git add/rm '\n" -"um die Auflösung entsprechend zu markieren und einzutragen,\n" +"um die Auflösung entsprechend zu markieren und zu committen,\n" "oder benutzen Sie 'git commit -a'." #: archive.c:10 msgid "git archive [options] [...]" -msgstr "git archive [Optionen] [...]" +msgstr "git archive [Optionen] [...]" #: archive.c:11 msgid "git archive --list" @@ -50,12 +50,12 @@ msgstr "git archive --list" msgid "" "git archive --remote [--exec ] [options] [...]" msgstr "" -"git archive --remote [--exec ] [Optionen] " -" [Pfad...]" +"git archive --remote [--exec ] [Optionen] [Pfad...]" #: archive.c:13 msgid "git archive --remote [--exec ] --list" -msgstr "git archive --remote [--exec ] --list" +msgstr "git archive --remote [--exec ] --list" #: archive.c:323 msgid "fmt" @@ -63,27 +63,27 @@ msgstr "Format" #: archive.c:323 msgid "archive format" -msgstr "Ausgabeformat" +msgstr "Archivformat" -#: archive.c:324 builtin/log.c:1126 +#: archive.c:324 builtin/log.c:1173 msgid "prefix" msgstr "Prefix" #: archive.c:325 msgid "prepend prefix to each pathname in the archive" -msgstr "stellt einen Präfix vor jeden Pfadnamen in der Ausgabe" +msgstr "stellt einen Präfix vor jeden Pfadnamen in dem Archiv" -#: archive.c:326 builtin/archive.c:88 builtin/blame.c:2371 -#: builtin/blame.c:2372 builtin/config.c:55 builtin/fast-export.c:665 -#: builtin/fast-export.c:667 builtin/grep.c:715 builtin/hash-object.c:77 -#: builtin/ls-files.c:490 builtin/ls-files.c:493 builtin/notes.c:536 -#: builtin/notes.c:693 builtin/read-tree.c:107 parse-options.h:149 +#: archive.c:326 builtin/archive.c:88 builtin/blame.c:2292 +#: builtin/blame.c:2293 builtin/config.c:56 builtin/fast-export.c:673 +#: builtin/fast-export.c:675 builtin/grep.c:714 builtin/hash-object.c:77 +#: builtin/ls-files.c:496 builtin/ls-files.c:499 builtin/notes.c:408 +#: builtin/notes.c:565 builtin/read-tree.c:108 parse-options.h:152 msgid "file" msgstr "Datei" #: archive.c:327 builtin/archive.c:89 msgid "write the archive to this file" -msgstr "schreibt die Ausgabe in diese Datei" +msgstr "schreibt das Archiv in diese Datei" #: archive.c:329 msgid "read .gitattributes in working directory" @@ -107,17 +107,17 @@ msgstr "besser komprimieren" #: archive.c:343 msgid "list supported archive formats" -msgstr "listet unterstützte Ausgabeformate auf" +msgstr "listet unterstützte Archivformate auf" -#: archive.c:345 builtin/archive.c:90 builtin/clone.c:86 +#: archive.c:345 builtin/archive.c:90 builtin/clone.c:85 msgid "repo" -msgstr "Projektarchiv" +msgstr "Repository" #: archive.c:346 builtin/archive.c:91 msgid "retrieve the archive from remote repository " -msgstr "ruft das Archiv von externem Projektarchiv ab" +msgstr "ruft das Archiv von Remote-Repository ab" -#: archive.c:347 builtin/archive.c:92 builtin/notes.c:615 +#: archive.c:347 builtin/archive.c:92 builtin/notes.c:487 msgid "command" msgstr "Programm" @@ -136,88 +136,90 @@ msgstr "" #: branch.c:60 #, c-format msgid "Not setting branch %s as its own upstream." -msgstr "Zweig %s kann nicht sein eigener Übernahmezweig sein." +msgstr "Branch %s kann nicht sein eigener Upstream-Branch sein." #: branch.c:82 #, c-format msgid "Branch %s set up to track remote branch %s from %s by rebasing." -msgstr "Zweig %s konfiguriert zum Folgen von externem Zweig %s von %s durch " -"Neuaufbau." +msgstr "" +"Branch %s konfiguriert zum Folgen von Remote-Branch %s von %s durch Rebase." #: branch.c:83 #, c-format msgid "Branch %s set up to track remote branch %s from %s." -msgstr "Zweig %s konfiguriert zum Folgen von externem Zweig %s von %s." +msgstr "Branch %s konfiguriert zum Folgen von Remote-Branch %s von %s." #: branch.c:87 #, c-format msgid "Branch %s set up to track local branch %s by rebasing." -msgstr "Zweig %s konfiguriert zum Folgen von lokalem Zweig %s durch Neuaufbau." +msgstr "Branch %s konfiguriert zum Folgen von lokalem Branch %s durch Rebase." #: branch.c:88 #, c-format msgid "Branch %s set up to track local branch %s." -msgstr "Zweig %s konfiguriert zum Folgen von lokalem Zweig %s." +msgstr "Branch %s konfiguriert zum Folgen von lokalem Branch %s." #: branch.c:92 #, c-format msgid "Branch %s set up to track remote ref %s by rebasing." -msgstr "Zweig %s konfiguriert zum Folgen von externer Referenz %s durch " -"Neuaufbau." +msgstr "Branch %s konfiguriert zum Folgen von Remote-Referenz %s durch Rebase." #: branch.c:93 #, c-format msgid "Branch %s set up to track remote ref %s." -msgstr "Zweig %s konfiguriert zum Folgen von externer Referenz %s." +msgstr "Branch %s konfiguriert zum Folgen von Remote-Referenz %s." #: branch.c:97 #, c-format msgid "Branch %s set up to track local ref %s by rebasing." -msgstr "Zweig %s konfiguriert zum Folgen von lokaler Referenz %s durch " -"Neuaufbau." +msgstr "" +"Branch %s konfiguriert zum Folgen von lokaler Referenz %s durch Rebase." #: branch.c:98 #, c-format msgid "Branch %s set up to track local ref %s." -msgstr "Zweig %s konfiguriert zum Folgen von lokaler Referenz %s." +msgstr "Branch %s konfiguriert zum Folgen von lokaler Referenz %s." #: branch.c:118 #, c-format msgid "Tracking not set up: name too long: %s" -msgstr "Konfiguration zum Folgen von Zweig nicht eingerichtet. Name zu lang: %s" +msgstr "" +"Konfiguration zum Folgen von Branch nicht eingerichtet. Name zu lang: %s" #: branch.c:137 #, c-format msgid "Not tracking: ambiguous information for ref %s" -msgstr "Konfiguration zum Folgen von Zweig nicht eingerichtet. Referenz %s ist mehrdeutig." +msgstr "" +"Konfiguration zum Folgen von Branch nicht eingerichtet. Referenz %s ist " +"mehrdeutig." #: branch.c:182 #, c-format msgid "'%s' is not a valid branch name." -msgstr "'%s' ist kein gültiger Zweigname." +msgstr "'%s' ist kein gültiger Branchname." #: branch.c:187 #, c-format msgid "A branch named '%s' already exists." -msgstr "Zweig '%s' existiert bereits." +msgstr "Branch '%s' existiert bereits." #: branch.c:195 msgid "Cannot force update the current branch." -msgstr "Kann Aktualisierung des aktuellen Zweiges nicht erzwingen." +msgstr "Kann Aktualisierung des aktuellen Branches nicht erzwingen." -#: branch.c:201 +#: branch.c:216 #, c-format msgid "Cannot setup tracking information; starting point '%s' is not a branch." msgstr "" -"Kann Informationen zum Übernahmezweig nicht einrichten; Startpunkt '%s' ist " -"kein Zweig." +"Kann Tracking-Informationen nicht einrichten; Startpunkt '%s' ist kein " +"Branch." -#: branch.c:203 +#: branch.c:218 #, c-format msgid "the requested upstream branch '%s' does not exist" -msgstr "der angeforderte externe Übernahmezweig '%s' existiert nicht" +msgstr "der angeforderte Upstream-Branch '%s' existiert nicht" -#: branch.c:205 +#: branch.c:220 msgid "" "\n" "If you are planning on basing your work on an upstream\n" @@ -229,35 +231,35 @@ msgid "" "\"git push -u\" to set the upstream config as you push." msgstr "" "\n" -"Falls Sie vorhaben, Ihre Arbeit auf einem bereits existierenden,\n" -"externen Übernahmezweig aufzubauen, sollten Sie \"git fetch\"\n" +"Falls Sie vorhaben, Ihre Arbeit auf einem bereits existierenden\n" +"Upstream-Branch aufzubauen, sollten Sie \"git fetch\"\n" "ausführen, um diesen abzurufen.\n" "\n" -"Falls Sie vorhaben, einen neuen lokalen Zweig zu versenden\n" +"Falls Sie vorhaben, einen neuen lokalen Branch zu versenden\n" "der seinem externen Gegenstück folgen soll, können Sie\n" -"\"git push -u\" verwenden, um den externen Übernahmezweig\n" -"beim Versand zu konfigurieren." +"\"git push -u\" verwenden, um den Upstream-Branch beim \"push\"\n" +"zu konfigurieren." -#: branch.c:250 +#: branch.c:265 #, c-format msgid "Not a valid object name: '%s'." msgstr "Ungültiger Objekt-Name: '%s'" -#: branch.c:270 +#: branch.c:285 #, c-format msgid "Ambiguous object name: '%s'." msgstr "mehrdeutiger Objekt-Name: '%s'" -#: branch.c:275 +#: branch.c:290 #, c-format msgid "Not a valid branch point: '%s'." -msgstr "Ungültiger Verzweigungspunkt: '%s'" +msgstr "Ungültiger Branchpunkt: '%s'" -#: branch.c:281 +#: branch.c:296 msgid "Failed to lock ref for update" msgstr "Fehler beim Sperren der Referenz zur Aktualisierung." -#: branch.c:299 +#: branch.c:314 msgid "Failed to write ref" msgstr "Fehler beim Schreiben der Referenz." @@ -271,18 +273,18 @@ 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:676 +#: bundle.c:89 builtin/commit.c:697 #, c-format msgid "could not open '%s'" msgstr "Konnte '%s' nicht öffnen" #: bundle.c:140 msgid "Repository lacks these prerequisite commits:" -msgstr "Dem Projektarchiv fehlen folgende vorausgesetzte Versionen:" +msgstr "Dem Repository fehlen folgende vorausgesetzte Commits:" -#: bundle.c:164 sequencer.c:651 sequencer.c:1101 builtin/log.c:300 -#: builtin/log.c:770 builtin/log.c:1344 builtin/log.c:1570 builtin/merge.c:349 -#: builtin/shortlog.c:155 +#: bundle.c:164 sequencer.c:661 sequencer.c:1111 builtin/log.c:331 +#: builtin/log.c:801 builtin/log.c:1399 builtin/log.c:1625 builtin/merge.c:364 +#: builtin/shortlog.c:156 msgid "revision walk setup failed" msgstr "Einrichtung des Revisionsgangs fehlgeschlagen" @@ -308,7 +310,7 @@ msgstr[1] "Das Paket benötigt diese %d Referenzen:" msgid "rev-list died" msgstr "\"rev-list\" abgebrochen" -#: bundle.c:300 builtin/log.c:1255 builtin/shortlog.c:258 +#: bundle.c:300 builtin/log.c:1310 builtin/shortlog.c:259 #, c-format msgid "unrecognized argument: %s" msgstr "nicht erkanntes Argument: %s" @@ -339,30 +341,30 @@ msgstr "kann '%s' nicht erstellen" msgid "index-pack died" msgstr "Erstellung der Paketindexdatei abgebrochen" -#: commit.c:50 +#: commit.c:53 #, c-format msgid "could not parse %s" msgstr "konnte %s nicht parsen" -#: commit.c:52 +#: commit.c:55 #, c-format msgid "%s %s is not a commit!" -msgstr "%s %s ist keine Version!" +msgstr "%s %s ist kein Commit!" #: compat/obstack.c:406 compat/obstack.c:408 msgid "memory exhausted" msgstr "Speicher verbraucht" -#: connected.c:39 +#: connected.c:60 msgid "Could not run 'git rev-list'" msgstr "Konnte 'git rev-list' nicht ausführen" -#: connected.c:48 +#: connected.c:80 #, c-format msgid "failed write to rev-list: %s" msgstr "Fehler beim Schreiben nach rev-list: %s" -#: connected.c:56 +#: connected.c:88 #, c-format msgid "failed to close rev-list's stdin: %s" msgstr "Fehler beim Schließen von rev-list's Standard-Eingabe: %s" @@ -459,7 +461,7 @@ msgstr "" "Fehler in 'diff.dirstat' Konfigurationsvariable gefunden:\n" "%s" -#: diff.c:3481 +#: diff.c:3487 #, c-format msgid "" "Failed to parse --dirstat/-X option parameter:\n" @@ -468,7 +470,7 @@ msgstr "" "Fehler beim Parsen des --dirstat/-X Optionsparameters:\n" "%s" -#: diff.c:3495 +#: diff.c:3501 #, c-format msgid "Failed to parse --submodule option parameter: '%s'" msgstr "Fehler beim Parsen des --submodule Optionsparameters: '%s'" @@ -510,20 +512,20 @@ msgstr "'%s': %s" msgid "'%s': short read %s" msgstr "'%s': read() zu kurz %s" -#: help.c:212 +#: help.c:210 #, c-format msgid "available git commands in '%s'" msgstr "Vorhandene Git-Kommandos in '%s'" -#: help.c:219 +#: help.c:217 msgid "git commands available from elsewhere on your $PATH" msgstr "Vorhandene Git-Kommandos irgendwo in Ihrem $PATH" -#: help.c:235 +#: help.c:233 msgid "The most commonly used git commands are:" msgstr "Die allgemein verwendeten Git-Kommandos sind:" -#: help.c:292 +#: help.c:290 #, c-format msgid "" "'%s' appears to be a git command, but we were not\n" @@ -532,11 +534,11 @@ msgstr "" "'%s' scheint ein git-Kommando zu sein, konnte aber\n" "nicht ausgeführt werden. Vielleicht ist git-%s fehlerhaft?" -#: help.c:349 +#: help.c:347 msgid "Uh oh. Your system reports no Git commands at all." msgstr "Uh oh. Keine Git-Kommandos auf Ihrem System vorhanden." -#: help.c:371 +#: help.c:369 #, c-format msgid "" "WARNING: You called a Git command named '%s', which does not exist.\n" @@ -545,17 +547,17 @@ msgstr "" "Warnung: Sie haben das nicht existierende Git-Kommando '%s' ausgeführt.\n" "Setze fort unter der Annahme, dass Sie '%s' gemeint haben" -#: help.c:376 +#: help.c:374 #, c-format msgid "in %0.1f seconds automatically..." msgstr "automatisch in %0.1f Sekunden..." -#: help.c:383 +#: help.c:381 #, c-format msgid "git: '%s' is not a git command. See 'git --help'." msgstr "git: '%s' ist kein Git-Kommando. Siehe 'git --help'." -#: help.c:387 +#: help.c:385 help.c:444 msgid "" "\n" "Did you mean this?" @@ -569,89 +571,94 @@ msgstr[1] "" "\n" "Haben Sie eines von diesen gemeint?" +#: help.c:440 +#, c-format +msgid "%s: %s - %s" +msgstr "%s: %s - %s" + #: merge.c:56 msgid "failed to read the cache" msgstr "Lesen des Zwischenspeichers fehlgeschlagen" #: merge.c:110 builtin/checkout.c:365 builtin/checkout.c:566 -#: builtin/clone.c:645 +#: builtin/clone.c:656 msgid "unable to write new index file" -msgstr "Konnte neue Bereitstellungsdatei nicht schreiben." +msgstr "Konnte neue Staging-Area-Datei nicht schreiben." #: merge-recursive.c:190 #, c-format msgid "(bad commit)\n" -msgstr "(ungültige Version)\n" +msgstr "(ungültiger Commit)\n" #: merge-recursive.c:206 #, c-format msgid "addinfo_cache failed for path '%s'" msgstr "addinfo_cache für Pfad '%s' fehlgeschlagen" -#: merge-recursive.c:268 +#: merge-recursive.c:269 msgid "error building trees" -msgstr "Fehler beim Erstellen der Bäume" +msgstr "Fehler beim Erstellen der \"Tree\"-Objekte" -#: merge-recursive.c:672 +#: merge-recursive.c:673 #, c-format msgid "failed to create path '%s'%s" msgstr "Fehler beim Erstellen des Pfades '%s'%s" -#: merge-recursive.c:683 +#: merge-recursive.c:684 #, c-format msgid "Removing %s to make room for subdirectory\n" msgstr "Entferne %s um Platz für Unterverzeichnis zu schaffen\n" #. something else exists #. .. but not some other error (who really cares what?) -#: merge-recursive.c:697 merge-recursive.c:718 +#: merge-recursive.c:698 merge-recursive.c:719 msgid ": perhaps a D/F conflict?" msgstr ": vielleicht ein Verzeichnis/Datei-Konflikt?" -#: merge-recursive.c:708 +#: merge-recursive.c:709 #, c-format msgid "refusing to lose untracked file at '%s'" msgstr "verweigere, da unbeobachtete Dateien in '%s' verloren gehen würden" -#: merge-recursive.c:748 +#: merge-recursive.c:749 #, c-format msgid "cannot read object %s '%s'" msgstr "kann Objekt %s '%s' nicht lesen" -#: merge-recursive.c:750 +#: merge-recursive.c:751 #, c-format msgid "blob expected for %s '%s'" msgstr "Blob erwartet für %s '%s'" -#: merge-recursive.c:773 builtin/clone.c:313 +#: merge-recursive.c:774 builtin/clone.c:312 #, c-format msgid "failed to open '%s'" msgstr "Fehler beim Öffnen von '%s'" -#: merge-recursive.c:781 +#: merge-recursive.c:782 #, c-format msgid "failed to symlink '%s'" -msgstr "Fehler beim Erstellen einer symbolischen Verknüpfung für '%s'" +msgstr "Fehler beim Erstellen eines symbolischen Verweises für '%s'" -#: merge-recursive.c:784 +#: merge-recursive.c:785 #, c-format 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:922 +#: merge-recursive.c:923 msgid "Failed to execute internal merge" -msgstr "Fehler bei Ausführung der internen Zusammenführung" +msgstr "Fehler bei Ausführung des internen Merges" -#: merge-recursive.c:926 +#: merge-recursive.c:927 #, c-format msgid "Unable to add %s to database" msgstr "Konnte %s nicht zur Datenbank hinzufügen" -#: merge-recursive.c:942 +#: merge-recursive.c:943 msgid "unsupported object type in the tree" -msgstr "nicht unterstützter Objekttyp im Baum" +msgstr "nicht unterstützter Objekttyp im Verzeichnis" -#: merge-recursive.c:1021 merge-recursive.c:1035 +#: merge-recursive.c:1022 merge-recursive.c:1036 #, c-format msgid "" "CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left " @@ -660,7 +667,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:1027 merge-recursive.c:1040 +#: merge-recursive.c:1028 merge-recursive.c:1041 #, c-format msgid "" "CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left " @@ -669,174 +676,197 @@ 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:1081 +#: merge-recursive.c:1082 msgid "rename" msgstr "umbenennen" -#: merge-recursive.c:1081 +#: merge-recursive.c:1082 msgid "renamed" msgstr "umbenannt" -#: merge-recursive.c:1137 +#: merge-recursive.c:1138 #, 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:1159 +#: merge-recursive.c:1160 #, c-format msgid "" "CONFLICT (rename/rename): Rename \"%s\"->\"%s\" in branch \"%s\" rename \"%s" "\"->\"%s\" in \"%s\"%s" msgstr "" -"KONFLIKT (umbenennen/umbenennen): Benenne um \"%s\"->\"%s\" in Zweig \"%s\" " -"und \"%s\"->\"%s\" in Zweig \"%s\"%s" +"KONFLIKT (umbenennen/umbenennen): Benenne um \"%s\"->\"%s\" in Branch \"%s\" " +"und \"%s\"->\"%s\" in Branch \"%s\"%s" -#: merge-recursive.c:1164 +#: merge-recursive.c:1165 msgid " (left unresolved)" msgstr " (bleibt unaufgelöst)" -#: merge-recursive.c:1218 +#: merge-recursive.c:1219 #, 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:1248 +#: merge-recursive.c:1249 #, 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:1447 +#: merge-recursive.c:1448 #, 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:1457 +#: merge-recursive.c:1458 #, c-format msgid "Adding merged %s" msgstr "Füge zusammengeführte Datei %s hinzu" -#: merge-recursive.c:1462 merge-recursive.c:1660 +#: merge-recursive.c:1463 merge-recursive.c:1661 #, c-format msgid "Adding as %s instead" msgstr "Füge stattdessen als %s hinzu" -#: merge-recursive.c:1513 +#: merge-recursive.c:1514 #, c-format msgid "cannot read object %s" msgstr "kann Objekt %s nicht lesen" -#: merge-recursive.c:1516 +#: merge-recursive.c:1517 #, c-format msgid "object %s is not a blob" msgstr "Objekt %s ist kein Blob" -#: merge-recursive.c:1564 +#: merge-recursive.c:1565 msgid "modify" msgstr "ändern" -#: merge-recursive.c:1564 +#: merge-recursive.c:1565 msgid "modified" msgstr "geändert" -#: merge-recursive.c:1574 +#: merge-recursive.c:1575 msgid "content" msgstr "Inhalt" -#: merge-recursive.c:1581 +#: merge-recursive.c:1582 msgid "add/add" msgstr "hinzufügen/hinzufügen" -#: merge-recursive.c:1615 +#: merge-recursive.c:1616 #, c-format msgid "Skipped %s (merged same as existing)" -msgstr "%s ausgelassen (Ergebnis der Zusammenführung existiert bereits)" +msgstr "%s ausgelassen (Ergebnis des Merges existiert bereits)" -#: merge-recursive.c:1629 +#: merge-recursive.c:1630 #, c-format msgid "Auto-merging %s" -msgstr "automatische Zusammenführung von %s" +msgstr "automatischer Merge von %s" -#: merge-recursive.c:1633 git-submodule.sh:1029 +#: merge-recursive.c:1634 git-submodule.sh:1118 msgid "submodule" -msgstr "Unterprojekt" +msgstr "Submodul" -#: merge-recursive.c:1634 +#: merge-recursive.c:1635 #, c-format msgid "CONFLICT (%s): Merge conflict in %s" -msgstr "KONFLIKT (%s): Zusammenführungskonflikt in %s" +msgstr "KONFLIKT (%s): Merge-Konflikt in %s" -#: merge-recursive.c:1724 +#: merge-recursive.c:1725 #, c-format msgid "Removing %s" msgstr "Entferne %s" -#: merge-recursive.c:1749 +#: merge-recursive.c:1750 msgid "file/directory" msgstr "Datei/Verzeichnis" -#: merge-recursive.c:1755 +#: merge-recursive.c:1756 msgid "directory/file" msgstr "Verzeichnis/Datei" -#: merge-recursive.c:1760 +#: merge-recursive.c:1761 #, 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:1770 +#: merge-recursive.c:1771 #, c-format msgid "Adding %s" msgstr "Füge %s hinzu" -#: merge-recursive.c:1787 +#: merge-recursive.c:1788 msgid "Fatal merge failure, shouldn't happen." -msgstr "Fataler Fehler bei der Zusammenführung. Sollte nicht passieren." +msgstr "Fataler Merge-Fehler. Sollte nicht passieren." -#: merge-recursive.c:1806 +#: merge-recursive.c:1807 msgid "Already up-to-date!" msgstr "Bereits aktuell!" -#: merge-recursive.c:1815 +#: merge-recursive.c:1816 #, c-format msgid "merging of trees %s and %s failed" -msgstr "Zusammenführen der Bäume %s und %s fehlgeschlagen" +msgstr "Zusammenführen der \"Tree\"-Objekte %s und %s fehlgeschlagen" -#: merge-recursive.c:1845 +#: merge-recursive.c:1846 #, c-format msgid "Unprocessed path??? %s" msgstr "unverarbeiteter Pfad??? %s" -#: merge-recursive.c:1890 +#: merge-recursive.c:1891 msgid "Merging:" -msgstr "Zusammenführung:" +msgstr "Merge:" -#: merge-recursive.c:1903 +#: merge-recursive.c:1904 #, 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" +msgstr[0] "%u gemeinsamen Vorgänger-Commit gefunden" +msgstr[1] "%u gemeinsame Vorgänger-Commits gefunden" -#: merge-recursive.c:1940 +#: merge-recursive.c:1941 msgid "merge returned no commit" -msgstr "Zusammenführung hat keine Version zurückgegeben" +msgstr "Merge hat keinen Commit zurückgegeben" -#: merge-recursive.c:1997 +#: merge-recursive.c:1998 #, c-format msgid "Could not parse object '%s'" msgstr "Konnte Objekt '%s' nicht parsen." -#: merge-recursive.c:2009 builtin/merge.c:658 +#: merge-recursive.c:2010 builtin/merge.c:672 msgid "Unable to write index." -msgstr "Konnte Bereitstellung nicht schreiben." +msgstr "Konnte Staging-Area nicht schreiben." + +#: notes-utils.c:40 +msgid "Cannot commit uninitialized/unreferenced notes tree" +msgstr "" +"Kann uninitialisiertes/unreferenzierte Notiz-Verzeichnis nicht committen." -#: object.c:195 +#: notes-utils.c:81 +#, c-format +msgid "Bad notes.rewriteMode value: '%s'" +msgstr "Ungültiger notes.rewriteMode Wert: '%s'" + +#: notes-utils.c:91 +#, c-format +msgid "Refusing to rewrite notes in %s (outside of refs/notes/)" +msgstr "" +"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 +#: notes-utils.c:118 +#, c-format +msgid "Bad %s value: '%s'" +msgstr "Ungültiger %s Wert: '%s'" + +#: object.c:204 #, c-format msgid "unable to parse object: %s" msgstr "Konnte Objekt '%s' nicht parsen." @@ -869,41 +899,40 @@ msgstr "-NUM" #: pathspec.c:83 #, c-format msgid "Path '%s' is in submodule '%.*s'" -msgstr "Pfad '%s' befindet sich in Unterprojekt '%.*s'" +msgstr "Pfad '%s' befindet sich in Submodul '%.*s'" #: pathspec.c:99 #, c-format msgid "'%s' is beyond a symbolic link" -msgstr "'%s' ist über einem symbolischen Link" +msgstr "'%s' ist hinter einem symbolischen Verweis" -#: remote.c:1781 +#: remote.c:1788 #, c-format msgid "Your branch is ahead of '%s' by %d commit.\n" msgid_plural "Your branch is ahead of '%s' by %d commits.\n" -msgstr[0] "Ihr Zweig ist vor '%s' um %d Version.\n" -msgstr[1] "Ihr Zweig ist vor '%s' um %d Versionen.\n" +msgstr[0] "Ihr Branch ist vor '%s' um %d Commit.\n" +msgstr[1] "Ihr Branch ist vor '%s' um %d Commits.\n" -#: remote.c:1787 +#: remote.c:1794 msgid " (use \"git push\" to publish your local commits)\n" -msgstr " (benutzen Sie \"git push\" um lokalen Versionen herauszubringen)\n" +msgstr " (benutzen Sie \"git push\" um lokale Commits zu publizieren)\n" -#: remote.c:1790 +#: remote.c:1797 #, 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] "" -"Ihr Zweig ist zu '%s' um %d Version hinterher, und kann vorgespult werden.\n" +"Ihr Branch ist zu '%s' um %d Commit hinterher, und kann vorgespult werden.\n" msgstr[1] "" -"Ihr Zweig ist zu '%s' um %d Versionen hinterher, und kann vorgespult " -"werden.\n" +"Ihr Branch ist zu '%s' um %d Commits hinterher, und kann vorgespult werden.\n" -#: remote.c:1798 +#: remote.c:1805 msgid " (use \"git pull\" to update your local branch)\n" msgstr "" -" (benutzen Sie \"git pull\" um Ihren lokalen Zweig zu aktualisieren)\n" +" (benutzen Sie \"git pull\" um Ihren lokalen Branch zu aktualisieren)\n" -#: remote.c:1801 +#: remote.c:1808 #, c-format msgid "" "Your branch and '%s' have diverged,\n" @@ -912,26 +941,35 @@ msgid_plural "" "Your branch and '%s' have diverged,\n" "and have %d and %d different commits each, respectively.\n" msgstr[0] "" -"Ihr Zweig und '%s' sind divergiert,\n" -"und haben jeweils %d und %d unterschiedliche Versionen.\n" +"Ihr Branch und '%s' sind divergiert,\n" +"und haben jeweils %d und %d unterschiedliche Commits.\n" msgstr[1] "" -"Ihr Zweig und '%s' sind divergiert,\n" -"und haben jeweils %d und %d unterschiedliche Versionen.\n" +"Ihr Branch und '%s' sind divergiert,\n" +"und haben jeweils %d und %d unterschiedliche Commits.\n" -#: remote.c:1811 +#: remote.c:1818 msgid " (use \"git pull\" to merge the remote branch into yours)\n" msgstr "" -" (benutzen Sie \"git pull\" um Ihren Zweig mit dem externen " +" (benutzen Sie \"git pull\" um Ihren Branch mit dem Remote-Branch " "zusammenzuführen)\n" -#: sequencer.c:206 builtin/merge.c:776 builtin/merge.c:889 builtin/merge.c:999 -#: builtin/merge.c:1009 +#: run-command.c:80 +msgid "open /dev/null failed" +msgstr "Öffnen von /dev/null fehlgeschlagen" + +#: run-command.c:82 +#, c-format +msgid "dup2(%d,%d) failed" +msgstr "dup2(%d,%d) fehlgeschlagen" + +#: sequencer.c:206 builtin/merge.c:790 builtin/merge.c:903 +#: builtin/merge.c:1013 builtin/merge.c:1023 #, c-format msgid "Could not open '%s' for writing" msgstr "Konnte '%s' nicht zum Schreiben öffnen." -#: sequencer.c:208 builtin/merge.c:335 builtin/merge.c:779 -#: builtin/merge.c:1001 builtin/merge.c:1014 +#: sequencer.c:208 builtin/merge.c:350 builtin/merge.c:793 +#: builtin/merge.c:1015 builtin/merge.c:1028 #, c-format msgid "Could not write to '%s'" msgstr "Konnte nicht nach '%s' schreiben." @@ -954,7 +992,7 @@ msgstr "" "mit 'git add ' oder 'git rm 'und tragen Sie das Ergebnis mit\n" "'git commit' ein" -#: sequencer.c:245 sequencer.c:859 sequencer.c:942 +#: sequencer.c:245 sequencer.c:869 sequencer.c:952 #, c-format msgid "Could not write to %s" msgstr "Konnte nicht nach %s schreiben" @@ -979,396 +1017,421 @@ msgstr "" "Tragen Sie Ihre Änderungen ein oder benutzen Sie \"stash\" um fortzufahren." #. TRANSLATORS: %s will be "revert" or "cherry-pick" -#: sequencer.c:319 +#: sequencer.c:324 #, c-format msgid "%s: Unable to write new index file" -msgstr "%s: Konnte neue Bereitstellungsdatei nicht schreiben" +msgstr "%s: Konnte neue Staging-Area-Datei nicht schreiben" -#: sequencer.c:350 +#: sequencer.c:355 msgid "Could not resolve HEAD commit\n" -msgstr "Konnte Version der Zweigspitze (HEAD) nicht auflösen\n" +msgstr "Konnte Commit von HEAD nicht auflösen\n" -#: sequencer.c:371 +#: sequencer.c:377 msgid "Unable to update cache tree\n" -msgstr "Konnte zwischengespeicherten Baum nicht aktualisieren\n" +msgstr "Konnte Cache-Verzeichnis nicht aktualisieren\n" -#: sequencer.c:416 +#: sequencer.c:422 #, c-format msgid "Could not parse commit %s\n" -msgstr "Konnte Version %s nicht parsen\n" +msgstr "Konnte Commit %s nicht parsen\n" -#: sequencer.c:421 +#: sequencer.c:427 #, c-format msgid "Could not parse parent commit %s\n" -msgstr "Konnte Elternversion %s nicht parsen\n" +msgstr "Konnte Eltern-Commit %s nicht parsen\n" -#: sequencer.c:487 +#: sequencer.c:493 msgid "Your index file is unmerged." -msgstr "Ihre Bereitstellungsdatei ist nicht zusammengeführt." +msgstr "Ihre Staging-Area-Datei ist nicht zusammengeführt." -#: sequencer.c:506 +#: sequencer.c:512 #, 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." +msgstr "Commit %s ist ein Merge, aber die Option -m wurde nicht angegeben." -#: sequencer.c:514 +#: sequencer.c:520 #, c-format msgid "Commit %s does not have parent %d" -msgstr "Version %s hat keinen Elternteil %d" +msgstr "Commit %s hat keinen Elternteil %d" -#: sequencer.c:518 +#: sequencer.c:524 #, c-format msgid "Mainline was specified but commit %s is not a merge." -msgstr "" -"Hauptlinie wurde spezifiziert, aber Version %s ist keine Zusammenführung." +msgstr "Hauptlinie wurde spezifiziert, aber Commit %s ist kein Merge." #. TRANSLATORS: The first %s will be "revert" or #. "cherry-pick", the second %s a SHA1 -#: sequencer.c:531 +#: sequencer.c:537 #, c-format msgid "%s: cannot parse parent commit %s" -msgstr "%s: kann Elternversion %s nicht parsen" +msgstr "%s: kann Eltern-Commit %s nicht parsen" -#: sequencer.c:535 +#: sequencer.c:541 #, c-format msgid "Cannot get commit message for %s" -msgstr "Kann keine Versionsbeschreibung für %s bekommen" +msgstr "Kann keine Commit-Beschreibung für %s bekommen" -#: sequencer.c:621 +#: sequencer.c:627 #, c-format msgid "could not revert %s... %s" -msgstr "Konnte %s nicht zurücknehmen... %s" +msgstr "Konnte \"revert\" nicht auf %s ausführen... %s" -#: sequencer.c:622 +#: sequencer.c:628 #, c-format msgid "could not apply %s... %s" msgstr "Konnte %s nicht anwenden... %s" -#: sequencer.c:654 +#: sequencer.c:664 msgid "empty commit set passed" -msgstr "leere Menge von Versionen übergeben" +msgstr "leere Menge von Commits übergeben" -#: sequencer.c:662 +#: sequencer.c:672 #, c-format msgid "git %s: failed to read the index" -msgstr "git %s: Fehler beim Lesen der Bereitstellung" +msgstr "git %s: Fehler beim Lesen der Staging-Area" -#: sequencer.c:667 +#: sequencer.c:677 #, c-format msgid "git %s: failed to refresh the index" -msgstr "git %s: Fehler beim Aktualisieren der Bereitstellung" +msgstr "git %s: Fehler beim Aktualisieren der Staging-Area" -#: sequencer.c:725 +#: sequencer.c:735 #, c-format msgid "Cannot %s during a %s" msgstr "Kann %s nicht während eines %s durchführen" -#: sequencer.c:747 +#: sequencer.c:757 #, c-format msgid "Could not parse line %d." msgstr "Konnte Zeile %d nicht parsen." -#: sequencer.c:752 +#: sequencer.c:762 msgid "No commits parsed." -msgstr "Keine Versionen geparst." +msgstr "Keine Commits geparst." -#: sequencer.c:765 +#: sequencer.c:775 #, c-format msgid "Could not open %s" msgstr "Konnte %s nicht öffnen" -#: sequencer.c:769 +#: sequencer.c:779 #, c-format msgid "Could not read %s." msgstr "Konnte %s nicht lesen." -#: sequencer.c:776 +#: sequencer.c:786 #, c-format msgid "Unusable instruction sheet: %s" msgstr "Unbenutzbares Instruktionsblatt: %s" -#: sequencer.c:804 +#: sequencer.c:814 #, c-format msgid "Invalid key: %s" msgstr "Ungültiger Schlüssel: %s" -#: sequencer.c:807 +#: sequencer.c:817 #, c-format msgid "Invalid value for %s: %s" msgstr "Ungültiger Wert für %s: %s" -#: sequencer.c:819 +#: sequencer.c:829 #, c-format msgid "Malformed options sheet: %s" msgstr "Fehlerhaftes Optionsblatt: %s" -#: sequencer.c:840 +#: sequencer.c:850 msgid "a cherry-pick or revert is already in progress" msgstr "\"cherry-pick\" oder \"revert\" ist bereits im Gang" -#: sequencer.c:841 +#: sequencer.c:851 msgid "try \"git cherry-pick (--continue | --quit | --abort)\"" msgstr "versuchen Sie \"git cherry-pick (--continue | --quit | --abort)\"" -#: sequencer.c:845 +#: sequencer.c:855 #, c-format msgid "Could not create sequencer directory %s" msgstr "Konnte \"sequencer\"-Verzeichnis %s nicht erstellen" -#: sequencer.c:861 sequencer.c:946 +#: sequencer.c:871 sequencer.c:956 #, c-format msgid "Error wrapping up %s." msgstr "Fehler beim Einpacken von %s." -#: sequencer.c:880 sequencer.c:1014 +#: sequencer.c:890 sequencer.c:1024 msgid "no cherry-pick or revert in progress" msgstr "kein \"cherry-pick\" oder \"revert\" im Gang" -#: sequencer.c:882 +#: sequencer.c:892 msgid "cannot resolve HEAD" -msgstr "kann Zweigspitze (HEAD) nicht auflösen" +msgstr "kann HEAD nicht auflösen" -#: sequencer.c:884 +#: sequencer.c:894 msgid "cannot abort from a branch yet to be born" -msgstr "kann nicht abbrechen: bin auf einem Zweig, der noch geboren wird" +msgstr "kann nicht abbrechen: bin auf einem Branch, der noch geboren wird" -#: sequencer.c:906 builtin/apply.c:4060 +#: sequencer.c:916 builtin/apply.c:4061 #, c-format msgid "cannot open %s: %s" msgstr "Kann %s nicht öffnen: %s" -#: sequencer.c:909 +#: sequencer.c:919 #, c-format msgid "cannot read %s: %s" msgstr "Kann %s nicht lesen: %s" -#: sequencer.c:910 +#: sequencer.c:920 msgid "unexpected end of file" msgstr "Unerwartetes Dateiende" -#: sequencer.c:916 +#: sequencer.c:926 #, 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" +msgstr "gespeicherte \"pre-cherry-pick\" HEAD Datei '%s' ist beschädigt" -#: sequencer.c:939 +#: sequencer.c:949 #, c-format msgid "Could not format %s." msgstr "Konnte %s nicht formatieren." -#: sequencer.c:1083 +#: sequencer.c:1092 #, c-format msgid "%s: can't cherry-pick a %s" msgstr "%s: %s kann nicht in \"cherry-pick\" benutzt werden" -#: sequencer.c:1085 +#: sequencer.c:1095 #, c-format msgid "%s: bad revision" -msgstr "%s: ungültige Revision" +msgstr "%s: ungültiger Commit" -#: sequencer.c:1119 +#: sequencer.c:1129 msgid "Can't revert as initial commit" -msgstr "Rücknahme-Version kann nicht initial sein." +msgstr "Kann nicht als allerersten Commit einen Revert ausführen." -#: sequencer.c:1120 +#: sequencer.c:1130 msgid "Can't cherry-pick into empty head" -msgstr "Kann \"cherry-pick\" nicht in einem leeren Zweig ausführen." +msgstr "Kann nicht als allerersten Commit einen Cherry-Pick ausführen." + +#: sha1_name.c:440 +msgid "" +"Git normally never creates a ref that ends with 40 hex characters\n" +"because it will be ignored when you just specify 40-hex. These refs\n" +"may be created by mistake. For example,\n" +"\n" +" git checkout -b $br $(git rev-parse ...)\n" +"\n" +"where \"$br\" is somehow empty and a 40-hex ref is created. Please\n" +"examine these refs and maybe delete them. Turn this message off by\n" +"running \"git config advice.objectNameWarning false\"" +msgstr "" +"Git erzeugt normalerweise keine Referenzen die mit\n" +"40 Hex-Zeichen enden, da diese ignoriert werden wenn\n" +"Sie diese angeben. Diese Referenzen könnten aus Versehen\n" +"erzeugt worden sein. Zum Beispiel,\n" +"\n" +" git checkout -b $br $(git rev-parse ...)\n" +"\n" +"wobei \"$br\" leer ist und eine 40-Hex-Referenz erzeugt\n" +"wurde. Bitte prüfen Sie diese Referenzen und löschen\n" +"Sie sie gegebenenfalls. Unterdrücken Sie diese Meldung\n" +"indem Sie \"git config advice.objectNameWarning false\"\n" +"ausführen." -#: sha1_name.c:1036 +#: sha1_name.c:1097 msgid "HEAD does not point to a branch" -msgstr "Zweigspitze (HEAD) zeigt auf keinen Zweig" +msgstr "HEAD zeigt auf keinen Branch" -#: sha1_name.c:1039 +#: sha1_name.c:1100 #, c-format msgid "No such branch: '%s'" -msgstr "Kein solcher Zweig '%s'" +msgstr "Kein solcher Branch '%s'" -#: sha1_name.c:1041 +#: sha1_name.c:1102 #, c-format msgid "No upstream configured for branch '%s'" -msgstr "Kein entferntes Projektarchiv für Zweig '%s' konfiguriert." +msgstr "Kein Upstream-Branch für Branch '%s' konfiguriert." -#: sha1_name.c:1044 +#: sha1_name.c:1106 #, c-format msgid "Upstream branch '%s' not stored as a remote-tracking branch" -msgstr "" -"Zweig '%s' des entfernten Projektarchivs ist kein gefolgter Übernahmezweig" +msgstr "Upstream-Branch '%s' ist nicht als Remote-Tracking-Branch gespeichert" #: wrapper.c:408 #, c-format msgid "unable to access '%s': %s" msgstr "konnte nicht auf '%s' zugreifen: %s" -#: wrapper.c:423 +#: wrapper.c:429 #, c-format msgid "unable to access '%s'" msgstr "konnte nicht auf '%s' zugreifen" -#: wrapper.c:434 +#: wrapper.c:440 #, 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:435 +#: wrapper.c:441 msgid "no such user" msgstr "kein solcher Benutzer" -#: wt-status.c:140 +#: wt-status.c:141 msgid "Unmerged paths:" msgstr "Nicht zusammengeführte Pfade:" -#: wt-status.c:167 wt-status.c:194 +#: wt-status.c:168 wt-status.c:195 #, c-format msgid " (use \"git reset %s ...\" to unstage)" msgstr "" -" (benutzen Sie \"git reset %s ...\" zum Herausnehmen aus der " -"Bereitstellung)" +" (benutzen Sie \"git reset %s ...\" zum Entfernen aus der Staging-" +"Area)" -#: wt-status.c:169 wt-status.c:196 +#: wt-status.c:170 wt-status.c:197 msgid " (use \"git rm --cached ...\" to unstage)" msgstr "" -" (benutzen Sie \"git rm --cached ...\" zum Herausnehmen aus der " -"Bereitstellung)" +" (benutzen Sie \"git rm --cached ...\" zum Entfernen aus der Staging-" +"Area)" -#: wt-status.c:173 +#: wt-status.c:174 msgid " (use \"git add ...\" to mark resolution)" msgstr "" " (benutzen Sie \"git add/rm ...\" um die Auflösung zu markieren)" -#: wt-status.c:175 wt-status.c:179 +#: wt-status.c:176 wt-status.c:180 msgid " (use \"git add/rm ...\" as appropriate to mark resolution)" msgstr "" " (benutzen Sie \"git add/rm ...\" um die Auflösung entsprechend zu " "markieren)" -#: wt-status.c:177 +#: wt-status.c:178 msgid " (use \"git rm ...\" to mark resolution)" msgstr "" " (benutzen Sie \"git add/rm ...\" um die Auflösung zu markieren)" -#: wt-status.c:188 +#: wt-status.c:189 msgid "Changes to be committed:" -msgstr "zum Eintragen bereitgestellte Änderungen:" +msgstr "zum Commit vorgemerkte Änderungen:" -#: wt-status.c:206 +#: wt-status.c:207 msgid "Changes not staged for commit:" -msgstr "Änderungen, die nicht zum Eintragen bereitgestellt sind:" +msgstr "Änderungen, die nicht zum Commit vorgemerkt sind:" -#: wt-status.c:210 +#: wt-status.c:211 msgid " (use \"git add ...\" to update what will be committed)" -msgstr " (benutzen Sie \"git add ...\" zum Bereitstellen)" +msgstr "" +" (benutzen Sie \"git add ...\" um die Änderungen zum Commit " +"vorzumerken)" -#: wt-status.c:212 +#: wt-status.c:213 msgid " (use \"git add/rm ...\" to update what will be committed)" -msgstr " (benutzen Sie \"git add/rm ...\" zum Bereitstellen)" +msgstr "" +" (benutzen Sie \"git add/rm ...\" um die Änderungen zum Commit " +"vorzumerken)" -#: wt-status.c:213 +#: wt-status.c:214 msgid "" " (use \"git checkout -- ...\" to discard changes in working directory)" msgstr "" " (benutzen Sie \"git checkout -- ...\" um die Änderungen im " "Arbeitsverzeichnis zu verwerfen)" -#: wt-status.c:215 +#: wt-status.c:216 msgid " (commit or discard the untracked or modified content in submodules)" msgstr "" -" (tragen Sie ein oder verwerfen Sie den unbeobachteten oder geänderten " -"Inhalt in den Unterprojekten)" +" (committen oder verwerfen Sie den unbeobachteten oder geänderten Inhalt in " +"den Submodulen)" -#: wt-status.c:227 +#: wt-status.c:228 #, c-format msgid " (use \"git %s ...\" to include in what will be committed)" -msgstr " (benutzen Sie \"git %s ...\" zum Einfügen in die Eintragung)" +msgstr "" +" (benutzen Sie \"git %s ...\" um die Änderungen zum Commit " +"vorzumerken)" -#: wt-status.c:244 +#: wt-status.c:245 msgid "bug" msgstr "Fehler" -#: wt-status.c:249 +#: wt-status.c:250 msgid "both deleted:" msgstr "beide gelöscht:" -#: wt-status.c:250 +#: wt-status.c:251 msgid "added by us:" msgstr "von uns hinzugefügt:" -#: wt-status.c:251 +#: wt-status.c:252 msgid "deleted by them:" msgstr "von denen gelöscht:" -#: wt-status.c:252 +#: wt-status.c:253 msgid "added by them:" msgstr "von denen hinzugefügt:" -#: wt-status.c:253 +#: wt-status.c:254 msgid "deleted by us:" msgstr "von uns gelöscht:" -#: wt-status.c:254 +#: wt-status.c:255 msgid "both added:" msgstr "von beiden hinzugefügt:" -#: wt-status.c:255 +#: wt-status.c:256 msgid "both modified:" msgstr "von beiden geändert:" -#: wt-status.c:285 +#: wt-status.c:286 msgid "new commits, " -msgstr "neue Versionen, " +msgstr "neue Commits, " -#: wt-status.c:287 +#: wt-status.c:288 msgid "modified content, " msgstr "geänderter Inhalt, " -#: wt-status.c:289 +#: wt-status.c:290 msgid "untracked content, " msgstr "unbeobachteter Inhalt, " -#: wt-status.c:306 +#: wt-status.c:307 #, c-format msgid "new file: %s" msgstr "neue Datei: %s" -#: wt-status.c:309 +#: wt-status.c:310 #, c-format msgid "copied: %s -> %s" msgstr "kopiert: %s -> %s" -#: wt-status.c:312 +#: wt-status.c:313 #, c-format msgid "deleted: %s" msgstr "gelöscht: %s" -#: wt-status.c:315 +#: wt-status.c:316 #, c-format msgid "modified: %s" msgstr "geändert: %s" -#: wt-status.c:318 +#: wt-status.c:319 #, c-format msgid "renamed: %s -> %s" msgstr "umbenannt: %s -> %s" -#: wt-status.c:321 +#: wt-status.c:322 #, c-format msgid "typechange: %s" msgstr "Typänderung: %s" -#: wt-status.c:324 +#: wt-status.c:325 #, c-format msgid "unknown: %s" msgstr "unbekannt: %s" -#: wt-status.c:327 +#: wt-status.c:328 #, c-format msgid "unmerged: %s" msgstr "nicht zusammengeführt: %s" -#: wt-status.c:330 +#: wt-status.c:331 #, c-format msgid "bug: unhandled diff status %c" msgstr "Fehler: unbehandelter Differenz-Status %c" @@ -1377,18 +1440,17 @@ msgstr "Fehler: unbehandelter Differenz-Status %c" msgid "You have unmerged paths." msgstr "Sie haben nicht zusammengeführte Pfade." -#: wt-status.c:806 wt-status.c:958 +#: wt-status.c:806 msgid " (fix conflicts and run \"git commit\")" msgstr " (beheben Sie die Konflikte und führen Sie \"git commit\" aus)" #: wt-status.c:809 msgid "All conflicts fixed but you are still merging." -msgstr "" -"Alle Konflikte sind behoben, aber Sie sind immer noch beim Zusammenführen." +msgstr "Alle Konflikte sind behoben, aber Sie sind immer noch beim Merge." #: wt-status.c:812 msgid " (use \"git commit\" to conclude merge)" -msgstr " (benutzen Sie \"git commit\" um die Zusammenführung abzuschließen)" +msgstr " (benutzen Sie \"git commit\" um den Merge abzuschließen)" #: wt-status.c:822 msgid "You are in the middle of an am session." @@ -1399,28 +1461,28 @@ msgid "The current patch is empty." msgstr "Der aktuelle Patch ist leer." #: wt-status.c:829 -msgid " (fix conflicts and then run \"git am --resolved\")" +msgid " (fix conflicts and then run \"git am --continue\")" msgstr "" -" (beheben Sie die Konflikte und führen Sie dann \"git am --resolved\" aus)" +" (beheben Sie die Konflikte und führen Sie dann \"git am --continue\" aus)" #: wt-status.c:831 msgid " (use \"git am --skip\" to skip this patch)" -msgstr " (benutzen Sie \"git am --skip\" um diesen Patch auszulassen)" +msgstr " (benutzen Sie \"git am --skip\" um diesen Patch auszulassen)" #: wt-status.c:833 msgid " (use \"git am --abort\" to restore the original branch)" msgstr "" -" (benutzen Sie \"git am --abort\" um den ursprünglichen Zweig " +" (benutzen Sie \"git am --abort\" um den ursprünglichen Branch " "wiederherzustellen)" #: wt-status.c:893 wt-status.c:910 #, c-format msgid "You are currently rebasing branch '%s' on '%s'." -msgstr "Sie sind gerade beim Neuaufbau von Zweig '%s' auf '%s'." +msgstr "Sie sind gerade beim Rebase von Branch '%s' auf '%s'." #: wt-status.c:898 wt-status.c:915 msgid "You are currently rebasing." -msgstr "Sie sind gerade beim Neuaufbau." +msgstr "Sie sind gerade beim Rebase." #: wt-status.c:901 msgid " (fix conflicts and then run \"git rebase --continue\")" @@ -1435,7 +1497,7 @@ msgstr " (benutzen Sie \"git rebase --skip\" um diesen Patch auszulassen)" #: wt-status.c:905 msgid " (use \"git rebase --abort\" to check out the original branch)" msgstr "" -" (benutzen Sie \"git rebase --abort\" um den ursprünglichen Zweig " +" (benutzen Sie \"git rebase --abort\" um den ursprünglichen Branch " "auszuchecken)" #: wt-status.c:918 @@ -1447,34 +1509,34 @@ msgstr " (alle Konflikte behoben: führen Sie \"git rebase --continue\" aus)" msgid "" "You are currently splitting a commit while rebasing branch '%s' on '%s'." msgstr "" -"Sie teilen gerade eine Version auf, während ein Neuaufbau von Zweig '%s' auf " +"Sie teilen gerade einen Commit auf, während ein Rebase von Branch '%s' auf " "'%s' im Gange ist." #: wt-status.c:927 msgid "You are currently splitting a commit during a rebase." -msgstr "Sie teilen gerade eine Version während eines Neuaufbaus auf." +msgstr "Sie teilen gerade einen Commit während eines Rebase auf." #: wt-status.c:930 msgid " (Once your working directory is clean, run \"git rebase --continue\")" msgstr "" -" (Sobald Ihr Arbeitsverzeichnis sauber ist, führen Sie \"git rebase --" +" (Sobald Ihr Arbeitsverzeichnis unverändert ist, führen Sie \"git rebase --" "continue\" aus)" #: wt-status.c:934 #, c-format msgid "You are currently editing a commit while rebasing branch '%s' on '%s'." msgstr "" -"Sie editieren gerade eine Version während eines Neuaufbaus von Zweig '%s' " -"auf '%s'." +"Sie editieren gerade einen Commit während eines Rebase von Branch '%s' auf " +"'%s'." #: wt-status.c:939 msgid "You are currently editing a commit during a rebase." -msgstr "Sie editieren gerade eine Version während eines Neuaufbaus." +msgstr "Sie editieren gerade einen Commit während eines Rebase." #: wt-status.c:942 msgid " (use \"git commit --amend\" to amend the current commit)" msgstr "" -" (benutzen Sie \"git commit --amend\" um die aktuelle Version nachzubessern)" +" (benutzen Sie \"git commit --amend\" um den aktuellen Commit nachzubessern)" #: wt-status.c:944 msgid "" @@ -1487,74 +1549,91 @@ msgstr "" msgid "You are currently cherry-picking." msgstr "Sie führen gerade \"cherry-pick\" aus." +#: wt-status.c:958 +msgid " (fix conflicts and run \"git cherry-pick --continue\")" +msgstr "" +" (beheben Sie die Konflikte und führen Sie dann \"git cherry-pick --continue" +"\" aus)" + #: wt-status.c:961 -msgid " (all conflicts fixed: run \"git commit\")" -msgstr " (alle Konflikte behoben: führen Sie \"git commit\" aus)" +msgid " (all conflicts fixed: run \"git cherry-pick --continue\")" +msgstr "" +" (alle Konflikte behoben: führen Sie \"git cherry-pick --continue\" aus)" -#: wt-status.c:970 +#: wt-status.c:963 +msgid " (use \"git cherry-pick --abort\" to cancel the cherry-pick operation)" +msgstr "" +" (benutzen Sie \"git cherry-pick --abort\" um die Cherry-Pick-Operation " +"abzubrechen)" + +#: wt-status.c:972 #, c-format msgid "You are currently reverting commit %s." -msgstr "Sie nehmen gerade Version '%s' zurück." +msgstr "Sie sind gerade an einem Revert von Commit '%s'." -#: wt-status.c:975 +#: wt-status.c:977 msgid " (fix conflicts and run \"git revert --continue\")" msgstr "" " (beheben Sie die Konflikte und führen Sie dann \"git revert --continue\" " "aus)" -#: wt-status.c:978 +#: wt-status.c:980 msgid " (all conflicts fixed: run \"git revert --continue\")" msgstr " (alle Konflikte behoben: führen Sie \"git revert --continue\" aus)" -#: wt-status.c:980 +#: wt-status.c:982 msgid " (use \"git revert --abort\" to cancel the revert operation)" msgstr "" -" (benutzen Sie \"git revert --abort\" um die Umkehroperation abzubrechen)" +" (benutzen Sie \"git revert --abort\" um die Revert-Operation abzubrechen)" -#: wt-status.c:991 +#: wt-status.c:993 #, c-format msgid "You are currently bisecting, started from branch '%s'." -msgstr "Sie sind gerade bei einer binären Suche, gestartet von Zweig '%s'." +msgstr "Sie sind gerade bei einer binären Suche, gestartet von Branch '%s'." -#: wt-status.c:995 +#: wt-status.c:997 msgid "You are currently bisecting." msgstr "Sie sind gerade bei einer binären Suche." -#: wt-status.c:998 +#: wt-status.c:1000 msgid " (use \"git bisect reset\" to get back to the original branch)" msgstr "" -" (benutzen Sie \"git bisect reset\" um zum ursprünglichen Zweig " +" (benutzen Sie \"git bisect reset\" um zum ursprünglichen Branch " "zurückzukehren)" #: wt-status.c:1173 msgid "On branch " -msgstr "Auf Zweig " +msgstr "Auf Branch " -#: wt-status.c:1184 +#: wt-status.c:1180 +msgid "rebase in progress; onto " +msgstr "Rebase im Gange; auf " + +#: wt-status.c:1187 msgid "HEAD detached at " -msgstr "Zweigspitze (HEAD) losgelöst bei " +msgstr "HEAD losgelöst bei " -#: wt-status.c:1186 +#: wt-status.c:1189 msgid "HEAD detached from " -msgstr "Zweigspitze (HEAD) losgelöst von " +msgstr "HEAD losgelöst von " -#: wt-status.c:1189 +#: wt-status.c:1192 msgid "Not currently on any branch." -msgstr "Im Moment auf keinem Zweig." +msgstr "Im Moment auf keinem Branch." -#: wt-status.c:1206 +#: wt-status.c:1209 msgid "Initial commit" -msgstr "Initiale Version" +msgstr "Initialer Commit" -#: wt-status.c:1220 +#: wt-status.c:1223 msgid "Untracked files" msgstr "Unbeobachtete Dateien" -#: wt-status.c:1222 +#: wt-status.c:1225 msgid "Ignored files" msgstr "Ignorierte Dateien" -#: wt-status.c:1226 +#: wt-status.c:1229 #, c-format msgid "" "It took %.2f seconds to enumerate untracked files. 'status -uno'\n" @@ -1565,90 +1644,90 @@ msgstr "" "'status -uno' könnte das beschleunigen, aber Sie müssen darauf achten,\n" "neue Dateien selbstständig hinzuzufügen (siehe 'git help status')." -#: wt-status.c:1232 +#: wt-status.c:1235 #, c-format msgid "Untracked files not listed%s" msgstr "Unbeobachtete Dateien nicht aufgelistet%s" -#: wt-status.c:1234 +#: wt-status.c:1237 msgid " (use -u option to show untracked files)" msgstr " (benutzen Sie die Option -u um unbeobachteten Dateien anzuzeigen)" -#: wt-status.c:1240 +#: wt-status.c:1243 msgid "No changes" msgstr "Keine Änderungen" -#: wt-status.c:1245 +#: wt-status.c:1248 #, c-format msgid "no changes added to commit (use \"git add\" and/or \"git commit -a\")\n" msgstr "" -"keine Änderungen zum Eintragen hinzugefügt (benutzen Sie \"git add\" und/" -"oder \"git commit -a\")\n" +"keine Änderungen zum Commit vorgemerkt (benutzen Sie \"git add\" und/oder " +"\"git commit -a\")\n" -#: wt-status.c:1248 +#: wt-status.c:1251 #, c-format msgid "no changes added to commit\n" -msgstr "keine Änderungen zum Eintragen hinzugefügt\n" +msgstr "keine Änderungen zum Commit vorgemerkt\n" -#: wt-status.c:1251 +#: wt-status.c:1254 #, 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 " -"(benutzen Sie \"git add\" zum Beobachten)\n" +"nichts zum Commit vorgemerkt, aber es gibt unbeobachtete Dateien (benutzen " +"Sie \"git add\" zum Beobachten)\n" -#: wt-status.c:1254 +#: wt-status.c:1257 #, c-format msgid "nothing added to commit but untracked files present\n" -msgstr "nichts zum Eintragen hinzugefügt, aber es gibt unbeobachtete Dateien\n" +msgstr "nichts zum Commit vorgemerkt, aber es gibt unbeobachtete Dateien\n" -#: wt-status.c:1257 +#: wt-status.c:1260 #, c-format msgid "nothing to commit (create/copy files and use \"git add\" to track)\n" msgstr "" -"nichts einzutragen (Erstellen/Kopieren Sie Dateien und benutzen Sie \"git add" -"\" zum Beobachten)\n" +"nichts zu committen (Erstellen/Kopieren Sie Dateien und benutzen Sie \"git " +"add\" zum Beobachten)\n" -#: wt-status.c:1260 wt-status.c:1265 +#: wt-status.c:1263 wt-status.c:1268 #, c-format msgid "nothing to commit\n" -msgstr "nichts einzutragen\n" +msgstr "nichts zu committen\n" -#: wt-status.c:1263 +#: wt-status.c:1266 #, c-format msgid "nothing to commit (use -u to show untracked files)\n" msgstr "" -"nichts einzutragen (benutzen Sie die Option -u, um unbeobachtete Dateien " +"nichts zu committen (benutzen Sie die Option -u, um unbeobachtete Dateien " "anzuzeigen)\n" -#: wt-status.c:1267 +#: wt-status.c:1270 #, c-format msgid "nothing to commit, working directory clean\n" -msgstr "nichts einzutragen, Arbeitsverzeichnis sauber\n" +msgstr "nichts zu committen, Arbeitsverzeichnis unverändert\n" -#: wt-status.c:1375 +#: wt-status.c:1378 msgid "HEAD (no branch)" -msgstr "HEAD (kein Zweig)" +msgstr "HEAD (kein Branch)" -#: wt-status.c:1381 +#: wt-status.c:1384 msgid "Initial commit on " -msgstr "Initiale Version auf " +msgstr "Initialer Commit auf " -#: wt-status.c:1396 +#: wt-status.c:1399 msgid "behind " msgstr "hinterher " -#: wt-status.c:1399 wt-status.c:1402 +#: wt-status.c:1402 wt-status.c:1405 msgid "ahead " msgstr "voraus " -#: wt-status.c:1404 +#: wt-status.c:1407 msgid ", behind " msgstr ", hinterher " -#: compat/precompose_utf8.c:58 builtin/clone.c:352 +#: compat/precompose_utf8.c:58 builtin/clone.c:351 #, c-format msgid "failed to unlink '%s'" msgstr "Konnte '%s' nicht entfernen." @@ -1724,11 +1803,9 @@ msgstr "" "dieser Version von Git ignoriert.\n" "\n" "* 'git add --ignore-removal ', was der aktuelle\n" -" Standardwert ist, ignoriert gelöschte Pfade im Arbeitsverzeichnis." -"\n" +" Standardwert ist, ignoriert gelöschte Pfade im Arbeitsverzeichnis.\n" "* 'git add --all ' berücksichtigt ebenfalls gelöschte\n" -" Pfade." -"\n" +" Pfade.\n" "Führen Sie 'git status' aus, um die gelöschten Pfade zu überprüfen.\n" #: builtin/add.c:144 @@ -1736,7 +1813,7 @@ msgstr "" msgid "unexpected diff status %c" msgstr "unerwarteter Differenz-Status %c" -#: builtin/add.c:149 builtin/commit.c:233 +#: builtin/add.c:149 builtin/commit.c:252 msgid "updating files failed" msgstr "Aktualisierung der Dateien fehlgeschlagen" @@ -1748,147 +1825,146 @@ msgstr "lösche '%s'\n" #: builtin/add.c:253 msgid "Unstaged changes after refreshing the index:" msgstr "" -"Nicht bereitgestellte Änderungen nach Aktualisierung der Bereitstellung:" +"Nicht zum Commit vorgemerkte Änderungen nach Aktualisierung der Staging-Area:" -#: builtin/add.c:256 builtin/add.c:572 builtin/rm.c:275 +#: builtin/add.c:256 builtin/add.c:573 builtin/rm.c:337 #, c-format msgid "pathspec '%s' did not match any files" msgstr "Pfadspezifikation '%s' stimmt mit keinen Dateien überein" #: builtin/add.c:339 msgid "Could not read the index" -msgstr "Konnte die Bereitstellung nicht lesen" +msgstr "Konnte die Staging-Area nicht lesen" -#: builtin/add.c:349 +#: builtin/add.c:350 #, c-format msgid "Could not open '%s' for writing." msgstr "Konnte '%s' nicht zum Schreiben öffnen." -#: builtin/add.c:353 +#: builtin/add.c:354 msgid "Could not write patch" msgstr "Konnte Patch nicht schreiben" -#: builtin/add.c:358 +#: builtin/add.c:359 #, c-format msgid "Could not stat '%s'" msgstr "Konnte Verzeichnis '%s' nicht lesen" -#: builtin/add.c:360 +#: builtin/add.c:361 msgid "Empty patch. Aborted." msgstr "Leerer Patch. Abgebrochen." -#: builtin/add.c:366 +#: builtin/add.c:367 #, c-format msgid "Could not apply '%s'" msgstr "Konnte '%s' nicht anwenden." -#: builtin/add.c:376 +#: builtin/add.c:377 msgid "The following paths are ignored by one of your .gitignore files:\n" msgstr "" "Die folgenden Pfade werden durch eine Ihrer \".gitignore\" Dateien " "ignoriert:\n" -#: builtin/add.c:393 builtin/clean.c:161 builtin/fetch.c:78 builtin/mv.c:63 -#: builtin/prune-packed.c:76 builtin/push.c:425 builtin/remote.c:1253 -#: builtin/rm.c:206 +#: builtin/add.c:394 builtin/clean.c:875 builtin/fetch.c:78 builtin/mv.c:63 +#: builtin/prune-packed.c:73 builtin/push.c:451 builtin/remote.c:1253 +#: builtin/rm.c:268 msgid "dry run" msgstr "Probelauf" -#: builtin/add.c:394 builtin/apply.c:4409 builtin/check-ignore.c:19 -#: builtin/commit.c:1152 builtin/count-objects.c:95 builtin/fsck.c:613 -#: builtin/log.c:1518 builtin/mv.c:62 builtin/read-tree.c:112 +#: builtin/add.c:395 builtin/apply.c:4410 builtin/check-ignore.c:19 +#: builtin/commit.c:1220 builtin/count-objects.c:95 builtin/fsck.c:613 +#: builtin/log.c:1573 builtin/mv.c:62 builtin/read-tree.c:113 msgid "be verbose" msgstr "erweiterte Ausgaben" -#: builtin/add.c:396 +#: builtin/add.c:397 msgid "interactive picking" msgstr "interaktives Auswählen" -#: builtin/add.c:397 builtin/checkout.c:1063 builtin/reset.c:258 +#: builtin/add.c:398 builtin/checkout.c:1073 builtin/reset.c:261 msgid "select hunks interactively" -msgstr "interaktiv Bereiche auswählen" +msgstr "Blöcke interaktiv auswählen" -#: builtin/add.c:398 +#: builtin/add.c:399 msgid "edit current diff and apply" msgstr "aktuelle Unterschiede editieren und anwenden" -#: builtin/add.c:399 +#: builtin/add.c:400 msgid "allow adding otherwise ignored files" msgstr "erlaubt das Hinzufügen andernfalls ignorierter Dateien" -#: builtin/add.c:400 +#: builtin/add.c:401 msgid "update tracked files" msgstr "aktualisiert beobachtete Dateien" -#: builtin/add.c:401 +#: builtin/add.c:402 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:402 +#: builtin/add.c:403 msgid "add changes from all tracked and untracked files" msgstr "" "fügt Änderungen von allen beobachteten und unbeobachteten Dateien hinzu" #. takes no arguments -#: builtin/add.c:405 +#: builtin/add.c:406 msgid "ignore paths removed in the working tree (same as --no-all)" -msgstr "ignoriert gelöschte Pfade im Arbeitsverzeichnis (genau wie " -"--no-all)" +msgstr "ignoriert gelöschte Pfade im Arbeitsverzeichnis (genau wie --no-all)" -#: builtin/add.c:407 +#: builtin/add.c:408 msgid "don't add, only refresh the index" -msgstr "fügt nichts hinzu, aktualisiert nur die Bereitstellung" +msgstr "fügt nichts hinzu, aktualisiert nur die Staging-Area" -#: builtin/add.c:408 +#: builtin/add.c:409 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:409 +#: builtin/add.c:410 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:431 +#: builtin/add.c:432 #, c-format msgid "Use -f if you really want to add them.\n" msgstr "Verwenden Sie -f wenn Sie diese wirklich hinzufügen möchten.\n" -#: builtin/add.c:432 +#: builtin/add.c:433 msgid "no files added" msgstr "keine Dateien hinzugefügt" -#: builtin/add.c:438 +#: builtin/add.c:439 msgid "adding files failed" msgstr "Hinzufügen von Dateien fehlgeschlagen" -#: builtin/add.c:477 +#: builtin/add.c:478 msgid "-A and -u are mutually incompatible" msgstr "Die Optionen -A und -u sind zueinander inkompatibel." -#: builtin/add.c:495 +#: builtin/add.c:496 msgid "Option --ignore-missing can only be used together with --dry-run" msgstr "" "Die Option --ignore-missing kann nur zusammen mit --dry-run verwendet werden." -#: builtin/add.c:525 +#: builtin/add.c:526 #, c-format msgid "Nothing specified, nothing added.\n" msgstr "Nichts spezifiziert, nichts hinzugefügt.\n" -#: builtin/add.c:526 +#: builtin/add.c:527 #, c-format msgid "Maybe you wanted to say 'git add .'?\n" msgstr "Wollten Sie vielleicht 'git add .' sagen?\n" -#: builtin/add.c:532 builtin/check-ignore.c:66 builtin/clean.c:204 -#: builtin/commit.c:293 builtin/mv.c:82 builtin/rm.c:235 +#: builtin/add.c:533 builtin/check-ignore.c:161 builtin/clean.c:919 +#: builtin/commit.c:312 builtin/mv.c:82 builtin/rm.c:297 msgid "index file corrupt" -msgstr "Bereitstellungsdatei beschädigt" +msgstr "Staging-Area-Datei beschädigt" -#: builtin/add.c:604 builtin/apply.c:4505 builtin/mv.c:229 builtin/rm.c:370 +#: builtin/add.c:605 builtin/apply.c:4506 builtin/mv.c:229 builtin/rm.c:432 msgid "Unable to write new index file" -msgstr "Konnte neue Bereitstellungsdatei nicht schreiben." +msgstr "Konnte neue Staging-Area-Datei nicht schreiben." #: builtin/apply.c:57 msgid "git apply [options] [...]" @@ -1897,12 +1973,12 @@ msgstr "git apply [Optionen] [...]" #: builtin/apply.c:110 #, c-format msgid "unrecognized whitespace option '%s'" -msgstr "nicht erkannte Option für Leerzeichen: '%s'" +msgstr "nicht erkannte Whitespace-Option: '%s'" #: builtin/apply.c:125 #, c-format msgid "unrecognized whitespace ignore option '%s'" -msgstr "nicht erkannte Option zum Ignorieren von Leerzeichen: '%s'" +msgstr "nicht erkannte Option zum Ignorieren von Whitespace: '%s'" #: builtin/apply.c:823 #, c-format @@ -2015,7 +2091,7 @@ msgstr "Patch mit nutzlosen Informationen bei Zeile %d" #: builtin/apply.c:2076 #, c-format msgid "unable to read symlink %s" -msgstr "konnte symbolische Verknüpfung %s nicht lesen" +msgstr "konnte symbolischen Verweis %s nicht lesen" #: builtin/apply.c:2080 #, c-format @@ -2075,319 +2151,315 @@ msgstr "Anwendung des Patches fehlgeschlagen: %s:%ld" msgid "cannot checkout %s" msgstr "kann %s nicht auschecken" -#: builtin/apply.c:3140 builtin/apply.c:3149 builtin/apply.c:3193 +#: builtin/apply.c:3140 builtin/apply.c:3149 builtin/apply.c:3194 #, c-format msgid "read of %s failed" msgstr "Konnte %s nicht lesen" -#: builtin/apply.c:3173 builtin/apply.c:3395 +#: builtin/apply.c:3174 builtin/apply.c:3396 #, c-format msgid "path %s has been renamed/deleted" msgstr "Pfad %s wurde umbenannt/gelöscht" -#: builtin/apply.c:3254 builtin/apply.c:3409 +#: builtin/apply.c:3255 builtin/apply.c:3410 #, c-format msgid "%s: does not exist in index" -msgstr "%s ist nicht bereitgestellt" +msgstr "%s ist nicht in der Staging-Area" -#: builtin/apply.c:3258 builtin/apply.c:3401 builtin/apply.c:3423 +#: builtin/apply.c:3259 builtin/apply.c:3402 builtin/apply.c:3424 #, c-format msgid "%s: %s" msgstr "%s: %s" -#: builtin/apply.c:3263 builtin/apply.c:3417 +#: builtin/apply.c:3264 builtin/apply.c:3418 #, c-format msgid "%s: does not match index" -msgstr "%s entspricht nicht der Bereitstellung" +msgstr "%s entspricht nicht der Version in der Staging-Area" -#: builtin/apply.c:3365 +#: builtin/apply.c:3366 msgid "removal patch leaves file contents" msgstr "Lösch-Patch hinterlässt Dateiinhalte" -#: builtin/apply.c:3434 +#: builtin/apply.c:3435 #, c-format msgid "%s: wrong type" msgstr "%s: falscher Typ" -#: builtin/apply.c:3436 +#: builtin/apply.c:3437 #, c-format msgid "%s has type %o, expected %o" msgstr "%s ist vom Typ %o, erwartete %o" -#: builtin/apply.c:3537 +#: builtin/apply.c:3538 #, c-format msgid "%s: already exists in index" msgstr "%s ist bereits bereitgestellt" -#: builtin/apply.c:3540 +#: builtin/apply.c:3541 #, c-format msgid "%s: already exists in working directory" msgstr "%s existiert bereits im Arbeitsverzeichnis" -#: builtin/apply.c:3560 +#: builtin/apply.c:3561 #, 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:3565 +#: builtin/apply.c:3566 #, 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:3573 +#: builtin/apply.c:3574 #, c-format msgid "%s: patch does not apply" msgstr "%s: Patch konnte nicht angewendet werden" -#: builtin/apply.c:3586 +#: builtin/apply.c:3587 #, c-format msgid "Checking patch %s..." msgstr "Prüfe Patch %s..." -#: builtin/apply.c:3679 builtin/checkout.c:216 builtin/reset.c:124 +#: builtin/apply.c:3680 builtin/checkout.c:216 builtin/reset.c:127 #, c-format msgid "make_cache_entry failed for path '%s'" msgstr "make_cache_entry für Pfad '%s' fehlgeschlagen" -#: builtin/apply.c:3822 +#: builtin/apply.c:3823 #, c-format msgid "unable to remove %s from index" -msgstr "konnte %s nicht aus der Bereitstellung entfernen" +msgstr "konnte %s nicht aus der Staging-Area entfernen" -#: builtin/apply.c:3850 +#: builtin/apply.c:3851 #, c-format -msgid "corrupt patch for subproject %s" -msgstr "fehlerhafter Patch für Unterprojekt %s" +msgid "corrupt patch for submodule %s" +msgstr "fehlerhafter Patch für Submodul %s" -#: builtin/apply.c:3854 +#: builtin/apply.c:3855 #, c-format msgid "unable to stat newly created file '%s'" msgstr "konnte neu erstellte Datei '%s' nicht lesen" -#: builtin/apply.c:3859 +#: builtin/apply.c:3860 #, 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:3862 builtin/apply.c:3970 +#: builtin/apply.c:3863 builtin/apply.c:3971 #, 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:3895 +#: builtin/apply.c:3896 #, c-format msgid "closing file '%s'" msgstr "schließe Datei '%s'" -#: builtin/apply.c:3944 +#: builtin/apply.c:3945 #, c-format msgid "unable to write file '%s' mode %o" msgstr "konnte Datei '%s' mit Modus %o nicht schreiben" -#: builtin/apply.c:4031 +#: builtin/apply.c:4032 #, c-format msgid "Applied patch %s cleanly." msgstr "Patch %s sauber angewendet" -#: builtin/apply.c:4039 +#: builtin/apply.c:4040 msgid "internal error" msgstr "interner Fehler" #. Say this even without --verbose -#: builtin/apply.c:4042 +#: builtin/apply.c:4043 #, 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:4052 +#: builtin/apply.c:4053 #, c-format msgid "truncating .rej filename to %.*s.rej" msgstr "Verkürze Name von .rej Datei zu %.*s.rej" -#: builtin/apply.c:4073 +#: builtin/apply.c:4074 #, c-format msgid "Hunk #%d applied cleanly." msgstr "Patch-Bereich #%d sauber angewendet." -#: builtin/apply.c:4076 +#: builtin/apply.c:4077 #, c-format msgid "Rejected hunk #%d." -msgstr "Patch-Bereich #%d zurückgewiesen." +msgstr "Patch-Block #%d zurückgewiesen." -#: builtin/apply.c:4226 +#: builtin/apply.c:4227 msgid "unrecognized input" msgstr "nicht erkannte Eingabe" -#: builtin/apply.c:4237 +#: builtin/apply.c:4238 msgid "unable to read index file" -msgstr "Konnte Bereitstellungsdatei nicht lesen" +msgstr "Konnte Staging-Area-Datei nicht lesen" -#: builtin/apply.c:4356 builtin/apply.c:4359 builtin/clone.c:92 +#: builtin/apply.c:4357 builtin/apply.c:4360 builtin/clone.c:91 #: builtin/fetch.c:63 msgid "path" msgstr "Pfad" -#: builtin/apply.c:4357 +#: builtin/apply.c:4358 msgid "don't apply changes matching the given path" msgstr "wendet keine Änderungen im angegebenen Pfad an" -#: builtin/apply.c:4360 +#: builtin/apply.c:4361 msgid "apply changes matching the given path" msgstr "wendet Änderungen nur im angegebenen Pfad an" -#: builtin/apply.c:4362 +#: builtin/apply.c:4363 msgid "num" msgstr "Anzahl" -#: builtin/apply.c:4363 +#: builtin/apply.c:4364 msgid "remove leading slashes from traditional diff paths" msgstr "" "entfernt vorangestellte Schrägstriche von herkömmlichen " "Differenzpfaden" -#: builtin/apply.c:4366 +#: builtin/apply.c:4367 msgid "ignore additions made by the patch" msgstr "ignoriert hinzugefügte Zeilen des Patches" -#: builtin/apply.c:4368 +#: builtin/apply.c:4369 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:4372 +#: builtin/apply.c:4373 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:4374 +#: builtin/apply.c:4375 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:4376 +#: builtin/apply.c:4377 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:4378 +#: builtin/apply.c:4379 msgid "make sure the patch is applicable to the current index" msgstr "" -"stellt sicher, dass der Patch in der aktuellen Bereitstellung angewendet " +"stellt sicher, dass der Patch in der aktuellen Staging-Area angewendet " "werden kann" -#: builtin/apply.c:4380 +#: builtin/apply.c:4381 msgid "apply a patch without touching the working tree" -msgstr "wendet einen Patch an, ohne Änderungen im Arbeitszweig vorzunehmen" +msgstr "" +"wendet einen Patch an, ohne Änderungen im Arbeitsverzeichnis vorzunehmen" -#: builtin/apply.c:4382 +#: builtin/apply.c:4383 msgid "also apply the patch (use with --stat/--summary/--check)" msgstr "wendet den Patch an (Benutzung mit --stat/--summary/--check)" -#: builtin/apply.c:4384 +#: builtin/apply.c:4385 msgid "attempt three-way merge if a patch does not apply" -msgstr "" -"versucht 3-Wege-Zusammenführung, wenn der Patch nicht angewendet werden " -"konnte" +msgstr "versucht 3-Wege-Merge, wenn der Patch nicht angewendet werden konnte" -#: builtin/apply.c:4386 +#: builtin/apply.c:4387 msgid "build a temporary index based on embedded index information" msgstr "" -"erstellt eine temporäre Bereitstellung basierend auf den integrierten " -"Bereitstellungsinformationen" +"erstellt eine temporäre Staging-Area basierend auf den integrierten Staging-" +"Area-Informationen" -#: builtin/apply.c:4388 builtin/checkout-index.c:197 builtin/ls-files.c:456 +#: builtin/apply.c:4389 builtin/checkout-index.c:197 builtin/ls-files.c:462 msgid "paths are separated with NUL character" msgstr "Pfade sind getrennt durch NUL Zeichen" -#: builtin/apply.c:4391 +#: builtin/apply.c:4392 msgid "ensure at least lines of context match" msgstr "stellt sicher, dass mindestens Zeilen des Kontextes übereinstimmen" -#: builtin/apply.c:4392 +#: builtin/apply.c:4393 msgid "action" msgstr "Aktion" -#: builtin/apply.c:4393 +#: builtin/apply.c:4394 msgid "detect new or modified lines that have whitespace errors" -msgstr "ermittelt neue oder geänderte Zeilen die Fehler in Leerzeichen haben" +msgstr "ermittelt neue oder geänderte Zeilen die Whitespace-Fehler haben" -#: builtin/apply.c:4396 builtin/apply.c:4399 +#: builtin/apply.c:4397 builtin/apply.c:4400 msgid "ignore changes in whitespace when finding context" -msgstr "ignoriert Änderungen in Leerzeichen bei der Suche des Kontextes" +msgstr "ignoriert Änderungen im Whitespace bei der Suche des Kontextes" -#: builtin/apply.c:4402 +#: builtin/apply.c:4403 msgid "apply the patch in reverse" msgstr "wendet den Patch in umgekehrter Reihenfolge an" -#: builtin/apply.c:4404 +#: builtin/apply.c:4405 msgid "don't expect at least one line of context" msgstr "erwartet keinen Kontext" -#: builtin/apply.c:4406 +#: builtin/apply.c:4407 msgid "leave the rejected hunks in corresponding *.rej files" msgstr "" -"hinterlässt zurückgewiesene Patch-Bereiche in den entsprechenden *.rej " -"Dateien" +"hinterlässt zurückgewiesene Patch-Blöcke in entsprechenden *.rej Dateien" -#: builtin/apply.c:4408 +#: builtin/apply.c:4409 msgid "allow overlapping hunks" -msgstr "erlaubt sich überlappende Patch-Bereiche" +msgstr "erlaubt sich überlappende Patch-Blöcke" -#: builtin/apply.c:4411 +#: builtin/apply.c:4412 msgid "tolerate incorrectly detected missing new-line at the end of file" msgstr "toleriert fehlerhaft erkannten fehlenden Zeilenumbruch am Dateiende" -#: builtin/apply.c:4414 +#: builtin/apply.c:4415 msgid "do not trust the line counts in the hunk headers" -msgstr "vertraut nicht den Zeilennummern im Kopf des Patch-Bereiches" +msgstr "vertraut nicht den Zeilennummern im Kopf des Patch-Blocks" -#: builtin/apply.c:4416 +#: builtin/apply.c:4417 msgid "root" msgstr "Wurzelverzeichnis" -#: builtin/apply.c:4417 +#: builtin/apply.c:4418 msgid "prepend to all filenames" msgstr "stellt vor alle Dateinamen" -#: builtin/apply.c:4439 +#: builtin/apply.c:4440 msgid "--3way outside a repository" msgstr "" -"Die Option --3way kann nicht außerhalb eines Projektarchivs verwendet werden." +"Die Option --3way kann nicht außerhalb eines Repositories verwendet werden." -#: builtin/apply.c:4447 +#: builtin/apply.c:4448 msgid "--index outside a repository" msgstr "" -"Die Option --index kann nicht außerhalb eines Projektarchivs verwendet " -"werden." +"Die Option --index kann nicht außerhalb eines Repositories verwendet werden." -#: builtin/apply.c:4450 +#: builtin/apply.c:4451 msgid "--cached outside a repository" msgstr "" -"Die Option --cached kann nicht außerhalb eines Projektarchivs verwendet " -"werden." +"Die Option --cached kann nicht außerhalb eines Repositories verwendet werden." -#: builtin/apply.c:4466 +#: builtin/apply.c:4467 #, c-format msgid "can't open patch '%s'" msgstr "kann Patch '%s' nicht öffnen" -#: builtin/apply.c:4480 +#: builtin/apply.c:4481 #, 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" +msgstr[0] "unterdrückte %d Whitespace-Fehler" +msgstr[1] "unterdrückte %d Whitespace-Fehler" -#: builtin/apply.c:4486 builtin/apply.c:4496 +#: builtin/apply.c:4487 builtin/apply.c:4497 #, c-format msgid "%d line adds whitespace errors." msgid_plural "%d lines add whitespace errors." -msgstr[0] "%d Zeile fügt Fehler in Leerzeichen hinzu." -msgstr[1] "%d Zeilen fügen Fehler in Leerzeichen hinzu." +msgstr[0] "%d Zeile fügt Whitespace-Fehler hinzu." +msgstr[1] "%d Zeilen fügen Whitespace-Fehler hinzu." #: builtin/archive.c:17 #, c-format @@ -2434,106 +2506,106 @@ 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" +msgstr "aktualisiert BISECT_HEAD, anstatt den aktuellen Commit auszuchecken" -#: builtin/blame.c:25 +#: builtin/blame.c:26 msgid "git blame [options] [rev-opts] [rev] [--] file" msgstr "git blame [Optionen] [rev-opts] [rev] [--] Datei" -#: builtin/blame.c:30 +#: builtin/blame.c:31 msgid "[rev-opts] are documented in git-rev-list(1)" msgstr "[rev-opts] sind dokumentiert in git-rev-list(1)" -#: builtin/blame.c:2355 +#: builtin/blame.c:2276 msgid "Show blame entries as we find them, incrementally" msgstr "Zeigt \"blame\"-Einträge schrittweise, während wir sie generieren" -#: builtin/blame.c:2356 +#: builtin/blame.c:2277 msgid "Show blank SHA-1 for boundary commits (Default: off)" -msgstr "Zeigt leere SHA-1 für Grenzversionen (Standard: aus)" +msgstr "Zeigt leere SHA-1 für Grenz-Commits (Standard: aus)" -#: builtin/blame.c:2357 +#: builtin/blame.c:2278 msgid "Do not treat root commits as boundaries (Default: off)" -msgstr "Behandelt Ursprungsversionen nicht als Grenzen (Standard: aus)" +msgstr "Behandelt Ursprungs-Commit nicht als Grenzen (Standard: aus)" -#: builtin/blame.c:2358 +#: builtin/blame.c:2279 msgid "Show work cost statistics" msgstr "Zeigt Statistiken zum Arbeitsaufwand" -#: builtin/blame.c:2359 +#: builtin/blame.c:2280 msgid "Show output score for blame entries" msgstr "Zeigt Ausgabebewertung für \"blame\"-Einträge" -#: builtin/blame.c:2360 +#: builtin/blame.c:2281 msgid "Show original filename (Default: auto)" msgstr "Zeigt ursprünglichen Dateinamen (Standard: auto)" -#: builtin/blame.c:2361 +#: builtin/blame.c:2282 msgid "Show original linenumber (Default: off)" msgstr "Zeigt ursprüngliche Zeilennummer (Standard: aus)" -#: builtin/blame.c:2362 +#: builtin/blame.c:2283 msgid "Show in a format designed for machine consumption" msgstr "Anzeige in einem Format für maschinelle Auswertung" -#: builtin/blame.c:2363 +#: builtin/blame.c:2284 msgid "Show porcelain format with per-line commit information" msgstr "" -"Anzeige in Format für Fremdprogramme mit Versionsinformationen pro Zeile" +"Anzeige in Format für Fremdprogramme mit Commit-Informationen pro Zeile" -#: builtin/blame.c:2364 +#: builtin/blame.c:2285 msgid "Use the same output mode as git-annotate (Default: off)" msgstr "Benutzt den gleichen Ausgabemodus wie \"git-annotate\" (Standard: aus)" -#: builtin/blame.c:2365 +#: builtin/blame.c:2286 msgid "Show raw timestamp (Default: off)" msgstr "Zeigt unbearbeiteten Zeitstempel (Standard: aus)" -#: builtin/blame.c:2366 +#: builtin/blame.c:2287 msgid "Show long commit SHA1 (Default: off)" -msgstr "Zeigt langen Versions-SHA1 (Standard: aus)" +msgstr "Zeigt langen Commit-SHA1 (Standard: aus)" -#: builtin/blame.c:2367 +#: builtin/blame.c:2288 msgid "Suppress author name and timestamp (Default: off)" msgstr "Unterdrückt den Namen des Autors und den Zeitstempel (Standard: aus)" -#: builtin/blame.c:2368 +#: builtin/blame.c:2289 msgid "Show author email instead of name (Default: off)" msgstr "Zeigt anstatt des Namens die Email-Adresse des Autors (Standard: aus)" -#: builtin/blame.c:2369 +#: builtin/blame.c:2290 msgid "Ignore whitespace differences" -msgstr "Ignoriert Unterschiede in Leerzeichen" +msgstr "Ignoriert Unterschiede im Whitespace" -#: builtin/blame.c:2370 +#: builtin/blame.c:2291 msgid "Spend extra cycles to find better match" msgstr "arbeite länger, um bessere Übereinstimmungen zu finden" -#: builtin/blame.c:2371 +#: builtin/blame.c:2292 msgid "Use revisions from instead of calling git-rev-list" -msgstr "Benutzt Revisionen von anstatt \"git-rev-list\" aufzurufen" +msgstr "Benutzt Commits von anstatt \"git-rev-list\" aufzurufen" -#: builtin/blame.c:2372 +#: builtin/blame.c:2293 msgid "Use 's contents as the final image" msgstr "Benutzt Inhalte der en als entgültiges Abbild" -#: builtin/blame.c:2373 builtin/blame.c:2374 +#: builtin/blame.c:2294 builtin/blame.c:2295 msgid "score" msgstr "Bewertung" -#: builtin/blame.c:2373 +#: builtin/blame.c:2294 msgid "Find line copies within and across files" msgstr "Findet kopierte Zeilen innerhalb oder zwischen Dateien" -#: builtin/blame.c:2374 +#: builtin/blame.c:2295 msgid "Find line movements within and across files" msgstr "Findet verschobene Zeilen innerhalb oder zwischen Dateien" -#: builtin/blame.c:2375 +#: builtin/blame.c:2296 msgid "n,m" msgstr "n,m" -#: builtin/blame.c:2375 +#: builtin/blame.c:2296 msgid "Process only line range n,m, counting from 1" msgstr "Verarbeitet nur Zeilen im Bereich n,m, gezählt von 1" @@ -2543,15 +2615,15 @@ msgstr "git branch [Optionen] [-r | -a] [--merged | --no-merged]" #: builtin/branch.c:25 msgid "git branch [options] [-l] [-f] []" -msgstr "git branch [Optionen] [-l] [-f] []" +msgstr "git branch [Optionen] [-l] [-f] []" #: builtin/branch.c:26 msgid "git branch [options] [-r] (-d | -D) ..." -msgstr "git branch [Optionen] [-r] (-d | -D) ..." +msgstr "git branch [Optionen] [-r] (-d | -D) ..." #: builtin/branch.c:27 msgid "git branch [options] (-m | -M) [] " -msgstr "git branch [Optionen] (-m | -M) [] " +msgstr "git branch [Optionen] (-m | -M) [] " #: builtin/branch.c:150 #, c-format @@ -2559,9 +2631,8 @@ msgid "" "deleting branch '%s' that has been merged to\n" " '%s', but not yet merged to HEAD." msgstr "" -"entferne Zweig '%s', der zusammengeführt wurde mit\n" -" '%s', aber noch nicht mit der Zweigspitze (HEAD) zusammengeführt " -"wurde." +"entferne Branch '%s', der zusammengeführt wurde mit\n" +" '%s', aber noch nicht mit HEAD zusammengeführt wurde." #: builtin/branch.c:154 #, c-format @@ -2569,13 +2640,13 @@ msgid "" "not deleting branch '%s' that is not yet merged to\n" " '%s', even though it is merged to HEAD." msgstr "" -"entferne Zweig '%s' nicht, der noch nicht zusammengeführt wurde mit\n" -" '%s', obwohl er mit der Zweigspitze (HEAD) zusammengeführt wurde." +"entferne Branch '%s' nicht, der noch nicht zusammengeführt wurde mit\n" +" '%s', obwohl er mit HEAD zusammengeführt wurde." #: builtin/branch.c:168 #, c-format msgid "Couldn't look up commit object for '%s'" -msgstr "Konnte Versionsobjekt für '%s' nicht nachschlagen." +msgstr "Konnte Commit-Objekt für '%s' nicht nachschlagen." #: builtin/branch.c:172 #, c-format @@ -2583,8 +2654,8 @@ 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 Sie sicher sind diesen Zweig zu entfernen, führen Sie 'git branch -D " +"Der Branch '%s' ist nicht vollständig zusammengeführt.\n" +"Wenn Sie sicher sind diesen Branch zu entfernen, führen Sie 'git branch -D " "%s' aus." #: builtin/branch.c:185 @@ -2597,48 +2668,48 @@ msgstr "kann -a nicht mit -d benutzen" #: builtin/branch.c:219 msgid "Couldn't look up commit object for HEAD" -msgstr "Konnte Versionsobjekt für Zweigspitze (HEAD) nicht nachschlagen." +msgstr "Konnte Commit-Objekt für HEAD nicht nachschlagen." #: builtin/branch.c:227 #, c-format msgid "Cannot delete the branch '%s' which you are currently on." msgstr "" -"Kann Zweig '%s' nicht entfernen, da Sie sich gerade auf diesem befinden." +"Kann Branch '%s' nicht entfernen, da Sie sich gerade auf diesem befinden." #: builtin/branch.c:240 #, c-format msgid "remote branch '%s' not found." -msgstr "externer Zweig '%s' nicht gefunden" +msgstr "Remote-Branch '%s' nicht gefunden" #: builtin/branch.c:241 #, c-format msgid "branch '%s' not found." -msgstr "Zweig '%s' nicht gefunden." +msgstr "Branch '%s' nicht gefunden." #: builtin/branch.c:255 #, c-format msgid "Error deleting remote branch '%s'" -msgstr "Fehler beim Entfernen des externen Zweiges '%s'" +msgstr "Fehler beim Entfernen des Remote-Branches '%s'" #: builtin/branch.c:256 #, c-format msgid "Error deleting branch '%s'" -msgstr "Fehler beim Entfernen des Zweiges '%s'" +msgstr "Fehler beim Entfernen des Branches '%s'" #: builtin/branch.c:263 #, c-format msgid "Deleted remote branch %s (was %s).\n" -msgstr "Externer Zweig %s entfernt (war %s).\n" +msgstr "Remote-Branch %s entfernt (war %s).\n" #: builtin/branch.c:264 #, c-format msgid "Deleted branch %s (was %s).\n" -msgstr "Zweig %s entfernt (war %s).\n" +msgstr "Branch %s entfernt (war %s).\n" #: builtin/branch.c:366 #, c-format msgid "branch '%s' does not point at a commit" -msgstr "Zweig '%s' zeigt auf keine Version" +msgstr "Branch '%s' zeigt auf keinen Commit" #: builtin/branch.c:453 #, c-format @@ -2677,12 +2748,12 @@ msgstr " **** ungültige Referenz ****" #: builtin/branch.c:582 #, c-format msgid "(no branch, rebasing %s)" -msgstr "(kein Zweig, Neuaufbau von Zweig %s im Gange)" +msgstr "(kein Branch, Rebase von Branch %s im Gange)" #: builtin/branch.c:585 #, c-format msgid "(no branch, bisect started on %s)" -msgstr "(kein Zweig, Neuaufbau begonnen bei %s)" +msgstr "(kein Branch, binäre Suche begonnen bei %s)" #: builtin/branch.c:588 #, c-format @@ -2691,12 +2762,12 @@ msgstr "(losgelöst von %s)" #: builtin/branch.c:591 msgid "(no branch)" -msgstr "(kein Zweig)" +msgstr "(kein Branch)" #: builtin/branch.c:637 #, c-format msgid "object '%s' does not point to a commit" -msgstr "Objekt '%s' zeigt auf keine Version" +msgstr "Objekt '%s' zeigt auf keinen Commit" #: builtin/branch.c:669 msgid "some refs could not be read" @@ -2705,31 +2776,31 @@ msgstr "Konnte einige Referenzen nicht lesen" #: builtin/branch.c:682 msgid "cannot rename the current branch while not on any." msgstr "" -"Kann aktuellen Zweig nicht umbenennen, solange Sie sich auf keinem befinden." +"Kann aktuellen Branch nicht umbenennen, solange Sie sich auf keinem befinden." #: builtin/branch.c:692 #, c-format msgid "Invalid branch name: '%s'" -msgstr "Ungültiger Zweig-Name: '%s'" +msgstr "Ungültiger Branchname: '%s'" #: builtin/branch.c:707 msgid "Branch rename failed" -msgstr "Umbenennung des Zweiges fehlgeschlagen" +msgstr "Umbenennung des Branches fehlgeschlagen" #: builtin/branch.c:711 #, c-format msgid "Renamed a misnamed branch '%s' away" -msgstr "falsch benannten Zweig '%s' umbenannt" +msgstr "falsch benannten Branch '%s' umbenannt" #: builtin/branch.c:715 #, c-format msgid "Branch renamed to %s, but HEAD is not updated!" -msgstr "Zweig umbenannt zu %s, aber Zweigspitze (HEAD) ist nicht aktualisiert!" +msgstr "Branch umbenannt zu %s, aber HEAD ist nicht aktualisiert!" #: builtin/branch.c:722 msgid "Branch is renamed, but update of config-file failed" msgstr "" -"Zweig ist umbenannt, aber die Aktualisierung der Konfigurationsdatei ist " +"Branch ist umbenannt, aber die Aktualisierung der Konfigurationsdatei ist " "fehlgeschlagen." #: builtin/branch.c:737 @@ -2740,7 +2811,7 @@ msgstr "Missgebildeter Objektname %s" #: builtin/branch.c:761 #, c-format msgid "could not write branch description template: %s" -msgstr "Konnte Beschreibungsvorlage für Zweig nicht schreiben: %s" +msgstr "Konnte Beschreibungsvorlage für Branch nicht schreiben: %s" #: builtin/branch.c:791 msgid "Generic options" @@ -2748,7 +2819,7 @@ msgstr "Allgemeine Optionen" #: builtin/branch.c:793 msgid "show hash and subject, give twice for upstream branch" -msgstr "Zeigt Hash und Betreff; -vv: zusätzlich externen Übernahmezweig" +msgstr "Zeigt Hash und Betreff; -vv: zusätzlich Upstream-Branch" #: builtin/branch.c:794 msgid "suppress informational messages" @@ -2760,7 +2831,7 @@ msgstr "stellt den Übernahmemodus ein (siehe git-pull(1))" #: builtin/branch.c:797 msgid "change upstream info" -msgstr "ändert Informationen zum externen Übernahmezweig" +msgstr "ändert Informationen zum Upstream-Branch" #: builtin/branch.c:801 msgid "use colored output" @@ -2768,17 +2839,17 @@ msgstr "verwendet farbliche Ausgaben" #: builtin/branch.c:802 msgid "act on remote-tracking branches" -msgstr "wirkt auf externe Übernahmezweige" +msgstr "wirkt auf Remote-Tracking-Branches" #: builtin/branch.c:805 builtin/branch.c:811 builtin/branch.c:832 -#: builtin/branch.c:838 builtin/commit.c:1368 builtin/commit.c:1369 -#: builtin/commit.c:1370 builtin/commit.c:1371 builtin/tag.c:468 +#: builtin/branch.c:838 builtin/commit.c:1433 builtin/commit.c:1434 +#: builtin/commit.c:1435 builtin/commit.c:1436 builtin/tag.c:468 msgid "commit" -msgstr "Version" +msgstr "Commit" #: builtin/branch.c:806 builtin/branch.c:812 msgid "print only branches that contain the commit" -msgstr "gibt nur Zweige aus, welche diese Version beinhalten" +msgstr "gibt nur Branches aus, welche diesen Commit beinhalten" #: builtin/branch.c:818 msgid "Specific git-branch actions:" @@ -2786,60 +2857,60 @@ msgstr "spezifische Aktionen für \"git-branch\":" #: builtin/branch.c:819 msgid "list both remote-tracking and local branches" -msgstr "listet externe Übernahmezweige und lokale Zweige auf" +msgstr "listet Remote-Tracking und lokale Branches auf" #: builtin/branch.c:821 msgid "delete fully merged branch" -msgstr "entfernt vollständig zusammengeführten Zweig" +msgstr "entfernt vollständig zusammengeführten Branch" #: builtin/branch.c:822 msgid "delete branch (even if not merged)" -msgstr "löscht Zweig (auch wenn nicht zusammengeführt)" +msgstr "löscht Branch (auch wenn nicht zusammengeführt)" #: builtin/branch.c:823 msgid "move/rename a branch and its reflog" -msgstr "verschiebt/benennt einen Zweig und dessen Referenzprotokoll um" +msgstr "verschiebt/benennt einen Branch und dessen Reflog um" #: builtin/branch.c:824 msgid "move/rename a branch, even if target exists" msgstr "" -"verschiebt/benennt einen Zweig um, auch wenn das Ziel bereits existiert" +"verschiebt/benennt einen Branch um, auch wenn das Ziel bereits existiert" #: builtin/branch.c:825 msgid "list branch names" -msgstr "listet Zweignamen auf" +msgstr "listet Branchnamen auf" #: builtin/branch.c:826 msgid "create the branch's reflog" -msgstr "erzeugt das Referenzprotokoll des Zweiges" +msgstr "erzeugt das Reflog des Branches" #: builtin/branch.c:828 msgid "edit the description for the branch" -msgstr "bearbeitet die Beschreibung für den Zweig" +msgstr "bearbeitet die Beschreibung für den Branch" #: builtin/branch.c:829 msgid "force creation (when already exists)" -msgstr "erzeuge auch, wenn der Zweig bereits existiert" +msgstr "erzeuge auch, wenn der Branch bereits existiert" #: builtin/branch.c:832 msgid "print only not merged branches" -msgstr "gibt nur Zweige aus, die nicht zusammengeführt sind" +msgstr "gibt nur Branches aus, die nicht zusammengeführt sind" #: builtin/branch.c:838 msgid "print only merged branches" -msgstr "gibt nur Zweige aus, die zusammengeführt sind" +msgstr "gibt nur Branches aus, die zusammengeführt sind" #: builtin/branch.c:842 msgid "list branches in columns" -msgstr "listet Zweige in Spalten auf" +msgstr "listet Branches in Spalten auf" #: builtin/branch.c:855 msgid "Failed to resolve HEAD as a valid ref." -msgstr "Konnte Zweigspitze (HEAD) nicht als gültige Referenz auflösen." +msgstr "Konnte HEAD nicht als gültige Referenz auflösen." -#: builtin/branch.c:860 builtin/clone.c:619 +#: builtin/branch.c:860 builtin/clone.c:630 msgid "HEAD not found below refs/heads!" -msgstr "Zweigspitze (HEAD) wurde nicht unter \"refs/heads\" gefunden!" +msgstr "HEAD wurde nicht unter \"refs/heads\" gefunden!" #: builtin/branch.c:883 msgid "--column and --verbose are incompatible" @@ -2847,68 +2918,67 @@ msgstr "Die Optionen --column und --verbose sind inkompatibel." #: builtin/branch.c:889 builtin/branch.c:928 msgid "branch name required" -msgstr "Zweigname erforderlich" +msgstr "Branchname erforderlich" #: builtin/branch.c:904 msgid "Cannot give description to detached HEAD" -msgstr "" -"zu losgelöster Zweigspitze (HEAD) kann keine Beschreibung hinterlegt werden" +msgstr "zu losgelöstem HEAD kann keine Beschreibung hinterlegt werden" #: builtin/branch.c:909 msgid "cannot edit description of more than one branch" -msgstr "Beschreibung von mehr als einem Zweig kann nicht bearbeitet werden" +msgstr "Beschreibung von mehr als einem Branch kann nicht bearbeitet werden" #: builtin/branch.c:916 #, c-format msgid "No commit on branch '%s' yet." -msgstr "Noch keine Version in Zweig '%s'." +msgstr "Noch kein Commit in Branch '%s'." #: builtin/branch.c:919 #, c-format msgid "No branch named '%s'." -msgstr "Zweig '%s' nicht vorhanden." +msgstr "Branch '%s' nicht vorhanden." #: builtin/branch.c:934 msgid "too many branches for a rename operation" -msgstr "zu viele Zweige für eine Umbenennen-Operation angegeben" +msgstr "zu viele Branches für eine Umbenennen-Operation angegeben" #: builtin/branch.c:939 msgid "too many branches to set new upstream" -msgstr "zu viele Zweige angegeben um neuen Übernahmezweig zu setzen" +msgstr "zu viele Branches angegeben um Upstream-Branch zu setzen" #: builtin/branch.c:943 #, c-format msgid "" "could not set upstream of HEAD to %s when it does not point to any branch." msgstr "" -"Konnte keinen neuen Übernahmezweig von Zweigspitze (HEAD) zu %s setzen,\n" -"da diese auf keinen Zweig zeigt." +"Konnte keinen neuen Upstream-Branch von HEAD zu %s setzen, da dieser auf\n" +"keinen Branch zeigt." #: builtin/branch.c:946 builtin/branch.c:968 builtin/branch.c:990 #, c-format msgid "no such branch '%s'" -msgstr "Kein solcher Zweig '%s'" +msgstr "Kein solcher Branch '%s'" #: builtin/branch.c:950 #, c-format msgid "branch '%s' does not exist" -msgstr "Zweig '%s' existiert nicht" +msgstr "Branch '%s' existiert nicht" #: builtin/branch.c:962 msgid "too many branches to unset upstream" msgstr "" -"zu viele Zweige angegeben um Konfiguration zu Übernahmezweig zu entfernen" +"zu viele Branches angegeben um Konfiguration zu Upstream-Branch zu entfernen" #: builtin/branch.c:966 msgid "could not unset upstream of HEAD when it does not point to any branch." msgstr "" -"Konnte Konfiguration zum Übernahmezweig von Zweigspitze (HEAD) nicht\n" -"entfernen, da diese auf keinen Zweig zeigt." +"Konnte Konfiguration zu Upstream-Branch von HEAD nicht entfernen, da dieser\n" +"auf keinen Branch zeigt." #: builtin/branch.c:972 #, c-format msgid "Branch '%s' has no upstream information" -msgstr "Zweig '%s' hat keinen externen Übernahmezweig gesetzt" +msgstr "Branch '%s' hat keinen Upstream-Branch gesetzt" #: builtin/branch.c:987 msgid "it does not make sense to create 'HEAD' manually" @@ -2918,7 +2988,7 @@ msgstr "'HEAD' darf nicht manuell erstellt werden" msgid "-a and -r options to 'git branch' do not make sense with a branch name" msgstr "" "Die Optionen -a und -r bei 'git branch' können nicht gemeimsam mit einem " -"Zweignamen verwendet werden." +"Branchnamen verwendet werden." #: builtin/branch.c:996 #, c-format @@ -2937,8 +3007,8 @@ msgid "" "\n" msgstr "" "\n" -"Wenn Sie wollten, dass '%s' den Zweig '%s' als externen Übernahmezweig hat, " -"führen Sie aus:\n" +"Wenn Sie wollten, dass '%s' den Branch '%s' als Upstream-Branch hat, führen " +"Sie aus:\n" #: builtin/branch.c:1014 #, c-format @@ -2957,51 +3027,51 @@ msgstr "%s ist in Ordnung\n" #: builtin/bundle.c:56 msgid "Need a repository to create a bundle." -msgstr "Um ein Paket zu erstellen wird ein Projektarchiv benötigt." +msgstr "Um ein Paket zu erstellen wird ein Repository benötigt." #: builtin/bundle.c:60 msgid "Need a repository to unbundle." -msgstr "Zum Entpacken wird ein Projektarchiv benötigt." +msgstr "Zum Entpacken wird ein Repository benötigt." -#: builtin/cat-file.c:176 +#: builtin/cat-file.c:285 msgid "git cat-file (-t|-s|-e|-p||--textconv) " msgstr "git cat-file (-t|-s|-e|-p||--textconv) " -#: builtin/cat-file.c:177 +#: builtin/cat-file.c:286 msgid "git cat-file (--batch|--batch-check) < " msgstr "git cat-file (--batch|--batch-check) < " -#: builtin/cat-file.c:195 +#: builtin/cat-file.c:323 msgid " can be one of: blob, tree, commit, tag" msgstr " kann sein: blob, tree, commit, tag" -#: builtin/cat-file.c:196 +#: builtin/cat-file.c:324 msgid "show object type" msgstr "zeigt Objektart" -#: builtin/cat-file.c:197 +#: builtin/cat-file.c:325 msgid "show object size" msgstr "zeigt Objektgröße" -#: builtin/cat-file.c:199 +#: builtin/cat-file.c:327 msgid "exit with zero when there's no error" msgstr "beendet mit Rückgabewert 0, wenn kein Fehler aufgetreten ist" -#: builtin/cat-file.c:200 +#: builtin/cat-file.c:328 msgid "pretty-print object's content" msgstr "ansprechende Anzeige des Objektinhaltes" -#: builtin/cat-file.c:202 +#: builtin/cat-file.c:330 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:204 +#: builtin/cat-file.c:332 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:207 +#: builtin/cat-file.c:335 msgid "show info about objects fed from the standard input" msgstr "" "Anzeige von Informationen über Objekte, gelesen von der Standard-Eingabe" @@ -3021,7 +3091,7 @@ 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" +msgstr "verwendet .gitattributes nur von der Staging-Area" #: builtin/check-attr.c:21 builtin/check-ignore.c:22 builtin/hash-object.c:75 msgid "read file names from stdin" @@ -3031,38 +3101,63 @@ msgstr "liest Dateinamen von der Standard-Eingabe" msgid "input paths are terminated by a null character" msgstr "Eingabepfade sind durch ein NUL Zeichen abgeschlossen" -#: builtin/check-ignore.c:18 builtin/checkout.c:1044 builtin/gc.c:177 +#: builtin/check-ignore.c:18 builtin/checkout.c:1054 builtin/gc.c:177 msgid "suppress progress reporting" msgstr "unterdrückt Fortschrittsanzeige" -#: builtin/check-ignore.c:146 +#: builtin/check-ignore.c:26 +msgid "show non-matching input paths" +msgstr "zeigt Eingabe-Pfade ohne Übereinstimmungen" + +#: builtin/check-ignore.c:143 msgid "cannot specify pathnames with --stdin" msgstr "Angabe von Pfadnamen kann nicht gemeinsam mit --stdin verwendet werden" -#: builtin/check-ignore.c:149 +#: builtin/check-ignore.c:146 msgid "-z only makes sense with --stdin" msgstr "Die Option -z kann nur mit --stdin verwendet werden." -#: builtin/check-ignore.c:151 +#: builtin/check-ignore.c:148 msgid "no path specified" msgstr "kein Pfad angegeben" -#: builtin/check-ignore.c:155 +#: builtin/check-ignore.c:152 msgid "--quiet is only valid with a single pathname" msgstr "Die Option --quiet ist nur mit einem einzelnen Pfadnamen gültig." -#: builtin/check-ignore.c:157 +#: builtin/check-ignore.c:154 msgid "cannot have both --quiet and --verbose" msgstr "" "Die Optionen --quiet und --verbose können nicht gemeinsam verwendet werden." +#: builtin/check-ignore.c:157 +msgid "--non-matching is only valid with --verbose" +msgstr "--non-matching ist nur mit --verbose zulässig" + +#: builtin/check-mailmap.c:8 +msgid "git check-mailmap [options] ..." +msgstr "git check-mailmap [Optionen] ..." + +#: builtin/check-mailmap.c:13 +msgid "also read contacts from stdin" +msgstr "liest ebenfalls Kontakte von der Standard-Eingabe" + +#: builtin/check-mailmap.c:24 +#, c-format +msgid "unable to parse contact: %s" +msgstr "Konnte Kontakt '%s' nicht parsen." + +#: builtin/check-mailmap.c:47 +msgid "no contacts specified" +msgstr "keine Kontakte angegeben" + #: builtin/checkout-index.c:126 msgid "git checkout-index [options] [--] [...]" msgstr "git checkout-index [Optionen] [--] [...]" #: builtin/checkout-index.c:187 msgid "check out all files in the index" -msgstr "checkt alle Dateien in der Bereitstellung aus" +msgstr "checkt alle Dateien in der Staging-Area aus" #: builtin/checkout-index.c:188 msgid "force overwrite of existing files" @@ -3072,7 +3167,7 @@ msgstr "erzwingt das Überschreiben bereits existierender Dateien" 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" +"Staging-Area befinden" #: builtin/checkout-index.c:192 msgid "don't checkout new files" @@ -3080,7 +3175,7 @@ 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" +msgstr "aktualisiert Dateiinformationen in der Staging-Area-Datei" #: builtin/checkout-index.c:200 msgid "read list of paths from the standard input" @@ -3105,11 +3200,11 @@ msgstr "kopiert Dateien von dem benannten Stand" #: builtin/checkout.c:25 msgid "git checkout [options] " -msgstr "git checkout [Optionen] " +msgstr "git checkout [Optionen] " #: builtin/checkout.c:26 msgid "git checkout [options] [] -- ..." -msgstr "git checkout [Optionen] [Zweig>] -- ..." +msgstr "git checkout [Optionen] [] -- ..." #: builtin/checkout.c:117 builtin/checkout.c:150 #, c-format @@ -3139,7 +3234,7 @@ msgstr "Pfad '%s': kann nicht zusammenführen" #: builtin/checkout.c:213 #, c-format msgid "Unable to add merge result for '%s'" -msgstr "Konnte Ergebnis der Zusammenführung von '%s' nicht hinzufügen." +msgstr "Konnte Merge-Ergebnis von '%s' nicht hinzufügen." #: builtin/checkout.c:237 builtin/checkout.c:240 builtin/checkout.c:243 #: builtin/checkout.c:246 @@ -3155,11 +3250,12 @@ msgstr "'%s' kann nicht mit '%s' verwendet werden" #: builtin/checkout.c:255 #, c-format msgid "Cannot update paths and switch to branch '%s' at the same time." -msgstr "Kann nicht gleichzeitig Pfade aktualisieren und zu Zweig '%s' wechseln" +msgstr "" +"Kann nicht gleichzeitig Pfade aktualisieren und zu Branch '%s' wechseln" #: builtin/checkout.c:266 builtin/checkout.c:458 msgid "corrupt index file" -msgstr "beschädigte Bereitstellungsdatei" +msgstr "beschädigte Staging-Area-Datei" #: builtin/checkout.c:329 builtin/checkout.c:336 #, c-format @@ -3168,49 +3264,49 @@ msgstr "Pfad '%s' ist nicht zusammengeführt." #: builtin/checkout.c:480 msgid "you need to resolve your current index first" -msgstr "Sie müssen zuerst Ihre aktuelle Bereitstellung auflösen." +msgstr "Sie müssen zuerst Ihre aktuelle Staging-Area auflösen." #: builtin/checkout.c:601 #, c-format msgid "Can not do reflog for '%s'\n" msgstr "Konnte \"reflog\" für '%s' nicht durchführen\n" -#: builtin/checkout.c:634 +#: builtin/checkout.c:639 msgid "HEAD is now at" -msgstr "Zweigspitze (HEAD) ist jetzt bei" +msgstr "HEAD ist jetzt bei" -#: builtin/checkout.c:641 +#: builtin/checkout.c:646 #, c-format msgid "Reset branch '%s'\n" -msgstr "Setze Zweig '%s' neu\n" +msgstr "Setze Branch '%s' neu\n" -#: builtin/checkout.c:644 +#: builtin/checkout.c:649 #, c-format msgid "Already on '%s'\n" msgstr "Bereits auf '%s'\n" -#: builtin/checkout.c:648 +#: builtin/checkout.c:653 #, c-format msgid "Switched to and reset branch '%s'\n" -msgstr "Gewechselt zu neu gesetztem Zweig '%s'\n" +msgstr "Gewechselt zu umgesetzten Branch '%s'\n" -#: builtin/checkout.c:650 builtin/checkout.c:987 +#: builtin/checkout.c:655 builtin/checkout.c:997 #, c-format msgid "Switched to a new branch '%s'\n" -msgstr "Gewechselt zu einem neuen Zweig '%s'\n" +msgstr "Gewechselt zu einem neuem Branch '%s'\n" -#: builtin/checkout.c:652 +#: builtin/checkout.c:657 #, c-format msgid "Switched to branch '%s'\n" -msgstr "Gewechselt zu Zweig '%s'\n" +msgstr "Gewechselt zu Branch '%s'\n" -#: builtin/checkout.c:708 +#: builtin/checkout.c:713 #, c-format msgid " ... and %d more.\n" msgstr " ... und %d weitere.\n" #. The singular version -#: builtin/checkout.c:714 +#: builtin/checkout.c:719 #, c-format msgid "" "Warning: you are leaving %d commit behind, not connected to\n" @@ -3223,17 +3319,17 @@ msgid_plural "" "\n" "%s\n" msgstr[0] "" -"Warnung: Sie sind um %d Version hinterher, nicht verbunden zu\n" -"einem Ihrer Zweige:\n" +"Warnung: Sie sind um %d Commit hinterher, nicht verbunden zu\n" +"einem Ihrer Branches:\n" "\n" "%s\n" msgstr[1] "" -"Warnung: Sie sind um %d Versionen hinterher, nicht verbunden zu\n" -"einem Ihrer Zweige:\n" +"Warnung: Sie sind um %d Commits hinterher, nicht verbunden zu\n" +"einem Ihrer Branches:\n" "\n" "%s\n" -#: builtin/checkout.c:732 +#: builtin/checkout.c:737 #, c-format msgid "" "If you want to keep them by creating a new branch, this may be a good time\n" @@ -3242,376 +3338,478 @@ msgid "" " git branch new_branch_name %s\n" "\n" msgstr "" -"Wenn Sie diese durch einen neuen Zweig behalten möchten, dann könnte jetzt\n" +"Wenn Sie diese durch einen neuen Branch behalten möchten, dann könnte jetzt\n" "ein guter Zeitpunkt sein dies zu tun mit:\n" "\n" -" git branch neuer_zweig_name %s\n" +" git branch neuer_branch_name %s\n" "\n" -#: builtin/checkout.c:762 +#: builtin/checkout.c:767 msgid "internal error in revision walk" msgstr "interner Fehler im Revisionsgang" -#: builtin/checkout.c:766 +#: builtin/checkout.c:771 msgid "Previous HEAD position was" -msgstr "Vorherige Position der Zweigspitze (HEAD) war" +msgstr "Vorherige Position von HEAD war" -#: builtin/checkout.c:793 builtin/checkout.c:982 +#: builtin/checkout.c:798 builtin/checkout.c:992 msgid "You are on a branch yet to be born" -msgstr "Sie sind auf einem Zweig, der noch geboren wird" +msgstr "Sie sind auf einem Branch, der noch geboren wird" #. case (1) -#: builtin/checkout.c:918 +#: builtin/checkout.c:928 #, c-format msgid "invalid reference: %s" msgstr "Ungültige Referenz: %s" #. case (1): want a tree -#: builtin/checkout.c:957 +#: builtin/checkout.c:967 #, c-format msgid "reference is not a tree: %s" -msgstr "Referenz ist kein Baum: %s" +msgstr "Referenz ist kein \"Tree\"-Objekt: %s" -#: builtin/checkout.c:996 +#: builtin/checkout.c:1006 msgid "paths cannot be used with switching branches" -msgstr "Pfade können nicht beim Wechseln von Zweigen verwendet werden" +msgstr "Pfade können nicht beim Wechseln von Branches verwendet werden" -#: builtin/checkout.c:999 builtin/checkout.c:1003 +#: builtin/checkout.c:1009 builtin/checkout.c:1013 #, c-format msgid "'%s' cannot be used with switching branches" -msgstr "'%s' kann nicht beim Wechseln von Zweigen verwendet werden" +msgstr "'%s' kann nicht beim Wechseln von Branches verwendet werden" -#: builtin/checkout.c:1007 builtin/checkout.c:1010 builtin/checkout.c:1015 -#: builtin/checkout.c:1018 +#: builtin/checkout.c:1017 builtin/checkout.c:1020 builtin/checkout.c:1025 +#: builtin/checkout.c:1028 #, c-format msgid "'%s' cannot be used with '%s'" msgstr "'%s' kann nicht mit '%s' verwendet werden" -#: builtin/checkout.c:1023 +#: builtin/checkout.c:1033 #, c-format msgid "Cannot switch branch to a non-commit '%s'" -msgstr "Kann Zweig nicht zu Nicht-Version '%s' wechseln" +msgstr "Kann Branch nicht zu Nicht-Commit '%s' wechseln" -#: builtin/checkout.c:1045 builtin/checkout.c:1047 builtin/clone.c:90 +#: builtin/checkout.c:1055 builtin/checkout.c:1057 builtin/clone.c:89 #: builtin/remote.c:169 builtin/remote.c:171 msgid "branch" -msgstr "Zweig" +msgstr "Branch" -#: builtin/checkout.c:1046 +#: builtin/checkout.c:1056 msgid "create and checkout a new branch" -msgstr "erzeugt und checkt einen neuen Zweig aus" +msgstr "erzeugt und checkt einen neuen Branch aus" -#: builtin/checkout.c:1048 +#: builtin/checkout.c:1058 msgid "create/reset and checkout a branch" -msgstr "erzeugt/setzt neu und checkt einen Zweig aus" +msgstr "erzeugt/setzt um und checkt einen Branch aus" -#: builtin/checkout.c:1049 +#: builtin/checkout.c:1059 msgid "create reflog for new branch" -msgstr "erzeugt Referenzprotokoll für den neuen Zweig" +msgstr "erzeugt das Reflog für den neuen Branch" -#: builtin/checkout.c:1050 +#: builtin/checkout.c:1060 msgid "detach the HEAD at named commit" -msgstr "setzt die Zweigspitze (HEAD) zu benannter Version" +msgstr "setzt HEAD zu benanntem Commit" -#: builtin/checkout.c:1051 +#: builtin/checkout.c:1061 msgid "set upstream info for new branch" -msgstr "setzt Informationen zum externen Übernahmezweig für den neuen Zweig" +msgstr "setzt Informationen zum Upstream-Branch für den neuen Branch" -#: builtin/checkout.c:1053 +#: builtin/checkout.c:1063 msgid "new branch" -msgstr "neuer Zweig" +msgstr "neuer Branch" -#: builtin/checkout.c:1053 +#: builtin/checkout.c:1063 msgid "new unparented branch" -msgstr "neuer Zweig ohne Elternversion" +msgstr "neuer Branch ohne Eltern-Commit" -#: builtin/checkout.c:1054 +#: builtin/checkout.c:1064 msgid "checkout our version for unmerged files" msgstr "checkt unsere Variante für nicht zusammengeführte Dateien aus" -#: builtin/checkout.c:1056 +#: builtin/checkout.c:1066 msgid "checkout their version for unmerged files" msgstr "checkt ihre Variante für nicht zusammengeführte Dateien aus" -#: builtin/checkout.c:1058 +#: builtin/checkout.c:1068 msgid "force checkout (throw away local modifications)" msgstr "erzwingt Auschecken (verwirft lokale Änderungen)" -#: builtin/checkout.c:1059 +#: builtin/checkout.c:1069 msgid "perform a 3-way merge with the new branch" -msgstr "führt eine 3-Wege-Zusammenführung mit dem neuen Zweig aus" +msgstr "führt einen 3-Wege-Merge mit dem neuen Branch aus" -#: builtin/checkout.c:1060 builtin/merge.c:217 +#: builtin/checkout.c:1070 builtin/merge.c:232 msgid "update ignored files (default)" msgstr "aktualisiert ignorierte Dateien (Standard)" -#: builtin/checkout.c:1061 builtin/log.c:1158 parse-options.h:245 +#: builtin/checkout.c:1071 builtin/log.c:1208 parse-options.h:249 msgid "style" msgstr "Stil" -#: builtin/checkout.c:1062 +#: builtin/checkout.c:1072 msgid "conflict style (merge or diff3)" msgstr "Konfliktstil (merge oder diff3)" -#: builtin/checkout.c:1065 +#: builtin/checkout.c:1075 msgid "do not limit pathspecs to sparse entries only" msgstr "Pfadspezifikationen ignorieren Einstellungen zum partiellen Auschecken" -#: builtin/checkout.c:1067 +#: builtin/checkout.c:1077 msgid "second guess 'git checkout no-such-branch'" msgstr "second guess 'git checkout no-such-branch'" -#: builtin/checkout.c:1091 +#: builtin/checkout.c:1101 msgid "-b, -B and --orphan are mutually exclusive" msgstr "Die Optionen -b, -B und --orphan schließen sich gegenseitig aus." -#: builtin/checkout.c:1108 +#: builtin/checkout.c:1118 msgid "--track needs a branch name" -msgstr "Bei der Option --track muss ein Zweigname angegeben werden." +msgstr "Bei der Option --track muss ein Branchname angegeben werden." -#: builtin/checkout.c:1115 +#: builtin/checkout.c:1125 msgid "Missing branch name; try -b" -msgstr "Vermisse Zweignamen; versuchen Sie -b" +msgstr "Vermisse Branchnamen; versuchen Sie -b" -#: builtin/checkout.c:1150 +#: builtin/checkout.c:1160 msgid "invalid path specification" msgstr "ungültige Pfadspezifikation" -#: builtin/checkout.c:1157 +#: builtin/checkout.c:1167 #, 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 "" -"Kann nicht gleichzeitig Pfade aktualisieren und zu Zweig '%s' wechseln.\n" -"Haben Sie beabsichtigt '%s' auszuchecken, welcher nicht als Version " -"aufgelöst werden kann?" +"Kann nicht gleichzeitig Pfade aktualisieren und zu Branch '%s' wechseln.\n" +"Haben Sie beabsichtigt '%s' auszuchecken, welcher nicht als Commit aufgelöst " +"werden kann?" -#: builtin/checkout.c:1162 +#: builtin/checkout.c:1172 #, 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:1166 +#: builtin/checkout.c:1176 msgid "" "git checkout: --ours/--theirs, --force and --merge are incompatible when\n" "checking out of the index." msgstr "" "git checkout: --ours/--theirs, --force und --merge sind inkompatibel wenn\n" -"Sie aus der Bereitstellung auschecken." +"Sie aus der Staging-Area auschecken." -#: builtin/clean.c:20 -msgid "git clean [-d] [-f] [-n] [-q] [-e ] [-x | -X] [--] ..." -msgstr "git clean [-d] [-f] [-n] [-q] [-e ] [-x | -X] [--] ..." +#: builtin/clean.c:25 +msgid "" +"git clean [-d] [-f] [-i] [-n] [-q] [-e ] [-x | -X] [--] ..." +msgstr "" +"git clean [-d] [-f] [-i] [-n] [-q] [-e ] [-x | -X] [--] ..." -#: builtin/clean.c:24 +#: builtin/clean.c:29 #, c-format msgid "Removing %s\n" msgstr "Lösche %s\n" -#: builtin/clean.c:25 +#: builtin/clean.c:30 #, c-format msgid "Would remove %s\n" msgstr "Würde %s löschen\n" -#: builtin/clean.c:26 +#: builtin/clean.c:31 #, c-format msgid "Skipping repository %s\n" -msgstr "Überspringe Projektarchiv %s\n" +msgstr "Überspringe Repository %s\n" -#: builtin/clean.c:27 +#: builtin/clean.c:32 #, c-format msgid "Would skip repository %s\n" -msgstr "Würde Projektarchiv %s überspringen\n" +msgstr "Würde Repository %s überspringen\n" -#: builtin/clean.c:28 +#: builtin/clean.c:33 #, c-format msgid "failed to remove %s" msgstr "Fehler beim Löschen von %s" -#: builtin/clean.c:160 +#: builtin/clean.c:293 +msgid "" +"Prompt help:\n" +"1 - select a numbered item\n" +"foo - select item based on unique prefix\n" +" - (empty) select nothing" +msgstr "" +"Eingabehilfe:\n" +"1 - nummeriertes Element auswählen\n" +"foo - Element anhand eines eindeutigen Prefix auswählen\n" +" - (leer) nichts auswählen" + +#: builtin/clean.c:297 +msgid "" +"Prompt help:\n" +"1 - select a single item\n" +"3-5 - select a range of items\n" +"2-3,6-9 - select multiple ranges\n" +"foo - select item based on unique prefix\n" +"-... - unselect specified items\n" +"* - choose all items\n" +" - (empty) finish selecting" +msgstr "" +"Eingabehilfe:\n" +"1 - einzelnes Element auswählen\n" +"3-5 - Bereich von Elementen auswählen\n" +"2-3,6-9 - mehrere Bereiche auswählen\n" +"foo - Element anhand eines eindeutigen Prefix auswählen\n" +"-... - angegebenes Element abwählen\n" +"* - alle Elemente auswählen\n" +" - (leer) Auswahl beenden" + +#: builtin/clean.c:515 +#, c-format +msgid "Huh (%s)?" +msgstr "Wie bitte (%s)?" + +#: builtin/clean.c:658 +#, c-format +msgid "Input ignore patterns>> " +msgstr "Ignorier-Muster eingeben>> " + +#: builtin/clean.c:695 +#, c-format +msgid "WARNING: Cannot find items matched by: %s" +msgstr "WARNUNG: Kann keine Einträge finden die Muster entsprechen: %s" + +#: builtin/clean.c:716 +msgid "Select items to delete" +msgstr "Wählen Sie Einträge zum Löschen" + +#: builtin/clean.c:756 +#, c-format +msgid "remove %s? " +msgstr "'%s' löschen? " + +#: builtin/clean.c:781 +msgid "Bye." +msgstr "Tschüss." + +#: builtin/clean.c:789 +msgid "" +"clean - start cleaning\n" +"filter by pattern - exclude items from deletion\n" +"select by numbers - select items to be deleted by numbers\n" +"ask each - confirm each deletion (like \"rm -i\")\n" +"quit - stop cleaning\n" +"help - this screen\n" +"? - help for prompt selection" +msgstr "" +"clean - Clean starten\n" +"filter by pattern - Einträge von Löschung ausschließen\n" +"select by numbers - Auswahl von Einträgen über Nummern\n" +"ask each - jede Löschung bestätigen (wie \"rm -i\")\n" +"quit - Clean beenden\n" +"help - diese Meldung anzeigen\n" +"? - Hilfe zur Auswahl mittels Eingabe anzeigen" + +#: builtin/clean.c:816 +msgid "*** Commands ***" +msgstr "*** Kommandos ***" + +#: builtin/clean.c:817 +msgid "What now" +msgstr "Was nun" + +#: builtin/clean.c:825 +msgid "Would remove the following item:" +msgid_plural "Would remove the following items:" +msgstr[0] "Würde das folgende Element entfernen:" +msgstr[1] "Würde die folgenden Elemente entfernen:" + +#: builtin/clean.c:842 +msgid "No more files to clean, exiting." +msgstr "Keine Dateien mehr zum Löschen, beende." + +#: builtin/clean.c:874 msgid "do not print names of files removed" msgstr "gibt keine Namen von gelöschten Dateien aus" -#: builtin/clean.c:162 +#: builtin/clean.c:876 msgid "force" msgstr "erzwingt Aktion" -#: builtin/clean.c:164 +#: builtin/clean.c:877 +msgid "interactive cleaning" +msgstr "interaktives Clean" + +#: builtin/clean.c:879 msgid "remove whole directories" msgstr "löscht ganze Verzeichnisse" -#: builtin/clean.c:165 builtin/describe.c:412 builtin/grep.c:717 -#: builtin/ls-files.c:487 builtin/name-rev.c:231 builtin/show-ref.c:182 +#: builtin/clean.c:880 builtin/describe.c:420 builtin/grep.c:716 +#: builtin/ls-files.c:493 builtin/name-rev.c:315 builtin/show-ref.c:186 msgid "pattern" msgstr "Muster" -#: builtin/clean.c:166 +#: builtin/clean.c:881 msgid "add to ignore rules" msgstr "fügt zu den Regeln für ignorierte Pfade hinzu" -#: builtin/clean.c:167 +#: builtin/clean.c:882 msgid "remove ignored files, too" msgstr "löscht auch ignorierte Dateien" -#: builtin/clean.c:169 +#: builtin/clean.c:884 msgid "remove only ignored files" msgstr "löscht nur ignorierte Dateien" -#: builtin/clean.c:187 +#: builtin/clean.c:902 msgid "-x and -X cannot be used together" msgstr "Die Optionen -x und -X können nicht gemeinsam verwendet werden." -#: builtin/clean.c:191 +#: builtin/clean.c:906 msgid "" -"clean.requireForce set to true and neither -n nor -f given; refusing to clean" +"clean.requireForce set to true and neither -i, -n nor -f given; refusing to " +"clean" msgstr "" -"clean.requireForce auf \"true\" gesetzt und weder -n noch -f gegeben; " -"Säuberung verweigert" +"clean.requireForce auf \"true\" gesetzt und weder -i, -n noch -f gegeben; " +"\"clean\" verweigert" -#: builtin/clean.c:194 +#: builtin/clean.c:909 msgid "" -"clean.requireForce defaults to true and neither -n nor -f given; refusing to " -"clean" +"clean.requireForce defaults to true and neither -i, -n nor -f given; " +"refusing to clean" msgstr "" -"clean.requireForce standardmäßig auf \"true\" gesetzt und weder -n noch -f " -"gegeben; Säuberung verweigert" +"clean.requireForce standardmäßig auf \"true\" gesetzt und weder -i, -n noch -" +"f gegeben; \"clean\" verweigert" -#: builtin/clone.c:37 +#: builtin/clone.c:36 msgid "git clone [options] [--] []" -msgstr "git clone [Optionen] [--] []" +msgstr "git clone [Optionen] [--] []" -#: builtin/clone.c:65 builtin/fetch.c:82 builtin/merge.c:214 -#: builtin/push.c:436 +#: builtin/clone.c:64 builtin/fetch.c:82 builtin/merge.c:229 +#: builtin/push.c:462 msgid "force progress reporting" msgstr "erzwingt Fortschrittsanzeige" -#: builtin/clone.c:67 +#: builtin/clone.c:66 msgid "don't create a checkout" msgstr "kein Auschecken" -#: builtin/clone.c:68 builtin/clone.c:70 builtin/init-db.c:488 +#: builtin/clone.c:67 builtin/clone.c:69 builtin/init-db.c:488 msgid "create a bare repository" -msgstr "erstellt ein bloßes Projektarchiv" +msgstr "erstellt ein Bare-Repository" -#: builtin/clone.c:73 +#: builtin/clone.c:72 msgid "create a mirror repository (implies bare)" -msgstr "erstellt ein Spiegelarchiv (impliziert bloßes Projektarchiv)" +msgstr "erstellt ein Spiegelarchiv (impliziert --bare)" -#: builtin/clone.c:75 +#: builtin/clone.c:74 msgid "to clone from a local repository" -msgstr "um von einem lokalen Projektarchiv zu klonen" +msgstr "um von einem lokalen Repository zu klonen" -#: builtin/clone.c:77 +#: builtin/clone.c:76 msgid "don't use local hardlinks, always copy" -msgstr "verwendet lokal keine harten Links, immer Kopien" +msgstr "verwendet lokal keine harten Verweise, immer Kopien" -#: builtin/clone.c:79 +#: builtin/clone.c:78 msgid "setup as shared repository" -msgstr "Einrichtung als verteiltes Projektarchiv" +msgstr "Einrichtung als verteiltes Repository" -#: builtin/clone.c:81 builtin/clone.c:83 +#: builtin/clone.c:80 builtin/clone.c:82 msgid "initialize submodules in the clone" -msgstr "initialisiert Unterprojekte im Klon" +msgstr "initialisiert Submodule im Klon" -#: builtin/clone.c:84 builtin/init-db.c:485 +#: builtin/clone.c:83 builtin/init-db.c:485 msgid "template-directory" msgstr "Vorlagenverzeichnis" -#: builtin/clone.c:85 builtin/init-db.c:486 +#: 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:87 +#: builtin/clone.c:86 msgid "reference repository" -msgstr "referenziert Projektarchiv" +msgstr "referenziert Repository" -#: builtin/clone.c:88 builtin/column.c:26 builtin/merge-file.c:44 +#: builtin/clone.c:87 builtin/column.c:26 builtin/merge-file.c:44 msgid "name" msgstr "Name" -#: builtin/clone.c:89 +#: builtin/clone.c:88 msgid "use instead of 'origin' to track upstream" -msgstr "verwendet statt 'origin' für externes Projektarchiv" +msgstr "verwendet statt 'origin' für Upstream-Repository" -#: builtin/clone.c:91 +#: builtin/clone.c:90 msgid "checkout instead of the remote's HEAD" -msgstr "" -"checkt aus, anstatt Zweigspitze (HEAD) des externen Projektarchivs" +msgstr "checkt aus, anstatt HEAD des Remote-Repositories" -#: builtin/clone.c:93 +#: 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:94 builtin/fetch.c:83 builtin/grep.c:662 +#: builtin/clone.c:93 builtin/fetch.c:83 builtin/grep.c:661 msgid "depth" msgstr "Tiefe" -#: builtin/clone.c:95 +#: builtin/clone.c:94 msgid "create a shallow clone of that depth" msgstr "erstellt einen flachen Klon mit dieser Tiefe" -#: builtin/clone.c:97 +#: builtin/clone.c:96 msgid "clone only one branch, HEAD or --branch" -msgstr "klont nur einen Zweig, Zweigspitze (HEAD) oder --branch" +msgstr "klont nur einen Branch, HEAD oder --branch" -#: builtin/clone.c:98 builtin/init-db.c:494 +#: builtin/clone.c:97 builtin/init-db.c:494 msgid "gitdir" msgstr ".git-Verzeichnis" -#: builtin/clone.c:99 builtin/init-db.c:495 +#: builtin/clone.c:98 builtin/init-db.c:495 msgid "separate git dir from working tree" -msgstr "separiert Git-Verzeichnis vom Arbeitsbaum" +msgstr "separiert Git-Verzeichnis vom Arbeitsverzeichnis" -#: builtin/clone.c:100 +#: builtin/clone.c:99 msgid "key=value" msgstr "Schlüssel=Wert" -#: builtin/clone.c:101 +#: builtin/clone.c:100 msgid "set config inside the new repository" -msgstr "setzt Konfiguration innerhalb des neuen Projektarchivs" +msgstr "setzt Konfiguration innerhalb des neuen Repositories" -#: builtin/clone.c:254 +#: builtin/clone.c:253 #, c-format msgid "reference repository '%s' is not a local repository." -msgstr "Referenziertes Projektarchiv '%s' ist kein lokales Projektarchiv." +msgstr "Referenziertes Repository '%s' ist kein lokales Repository." -#: builtin/clone.c:317 +#: builtin/clone.c:316 #, c-format msgid "failed to create directory '%s'" msgstr "Fehler beim Erstellen von Verzeichnis '%s'" -#: builtin/clone.c:319 builtin/diff.c:77 +#: builtin/clone.c:318 builtin/diff.c:77 #, c-format msgid "failed to stat '%s'" msgstr "Konnte '%s' nicht lesen" -#: builtin/clone.c:321 +#: builtin/clone.c:320 #, c-format msgid "%s exists and is not a directory" msgstr "%s existiert und ist kein Verzeichnis" -#: builtin/clone.c:335 +#: builtin/clone.c:334 #, c-format msgid "failed to stat %s\n" msgstr "Konnte %s nicht lesen\n" -#: builtin/clone.c:357 +#: builtin/clone.c:356 #, c-format msgid "failed to create link '%s'" -msgstr "Konnte Verknüpfung '%s' nicht erstellen" +msgstr "Konnte Verweis '%s' nicht erstellen" -#: builtin/clone.c:361 +#: builtin/clone.c:360 #, c-format msgid "failed to copy file to '%s'" msgstr "Konnte Datei nicht nach '%s' kopieren" -#: builtin/clone.c:384 +#: builtin/clone.c:383 #, c-format msgid "done.\n" msgstr "Fertig.\n" -#: builtin/clone.c:397 +#: builtin/clone.c:396 msgid "" "Clone succeeded, but checkout failed.\n" "You can inspect what was checked out with 'git status'\n" @@ -3621,96 +3819,110 @@ msgstr "" "Sie können mit 'git status' prüfen, was ausgecheckt worden ist\n" "und das Auschecken mit 'git checkout -f HEAD' erneut versuchen.\n" -#: builtin/clone.c:476 +#: builtin/clone.c:475 #, c-format msgid "Could not find remote branch %s to clone." -msgstr "Konnte zu klonenden externer Zweig %s nicht finden." +msgstr "Konnte zu klonenden Remote-Branch %s nicht finden." + +#: builtin/clone.c:555 +#, c-format +msgid "Checking connectivity... " +msgstr "Prüfe Konnektivität... " -#: builtin/clone.c:550 +#: builtin/clone.c:558 msgid "remote did not send all necessary objects" -msgstr "Fernarchiv hat nicht alle erforderlichen Objekte gesendet." +msgstr "Remote-Repository hat nicht alle erforderlichen Objekte gesendet." -#: builtin/clone.c:610 +#: builtin/clone.c:560 +#, c-format +msgid "done\n" +msgstr "Fertig\n" + +#: builtin/clone.c:621 msgid "remote HEAD refers to nonexistent ref, unable to checkout.\n" msgstr "" -"Externe Zweigspitze (HEAD) bezieht sich auf eine nicht existierende Referenz " -"und kann nicht ausgecheckt werden.\n" +"Externer HEAD bezieht sich auf eine nicht existierende Referenz und kann " +"nicht ausgecheckt werden.\n" -#: builtin/clone.c:641 +#: builtin/clone.c:652 msgid "unable to checkout working tree" -msgstr "Arbeitsbaum konnte nicht ausgecheckt werden" +msgstr "Arbeitsverzeichnis konnte nicht ausgecheckt werden" -#: builtin/clone.c:749 +#: builtin/clone.c:760 msgid "Too many arguments." msgstr "Zu viele Argumente." -#: builtin/clone.c:753 +#: builtin/clone.c:764 msgid "You must specify a repository to clone." -msgstr "Sie müssen ein Projektarchiv zum Klonen angeben." +msgstr "Sie müssen ein Repository zum Klonen angeben." -#: builtin/clone.c:764 +#: builtin/clone.c:775 #, c-format msgid "--bare and --origin %s options are incompatible." msgstr "Die Optionen --bare und --origin %s sind inkompatibel." -#: builtin/clone.c:767 +#: builtin/clone.c:778 msgid "--bare and --separate-git-dir are incompatible." msgstr "Die Optionen --bare und --separate-git-dir sind inkompatibel." -#: builtin/clone.c:780 +#: builtin/clone.c:791 #, c-format msgid "repository '%s' does not exist" -msgstr "Projektarchiv '%s' existiert nicht." +msgstr "Repository '%s' existiert nicht." -#: builtin/clone.c:785 +#: builtin/clone.c:796 msgid "--depth is ignored in local clones; use file:// instead." msgstr "" "Die Option --depth wird in lokalen Klonen ignoriert; benutzen Sie " "stattdessen file://" -#: builtin/clone.c:795 +#: builtin/clone.c:798 +msgid "--local is ignored" +msgstr "--local wird ignoriert" + +#: builtin/clone.c:808 #, 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:805 +#: builtin/clone.c:818 #, c-format msgid "working tree '%s' already exists." -msgstr "Arbeitsbaum '%s' existiert bereits." +msgstr "Arbeitsverzeichnis '%s' existiert bereits." -#: builtin/clone.c:818 builtin/clone.c:830 +#: builtin/clone.c:831 builtin/clone.c:843 #, c-format msgid "could not create leading directories of '%s'" msgstr "Konnte führende Verzeichnisse von '%s' nicht erstellen." -#: builtin/clone.c:821 +#: builtin/clone.c:834 #, c-format msgid "could not create work tree dir '%s'." msgstr "Konnte Arbeitsverzeichnis '%s' nicht erstellen." -#: builtin/clone.c:840 +#: builtin/clone.c:853 #, c-format msgid "Cloning into bare repository '%s'...\n" -msgstr "Klone in bloßes Projektarchiv '%s'...\n" +msgstr "Klone in Bare-Repository '%s'...\n" -#: builtin/clone.c:842 +#: builtin/clone.c:855 #, c-format msgid "Cloning into '%s'...\n" msgstr "Klone nach '%s'...\n" -#: builtin/clone.c:877 +#: builtin/clone.c:890 #, c-format msgid "Don't know how to clone %s" msgstr "Weiß nicht wie %s zu klonen ist." -#: builtin/clone.c:926 +#: builtin/clone.c:942 #, c-format msgid "Remote branch %s not found in upstream %s" -msgstr "externer Zweig %s nicht im anderen Projektarchiv %s gefunden" +msgstr "Remote-Branch %s nicht im Upstream-Repository %s gefunden" -#: builtin/clone.c:933 +#: builtin/clone.c:949 msgid "You appear to have cloned an empty repository." -msgstr "Sie scheinen ein leeres Projektarchiv geklont zu haben." +msgstr "Sie scheinen ein leeres Repository geklont zu haben." #: builtin/column.c:9 msgid "git column [options]" @@ -3744,15 +3956,15 @@ msgstr "Abstand zwischen Spalten" msgid "--command must be the first argument" msgstr "Die Option --command muss an erster Stelle stehen." -#: builtin/commit.c:34 +#: builtin/commit.c:35 msgid "git commit [options] [--] ..." msgstr "git commit [Optionen] [--] ..." -#: builtin/commit.c:39 +#: builtin/commit.c:40 msgid "git status [options] [--] ..." msgstr "git status [Optionen] [--] ..." -#: builtin/commit.c:44 +#: builtin/commit.c:45 msgid "" "Your name and email address were configured automatically based\n" "on your username and hostname. Please check that they are accurate.\n" @@ -3773,129 +3985,144 @@ msgstr "" " git config --global user.name \"Ihr Name\"\n" " git config --global user.email ihre@emailadresse.de\n" "\n" -"Nachdem Sie das getan hast, können Sie Ihre Identität für diese Version " +"Nachdem Sie das getan hast, können Sie Ihre Identität für diesen Commit " "ändern mit:\n" "\n" " git commit --amend --reset-author\n" -#: builtin/commit.c:56 +#: builtin/commit.c:57 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" "remove the commit entirely with \"git reset HEAD^\".\n" msgstr "" -"Sie fragten die jüngste Version nachzubessern, aber das würde diese leer\n" -"machen. Sie können Ihr Kommando mit --allow-empty wiederholen, oder die\n" -"Version mit \"git reset HEAD^\" vollständig entfernen.\n" +"Sie fragten den jüngsten Commit nachzubessern, aber das würde diesen leer\n" +"machen. Sie können Ihr Kommando mit --allow-empty wiederholen, oder diesen\n" +"Commit mit \"git reset HEAD^\" vollständig entfernen.\n" -#: builtin/commit.c:61 +#: builtin/commit.c:62 msgid "" "The previous cherry-pick is now empty, possibly due to conflict resolution.\n" "If you wish to commit it anyway, use:\n" "\n" " git commit --allow-empty\n" "\n" -"Otherwise, please use 'git reset'\n" msgstr "" "Der letzte \"cherry-pick\" ist jetzt leer, möglicherweise durch eine " "Konfliktauflösung.\n" -"Wenn Sie dies trotzdem eintragen wollen, benutzen Sie:\n" +"Wenn Sie dies trotzdem committen wollen, benutzen Sie:\n" "\n" " git commit --allow-empty\n" "\n" -"Andernfalls benutzen Sie bitte 'git reset'\n" -#: builtin/commit.c:260 +#: builtin/commit.c:69 +msgid "Otherwise, please use 'git reset'\n" +msgstr "Andernfalls benutzen Sie bitte 'git reset'\n" + +#: builtin/commit.c:72 +msgid "" +"If you wish to skip this commit, use:\n" +"\n" +" git reset\n" +"\n" +"Then \"git cherry-pick --continue\" will resume cherry-picking\n" +"the remaining commits.\n" +msgstr "" +"Wenn Sie diesen Commit auslassen möchten, benutzen Sie:\n" +"\n" +" git reset\n" +"\n" +"Benutzen Sie anschließend \"git cherry-pick --continue\", um die\n" +"Cherry-Pick-Operation mit den verbleibenden Commits fortzusetzen.\n" + +#: builtin/commit.c:279 msgid "failed to unpack HEAD tree object" -msgstr "Fehler beim Entpacken des Baum-Objektes der Zweigspitze (HEAD)." +msgstr "Fehler beim Entpacken des \"Tree\"-Objektes von HEAD." -#: builtin/commit.c:302 +#: builtin/commit.c:321 msgid "unable to create temporary index" -msgstr "Konnte temporäre Bereitstellung nicht erstellen." +msgstr "Konnte temporäre Staging-Area nicht erstellen." -#: builtin/commit.c:308 +#: builtin/commit.c:327 msgid "interactive add failed" msgstr "interaktives Hinzufügen fehlgeschlagen" -#: builtin/commit.c:341 builtin/commit.c:362 builtin/commit.c:412 +#: builtin/commit.c:360 builtin/commit.c:381 builtin/commit.c:431 msgid "unable to write new_index file" msgstr "Konnte new_index Datei nicht schreiben" -#: builtin/commit.c:393 +#: builtin/commit.c:412 msgid "cannot do a partial commit during a merge." -msgstr "" -"Kann keine partielle Eintragung durchführen, während eine Zusammenführung im " -"Gange ist." +msgstr "Kann keinen Teil-Commit durchführen, während ein Merge im Gange ist." -#: builtin/commit.c:395 +#: builtin/commit.c:414 msgid "cannot do a partial commit during a cherry-pick." msgstr "" -"Kann keine partielle Eintragung durchführen, während \"cherry-pick\" im " -"Gange ist." +"Kann keinen Teil-Commit durchführen, während \"cherry-pick\" im Gange ist." -#: builtin/commit.c:405 +#: builtin/commit.c:424 msgid "cannot read the index" -msgstr "Kann Bereitstellung nicht lesen" +msgstr "Kann Staging-Area nicht lesen" -#: builtin/commit.c:425 +#: builtin/commit.c:444 msgid "unable to write temporary index file" -msgstr "Konnte temporäre Bereitstellungsdatei nicht schreiben." +msgstr "Konnte temporäre Staging-Area-Datei nicht schreiben." -#: builtin/commit.c:513 builtin/commit.c:519 +#: builtin/commit.c:535 builtin/commit.c:541 #, c-format msgid "invalid commit: %s" -msgstr "Ungültige Version: %s" +msgstr "Ungültiger Commit: %s" -#: builtin/commit.c:542 +#: builtin/commit.c:563 msgid "malformed --author parameter" msgstr "Fehlerhafter --author Parameter" -#: builtin/commit.c:562 +#: builtin/commit.c:583 #, c-format msgid "Malformed ident string: '%s'" -msgstr "Fehlerhafte Identifikations-String: '%s'" +msgstr "Fehlerhafter Ident-String: '%s'" -#: builtin/commit.c:600 builtin/commit.c:633 builtin/commit.c:956 +#: builtin/commit.c:621 builtin/commit.c:654 builtin/commit.c:982 #, c-format msgid "could not lookup commit %s" -msgstr "Konnte Version %s nicht nachschlagen" +msgstr "Konnte Commit %s nicht nachschlagen" -#: builtin/commit.c:612 builtin/shortlog.c:270 +#: builtin/commit.c:633 builtin/shortlog.c:271 #, c-format msgid "(reading log message from standard input)\n" msgstr "(lese Log-Nachricht von Standard-Eingabe)\n" -#: builtin/commit.c:614 +#: builtin/commit.c:635 msgid "could not read log from standard input" msgstr "Konnte Log nicht von Standard-Eingabe lesen." -#: builtin/commit.c:618 +#: builtin/commit.c:639 #, c-format msgid "could not read log file '%s'" msgstr "Konnte Log-Datei '%s' nicht lesen" -#: builtin/commit.c:624 +#: builtin/commit.c:645 msgid "commit has empty message" -msgstr "Version hat eine leere Beschreibung" +msgstr "Commit hat eine leere Beschreibung" -#: builtin/commit.c:640 +#: builtin/commit.c:661 msgid "could not read MERGE_MSG" msgstr "Konnte MERGE_MSG nicht lesen" -#: builtin/commit.c:644 +#: builtin/commit.c:665 msgid "could not read SQUASH_MSG" msgstr "Konnte SQUASH_MSG nicht lesen" -#: builtin/commit.c:648 +#: builtin/commit.c:669 #, c-format msgid "could not read '%s'" msgstr "Konnte '%s' nicht lesen" -#: builtin/commit.c:709 +#: builtin/commit.c:730 msgid "could not write commit template" -msgstr "Konnte Versionsvorlage nicht schreiben" +msgstr "Konnte Commit-Vorlage nicht schreiben" -#: builtin/commit.c:720 +#: builtin/commit.c:741 #, c-format msgid "" "\n" @@ -3905,12 +4132,12 @@ msgid "" "and try again.\n" msgstr "" "\n" -"Es sieht so aus, als tragen Sie eine Zusammenführung ein.\n" +"Es sieht so aus, als committen Sie einen Merge.\n" "Falls das nicht korrekt ist, löschen Sie bitte die Datei\n" "\t%s\n" "und versuchen Sie es erneut.\n" -#: builtin/commit.c:725 +#: builtin/commit.c:746 #, c-format msgid "" "\n" @@ -3920,406 +4147,406 @@ msgid "" "and try again.\n" msgstr "" "\n" -"Es sieht so aus, als tragen Sie ein \"cherry-pick\" ein.\n" +"Es sieht so aus, als committen Sie einen \"cherry-pick\".\n" "Falls das nicht korrekt ist, löschen Sie bitte die Datei\n" "\t%s\n" "und versuchen Sie es erneut.\n" -#: builtin/commit.c:737 +#: builtin/commit.c:758 #, c-format msgid "" "Please enter the commit message for your changes. Lines starting\n" "with '%c' will be ignored, and an empty message aborts the commit.\n" msgstr "" -"Bitte geben Sie eine Versionsbeschreibung für Ihre Änderungen ein. Zeilen,\n" -"die mit '%c' beginnen, werden ignoriert, und eine leere " -"Versionsbeschreibung\n" -"bricht die Eintragung ab.\n" +"Bitte geben Sie eine Commit-Beschreibung für Ihre Änderungen ein. Zeilen,\n" +"die mit '%c' beginnen, werden ignoriert, und eine leere Beschreibung\n" +"bricht den Commit ab.\n" -#: builtin/commit.c:742 +#: builtin/commit.c:763 #, c-format msgid "" "Please enter the commit message for your changes. Lines starting\n" "with '%c' will be kept; you may remove them yourself if you want to.\n" "An empty message aborts the commit.\n" msgstr "" -"Bitte geben Sie eine Versionsbeschreibung für Ihre Änderungen ein. Zeilen, " +"Bitte geben Sie eine Commit-Beschreibung für Ihre Änderungen ein. Zeilen, " "die\n" "mit '%c' beginnen, werden beibehalten; wenn Sie möchten, können Sie diese " "entfernen.\n" -"Eine leere Versionsbeschreibung bricht die Eintragung ab.\n" +"Eine leere Beschreibung bricht den Commit ab.\n" -#: builtin/commit.c:755 +#: builtin/commit.c:776 #, c-format msgid "%sAuthor: %s" msgstr "%sAutor: %s" -#: builtin/commit.c:762 +#: builtin/commit.c:783 #, c-format msgid "%sCommitter: %s" -msgstr "%sEintragender: %s" +msgstr "%sCommit-Ersteller: %s" -#: builtin/commit.c:782 +#: builtin/commit.c:803 msgid "Cannot read index" -msgstr "Kann Bereitstellung nicht lesen" +msgstr "Kann Staging-Area nicht lesen" -#: builtin/commit.c:819 +#: builtin/commit.c:845 msgid "Error building trees" -msgstr "Fehler beim Erzeugen der Zweige" +msgstr "Fehler beim Erzeugen der \"Tree\"-Objekte" -#: builtin/commit.c:834 builtin/tag.c:359 +#: builtin/commit.c:860 builtin/tag.c:359 #, c-format msgid "Please supply the message using either -m or -F option.\n" -msgstr "Bitte liefere eine Beschreibung entweder mit der Option -m oder -F.\n" +msgstr "" +"Bitte liefern Sie eine Beschreibung entweder mit der Option -m oder -F.\n" -#: builtin/commit.c:931 +#: builtin/commit.c:957 #, c-format msgid "No existing author found with '%s'" msgstr "Kein existierender Autor mit '%s' gefunden." -#: builtin/commit.c:946 builtin/commit.c:1140 +#: builtin/commit.c:972 builtin/commit.c:1208 #, c-format msgid "Invalid untracked files mode '%s'" msgstr "Ungültiger Modus '%s' für unbeobachtete Dateien" -#: builtin/commit.c:976 +#: builtin/commit.c:1009 +msgid "--long and -z are incompatible" +msgstr "Die Optionen --long und -z sind inkompatibel." + +#: builtin/commit.c:1039 msgid "Using both --reset-author and --author does not make sense" msgstr "" "Die Optionen --reset-author und --author können nicht gemeinsam verwendet " "werden." -#: builtin/commit.c:987 +#: builtin/commit.c:1050 msgid "You have nothing to amend." -msgstr "Sie haben nichts zum nachbessern." +msgstr "Sie haben nichts für \"--amend\"." -#: builtin/commit.c:990 +#: builtin/commit.c:1053 msgid "You are in the middle of a merge -- cannot amend." -msgstr "Eine Zusammenführung ist im Gange -- kann nicht nachbessern." +msgstr "Ein Merge ist im Gange -- kann \"--amend\" nicht ausführen." -#: builtin/commit.c:992 +#: builtin/commit.c:1055 msgid "You are in the middle of a cherry-pick -- cannot amend." -msgstr "\"cherry-pick\" ist im Gange -- kann nicht nachbessern." +msgstr "\"cherry-pick\" ist im Gange -- kann \"--amend\" nicht ausführen." -#: builtin/commit.c:995 +#: builtin/commit.c:1058 msgid "Options --squash and --fixup cannot be used together" msgstr "" "Die Optionen --squash und --fixup können nicht gemeinsam verwendet werden." -#: builtin/commit.c:1005 +#: builtin/commit.c:1068 msgid "Only one of -c/-C/-F/--fixup can be used." msgstr "Es kann nur eine Option von -c/-C/-F/--fixup verwendet werden." -#: builtin/commit.c:1007 +#: builtin/commit.c:1070 msgid "Option -m cannot be combined with -c/-C/-F/--fixup." msgstr "Die Option -m kann nicht mit -c/-C/-F/--fixup kombiniert werden." -#: builtin/commit.c:1015 +#: builtin/commit.c:1078 msgid "--reset-author can be used only with -C, -c or --amend." msgstr "" "Die Option --reset--author kann nur mit -C, -c oder --amend verwendet werden." -#: builtin/commit.c:1032 +#: builtin/commit.c:1095 msgid "Only one of --include/--only/--all/--interactive/--patch can be used." msgstr "" "Es kann nur eine Option von --include/--only/--all/--interactive/--patch " "verwendet werden." -#: builtin/commit.c:1034 +#: builtin/commit.c:1097 msgid "No paths with --include/--only does not make sense." msgstr "" "Die Optionen --include und --only können nur mit der Angabe von Pfaden " "verwendet werden." -#: builtin/commit.c:1036 +#: builtin/commit.c:1099 msgid "Clever... amending the last one with dirty index." msgstr "" -"Klug... die letzte Version mit einer unsauberen Bereitstellung nachbessern." +"Klug... den letzten Commit mit einer geänderten Staging-Area nachbessern." -#: builtin/commit.c:1038 +#: builtin/commit.c:1101 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:1048 builtin/tag.c:575 +#: builtin/commit.c:1111 builtin/tag.c:575 #, c-format msgid "Invalid cleanup mode %s" msgstr "Ungültiger \"cleanup\" Modus %s" -#: builtin/commit.c:1053 +#: builtin/commit.c:1116 msgid "Paths with -a does not make sense." msgstr "Die Option -a kann nur mit der Angabe von Pfaden verwendet werden." -#: builtin/commit.c:1059 builtin/commit.c:1194 -msgid "--long and -z are incompatible" -msgstr "Die Optionen --long und -z sind inkompatibel." - -#: builtin/commit.c:1154 builtin/commit.c:1390 +#: builtin/commit.c:1222 builtin/commit.c:1455 msgid "show status concisely" msgstr "zeigt Status im Kurzformat" -#: builtin/commit.c:1156 builtin/commit.c:1392 +#: builtin/commit.c:1224 builtin/commit.c:1457 msgid "show branch information" -msgstr "zeigt Zweiginformationen" +msgstr "zeigt Branchinformationen" -#: builtin/commit.c:1158 builtin/commit.c:1394 builtin/push.c:426 +#: builtin/commit.c:1226 builtin/commit.c:1459 builtin/push.c:452 msgid "machine-readable output" msgstr "maschinenlesbare Ausgabe" -#: builtin/commit.c:1161 builtin/commit.c:1396 +#: builtin/commit.c:1229 builtin/commit.c:1461 msgid "show status in long format (default)" msgstr "zeigt Status im Langformat (Standard)" -#: builtin/commit.c:1164 builtin/commit.c:1399 +#: builtin/commit.c:1232 builtin/commit.c:1464 msgid "terminate entries with NUL" msgstr "schließt Einträge mit NUL-Zeichen ab" -#: builtin/commit.c:1166 builtin/commit.c:1402 builtin/fast-export.c:659 -#: builtin/fast-export.c:662 builtin/tag.c:459 +#: builtin/commit.c:1234 builtin/commit.c:1467 builtin/fast-export.c:667 +#: builtin/fast-export.c:670 builtin/tag.c:459 msgid "mode" msgstr "Modus" -#: builtin/commit.c:1167 builtin/commit.c:1402 +#: builtin/commit.c:1235 builtin/commit.c:1467 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:1170 +#: builtin/commit.c:1238 msgid "show ignored files" msgstr "zeigt ignorierte Dateien" -#: builtin/commit.c:1171 parse-options.h:151 +#: builtin/commit.c:1239 parse-options.h:154 msgid "when" msgstr "wann" -#: builtin/commit.c:1172 +#: builtin/commit.c:1240 msgid "" "ignore changes to submodules, optional when: all, dirty, untracked. " "(Default: all)" msgstr "" -"ignoriert Änderungen in Unterprojekten, optional wenn: all, dirty, " -"untracked. (Standard: all)" +"ignoriert Änderungen in Submodulen, optional wenn: all, dirty, untracked. " +"(Standard: all)" -#: builtin/commit.c:1174 +#: builtin/commit.c:1242 msgid "list untracked files in columns" msgstr "listet unbeobachtete Dateien in Spalten auf" -#: builtin/commit.c:1248 +#: builtin/commit.c:1313 msgid "couldn't look up newly created commit" -msgstr "Konnte neu erstellte Version nicht nachschlagen." +msgstr "Konnte neu erstellten Commit nicht nachschlagen." -#: builtin/commit.c:1250 +#: builtin/commit.c:1315 msgid "could not parse newly created commit" -msgstr "Konnte neulich erstellte Version nicht analysieren." +msgstr "Konnte neulich erstellten Commit nicht analysieren." -#: builtin/commit.c:1291 +#: builtin/commit.c:1356 msgid "detached HEAD" -msgstr "losgelöste Zweigspitze (HEAD)" +msgstr "losgelöster HEAD" -#: builtin/commit.c:1293 +#: builtin/commit.c:1358 msgid " (root-commit)" -msgstr " (Basis-Version)" +msgstr " (Basis-Commit)" -#: builtin/commit.c:1360 +#: builtin/commit.c:1425 msgid "suppress summary after successful commit" -msgstr "unterdrückt Zusammenfassung nach erfolgreicher Eintragung" +msgstr "unterdrückt Zusammenfassung nach erfolgreichem Commit" -#: builtin/commit.c:1361 +#: builtin/commit.c:1426 msgid "show diff in commit message template" -msgstr "zeigt Unterschiede in Versionsbeschreibungsvorlage an" +msgstr "zeigt Unterschiede in Commit-Beschreibungsvorlage an" -#: builtin/commit.c:1363 +#: builtin/commit.c:1428 msgid "Commit message options" -msgstr "Optionen für Versionsbeschreibung" +msgstr "Optionen für Commit-Beschreibung" -#: builtin/commit.c:1364 builtin/tag.c:457 +#: builtin/commit.c:1429 builtin/tag.c:457 msgid "read message from file" msgstr "liest Beschreibung von Datei" -#: builtin/commit.c:1365 +#: builtin/commit.c:1430 msgid "author" msgstr "Autor" -#: builtin/commit.c:1365 +#: builtin/commit.c:1430 msgid "override author for commit" -msgstr "überschreibt Autor von Version" +msgstr "überschreibt Autor eines Commits" -#: builtin/commit.c:1366 builtin/gc.c:178 +#: builtin/commit.c:1431 builtin/gc.c:178 msgid "date" msgstr "Datum" -#: builtin/commit.c:1366 +#: builtin/commit.c:1431 msgid "override date for commit" -msgstr "überschreibt Datum von Version" +msgstr "überschreibt Datum eines Commits" -#: builtin/commit.c:1367 builtin/merge.c:208 builtin/notes.c:533 -#: builtin/notes.c:690 builtin/tag.c:455 +#: builtin/commit.c:1432 builtin/merge.c:223 builtin/notes.c:405 +#: builtin/notes.c:562 builtin/tag.c:455 msgid "message" msgstr "Beschreibung" -#: builtin/commit.c:1367 +#: builtin/commit.c:1432 msgid "commit message" -msgstr "Versionsbeschreibung" +msgstr "Commit-Beschreibung" -#: builtin/commit.c:1368 +#: builtin/commit.c:1433 msgid "reuse and edit message from specified commit" -msgstr "verwendet wieder und editiert Beschreibung von der angegebenen Version" +msgstr "verwendet wieder und editiert Beschreibung des angegebenen Commits" -#: builtin/commit.c:1369 +#: builtin/commit.c:1434 msgid "reuse message from specified commit" -msgstr "verwendet Beschreibung der angegebenen Version wieder" +msgstr "verwendet Beschreibung des angegebenen Commits wieder" -#: builtin/commit.c:1370 +#: builtin/commit.c:1435 msgid "use autosquash formatted message to fixup specified commit" msgstr "" -"verwendet eine automatisch zusammengesetzte Beschreibung zum Nachbessern der " -"angegebenen Version" +"verwendet eine automatisch zusammengesetzte Beschreibung zum Nachbessern des " +"angegebenen Commits" -#: builtin/commit.c:1371 +#: builtin/commit.c:1436 msgid "use autosquash formatted message to squash specified commit" msgstr "" -"verwendet eine automatisch zusammengesetzte Beschreibung zum Zusammenführen " -"der angegebenen Version" +"verwendet eine automatisch zusammengesetzte Beschreibung beim \"squash\" des " +"angegebenen Commits" -#: builtin/commit.c:1372 +#: builtin/commit.c:1437 msgid "the commit is authored by me now (used with -C/-c/--amend)" -msgstr "Setzt Sie als Autor der Version (verwendet mit -C/-c/--amend)" +msgstr "Setzt Sie als Autor des Commits (verwendet mit -C/-c/--amend)" -#: builtin/commit.c:1373 builtin/log.c:1113 builtin/revert.c:109 +#: builtin/commit.c:1438 builtin/log.c:1160 builtin/revert.c:111 msgid "add Signed-off-by:" msgstr "fügt 'Signed-off-by:'-Zeile hinzu" -#: builtin/commit.c:1374 +#: builtin/commit.c:1439 msgid "use specified template file" msgstr "verwendet angegebene Vorlagendatei" -#: builtin/commit.c:1375 +#: builtin/commit.c:1440 msgid "force edit of commit" -msgstr "erzwingt Bearbeitung der Version" +msgstr "erzwingt Bearbeitung des Commits" -#: builtin/commit.c:1376 +#: builtin/commit.c:1441 msgid "default" msgstr "Standard" -#: builtin/commit.c:1376 builtin/tag.c:460 +#: builtin/commit.c:1441 builtin/tag.c:460 msgid "how to strip spaces and #comments from message" msgstr "" "wie Leerzeichen und #Kommentare von der Beschreibung getrennt werden sollen" -#: builtin/commit.c:1377 +#: builtin/commit.c:1442 msgid "include status in commit message template" -msgstr "fügt Status in die Versionsbeschreibungsvorlage ein" +msgstr "fügt Status in die Commit-Beschreibungsvorlage ein" -#: builtin/commit.c:1378 builtin/merge.c:215 builtin/tag.c:461 +#: builtin/commit.c:1443 builtin/merge.c:230 builtin/tag.c:461 msgid "key id" msgstr "Schlüssel-ID" -#: builtin/commit.c:1379 builtin/merge.c:216 +#: builtin/commit.c:1444 builtin/merge.c:231 msgid "GPG sign commit" -msgstr "signiert Version mit GPG" +msgstr "signiert Commit mit GPG" #. end commit message options -#: builtin/commit.c:1382 +#: builtin/commit.c:1447 msgid "Commit contents options" -msgstr "Optionen für Versionsinhalt" +msgstr "Optionen für Commit-Inhalt" -#: builtin/commit.c:1383 +#: builtin/commit.c:1448 msgid "commit all changed files" -msgstr "trägt alle geänderten Dateien ein" +msgstr "committet alle geänderten Dateien" -#: builtin/commit.c:1384 +#: builtin/commit.c:1449 msgid "add specified files to index for commit" -msgstr "trägt die angegebenen Dateien zusätzlich zur Bereitstellung ein" +msgstr "merkt die angegebenen Dateien zusätzlich zum Commit vor" -#: builtin/commit.c:1385 +#: builtin/commit.c:1450 msgid "interactively add files" msgstr "interaktives Hinzufügen von Dateien" -#: builtin/commit.c:1386 +#: builtin/commit.c:1451 msgid "interactively add changes" msgstr "interaktives Hinzufügen von Änderungen" -#: builtin/commit.c:1387 +#: builtin/commit.c:1452 msgid "commit only specified files" -msgstr "trägt nur die angegebenen Dateien ein" +msgstr "committet nur die angegebenen Dateien" -#: builtin/commit.c:1388 +#: builtin/commit.c:1453 msgid "bypass pre-commit hook" msgstr "umgeht \"pre-commit hook\"" -#: builtin/commit.c:1389 +#: builtin/commit.c:1454 msgid "show what would be committed" -msgstr "zeigt an, was eingetragen werden würde" +msgstr "zeigt an, was committet werden würde" -#: builtin/commit.c:1400 +#: builtin/commit.c:1465 msgid "amend previous commit" -msgstr "ändert vorherige Version" +msgstr "ändert vorherigen Commit" -#: builtin/commit.c:1401 +#: builtin/commit.c:1466 msgid "bypass post-rewrite hook" msgstr "umgeht \"post-rewrite hook\"" -#: builtin/commit.c:1406 +#: builtin/commit.c:1471 msgid "ok to record an empty change" msgstr "erlaubt Aufzeichnung einer leeren Änderung" -#: builtin/commit.c:1409 +#: builtin/commit.c:1474 msgid "ok to record a change with an empty message" msgstr "erlaubt Aufzeichnung einer Änderung mit einer leeren Beschreibung" -#: builtin/commit.c:1441 +#: builtin/commit.c:1507 msgid "could not parse HEAD commit" -msgstr "Konnte Version der Zweigspitze (HEAD) nicht analysieren." +msgstr "Konnte Commit von HEAD nicht analysieren." -#: builtin/commit.c:1479 builtin/merge.c:510 +#: builtin/commit.c:1545 builtin/merge.c:525 #, c-format msgid "could not open '%s' for reading" msgstr "Konnte '%s' nicht zum Lesen öffnen." -#: builtin/commit.c:1486 +#: builtin/commit.c:1552 #, c-format msgid "Corrupt MERGE_HEAD file (%s)" msgstr "Beschädigte MERGE_HEAD-Datei (%s)" -#: builtin/commit.c:1493 +#: builtin/commit.c:1559 msgid "could not read MERGE_MODE" msgstr "Konnte MERGE_MODE nicht lesen" -#: builtin/commit.c:1512 +#: builtin/commit.c:1578 #, c-format msgid "could not read commit message: %s" -msgstr "Konnte Versionsbeschreibung nicht lesen: %s" +msgstr "Konnte Commit-Beschreibung nicht lesen: %s" -#: builtin/commit.c:1526 +#: builtin/commit.c:1592 #, c-format msgid "Aborting commit; you did not edit the message.\n" -msgstr "Eintragung abgebrochen; Sie haben die Beschreibung nicht editiert.\n" +msgstr "Commit abgebrochen; Sie haben die Beschreibung nicht editiert.\n" -#: builtin/commit.c:1531 +#: builtin/commit.c:1597 #, c-format msgid "Aborting commit due to empty commit message.\n" -msgstr "Eintragung aufgrund leerer Versionsbeschreibung abgebrochen.\n" +msgstr "Commit aufgrund leerer Beschreibung abgebrochen.\n" -#: builtin/commit.c:1546 builtin/merge.c:847 builtin/merge.c:872 +#: builtin/commit.c:1612 builtin/merge.c:861 builtin/merge.c:886 msgid "failed to write commit object" -msgstr "Fehler beim Schreiben des Versionsobjektes." +msgstr "Fehler beim Schreiben des Commit-Objektes." -#: builtin/commit.c:1567 +#: builtin/commit.c:1633 msgid "cannot lock HEAD ref" -msgstr "Kann Referenz der Zweigspitze (HEAD) nicht sperren." +msgstr "Kann Referenz von HEAD nicht sperren." -#: builtin/commit.c:1571 +#: builtin/commit.c:1637 msgid "cannot update HEAD ref" -msgstr "Kann Referenz der Zweigspitze (HEAD) nicht aktualisieren." +msgstr "Kann Referenz von HEAD nicht aktualisieren." -#: builtin/commit.c:1582 +#: builtin/commit.c:1648 msgid "" "Repository has been updated, but unable to write\n" "new_index file. Check that disk is not full or quota is\n" "not exceeded, and then \"git reset HEAD\" to recover." msgstr "" -"Das Projektarchiv wurde aktualisiert, aber die \"new_index\"-Datei\n" +"Das Repository wurde aktualisiert, aber die \"new_index\"-Datei\n" "konnte nicht geschrieben werden. Prüfen Sie, dass Ihre Festplatte nicht\n" "voll und Ihr Kontingent nicht aufgebraucht ist und führen Sie\n" "anschließend \"git reset HEAD\" zu Wiederherstellung aus." @@ -4328,115 +4555,123 @@ msgstr "" msgid "git config [options]" msgstr "git config [Optionen]" -#: builtin/config.c:51 +#: builtin/config.c:52 msgid "Config file location" msgstr "Ort der Konfigurationsdatei" -#: builtin/config.c:52 +#: builtin/config.c:53 msgid "use global config file" msgstr "verwendet globale Konfigurationsdatei" -#: builtin/config.c:53 +#: builtin/config.c:54 msgid "use system config file" msgstr "verwendet systemweite Konfigurationsdatei" -#: builtin/config.c:54 +#: builtin/config.c:55 msgid "use repository config file" -msgstr "verwendet Konfigurationsdatei des Projektarchivs" +msgstr "verwendet Konfigurationsdatei des Repositories" -#: builtin/config.c:55 +#: builtin/config.c:56 msgid "use given config file" msgstr "verwendet die angegebene Konfigurationsdatei" -#: builtin/config.c:56 +#: builtin/config.c:57 +msgid "blob-id" +msgstr "Blob-Id" + +#: builtin/config.c:57 +msgid "read config from given blob object" +msgstr "liest Konfiguration von angegebenem Blob-Objekt" + +#: builtin/config.c:58 msgid "Action" msgstr "Aktion" -#: builtin/config.c:57 +#: builtin/config.c:59 msgid "get value: name [value-regex]" msgstr "gibt Wert zurück: Name [Wert-regex]" -#: builtin/config.c:58 +#: builtin/config.c:60 msgid "get all values: key [value-regex]" msgstr "gibt alle Werte zurück: Schlüssel [Wert-regex]" -#: builtin/config.c:59 +#: builtin/config.c:61 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 +#: builtin/config.c:62 msgid "replace all matching variables: name value [value_regex]" msgstr "ersetzt alle passenden Variablen: Name Wert [Wert-regex] " -#: builtin/config.c:61 +#: builtin/config.c:63 msgid "add a new variable: name value" msgstr "fügt neue Variable hinzu: Name Wert" -#: builtin/config.c:62 +#: builtin/config.c:64 msgid "remove a variable: name [value-regex]" msgstr "entfernt eine Variable: Name [Wert-regex]" -#: builtin/config.c:63 +#: builtin/config.c:65 msgid "remove all matches: name [value-regex]" msgstr "entfernt alle Übereinstimmungen: Name [Wert-regex]" -#: builtin/config.c:64 +#: builtin/config.c:66 msgid "rename section: old-name new-name" msgstr "benennt eine Sektion um: alter-Name neuer-Name" -#: builtin/config.c:65 +#: builtin/config.c:67 msgid "remove a section: name" msgstr "entfernt eine Sektion: Name" -#: builtin/config.c:66 +#: builtin/config.c:68 msgid "list all" msgstr "listet alles auf" -#: builtin/config.c:67 +#: builtin/config.c:69 msgid "open an editor" msgstr "öffnet einen Editor" -#: builtin/config.c:68 builtin/config.c:69 +#: builtin/config.c:70 builtin/config.c:71 msgid "slot" msgstr "Slot" -#: builtin/config.c:68 +#: builtin/config.c:70 msgid "find the color configured: [default]" msgstr "findet die konfigurierte Farbe: [Standard]" -#: builtin/config.c:69 +#: builtin/config.c:71 msgid "find the color setting: [stdout-is-tty]" msgstr "findet die Farbeinstellung: [Standard-Ausgabe-ist-Terminal]" -#: builtin/config.c:70 +#: builtin/config.c:72 msgid "Type" msgstr "Typ" -#: builtin/config.c:71 +#: builtin/config.c:73 msgid "value is \"true\" or \"false\"" msgstr "Wert ist \"true\" oder \"false\"" -#: builtin/config.c:72 +#: builtin/config.c:74 msgid "value is decimal number" msgstr "Wert ist eine Dezimalzahl" -#: builtin/config.c:73 +#: builtin/config.c:75 msgid "value is --bool or --int" msgstr "Wert ist --bool oder --int" -#: builtin/config.c:74 +#: builtin/config.c:76 msgid "value is a path (file or directory name)" msgstr "Wert ist ein Pfad (Datei oder Verzeichnisname)" -#: builtin/config.c:75 +#: builtin/config.c:77 msgid "Other" msgstr "Sonstiges" -#: builtin/config.c:76 +#: builtin/config.c:78 msgid "terminate values with NUL byte" msgstr "schließt Werte mit NUL-Byte ab" -#: builtin/config.c:77 +#: builtin/config.c:79 msgid "respect include directives on lookup" msgstr "beachtet \"include\"-Direktiven beim Nachschlagen" @@ -4448,173 +4683,173 @@ msgstr "git count-objects [-v] [-H | --human-readable]" msgid "print sizes in human readable format" msgstr "gibt Größenangaben in menschenlesbaren Format aus" -#: builtin/describe.c:15 +#: builtin/describe.c:16 msgid "git describe [options] *" msgstr "git describe [Optionen] *" -#: builtin/describe.c:16 +#: builtin/describe.c:17 msgid "git describe [options] --dirty" msgstr "git describe [Optionen] --dirty" -#: builtin/describe.c:233 +#: builtin/describe.c:237 #, c-format msgid "annotated tag %s not available" -msgstr "annotierte Markierung %s ist nicht verfügbar" +msgstr "annotierter Tag %s ist nicht verfügbar" -#: builtin/describe.c:237 +#: builtin/describe.c:241 #, c-format msgid "annotated tag %s has no embedded name" -msgstr "annotierte Markierung %s hat keinen eingebetteten Namen" +msgstr "annotierter Tag %s hat keinen eingebetteten Namen" -#: builtin/describe.c:239 +#: builtin/describe.c:243 #, c-format msgid "tag '%s' is really '%s' here" -msgstr "Markierung '%s' ist eigentlich '%s' hier" +msgstr "Tag '%s' ist eigentlich '%s' hier" -#: builtin/describe.c:266 +#: builtin/describe.c:270 #, c-format msgid "Not a valid object name %s" msgstr "%s ist kein gültiger Objekt-Name" -#: builtin/describe.c:269 +#: builtin/describe.c:273 #, c-format msgid "%s is not a valid '%s' object" msgstr "%s ist kein gültiges '%s' Objekt" -#: builtin/describe.c:286 +#: builtin/describe.c:290 #, c-format msgid "no tag exactly matches '%s'" -msgstr "kein Markierung entspricht exakt '%s'" +msgstr "kein Tag entspricht exakt '%s'" -#: builtin/describe.c:288 +#: builtin/describe.c:292 #, c-format msgid "searching to describe %s\n" msgstr "suche zur Beschreibung von %s\n" -#: builtin/describe.c:328 +#: builtin/describe.c:332 #, c-format msgid "finished search at %s\n" msgstr "beendete Suche bei %s\n" -#: builtin/describe.c:352 +#: builtin/describe.c:359 #, c-format msgid "" "No annotated tags can describe '%s'.\n" "However, there were unannotated tags: try --tags." msgstr "" -"Keine annotierten Markierungen können '%s' beschreiben.\n" -"Jedoch gab es nicht annotierte Markierungen: versuchen Sie --tags." +"Keine annotierten Tags können '%s' beschreiben.\n" +"Jedoch gab es nicht-annotierte Tags: versuchen Sie --tags." -#: builtin/describe.c:356 +#: builtin/describe.c:363 #, c-format msgid "" "No tags can describe '%s'.\n" "Try --always, or create some tags." msgstr "" -"Keine Markierungen können '%s' beschreiben.\n" -"Versuchen Sie --always oder erstellen Sie einige Markierungen." +"Keine Tags können '%s' beschreiben.\n" +"Versuchen Sie --always oder erstellen Sie einige Tags." -#: builtin/describe.c:377 +#: builtin/describe.c:384 #, c-format msgid "traversed %lu commits\n" -msgstr "%lu Versionen durchlaufen\n" +msgstr "%lu Commits durchlaufen\n" -#: builtin/describe.c:380 +#: builtin/describe.c:387 #, c-format msgid "" "more than %i tags found; listed %i most recent\n" "gave up search at %s\n" msgstr "" -"mehr als %i Markierungen gefunden; Führe die ersten %i auf\n" +"mehr als %i Tags gefunden; Führe die ersten %i auf\n" "Suche bei %s aufgegeben\n" -#: builtin/describe.c:402 +#: builtin/describe.c:409 msgid "find the tag that comes after the commit" -msgstr "findet die Markierung, die nach der Version kommt" +msgstr "findet den Tag, die nach Commit kommt" -#: builtin/describe.c:403 +#: builtin/describe.c:410 msgid "debug search strategy on stderr" msgstr "protokolliert die Suchstrategie in der Standard-Fehlerausgabe" -#: builtin/describe.c:404 +#: builtin/describe.c:411 msgid "use any ref" msgstr "verwendet alle Referenzen" -#: builtin/describe.c:405 +#: builtin/describe.c:412 msgid "use any tag, even unannotated" -msgstr "verwendet jede Markierung, auch nicht-annotierte" +msgstr "verwendet jeden Tag, auch nicht-annotierte" -#: builtin/describe.c:406 +#: builtin/describe.c:413 msgid "always use long format" msgstr "verwendet immer langes Format" -#: builtin/describe.c:409 +#: builtin/describe.c:414 +msgid "only follow first parent" +msgstr "folgt nur erstem Elternteil" + +#: builtin/describe.c:417 msgid "only output exact matches" msgstr "gibt nur exakte Übereinstimmungen aus" -#: builtin/describe.c:411 +#: builtin/describe.c:419 msgid "consider most recent tags (default: 10)" -msgstr "betrachtet die jüngsten Markierungen (Standard: 10)" +msgstr "betrachtet die jüngsten Tags (Standard: 10)" -#: builtin/describe.c:413 +#: builtin/describe.c:421 msgid "only consider tags matching " -msgstr "betrachtet nur Markierungen die entsprechen" +msgstr "betrachtet nur Tags die entsprechen" -#: builtin/describe.c:415 builtin/name-rev.c:238 +#: builtin/describe.c:423 builtin/name-rev.c:322 msgid "show abbreviated commit object as fallback" -msgstr "zeigt gekürztes Versionsobjekt, wenn sonst nichts zutrifft" +msgstr "zeigt gekürztes Commit-Objekt, wenn sonst nichts zutrifft" -#: builtin/describe.c:416 +#: builtin/describe.c:424 msgid "mark" msgstr "Kennzeichen" -#: builtin/describe.c:417 +#: builtin/describe.c:425 msgid "append on dirty working tree (default: \"-dirty\")" msgstr "" -"fügt bei geändertem Arbeitsbaum hinzu (Standard: \"-dirty\")" +"fügt bei geändertem Arbeitsverzeichnis hinzu (Standard: \"-" +"dirty\")" -#: builtin/describe.c:435 +#: builtin/describe.c:443 msgid "--long is incompatible with --abbrev=0" msgstr "Die Optionen --long und --abbrev=0 sind inkompatibel." -#: builtin/describe.c:461 +#: builtin/describe.c:469 msgid "No names found, cannot describe anything." msgstr "Keine Namen gefunden, kann nichts beschreiben." -#: builtin/describe.c:481 +#: builtin/describe.c:489 msgid "--dirty is incompatible with committishes" -msgstr "Die Option --dirty kann nicht mit Versionen verwendet werden." +msgstr "Die Option --dirty kann nicht mit Commits verwendet werden." #: builtin/diff.c:79 #, c-format msgid "'%s': not a regular file or symlink" -msgstr "'%s': keine reguläre Datei oder symbolischer Link" +msgstr "'%s': keine reguläre Datei oder symbolischer Verweis" -#: builtin/diff.c:228 +#: builtin/diff.c:230 #, c-format msgid "invalid option: %s" msgstr "Ungültige Option: %s" -#: builtin/diff.c:305 +#: builtin/diff.c:307 msgid "Not a git repository" -msgstr "Kein Git-Projektarchiv" +msgstr "Kein Git-Repository" -#: builtin/diff.c:348 +#: builtin/diff.c:350 #, c-format msgid "invalid object '%s' given." msgstr "Objekt '%s' ist ungültig." -#: builtin/diff.c:353 -#, c-format -msgid "more than %d trees given: '%s'" -msgstr "Mehr als %d Zweige angegeben: '%s'" - -#: builtin/diff.c:363 +#: builtin/diff.c:359 #, c-format msgid "more than two blobs given: '%s'" msgstr "Mehr als zwei Blobs angegeben: '%s'" -#: builtin/diff.c:371 +#: builtin/diff.c:366 #, c-format msgid "unhandled object '%s' given." msgstr "unbehandeltes Objekt '%s' angegeben" @@ -4623,46 +4858,45 @@ msgstr "unbehandeltes Objekt '%s' angegeben" msgid "git fast-export [rev-list-opts]" msgstr "git fast-export [rev-list-opts]" -#: builtin/fast-export.c:658 +#: builtin/fast-export.c:666 msgid "show progress after objects" msgstr "zeigt Fortschritt nach Objekten an" -#: builtin/fast-export.c:660 +#: builtin/fast-export.c:668 msgid "select handling of signed tags" -msgstr "wählt Behandlung von signierten Markierungen" +msgstr "wählt Behandlung von signierten Tags" -#: builtin/fast-export.c:663 +#: builtin/fast-export.c:671 msgid "select handling of tags that tag filtered objects" -msgstr "wählt Behandlung von Markierungen, die gefilterte Objekte markieren" +msgstr "wählt Behandlung von Tags, die gefilterte Objekte markieren" -#: builtin/fast-export.c:666 +#: builtin/fast-export.c:674 msgid "Dump marks to this file" msgstr "Schreibt Kennzeichen in diese Datei" -#: builtin/fast-export.c:668 +#: builtin/fast-export.c:676 msgid "Import marks from this file" msgstr "Importiert Kennzeichen von dieser Datei" -#: builtin/fast-export.c:670 +#: builtin/fast-export.c:678 msgid "Fake a tagger when tags lack one" -msgstr "" -"erzeugt künstlich einen Markierungsersteller, wenn die Markierung keinen hat" +msgstr "erzeugt künstlich einen Tag-Ersteller, wenn der Tag keinen hat" -#: builtin/fast-export.c:672 +#: builtin/fast-export.c:680 msgid "Output full tree for each commit" -msgstr "gibt für jede Version den gesamten Baum aus" +msgstr "gibt für jeden Commit das gesamte Verzeichnis aus" -#: builtin/fast-export.c:674 +#: builtin/fast-export.c:682 msgid "Use the done feature to terminate the stream" msgstr "Benutzt die \"done\"-Funktion um den Strom abzuschließen" -#: builtin/fast-export.c:675 +#: builtin/fast-export.c:683 msgid "Skip output of blob data" msgstr "Überspringt Ausgabe von Blob-Daten" #: builtin/fetch.c:20 msgid "git fetch [] [ [...]]" -msgstr "git fetch [] [ [...]]" +msgstr "git fetch [] [ [...]]" #: builtin/fetch.c:21 msgid "git fetch [] " @@ -4670,7 +4904,7 @@ msgstr "git fetch [] " #: builtin/fetch.c:22 msgid "git fetch --multiple [] [( | )...]" -msgstr "git fetch --multiple [] [( | )...]" +msgstr "git fetch --multiple [] [( | )...]" #: builtin/fetch.c:23 msgid "git fetch --all []" @@ -4678,7 +4912,7 @@ msgstr "git fetch --all []" #: builtin/fetch.c:60 msgid "fetch from all remotes" -msgstr "fordert von allen externen Projektarchiven an" +msgstr "fordert von allen Remote-Repositories an" #: builtin/fetch.c:62 msgid "append to .git/FETCH_HEAD instead of overwriting" @@ -4690,24 +4924,25 @@ 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" +msgstr "erzwingt das Überschreiben von lokalen Branches" #: builtin/fetch.c:67 msgid "fetch from multiple remotes" -msgstr "fordert von mehreren externen Projektarchiven an" +msgstr "fordert von mehreren Remote-Repositories an" #: builtin/fetch.c:69 msgid "fetch all tags and associated objects" -msgstr "fordert alle Markierungen und verbundene Objekte an" +msgstr "fordert alle Tags und verbundene Objekte an" #: builtin/fetch.c:71 msgid "do not fetch all tags (--no-tags)" -msgstr "fordert nicht alle Markierungen an (--no-tags)" +msgstr "fordert nicht alle Tags 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" +"entfernt Remote-Tracking-Branches, die sich nicht mehr im Remote-Repository " +"befinden" #: builtin/fetch.c:74 msgid "on-demand" @@ -4715,7 +4950,7 @@ msgstr "bei-Bedarf" #: builtin/fetch.c:75 msgid "control recursive fetching of submodules" -msgstr "kontrolliert rekursive Anforderungen von Unterprojekten" +msgstr "kontrolliert rekursive Anforderungen von Submodulen" #: builtin/fetch.c:79 msgid "keep downloaded pack" @@ -4727,203 +4962,204 @@ msgstr "erlaubt Aktualisierung der \"HEAD\"-Referenz" #: builtin/fetch.c:84 msgid "deepen history of shallow clone" -msgstr "vertieft die Historie eines flachen Klon" +msgstr "vertieft die Historie eines flachen Klons" #: builtin/fetch.c:86 msgid "convert to a complete repository" -msgstr "konvertiert zu einem vollständigen Projektarchiv" +msgstr "konvertiert zu einem vollständigen Repository" -#: builtin/fetch.c:88 builtin/log.c:1130 +#: builtin/fetch.c:88 builtin/log.c:1177 msgid "dir" msgstr "Verzeichnis" #: builtin/fetch.c:89 msgid "prepend this to submodule path output" -msgstr "stellt dies an die Ausgabe der Unterprojekt-Pfade voran" +msgstr "stellt dies an die Ausgabe der Submodul-Pfade voran" #: builtin/fetch.c:92 msgid "default mode for recursion" msgstr "Standard-Modus für Rekursion" -#: builtin/fetch.c:204 +#: builtin/fetch.c:220 msgid "Couldn't find remote ref HEAD" -msgstr "Konnte externe Referenz der Zweigspitze (HEAD) nicht finden." +msgstr "Konnte Remote-Referenz von HEAD nicht finden." -#: builtin/fetch.c:257 +#: builtin/fetch.c:273 #, c-format msgid "object %s not found" msgstr "Objekt %s nicht gefunden" -#: builtin/fetch.c:262 +#: builtin/fetch.c:278 msgid "[up to date]" msgstr "[aktuell]" -#: builtin/fetch.c:276 +#: builtin/fetch.c:292 #, c-format msgid "! %-*s %-*s -> %s (can't fetch in current branch)" -msgstr "! %-*s %-*s -> %s (kann nicht im aktuellen Zweig anfordern)" +msgstr "" +"! %-*s %-*s -> %s (kann \"fetch\" im aktuellen Branch nicht ausführen)" -#: builtin/fetch.c:277 builtin/fetch.c:363 +#: builtin/fetch.c:293 builtin/fetch.c:379 msgid "[rejected]" msgstr "[zurückgewiesen]" -#: builtin/fetch.c:288 +#: builtin/fetch.c:304 msgid "[tag update]" -msgstr "[Markierungsaktualisierung]" +msgstr "[Tag Aktualisierung]" -#: builtin/fetch.c:290 builtin/fetch.c:325 builtin/fetch.c:343 +#: builtin/fetch.c:306 builtin/fetch.c:341 builtin/fetch.c:359 msgid " (unable to update local ref)" msgstr " (kann lokale Referenz nicht aktualisieren)" -#: builtin/fetch.c:308 +#: builtin/fetch.c:324 msgid "[new tag]" -msgstr "[neue Markierung]" +msgstr "[neuer Tag]" -#: builtin/fetch.c:311 +#: builtin/fetch.c:327 msgid "[new branch]" -msgstr "[neuer Zweig]" +msgstr "[neuer Branch]" -#: builtin/fetch.c:314 +#: builtin/fetch.c:330 msgid "[new ref]" msgstr "[neue Referenz]" -#: builtin/fetch.c:359 +#: builtin/fetch.c:375 msgid "unable to update local ref" msgstr "kann lokale Referenz nicht aktualisieren" -#: builtin/fetch.c:359 +#: builtin/fetch.c:375 msgid "forced update" msgstr "Aktualisierung erzwungen" -#: builtin/fetch.c:365 +#: builtin/fetch.c:381 msgid "(non-fast-forward)" msgstr "(kein Vorspulen)" -#: builtin/fetch.c:396 builtin/fetch.c:688 +#: builtin/fetch.c:412 builtin/fetch.c:718 #, c-format msgid "cannot open %s: %s\n" msgstr "kann %s nicht öffnen: %s\n" -#: builtin/fetch.c:405 +#: builtin/fetch.c:421 #, c-format msgid "%s did not send all necessary objects\n" msgstr "%s hat nicht alle erforderlichen Objekte gesendet\n" -#: builtin/fetch.c:491 +#: builtin/fetch.c:520 #, c-format msgid "From %.*s\n" msgstr "Von %.*s\n" -#: builtin/fetch.c:502 +#: builtin/fetch.c:531 #, c-format msgid "" "some local refs could not be updated; try running\n" " 'git remote prune %s' to remove any old, conflicting branches" msgstr "" "Einige lokale Referenzen konnten nicht aktualisiert werden; versuchen Sie\n" -"'git remote prune %s' um jeden älteren, widersprüchlichen Zweig zu löschen." +"'git remote prune %s' um jeden älteren, widersprüchlichen Branch zu löschen." -#: builtin/fetch.c:552 +#: builtin/fetch.c:581 #, c-format msgid " (%s will become dangling)" msgstr " (%s wird unreferenziert)" -#: builtin/fetch.c:553 +#: builtin/fetch.c:582 #, c-format msgid " (%s has become dangling)" msgstr " (%s wurde unreferenziert)" -#: builtin/fetch.c:560 +#: builtin/fetch.c:589 msgid "[deleted]" msgstr "[gelöscht]" -#: builtin/fetch.c:561 builtin/remote.c:1055 +#: builtin/fetch.c:590 builtin/remote.c:1055 msgid "(none)" msgstr "(nichts)" -#: builtin/fetch.c:678 +#: builtin/fetch.c:708 #, c-format msgid "Refusing to fetch into current branch %s of non-bare repository" msgstr "" -"Das Anfordern in den aktuellen Zweig %s von einem nicht-bloßen Projektarchiv " +"Der \"fetch\" in den aktuellen Branch %s von einem nicht-Bare-Repository " "wurde verweigert." -#: builtin/fetch.c:712 +#: builtin/fetch.c:742 #, c-format msgid "Don't know how to fetch from %s" msgstr "Weiß nicht wie von %s angefordert wird." -#: builtin/fetch.c:789 +#: builtin/fetch.c:823 #, c-format msgid "Option \"%s\" value \"%s\" is not valid for %s" msgstr "Option \"%s\" Wert \"%s\" ist nicht gültig für %s" -#: builtin/fetch.c:792 +#: builtin/fetch.c:826 #, c-format msgid "Option \"%s\" is ignored for %s\n" msgstr "Option \"%s\" wird ignoriert für %s\n" -#: builtin/fetch.c:894 +#: builtin/fetch.c:928 #, c-format msgid "Fetching %s\n" msgstr "Fordere an von %s\n" -#: builtin/fetch.c:896 builtin/remote.c:100 +#: builtin/fetch.c:930 builtin/remote.c:100 #, c-format msgid "Could not fetch %s" msgstr "Konnte nicht von %s anfordern" -#: builtin/fetch.c:915 +#: builtin/fetch.c:949 msgid "" "No remote repository specified. Please, specify either a URL or a\n" "remote name from which new revisions should be fetched." msgstr "" -"Kein externes Projektarchiv angegeben. Bitte geben Sie entweder eine URL\n" -"oder den Namen des externen Archivs an, von welchem neue\n" -"Revisionen angefordert werden sollen." +"Kein Remote-Repository angegeben. Bitte geben Sie entweder eine URL\n" +"oder den Namen des Remote-Repositories an, von welchem neue\n" +"Commits angefordert werden sollen." -#: builtin/fetch.c:935 +#: builtin/fetch.c:969 msgid "You need to specify a tag name." -msgstr "Sie müssen den Namen der Markierung angeben." +msgstr "Sie müssen den Namen des Tags angeben." -#: builtin/fetch.c:981 +#: builtin/fetch.c:1015 msgid "--depth and --unshallow cannot be used together" msgstr "" "Die Optionen --depth und --unshallow können nicht gemeinsam verwendet werden." -#: builtin/fetch.c:983 +#: builtin/fetch.c:1017 msgid "--unshallow on a complete repository does not make sense" msgstr "" -"Die Option --unshallow kann nicht in einem vollständigen Projektarchiv " +"Die Option --unshallow kann nicht in einem vollständigen Repository " "verwendet werden." -#: builtin/fetch.c:1002 +#: builtin/fetch.c:1036 msgid "fetch --all does not take a repository argument" -msgstr "fetch --all akzeptiert kein Projektarchiv als Argument" +msgstr "fetch --all akzeptiert kein Repository als Argument" -#: builtin/fetch.c:1004 +#: builtin/fetch.c:1038 msgid "fetch --all does not make sense with refspecs" -msgstr "fetch --all kann nicht mit Referenzspezifikationen verwendet werden." +msgstr "fetch --all kann nicht mit Refspecs verwendet werden." -#: builtin/fetch.c:1015 +#: builtin/fetch.c:1049 #, c-format msgid "No such remote or remote group: %s" -msgstr "Kein externes Archiv (einzeln oder Gruppe): %s" +msgstr "Kein Remote-Repository (einzeln oder Gruppe): %s" -#: builtin/fetch.c:1023 +#: builtin/fetch.c:1057 msgid "Fetching a group and specifying refspecs does not make sense" msgstr "" -"Das Abholen einer Gruppe von externen Archiven kann nicht mit der Angabe\n" -"von Referenzspezifikationen verwendet werden." +"Das Abholen einer Gruppe von Remote-Repositories kann nicht mit der Angabe\n" +"von Refspecs verwendet werden." #: builtin/fmt-merge-msg.c:13 msgid "git fmt-merge-msg [-m ] [--log[=]|--no-log] [--file ]" msgstr "" "git fmt-merge-msg [-m ] [--log[=]|--no-log] [--file ]" -#: builtin/fmt-merge-msg.c:663 builtin/fmt-merge-msg.c:666 builtin/grep.c:701 -#: builtin/merge.c:188 builtin/show-branch.c:655 builtin/show-ref.c:175 -#: builtin/tag.c:446 parse-options.h:133 parse-options.h:239 +#: builtin/fmt-merge-msg.c:663 builtin/fmt-merge-msg.c:666 builtin/grep.c:700 +#: builtin/merge.c:203 builtin/show-branch.c:655 builtin/show-ref.c:179 +#: builtin/tag.c:446 parse-options.h:133 parse-options.h:243 msgid "n" msgstr "Anzahl" @@ -5001,7 +5237,7 @@ msgstr "zeigt unreferenzierte Objekte" #: builtin/fsck.c:616 msgid "report tags" -msgstr "meldet Markierungen" +msgstr "meldet Tags" #: builtin/fsck.c:617 msgid "report root nodes" @@ -5009,11 +5245,11 @@ msgstr "meldet Hauptwurzeln" #: builtin/fsck.c:618 msgid "make index objects head nodes" -msgstr "erzeugt Kopfknoten der Bereitstellungsobjekte" +msgstr "prüft Objekte in der Staging-Area" #: builtin/fsck.c:619 msgid "make reflogs head nodes (default)" -msgstr "erzeugt Kopfknoten des Referenzprotokolls (Standard)" +msgstr "prüft die Reflogs (Standard)" #: builtin/fsck.c:620 msgid "also consider packs and alternate objects" @@ -5063,7 +5299,7 @@ msgid "" "Auto packing the repository for optimum performance. You may also\n" "run \"git gc\" manually. See \"git help gc\" for more information.\n" msgstr "" -"Die Datenbank des Projektarchivs wird für eine optimale Performance\n" +"Die Datenbank des Repositories wird für eine optimale Performance\n" "komprimiert. Sie können auch \"git gc\" manuell ausführen.\n" "Siehe \"git help gc\" für weitere Informationen.\n" @@ -5076,240 +5312,240 @@ msgstr "" #: builtin/grep.c:22 msgid "git grep [options] [-e] [...] [[--] ...]" -msgstr "git grep [Optionen] [-e] [...] [[--] ...]" +msgstr "git grep [Optionen] [-e] [...] [[--] ...]" #: builtin/grep.c:217 #, c-format msgid "grep: failed to create thread: %s" msgstr "grep: Fehler beim Erzeugen eines Thread: %s" -#: builtin/grep.c:365 +#: builtin/grep.c:364 #, c-format msgid "Failed to chdir: %s" msgstr "Fehler beim Verzeichniswechsel: %s" -#: builtin/grep.c:443 builtin/grep.c:478 +#: builtin/grep.c:442 builtin/grep.c:477 #, c-format msgid "unable to read tree (%s)" -msgstr "konnte Zweig (%s) nicht lesen" +msgstr "konnte \"Tree\"-Objekt (%s) nicht lesen" -#: builtin/grep.c:493 +#: builtin/grep.c:492 #, 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:551 +#: builtin/grep.c:550 #, c-format msgid "switch `%c' expects a numerical value" msgstr "Schalter '%c' erwartet einen numerischen Wert" -#: builtin/grep.c:568 +#: builtin/grep.c:567 #, c-format msgid "cannot open '%s'" msgstr "kann '%s' nicht öffnen" -#: builtin/grep.c:643 +#: builtin/grep.c:642 msgid "search in index instead of in the work tree" -msgstr "sucht in der Bereitstellung anstatt im Arbeitsbaum" +msgstr "sucht in der Staging-Area anstatt im Arbeitsverzeichnis" -#: builtin/grep.c:645 +#: builtin/grep.c:644 msgid "find in contents not managed by git" msgstr "findet auch in Inhalten, die nicht von Git verwaltet werden" -#: builtin/grep.c:647 +#: builtin/grep.c:646 msgid "search in both tracked and untracked files" msgstr "sucht in beobachteten und unbeobachteten Dateien" -#: builtin/grep.c:649 +#: builtin/grep.c:648 msgid "search also in ignored files" msgstr "sucht auch in ignorierten Dateien" -#: builtin/grep.c:652 +#: builtin/grep.c:651 msgid "show non-matching lines" msgstr "zeigt Zeilen ohne Übereinstimmungen" -#: builtin/grep.c:654 +#: builtin/grep.c:653 msgid "case insensitive matching" msgstr "findet Übereinstimmungen unabhängig von Groß- und Kleinschreibung" -#: builtin/grep.c:656 +#: builtin/grep.c:655 msgid "match patterns only at word boundaries" msgstr "sucht nur ganze Wörter" -#: builtin/grep.c:658 +#: builtin/grep.c:657 msgid "process binary files as text" msgstr "verarbeitet binäre Dateien als Text" -#: builtin/grep.c:660 +#: builtin/grep.c:659 msgid "don't match patterns in binary files" msgstr "findet keine Muster in Binärdateien" -#: builtin/grep.c:663 +#: builtin/grep.c:662 msgid "descend at most levels" msgstr "durchläuft höchstens Ebenen" -#: builtin/grep.c:667 +#: builtin/grep.c:666 msgid "use extended POSIX regular expressions" msgstr "verwendet erweiterte reguläre Ausdrücke aus POSIX" -#: builtin/grep.c:670 +#: builtin/grep.c:669 msgid "use basic POSIX regular expressions (default)" msgstr "verwendet grundlegende reguläre Ausdrücke aus POSIX (Standard)" -#: builtin/grep.c:673 +#: builtin/grep.c:672 msgid "interpret patterns as fixed strings" msgstr "interpretiert Muster als feste Zeichenketten" -#: builtin/grep.c:676 +#: builtin/grep.c:675 msgid "use Perl-compatible regular expressions" msgstr "verwendet Perl-kompatible reguläre Ausdrücke" -#: builtin/grep.c:679 +#: builtin/grep.c:678 msgid "show line numbers" msgstr "zeigt Zeilennummern" -#: builtin/grep.c:680 +#: builtin/grep.c:679 msgid "don't show filenames" msgstr "zeigt keine Dateinamen" -#: builtin/grep.c:681 +#: builtin/grep.c:680 msgid "show filenames" msgstr "zeigt Dateinamen" -#: builtin/grep.c:683 +#: builtin/grep.c:682 msgid "show filenames relative to top directory" msgstr "zeigt Dateinamen relativ zum Projektverzeichnis" -#: builtin/grep.c:685 +#: builtin/grep.c:684 msgid "show only filenames instead of matching lines" msgstr "zeigt nur Dateinamen anstatt übereinstimmende Zeilen" -#: builtin/grep.c:687 +#: builtin/grep.c:686 msgid "synonym for --files-with-matches" msgstr "Synonym für --files-with-matches" -#: builtin/grep.c:690 +#: builtin/grep.c:689 msgid "show only the names of files without match" msgstr "zeigt nur die Dateinamen ohne Übereinstimmungen" -#: builtin/grep.c:692 +#: builtin/grep.c:691 msgid "print NUL after filenames" msgstr "gibt NUL-Zeichen nach Dateinamen aus" -#: builtin/grep.c:694 +#: builtin/grep.c:693 msgid "show the number of matches instead of matching lines" msgstr "zeigt, anstatt der Zeilen, die Anzahl der übereinstimmenden Zeilen" -#: builtin/grep.c:695 +#: builtin/grep.c:694 msgid "highlight matches" msgstr "hebt Übereinstimmungen hervor" -#: builtin/grep.c:697 +#: builtin/grep.c:696 msgid "print empty line between matches from different files" msgstr "" "gibt eine Leerzeile zwischen Übereinstimmungen in verschiedenen Dateien aus" -#: builtin/grep.c:699 +#: builtin/grep.c:698 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 +#: builtin/grep.c:701 msgid "show context lines before and after matches" msgstr "zeigt Zeilen vor und nach den Übereinstimmungen an" -#: builtin/grep.c:705 +#: builtin/grep.c:704 msgid "show context lines before matches" msgstr "zeigt Zeilen vor den Übereinstimmungen an" -#: builtin/grep.c:707 +#: builtin/grep.c:706 msgid "show context lines after matches" msgstr "zeigt Zeilen nach den Übereinstimmungen an" -#: builtin/grep.c:708 +#: builtin/grep.c:707 msgid "shortcut for -C NUM" msgstr "Kurzform für -C NUM" -#: builtin/grep.c:711 +#: builtin/grep.c:710 msgid "show a line with the function name before matches" msgstr "zeigt eine Zeile mit dem Funktionsnamen vor Übereinstimmungen an" -#: builtin/grep.c:713 +#: builtin/grep.c:712 msgid "show the surrounding function" msgstr "zeigt die umgebende Funktion an" -#: builtin/grep.c:716 +#: builtin/grep.c:715 msgid "read patterns from file" msgstr "liest Muster von einer Datei" -#: builtin/grep.c:718 +#: builtin/grep.c:717 msgid "match " msgstr "findet " -#: builtin/grep.c:720 +#: builtin/grep.c:719 msgid "combine patterns specified with -e" msgstr "kombiniert Muster, die mit -e angegeben wurden" -#: builtin/grep.c:732 +#: builtin/grep.c:731 msgid "indicate hit with exit status without output" msgstr "zeigt Übereinstimmungen nur durch Beendigungsstatus an" -#: builtin/grep.c:734 +#: builtin/grep.c:733 msgid "show only matches from files that match all patterns" msgstr "zeigt nur Übereinstimmungen von Dateien, die allen Mustern entsprechen" -#: builtin/grep.c:736 +#: builtin/grep.c:735 msgid "show parse tree for grep expression" -msgstr "zeigt geparsten Baum für \"grep\"-Ausdruck" +msgstr "zeigt geparstes Verzeichnis für \"grep\"-Ausdruck" -#: builtin/grep.c:740 +#: builtin/grep.c:739 msgid "pager" msgstr "Anzeigeprogramm" -#: builtin/grep.c:740 +#: builtin/grep.c:739 msgid "show matching files in the pager" msgstr "zeigt Dateien mit Übereinstimmungen im Anzeigeprogramm" -#: builtin/grep.c:743 +#: builtin/grep.c:742 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 +#: builtin/grep.c:743 builtin/show-ref.c:188 msgid "show usage" msgstr "zeigt Verwendung" -#: builtin/grep.c:811 +#: builtin/grep.c:810 msgid "no pattern given." msgstr "keine Muster angegeben" -#: builtin/grep.c:866 +#: builtin/grep.c:865 msgid "--open-files-in-pager only works on the worktree" msgstr "" -"Die Option --open-files-in-pager kann nur innerhalb des Arbeitsbaums " -"verwendet werden." +"Die Option --open-files-in-pager kann nur innerhalb des " +"Arbeitsverzeichnisses verwendet werden." -#: builtin/grep.c:889 +#: builtin/grep.c:888 msgid "--cached or --untracked cannot be used with --no-index." msgstr "" "Die Optionen --cached und --untracked können nicht mit --no-index verwendet " "werden." -#: builtin/grep.c:894 +#: builtin/grep.c:893 msgid "--no-index or --untracked cannot be used with revs." msgstr "" -"Die Optionen --no-index und --untracked können nicht mit Versionen verwendet " +"Die Optionen --no-index und --untracked können nicht mit Commits verwendet " "werden." -#: builtin/grep.c:897 +#: builtin/grep.c:896 msgid "--[no-]exclude-standard cannot be used for tracked contents." msgstr "" "Die Option --[no-]exclude-standard kann nicht mit beobachteten Inhalten " "verwendet werden." -#: builtin/grep.c:905 +#: builtin/grep.c:904 msgid "both --cached and trees are given." -msgstr "Die Option --cached kann nicht mit Zweigen verwendet werden." +msgstr "Die Option --cached kann nicht mit \"Tree\"-Objekten verwendet werden." #: builtin/hash-object.c:60 msgid "" @@ -5347,54 +5583,54 @@ msgstr "speichert Datei wie sie ist, ohne Filter" msgid "process file as it were from this path" msgstr "verarbeitet Datei, als ob sie von diesem Pfad wäre" -#: builtin/help.c:43 +#: builtin/help.c:41 msgid "print all available commands" msgstr "Anzeige aller vorhandenen Kommandos" -#: builtin/help.c:44 +#: builtin/help.c:42 msgid "print list of useful guides" msgstr "zeigt Liste von allgemein verwendeten Anleitungen" -#: builtin/help.c:45 +#: builtin/help.c:43 msgid "show man page" msgstr "zeigt Handbuch" -#: builtin/help.c:46 +#: builtin/help.c:44 msgid "show manual in web browser" msgstr "zeigt Handbuch in einem Webbrowser" -#: builtin/help.c:48 +#: builtin/help.c:46 msgid "show info page" msgstr "zeigt Info-Seite" -#: builtin/help.c:54 +#: builtin/help.c:52 msgid "git help [--all] [--guides] [--man|--web|--info] [command]" msgstr "git help [--all] [--guides] [--man|--web|--info] [Kommando]" -#: builtin/help.c:66 +#: builtin/help.c:64 #, c-format msgid "unrecognized help format '%s'" msgstr "nicht erkanntes Hilfeformat: %s" -#: builtin/help.c:94 +#: builtin/help.c:92 msgid "Failed to start emacsclient." msgstr "Konnte emacsclient nicht starten." -#: builtin/help.c:107 +#: builtin/help.c:105 msgid "Failed to parse emacsclient version." msgstr "Konnte Version des emacsclient nicht parsen." -#: builtin/help.c:115 +#: builtin/help.c:113 #, c-format msgid "emacsclient version '%d' too old (< 22)." msgstr "Version des emacsclient '%d' ist zu alt (< 22)." -#: builtin/help.c:133 builtin/help.c:161 builtin/help.c:170 builtin/help.c:178 +#: builtin/help.c:131 builtin/help.c:159 builtin/help.c:168 builtin/help.c:176 #, c-format msgid "failed to exec '%s': %s" msgstr "Fehler beim Ausführen von '%s': %s" -#: builtin/help.c:218 +#: builtin/help.c:216 #, c-format msgid "" "'%s': path for unsupported man viewer.\n" @@ -5403,7 +5639,7 @@ msgstr "" "'%s': Pfad für nicht unterstützten Handbuchbetrachter.\n" "Sie könnten stattdessen 'man..cmd' benutzen." -#: builtin/help.c:230 +#: builtin/help.c:228 #, c-format msgid "" "'%s': cmd for supported man viewer.\n" @@ -5412,336 +5648,336 @@ msgstr "" "'%s': Kommando für unterstützten Handbuchbetrachter.\n" "Sie könnten stattdessen 'man..path' benutzen." -#: builtin/help.c:351 +#: builtin/help.c:349 #, c-format msgid "'%s': unknown man viewer." msgstr "'%s': unbekannter Handbuch-Betrachter." -#: builtin/help.c:368 +#: builtin/help.c:366 msgid "no man viewer handled the request" msgstr "kein Handbuch-Betrachter konnte mit dieser Anfrage umgehen" -#: builtin/help.c:376 +#: builtin/help.c:374 msgid "no info viewer handled the request" msgstr "kein Informations-Betrachter konnte mit dieser Anfrage umgehen" -#: builtin/help.c:422 +#: builtin/help.c:420 msgid "Defining attributes per path" msgstr "Definition von Attributen pro Pfad" -#: builtin/help.c:423 +#: builtin/help.c:421 msgid "A Git glossary" msgstr "Ein Git-Glossar" -#: builtin/help.c:424 +#: builtin/help.c:422 msgid "Specifies intentionally untracked files to ignore" msgstr "Spezifikation von bewusst ignorierten, unbeobachteten Dateien" -#: builtin/help.c:425 +#: builtin/help.c:423 msgid "Defining submodule properties" -msgstr "Definition von Unterprojekt-Eigenschaften" +msgstr "Definition von Submodul-Eigenschaften" -#: builtin/help.c:426 +#: builtin/help.c:424 msgid "Specifying revisions and ranges for Git" -msgstr "Spezifikation von Revisionen und Bereichen für Git" +msgstr "Spezifikation von Commits und Bereichen für Git" -#: builtin/help.c:427 +#: builtin/help.c:425 msgid "A tutorial introduction to Git (for version 1.5.1 or newer)" msgstr "Eine einführende Anleitung zu Git (für Version 1.5.1 oder neuer)" -#: builtin/help.c:428 +#: builtin/help.c:426 msgid "An overview of recommended workflows with Git" msgstr "Eine Übersicht über empfohlene Arbeitsabläufe mit Git" -#: builtin/help.c:440 +#: builtin/help.c:438 msgid "The common Git guides are:\n" msgstr "Die allgemein verwendeten Git-Anleitungen sind:\n" -#: builtin/help.c:462 builtin/help.c:478 +#: builtin/help.c:460 builtin/help.c:476 #, c-format msgid "usage: %s%s" msgstr "Verwendung: %s%s" -#: builtin/help.c:494 +#: builtin/help.c:492 #, c-format msgid "`git %s' is aliased to `%s'" msgstr "für `git %s' wurde der Alias `%s' angelegt" -#: builtin/index-pack.c:182 +#: builtin/index-pack.c:184 #, c-format msgid "object type mismatch at %s" msgstr "Objekt-Typen passen bei %s nicht zusammen" -#: builtin/index-pack.c:202 +#: builtin/index-pack.c:204 msgid "object of unexpected type" msgstr "Objekt hat unerwarteten Typ" -#: builtin/index-pack.c:239 +#: builtin/index-pack.c:244 #, c-format msgid "cannot fill %d byte" msgid_plural "cannot fill %d bytes" msgstr[0] "kann %d Byte nicht lesen" msgstr[1] "kann %d Bytes nicht lesen" -#: builtin/index-pack.c:249 +#: builtin/index-pack.c:254 msgid "early EOF" msgstr "zu frühes Dateiende" -#: builtin/index-pack.c:250 +#: builtin/index-pack.c:255 msgid "read error on input" msgstr "Fehler beim Lesen der Eingabe" -#: builtin/index-pack.c:262 +#: builtin/index-pack.c:267 msgid "used more bytes than were available" msgstr "verwendete mehr Bytes als verfügbar waren" -#: builtin/index-pack.c:269 +#: builtin/index-pack.c:274 msgid "pack too large for current definition of off_t" msgstr "Paket ist zu groß für die aktuelle Definition von off_t" -#: builtin/index-pack.c:285 +#: builtin/index-pack.c:290 #, c-format msgid "unable to create '%s'" msgstr "konnte '%s' nicht erstellen" -#: builtin/index-pack.c:290 +#: builtin/index-pack.c:295 #, c-format msgid "cannot open packfile '%s'" msgstr "Kann Paketdatei '%s' nicht öffnen" -#: builtin/index-pack.c:304 +#: builtin/index-pack.c:309 msgid "pack signature mismatch" msgstr "Paketsignatur stimmt nicht überein" -#: builtin/index-pack.c:306 +#: builtin/index-pack.c:311 #, c-format msgid "pack version % unsupported" msgstr "Paketversion % nicht unterstützt" -#: builtin/index-pack.c:324 +#: builtin/index-pack.c:329 #, c-format msgid "pack has bad object at offset %lu: %s" msgstr "Paket hat ein ungültiges Objekt bei Versatz %lu: %s" -#: builtin/index-pack.c:446 +#: builtin/index-pack.c:451 #, c-format msgid "inflate returned %d" msgstr "Dekomprimierung gab %d zurück" -#: builtin/index-pack.c:495 +#: builtin/index-pack.c:500 msgid "offset value overflow for delta base object" msgstr "Wert für Versatz bei Differenzobjekt übergelaufen" -#: builtin/index-pack.c:503 +#: builtin/index-pack.c:508 msgid "delta base offset is out of bound" msgstr "" "Wert für Versatz bei Differenzobjekt liegt außerhalb des gültigen Bereichs" -#: builtin/index-pack.c:511 +#: builtin/index-pack.c:516 #, c-format msgid "unknown object type %d" msgstr "Unbekannter Objekt-Typ %d" -#: builtin/index-pack.c:542 +#: builtin/index-pack.c:547 msgid "cannot pread pack file" msgstr "Kann Paketdatei %s nicht lesen" -#: builtin/index-pack.c:544 +#: builtin/index-pack.c:549 #, c-format msgid "premature end of pack file, %lu byte missing" msgid_plural "premature end of pack file, %lu bytes missing" msgstr[0] "frühzeitiges Ende der Paketdatei, vermisse %lu Byte" msgstr[1] "frühzeitiges Ende der Paketdatei, vermisse %lu Bytes" -#: builtin/index-pack.c:570 +#: builtin/index-pack.c:575 msgid "serious inflate inconsistency" msgstr "ernsthafte Inkonsistenz nach Dekomprimierung" -#: builtin/index-pack.c:661 builtin/index-pack.c:667 builtin/index-pack.c:690 -#: builtin/index-pack.c:724 builtin/index-pack.c:733 +#: builtin/index-pack.c:666 builtin/index-pack.c:672 builtin/index-pack.c:695 +#: builtin/index-pack.c:729 builtin/index-pack.c:738 #, c-format msgid "SHA1 COLLISION FOUND WITH %s !" msgstr "SHA1 KOLLISION MIT %s GEFUNDEN !" -#: builtin/index-pack.c:664 builtin/pack-objects.c:170 +#: builtin/index-pack.c:669 builtin/pack-objects.c:170 #: builtin/pack-objects.c:262 #, c-format msgid "unable to read %s" msgstr "kann %s nicht lesen" -#: builtin/index-pack.c:730 +#: builtin/index-pack.c:735 #, c-format msgid "cannot read existing object %s" msgstr "Kann existierendes Objekt %s nicht lesen." -#: builtin/index-pack.c:744 +#: builtin/index-pack.c:749 #, c-format msgid "invalid blob object %s" msgstr "ungültiges Blob-Objekt %s" -#: builtin/index-pack.c:759 +#: builtin/index-pack.c:763 #, c-format msgid "invalid %s" msgstr "Ungültiger Objekt-Typ %s" -#: builtin/index-pack.c:761 +#: builtin/index-pack.c:766 msgid "Error in object" msgstr "Fehler in Objekt" -#: builtin/index-pack.c:763 +#: builtin/index-pack.c:768 #, c-format msgid "Not all child objects of %s are reachable" msgstr "Nicht alle Kind-Objekte von %s sind erreichbar" -#: builtin/index-pack.c:833 builtin/index-pack.c:863 +#: builtin/index-pack.c:838 builtin/index-pack.c:868 msgid "failed to apply delta" msgstr "Konnte Dateiunterschied nicht anwenden" -#: builtin/index-pack.c:1004 +#: builtin/index-pack.c:1009 msgid "Receiving objects" msgstr "Empfange Objekte" -#: builtin/index-pack.c:1004 +#: builtin/index-pack.c:1009 msgid "Indexing objects" msgstr "Indiziere Objekte" -#: builtin/index-pack.c:1030 +#: builtin/index-pack.c:1035 msgid "pack is corrupted (SHA1 mismatch)" msgstr "Paket ist beschädigt (SHA1 unterschiedlich)" -#: builtin/index-pack.c:1035 +#: builtin/index-pack.c:1040 msgid "cannot fstat packfile" msgstr "kann Paketdatei nicht lesen" -#: builtin/index-pack.c:1038 +#: builtin/index-pack.c:1043 msgid "pack has junk at the end" msgstr "Paketende enthält nicht verwendbaren Inhalt" -#: builtin/index-pack.c:1049 +#: builtin/index-pack.c:1054 msgid "confusion beyond insanity in parse_pack_objects()" msgstr "Fehler beim Ausführen von \"parse_pack_objects()\"" -#: builtin/index-pack.c:1072 +#: builtin/index-pack.c:1077 msgid "Resolving deltas" msgstr "Löse Unterschiede auf" -#: builtin/index-pack.c:1082 +#: builtin/index-pack.c:1087 #, c-format msgid "unable to create thread: %s" msgstr "kann Thread nicht erzeugen: %s" -#: builtin/index-pack.c:1124 +#: builtin/index-pack.c:1129 msgid "confusion beyond insanity" msgstr "Fehler beim Auflösen der Unterschiede" -#: builtin/index-pack.c:1132 +#: builtin/index-pack.c:1137 #, c-format msgid "completed with %d local objects" msgstr "vervollständigt mit %d lokalen Objekten" -#: builtin/index-pack.c:1142 +#: builtin/index-pack.c:1147 #, c-format msgid "Unexpected tail checksum for %s (disk corruption?)" msgstr "Unerwartete Prüfsumme für %s (Festplattenfehler?)" -#: builtin/index-pack.c:1146 +#: builtin/index-pack.c:1151 #, 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:1171 +#: builtin/index-pack.c:1176 #, c-format msgid "unable to deflate appended object (%d)" msgstr "Konnte angehängtes Objekt (%d) nicht komprimieren" -#: builtin/index-pack.c:1250 +#: builtin/index-pack.c:1255 #, c-format msgid "local object %s is corrupt" msgstr "lokales Objekt %s ist beschädigt" -#: builtin/index-pack.c:1274 +#: builtin/index-pack.c:1279 msgid "error while closing pack file" msgstr "Fehler beim Schließen der Paketdatei" -#: builtin/index-pack.c:1287 +#: builtin/index-pack.c:1292 #, c-format msgid "cannot write keep file '%s'" msgstr "Kann Paketbeschreibungsdatei '%s' nicht schreiben" -#: builtin/index-pack.c:1295 +#: builtin/index-pack.c:1300 #, c-format msgid "cannot close written keep file '%s'" msgstr "Kann eben erstellte Paketbeschreibungsdatei '%s' nicht schließen" -#: builtin/index-pack.c:1308 +#: builtin/index-pack.c:1313 msgid "cannot store pack file" msgstr "Kann Paketdatei nicht speichern" -#: builtin/index-pack.c:1319 +#: builtin/index-pack.c:1324 msgid "cannot store index file" msgstr "Kann Indexdatei nicht speichern" -#: builtin/index-pack.c:1352 +#: builtin/index-pack.c:1357 #, c-format msgid "bad pack.indexversion=%" msgstr "\"pack.indexversion=%\" ist ungültig" -#: builtin/index-pack.c:1358 +#: builtin/index-pack.c:1363 #, c-format msgid "invalid number of threads specified (%d)" msgstr "ungültige Anzahl von Threads angegeben (%d)" -#: builtin/index-pack.c:1362 builtin/index-pack.c:1535 +#: builtin/index-pack.c:1367 builtin/index-pack.c:1545 #, c-format msgid "no threads support, ignoring %s" msgstr "keine Unterstützung von Threads, '%s' wird ignoriert" -#: builtin/index-pack.c:1420 +#: builtin/index-pack.c:1425 #, c-format msgid "Cannot open existing pack file '%s'" msgstr "Kann existierende Paketdatei '%s' nicht öffnen" -#: builtin/index-pack.c:1422 +#: builtin/index-pack.c:1427 #, 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:1469 +#: builtin/index-pack.c:1474 #, 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:1476 +#: builtin/index-pack.c:1481 #, 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:1503 +#: builtin/index-pack.c:1509 msgid "Cannot come back to cwd" msgstr "Kann nicht zurück zu Arbeitsverzeichnis wechseln" -#: builtin/index-pack.c:1547 builtin/index-pack.c:1550 -#: builtin/index-pack.c:1562 builtin/index-pack.c:1566 +#: builtin/index-pack.c:1557 builtin/index-pack.c:1560 +#: builtin/index-pack.c:1572 builtin/index-pack.c:1576 #, c-format msgid "bad %s" msgstr "%s ist ungültig" -#: builtin/index-pack.c:1580 +#: builtin/index-pack.c:1590 msgid "--fix-thin cannot be used without --stdin" msgstr "Die Option --fix-thin kann nicht ohne --stdin verwendet werden." -#: builtin/index-pack.c:1584 builtin/index-pack.c:1594 +#: builtin/index-pack.c:1594 builtin/index-pack.c:1604 #, c-format msgid "packfile name '%s' does not end with '.pack'" msgstr "Name der Paketdatei '%s' endet nicht mit '.pack'" -#: builtin/index-pack.c:1603 +#: builtin/index-pack.c:1613 msgid "--verify with no packfile name given" msgstr "Die Option --verify wurde ohne Namen der Paketdatei angegeben." @@ -5773,17 +6009,17 @@ msgstr "kann Verzeichnis '%s' nicht öffnen" #: builtin/init-db.c:97 #, c-format msgid "cannot readlink '%s'" -msgstr "kann Verknüpfung '%s' nicht lesen" +msgstr "kann Verweis '%s' nicht lesen" #: builtin/init-db.c:99 #, c-format msgid "insanely long symlink %s" -msgstr "zu lange symbolische Verknüpfung %s" +msgstr "zu langer symbolischer Verweis %s" #: builtin/init-db.c:102 #, c-format msgid "cannot symlink '%s' '%s'" -msgstr "kann '%s' nicht mit '%s' symbolisch verknüpfen" +msgstr "kann symbolischen Verweis '%s' auf '%s' nicht erstellen" #: builtin/init-db.c:106 #, c-format @@ -5833,7 +6069,7 @@ msgstr "Konnte %s nicht nach %s verschieben" #: builtin/init-db.c:363 #, c-format msgid "Could not create git link %s" -msgstr "Konnte git-Verknüpfung %s nicht erstellen" +msgstr "Konnte git-Verweis %s nicht erstellen" #. #. * TRANSLATORS: The first '%s' is either "Reinitialized @@ -5843,7 +6079,7 @@ msgstr "Konnte git-Verknüpfung %s nicht erstellen" #: builtin/init-db.c:420 #, c-format msgid "%s%s Git repository in %s%s\n" -msgstr "%s%s Git-Projektarchiv in %s%s\n" +msgstr "%s%s Git-Repository in %s%s\n" #: builtin/init-db.c:421 msgid "Reinitialized existing" @@ -5875,10 +6111,9 @@ 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" +msgstr "gibt an, dass das Git-Repository mit mehreren Benutzern geteilt wird" -#: builtin/init-db.c:493 builtin/prune-packed.c:77 +#: builtin/init-db.c:493 builtin/prune-packed.c:75 msgid "be quiet" msgstr "weniger Ausgaben" @@ -5908,368 +6143,385 @@ msgstr "Kann nicht auf aktuelles Arbeitsverzeichnis zugreifen." #: builtin/init-db.c:586 #, c-format msgid "Cannot access work tree '%s'" -msgstr "Kann nicht auf Arbeitsbaum '%s' zugreifen." +msgstr "Kann nicht auf Arbeitsverzeichnis '%s' zugreifen." -#: builtin/log.c:40 +#: builtin/log.c:41 msgid "git log [] [] [[--] ...]\n" -msgstr "git log [] [Revisionsbereich>] [[--] ...]\n" +msgstr "git log [] [Commitbereich>] [[--] ...]\n" -#: builtin/log.c:41 +#: builtin/log.c:42 msgid " or: git show [options] ..." msgstr " oder: git show [Optionen] ..." -#: builtin/log.c:103 +#: builtin/log.c:124 msgid "suppress diff output" msgstr "unterdrückt Ausgabe der Unterschiede" -#: builtin/log.c:104 +#: builtin/log.c:125 msgid "show source" msgstr "zeigt Quelle" -#: builtin/log.c:105 +#: builtin/log.c:126 msgid "Use mail map file" msgstr "verwendet \"mailmap\"-Datei" -#: builtin/log.c:106 +#: builtin/log.c:127 msgid "decorate options" msgstr "decorate-Optionen" -#: builtin/log.c:199 +#: builtin/log.c:230 #, c-format msgid "Final output: %d %s\n" msgstr "letzte Ausgabe: %d %s\n" -#: builtin/log.c:422 builtin/log.c:514 +#: builtin/log.c:453 builtin/log.c:545 #, c-format msgid "Could not read object %s" msgstr "Kann Objekt %s nicht lesen." -#: builtin/log.c:538 +#: builtin/log.c:569 #, c-format msgid "Unknown type: %d" msgstr "Unbekannter Typ: %d" -#: builtin/log.c:638 +#: builtin/log.c:669 msgid "format.headers without value" msgstr "format.headers ohne Wert" -#: builtin/log.c:720 +#: builtin/log.c:751 msgid "name of output directory is too long" msgstr "Name des Ausgabeverzeichnisses ist zu lang." -#: builtin/log.c:736 +#: builtin/log.c:767 #, c-format msgid "Cannot open patch file %s" msgstr "Kann Patch-Datei %s nicht öffnen" -#: builtin/log.c:750 +#: builtin/log.c:781 msgid "Need exactly one range." -msgstr "Brauche genau einen Versionsbereich." +msgstr "Brauche genau einen Commit-Bereich." -#: builtin/log.c:758 +#: builtin/log.c:789 msgid "Not a range." -msgstr "Kein Versionsbereich." +msgstr "Kein Commit-Bereich." -#: builtin/log.c:860 +#: builtin/log.c:891 msgid "Cover letter needs email format" msgstr "Anschreiben benötigt E-Mail-Format" -#: builtin/log.c:936 +#: builtin/log.c:967 #, c-format msgid "insane in-reply-to: %s" msgstr "ungültiges in-reply-to: %s" -#: builtin/log.c:964 +#: builtin/log.c:995 msgid "git format-patch [options] [ | ]" -msgstr "git format-patch [Optionen] [ | ]" +msgstr "git format-patch [Optionen] [ | ]" -#: builtin/log.c:1009 +#: builtin/log.c:1040 msgid "Two output directories?" msgstr "Zwei Ausgabeverzeichnisse?" -#: builtin/log.c:1108 +#: builtin/log.c:1155 msgid "use [PATCH n/m] even with a single patch" msgstr "verwendet [PATCH n/m] auch mit einzelnem Patch" -#: builtin/log.c:1111 +#: builtin/log.c:1158 msgid "use [PATCH] even with multiple patches" msgstr "verwendet [PATCH] auch mit mehreren Patches" -#: builtin/log.c:1115 +#: builtin/log.c:1162 msgid "print patches to standard out" msgstr "Ausgabe der Patches in Standard-Ausgabe" -#: builtin/log.c:1117 +#: builtin/log.c:1164 msgid "generate a cover letter" msgstr "erzeugt ein Deckblatt" -#: builtin/log.c:1119 +#: builtin/log.c:1166 msgid "use simple number sequence for output file names" msgstr "verwendet einfache Nummernfolge für die Namen der Ausgabedateien" -#: builtin/log.c:1120 +#: builtin/log.c:1167 msgid "sfx" msgstr "Dateiendung" -#: builtin/log.c:1121 +#: builtin/log.c:1168 msgid "use instead of '.patch'" msgstr "verwendet anstatt '.patch'" -#: builtin/log.c:1123 +#: builtin/log.c:1170 msgid "start numbering patches at instead of 1" msgstr "beginnt die Nummerierung der Patches bei anstatt bei 1" -#: builtin/log.c:1125 +#: builtin/log.c:1172 msgid "mark the series as Nth re-roll" msgstr "kennzeichnet die Serie als n-te Fassung" -#: builtin/log.c:1127 +#: builtin/log.c:1174 msgid "Use [] instead of [PATCH]" msgstr "verwendet [] anstatt [PATCH]" -#: builtin/log.c:1130 +#: builtin/log.c:1177 msgid "store resulting files in " msgstr "speichert erzeugte Dateien in " -#: builtin/log.c:1133 +#: builtin/log.c:1180 msgid "don't strip/add [PATCH]" msgstr "[PATCH] wird nicht entfernt/hinzugefügt" -#: builtin/log.c:1136 +#: builtin/log.c:1183 msgid "don't output binary diffs" msgstr "gibt keine binären Unterschiede aus" -#: builtin/log.c:1138 +#: builtin/log.c:1185 msgid "don't include a patch matching a commit upstream" msgstr "" -"schließt keine Patches ein, die einer Version im Übernahmezweig entsprechen" +"schließt keine Patches ein, die einem Commit im Upstream-Branch entsprechen" -#: builtin/log.c:1140 +#: builtin/log.c:1187 msgid "show patch format instead of default (patch + stat)" msgstr "zeigt Patchformat anstatt des Standards (Patch + Zusammenfassung)" -#: builtin/log.c:1142 +#: builtin/log.c:1189 msgid "Messaging" msgstr "Email-Einstellungen" -#: builtin/log.c:1143 +#: builtin/log.c:1190 msgid "header" msgstr "Header" -#: builtin/log.c:1144 +#: builtin/log.c:1191 msgid "add email header" msgstr "fügt Email-Header hinzu" -#: builtin/log.c:1145 builtin/log.c:1147 +#: builtin/log.c:1192 builtin/log.c:1194 msgid "email" msgstr "Email" -#: builtin/log.c:1145 +#: builtin/log.c:1192 msgid "add To: header" msgstr "fügt \"To:\"-Header hinzu" -#: builtin/log.c:1147 +#: builtin/log.c:1194 msgid "add Cc: header" msgstr "fügt \"Cc:\"-Header hinzu" -#: builtin/log.c:1149 +#: builtin/log.c:1196 +msgid "ident" +msgstr "Ident" + +#: builtin/log.c:1197 +msgid "set From address to (or committer ident if absent)" +msgstr "" +"setzt \"From\"-Adresse auf (oder Ident des Commit-Erstellers,wenn " +"fehlend)" + +#: builtin/log.c:1199 msgid "message-id" msgstr "message-id" -#: builtin/log.c:1150 +#: builtin/log.c:1200 msgid "make first mail a reply to " msgstr "macht aus erster Email eine Antwort zu " -#: builtin/log.c:1151 builtin/log.c:1154 +#: builtin/log.c:1201 builtin/log.c:1204 msgid "boundary" msgstr "Grenze" -#: builtin/log.c:1152 +#: builtin/log.c:1202 msgid "attach the patch" msgstr "hängt einen Patch an" -#: builtin/log.c:1155 +#: builtin/log.c:1205 msgid "inline the patch" msgstr "fügt den Patch direkt in die Nachricht ein" -#: builtin/log.c:1159 +#: builtin/log.c:1209 msgid "enable message threading, styles: shallow, deep" msgstr "aktiviert Nachrichtenverkettung, Stile: shallow, deep" -#: builtin/log.c:1161 +#: builtin/log.c:1211 msgid "signature" msgstr "Signatur" -#: builtin/log.c:1162 +#: builtin/log.c:1212 msgid "add a signature" msgstr "fügt eine Signatur hinzu" -#: builtin/log.c:1164 +#: builtin/log.c:1214 msgid "don't print the patch filenames" msgstr "zeigt keine Dateinamen der Patches" -#: builtin/log.c:1248 +#: builtin/log.c:1288 +#, c-format +msgid "invalid ident line: %s" +msgstr "Ungültige Identifikationszeile: %s" + +#: builtin/log.c:1303 msgid "-n and -k are mutually exclusive." msgstr "Die Optionen -n und -k schließen sich gegenseitig aus." -#: builtin/log.c:1250 +#: builtin/log.c:1305 msgid "--subject-prefix and -k are mutually exclusive." msgstr "Die Optionen --subject-prefix und -k schließen sich gegenseitig aus." -#: builtin/log.c:1258 +#: builtin/log.c:1313 msgid "--name-only does not make sense" msgstr "Die Option --name-only kann nicht verwendet werden." -#: builtin/log.c:1260 +#: builtin/log.c:1315 msgid "--name-status does not make sense" msgstr "Die Option --name-status kann nicht verwendet werden." -#: builtin/log.c:1262 +#: builtin/log.c:1317 msgid "--check does not make sense" msgstr "Die Option --check kann nicht verwendet werden." -#: builtin/log.c:1285 +#: builtin/log.c:1340 msgid "standard output, or directory, which one?" msgstr "Standard-Ausgabe oder Verzeichnis, welches von beidem?" -#: builtin/log.c:1287 +#: builtin/log.c:1342 #, c-format msgid "Could not create directory '%s'" msgstr "Konnte Verzeichnis '%s' nicht erstellen." -#: builtin/log.c:1435 +#: builtin/log.c:1490 msgid "Failed to create output files" msgstr "Fehler beim Erstellen der Ausgabedateien." -#: builtin/log.c:1484 +#: builtin/log.c:1539 msgid "git cherry [-v] [ [ []]]" -msgstr "git cherry [-v] [<Übernahmezweig> [ []]]" +msgstr "git cherry [-v] [ [ []]]" -#: builtin/log.c:1539 +#: builtin/log.c:1594 #, c-format msgid "" "Could not find a tracked remote branch, please specify manually.\n" msgstr "" -"Konnte gefolgten, externen Zweig nicht finden, bitte geben Sie " +"Konnte gefolgten Remote-Branch nicht finden, bitte geben Sie " "manuell an.\n" -#: builtin/log.c:1552 builtin/log.c:1554 builtin/log.c:1566 +#: builtin/log.c:1607 builtin/log.c:1609 builtin/log.c:1621 #, c-format msgid "Unknown commit %s" -msgstr "Unbekannte Version %s" +msgstr "Unbekannter Commit %s" -#: builtin/ls-files.c:402 +#: builtin/ls-files.c:408 msgid "git ls-files [options] [...]" msgstr "git ls-files [Optionen] [...]" -#: builtin/ls-files.c:459 +#: builtin/ls-files.c:465 msgid "identify the file status with tags" -msgstr "zeigt den Dateistatus mit Markierungen" +msgstr "zeigt den Dateistatus mit Tags" -#: builtin/ls-files.c:461 +#: builtin/ls-files.c:467 msgid "use lowercase letters for 'assume unchanged' files" msgstr "" "verwendet Kleinbuchstaben für Dateien mit 'assume unchanged' Markierung" -#: builtin/ls-files.c:463 +#: builtin/ls-files.c:469 msgid "show cached files in the output (default)" msgstr "zeigt zwischengespeicherten Dateien in der Ausgabe an (Standard)" -#: builtin/ls-files.c:465 +#: builtin/ls-files.c:471 msgid "show deleted files in the output" msgstr "zeigt entfernte Dateien in der Ausgabe an" -#: builtin/ls-files.c:467 +#: builtin/ls-files.c:473 msgid "show modified files in the output" msgstr "zeigt geänderte Dateien in der Ausgabe an" -#: builtin/ls-files.c:469 +#: builtin/ls-files.c:475 msgid "show other files in the output" msgstr "zeigt sonstige Dateien in der Ausgabe an" -#: builtin/ls-files.c:471 +#: builtin/ls-files.c:477 msgid "show ignored files in the output" msgstr "zeigt ignorierte Dateien in der Ausgabe an" -#: builtin/ls-files.c:474 +#: builtin/ls-files.c:480 msgid "show staged contents' object name in the output" -msgstr "zeigt Objektnamen von Inhalten in der Bereitstellung in der Ausgabe an" +msgstr "" +"zeigt Objektnamen von Inhalten, die zum Commit vorgemerkt sind, in der " +"Ausgabe an" -#: builtin/ls-files.c:476 +#: builtin/ls-files.c:482 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:478 +#: builtin/ls-files.c:484 msgid "show 'other' directories' name only" msgstr "zeigt nur Namen von 'sonstigen' Verzeichnissen an" -#: builtin/ls-files.c:481 +#: builtin/ls-files.c:487 msgid "don't show empty directories" msgstr "zeigt keine leeren Verzeichnisse an" -#: builtin/ls-files.c:484 +#: builtin/ls-files.c:490 msgid "show unmerged files in the output" msgstr "zeigt nicht zusammengeführte Dateien in der Ausgabe an" -#: builtin/ls-files.c:486 +#: builtin/ls-files.c:492 msgid "show resolve-undo information" msgstr "zeigt 'resolve-undo' Informationen an" -#: builtin/ls-files.c:488 +#: builtin/ls-files.c:494 msgid "skip files matching pattern" msgstr "lässt Dateien aus, die einem Muster entsprechen" -#: builtin/ls-files.c:491 +#: builtin/ls-files.c:497 msgid "exclude patterns are read from " msgstr "schließt Muster, gelesen von , aus" -#: builtin/ls-files.c:494 +#: builtin/ls-files.c:500 msgid "read additional per-directory exclude patterns in " msgstr "liest zusätzliche pro-Verzeichnis Auschlussmuster aus " -#: builtin/ls-files.c:496 +#: builtin/ls-files.c:502 msgid "add the standard git exclusions" msgstr "fügt die standardmäßigen Git-Ausschlüsse hinzu" -#: builtin/ls-files.c:499 +#: builtin/ls-files.c:505 msgid "make the output relative to the project top directory" msgstr "Ausgabe relativ zum Projektverzeichnis" -#: builtin/ls-files.c:502 +#: builtin/ls-files.c:508 msgid "if any is not in the index, treat this as an error" msgstr "" -"behandle es als Fehler, wenn sich eine nicht in der Bereitstellung " +"behandle es als Fehler, wenn sich eine nicht in der Staging-Area " "befindet" -#: builtin/ls-files.c:503 +#: builtin/ls-files.c:509 msgid "tree-ish" -msgstr "Versionsreferenz" +msgstr "Commit-Referenz" -#: builtin/ls-files.c:504 +#: builtin/ls-files.c:510 msgid "pretend that paths removed since are still present" msgstr "" -"gibt vor, dass Pfade, die seit gelöscht wurden, immer " -"noch vorhanden sind" +"gibt vor, dass Pfade, die seit gelöscht wurden, immer noch " +"vorhanden sind" -#: builtin/ls-files.c:506 +#: builtin/ls-files.c:512 msgid "show debugging data" msgstr "zeigt Ausgaben zur Fehlersuche an" #: builtin/ls-tree.c:27 msgid "git ls-tree [] [...]" -msgstr "git ls-tree [] [...]" +msgstr "git ls-tree [] [...]" #: builtin/ls-tree.c:125 msgid "only show trees" -msgstr "zeigt nur Bäume an" +msgstr "zeigt nur Verzeichnisse an" #: builtin/ls-tree.c:127 msgid "recurse into subtrees" -msgstr "führt Rekursion in Teilbäumen durch" +msgstr "führt Rekursion in Unterverzeichnissen durch" #: builtin/ls-tree.c:129 msgid "show trees when recursing" -msgstr "zeigt Bäume bei Rekursion an" +msgstr "zeigt Verzeichnisse bei Rekursion an" #: builtin/ls-tree.c:132 msgid "terminate entries with NUL byte" @@ -6290,195 +6542,187 @@ msgstr "verwendet 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)" +"listet das gesamte Verzeichnis auf; nicht nur das aktuelle Verzeichnis " +"(impliziert --full-name)" #: builtin/merge.c:43 msgid "git merge [options] [...]" -msgstr "git merge [Optionen] [...]" +msgstr "git merge [Optionen] [...]" #: builtin/merge.c:44 msgid "git merge [options] HEAD " -msgstr "git merge [Optionen] HEAD " +msgstr "git merge [Optionen] HEAD " #: builtin/merge.c:45 msgid "git merge --abort" msgstr "git merge --abort" -#: builtin/merge.c:90 +#: builtin/merge.c:98 msgid "switch `m' requires a value" msgstr "Schalter 'm' erfordert einen Wert." -#: builtin/merge.c:127 +#: builtin/merge.c:135 #, c-format msgid "Could not find merge strategy '%s'.\n" -msgstr "Konnte Zusammenführungsstrategie '%s' nicht finden.\n" +msgstr "Konnte Merge-Strategie '%s' nicht finden.\n" -#: builtin/merge.c:128 +#: builtin/merge.c:136 #, c-format msgid "Available strategies are:" msgstr "Verfügbare Strategien sind:" -#: builtin/merge.c:133 +#: builtin/merge.c:141 #, c-format msgid "Available custom strategies are:" msgstr "Verfügbare benutzerdefinierte Strategien sind:" -#: builtin/merge.c:183 +#: builtin/merge.c:198 msgid "do not show a diffstat at the end of the merge" -msgstr "" -"zeigt keine Zusammenfassung der Unterschiede am Schluss der Zusammenführung " -"an" +msgstr "zeigt keine Zusammenfassung der Unterschiede am Schluss des Merges an" -#: builtin/merge.c:186 +#: builtin/merge.c:201 msgid "show a diffstat at the end of the merge" -msgstr "" -"zeigt eine Zusammenfassung der Unterschiede am Schluss der Zusammenführung an" +msgstr "zeigt eine Zusammenfassung der Unterschiede am Schluss des Merges an" -#: builtin/merge.c:187 +#: builtin/merge.c:202 msgid "(synonym to --stat)" msgstr "(Synonym für --stat)" -#: builtin/merge.c:189 +#: builtin/merge.c:204 msgid "add (at most ) entries from shortlog to merge commit message" msgstr "" -"fügt (höchstens ) Einträge von \"shortlog\" zur Beschreibung der " -"Zusammenführung hinzu" +"fügt (höchstens ) Einträge von \"shortlog\" zur Beschreibung des Merge-" +"Commits hinzu" -#: builtin/merge.c:192 +#: builtin/merge.c:207 msgid "create a single commit instead of doing a merge" -msgstr "erzeugt eine einzelne Version anstatt einer Zusammenführung" +msgstr "erzeugt einen einzelnen Commit anstatt eines Merges" -#: builtin/merge.c:194 +#: builtin/merge.c:209 msgid "perform a commit if the merge succeeds (default)" -msgstr "" -"führt eine Eintragung durch, wenn die Zusammenführung erfolgreich war " -"(Standard)" +msgstr "führt einen Commit durch, wenn der Merge erfolgreich war (Standard)" -#: builtin/merge.c:196 +#: builtin/merge.c:211 msgid "edit message before committing" -msgstr "Bearbeitung der Versionsbeschreibung vor der Eintragung" +msgstr "Bearbeitung der Beschreibung vor dem Commit" -#: builtin/merge.c:198 +#: builtin/merge.c:212 msgid "allow fast-forward (default)" msgstr "erlaubt Vorspulen (Standard)" -#: builtin/merge.c:200 +#: builtin/merge.c:214 msgid "abort if fast-forward is not possible" msgstr "bricht ab, wenn kein Vorspulen möglich ist" -#: builtin/merge.c:203 +#: builtin/merge.c:218 msgid "Verify that the named commit has a valid GPG signature" -msgstr "überprüft die genannte Version auf eine gültige GPG-Signatur" +msgstr "überprüft den genannten Commit auf eine gültige GPG-Signatur" -#: builtin/merge.c:204 builtin/notes.c:866 builtin/revert.c:112 +#: builtin/merge.c:219 builtin/notes.c:738 builtin/revert.c:114 msgid "strategy" msgstr "Strategie" -#: builtin/merge.c:205 +#: builtin/merge.c:220 msgid "merge strategy to use" -msgstr "zu verwendende Zusammenführungsstrategie" +msgstr "zu verwendende Merge-Strategie" -#: builtin/merge.c:206 +#: builtin/merge.c:221 msgid "option=value" msgstr "Option=Wert" -#: builtin/merge.c:207 +#: builtin/merge.c:222 msgid "option for selected merge strategy" -msgstr "Option für ausgewählte Zusammenführungsstrategie" +msgstr "Option für ausgewählte Merge-Strategie" -#: builtin/merge.c:209 +#: builtin/merge.c:224 msgid "merge commit message (for a non-fast-forward merge)" msgstr "" -"führt Versionsbeschreibung zusammen (für eine Zusammenführung, die kein " -"Vorspulen war)" +"führt Commit-Beschreibung zusammen (für einen Merge, der kein Vorspulen war)" -#: builtin/merge.c:213 +#: builtin/merge.c:228 msgid "abort the current in-progress merge" -msgstr "bricht die sich im Gange befindliche Zusammenführung ab" +msgstr "bricht den sich im Gange befindlichen Merge ab" -#: builtin/merge.c:242 +#: builtin/merge.c:257 msgid "could not run stash." msgstr "Konnte \"stash\" nicht ausführen." -#: builtin/merge.c:247 +#: builtin/merge.c:262 msgid "stash failed" msgstr "\"stash\" fehlgeschlagen" -#: builtin/merge.c:252 +#: builtin/merge.c:267 #, c-format msgid "not a valid object: %s" msgstr "kein gültiges Objekt: %s" -#: builtin/merge.c:271 builtin/merge.c:288 +#: builtin/merge.c:286 builtin/merge.c:303 msgid "read-tree failed" msgstr "read-tree fehlgeschlagen" -#: builtin/merge.c:318 +#: builtin/merge.c:333 msgid " (nothing to squash)" msgstr " (nichts zu quetschen)" -#: builtin/merge.c:331 +#: builtin/merge.c:346 #, c-format msgid "Squash commit -- not updating HEAD\n" -msgstr "Quetsche Version -- Zweigspitze (HEAD) wird nicht aktualisiert\n" +msgstr "Quetsche Commit -- HEAD wird nicht aktualisiert\n" -#: builtin/merge.c:363 +#: builtin/merge.c:378 msgid "Writing SQUASH_MSG" msgstr "Schreibe SQUASH_MSG" -#: builtin/merge.c:365 +#: builtin/merge.c:380 msgid "Finishing SQUASH_MSG" msgstr "Schließe SQUASH_MSG ab" -#: builtin/merge.c:388 +#: builtin/merge.c:403 #, c-format msgid "No merge message -- not updating HEAD\n" -msgstr "" -"Keine Zusammenführungsbeschreibung -- Zweigspitze (HEAD) wird nicht " -"aktualisiert\n" +msgstr "Keine Merge-Commit-Beschreibung -- HEAD wird nicht aktualisiert\n" -#: builtin/merge.c:438 +#: builtin/merge.c:453 #, c-format msgid "'%s' does not point to a commit" -msgstr "'%s' zeigt auf keine Version" +msgstr "'%s' zeigt auf keinen Commit" -#: builtin/merge.c:550 +#: builtin/merge.c:565 #, c-format msgid "Bad branch.%s.mergeoptions string: %s" msgstr "Ungültiger branch.%s.mergeoptions String: %s" -#: builtin/merge.c:643 +#: builtin/merge.c:657 msgid "git write-tree failed to write a tree" -msgstr "\"git write-tree\" schlug beim Schreiben eines Baumes fehl" +msgstr "\"git write-tree\" schlug beim Schreiben eines \"Tree\"-Objektes fehl" -#: builtin/merge.c:671 +#: builtin/merge.c:685 msgid "Not handling anything other than two heads merge." -msgstr "Es wird nur die Zusammenführung von zwei Zweigen behandelt." +msgstr "Es wird nur der Merge von zwei Branches behandelt." -#: builtin/merge.c:685 +#: builtin/merge.c:699 #, c-format msgid "Unknown option for merge-recursive: -X%s" msgstr "Unbekannte Option für merge-recursive: -X%s" -#: builtin/merge.c:699 +#: builtin/merge.c:713 #, c-format msgid "unable to write %s" msgstr "konnte %s nicht schreiben" -#: builtin/merge.c:788 +#: builtin/merge.c:802 #, c-format msgid "Could not read from '%s'" msgstr "konnte nicht von '%s' lesen" -#: builtin/merge.c:797 +#: builtin/merge.c:811 #, c-format msgid "Not committing merge; use 'git commit' to complete the merge.\n" msgstr "" -"Zusammenführung wurde nicht eingetragen; benutzen Sie 'git commit' um die " -"Zusammenführung abzuschließen.\n" +"Merge wurde nicht committet; benutzen Sie 'git commit' um den Merge " +"abzuschließen.\n" -#: builtin/merge.c:803 +#: builtin/merge.c:817 #, c-format msgid "" "Please enter a commit message to explain why this merge is necessary,\n" @@ -6487,219 +6731,212 @@ msgid "" "Lines starting with '%c' will be ignored, and an empty message aborts\n" "the commit.\n" msgstr "" -"Bitte geben Sie eine Versionsbeschreibung ein um zu erklären, warum diese " -"Zusammenführung erforderlich ist,\n" -"insbesondere wenn es einen aktualisierten, externen Zweig mit einem Thema-" -"Zweig zusammenführt.\n" +"Bitte geben Sie eine Commit-Beschreibung ein um zu erklären, warum dieser\n" +"Merge erforderlich ist, insbesondere wenn es einen aktualisierten\n" +"Upstream-Branch mit einem Thema-Branch zusammenführt.\n" "\n" -"Zeilen beginnend mit '%c' werden ignoriert, und eine leere Beschreibung " -"bricht die Eintragung ab.\n" +"Zeilen beginnend mit '%c' werden ignoriert, und eine leere Beschreibung\n" +"bricht den Commit ab.\n" -#: builtin/merge.c:827 +#: builtin/merge.c:841 msgid "Empty commit message." -msgstr "Leere Versionsbeschreibung" +msgstr "Leere Commit-Beschreibung" -#: builtin/merge.c:839 +#: builtin/merge.c:853 #, c-format msgid "Wonderful.\n" msgstr "Wunderbar.\n" -#: builtin/merge.c:904 +#: builtin/merge.c:918 #, c-format msgid "Automatic merge failed; fix conflicts and then commit the result.\n" msgstr "" -"Automatische Zusammenführung fehlgeschlagen; beheben Sie die Konflikte und " -"tragen Sie dann das Ergebnis ein.\n" +"Automatischer Merge fehlgeschlagen; beheben Sie die Konflikte und committen " +"Sie dann das Ergebnis.\n" -#: builtin/merge.c:920 +#: builtin/merge.c:934 #, c-format msgid "'%s' is not a commit" -msgstr "'%s' ist keine Version" +msgstr "'%s' ist kein Commit" -#: builtin/merge.c:961 +#: builtin/merge.c:975 msgid "No current branch." -msgstr "Sie befinden sich auf keinem Zweig." +msgstr "Sie befinden sich auf keinem Branch." -#: builtin/merge.c:963 +#: builtin/merge.c:977 msgid "No remote for the current branch." -msgstr "Kein externes Archiv für den aktuellen Zweig." +msgstr "Kein Remote-Repository für den aktuellen Branch." -#: builtin/merge.c:965 +#: builtin/merge.c:979 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:970 -#, c-format -msgid "No remote tracking branch for %s from %s" -msgstr "Kein externer Übernahmezweig für %s von %s" +"Es ist kein Standard-Upstream-Branch für den aktuellen Branch definiert." -#: builtin/merge.c:1057 builtin/merge.c:1214 +#: builtin/merge.c:984 #, c-format -msgid "%s - not something we can merge" -msgstr "%s - nichts was wir zusammenführen können" +msgid "No remote-tracking branch for %s from %s" +msgstr "Kein Remote-Tracking-Branch für %s von %s" -#: builtin/merge.c:1125 +#: builtin/merge.c:1140 msgid "There is no merge to abort (MERGE_HEAD missing)." -msgstr "Es gibt keine Zusammenführung zum Abbrechen (vermisse MERGE_HEAD)" +msgstr "Es gibt keinen Merge zum Abbrechen (vermisse MERGE_HEAD)" -#: builtin/merge.c:1141 git-pull.sh:31 +#: builtin/merge.c:1156 git-pull.sh:31 msgid "" "You have not concluded your merge (MERGE_HEAD exists).\n" "Please, commit your changes before you can merge." msgstr "" -"Sie haben Ihre Zusammenführung nicht abgeschlossen (MERGE_HEAD existiert).\n" -"Bitte tragen Sie Ihre Änderungen ein, bevor Sie zusammenführen können." +"Sie haben Ihren Merge nicht abgeschlossen (MERGE_HEAD existiert).\n" +"Bitte committen Sie Ihre Änderungen, bevor Sie \"merge\" ausführen können." -#: builtin/merge.c:1144 git-pull.sh:34 +#: builtin/merge.c:1159 git-pull.sh:34 msgid "You have not concluded your merge (MERGE_HEAD exists)." -msgstr "" -"Sie haben Ihre Zusammenführung nicht abgeschlossen (MERGE_HEAD existiert)." +msgstr "Sie haben Ihren Merge nicht abgeschlossen (MERGE_HEAD existiert)." -#: builtin/merge.c:1148 +#: builtin/merge.c:1163 msgid "" "You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists).\n" "Please, commit your changes before you can merge." msgstr "" "Sie haben \"cherry-pick\" nicht abgeschlossen (CHERRY_PICK_HEAD existiert).\n" -"Bitte tragen Sie Ihre Änderungen ein, bevor Sie zusammenführen können." +"Bitte committen Sie Ihre Änderungen, bevor Sie \"merge\" ausführen können." -#: builtin/merge.c:1151 +#: builtin/merge.c:1166 msgid "You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists)." msgstr "" "Sie haben \"cherry-pick\" nicht abgeschlossen (CHERRY_PICK_HEAD existiert)." -#: builtin/merge.c:1160 +#: builtin/merge.c:1175 msgid "You cannot combine --squash with --no-ff." msgstr "Sie können --squash nicht mit --no-ff kombinieren." -#: builtin/merge.c:1165 -msgid "You cannot combine --no-ff with --ff-only." -msgstr "Sie können --no-ff nicht mit --ff--only kombinieren." - -#: builtin/merge.c:1172 +#: builtin/merge.c:1184 msgid "No commit specified and merge.defaultToUpstream not set." -msgstr "Keine Version angegeben und merge.defaultToUpstream ist nicht gesetzt." +msgstr "Kein Commit angegeben und merge.defaultToUpstream ist nicht gesetzt." -#: builtin/merge.c:1204 +#: builtin/merge.c:1216 msgid "Can merge only exactly one commit into empty head" -msgstr "Kann nur exakt eine Version in einem leeren Zweig zusammenführen." +msgstr "Kann nur exakt einen Commit in einem leeren Branch zusammenführen." -#: builtin/merge.c:1207 +#: builtin/merge.c:1219 msgid "Squash commit into empty head not supported yet" -msgstr "Bin auf einem Zweig, der noch geboren wird; kann nicht quetschen." +msgstr "" +"Bin auf einem Commit, der noch geboren wird; kann \"squash\" nicht ausführen." -#: builtin/merge.c:1209 +#: builtin/merge.c:1221 msgid "Non-fast-forward commit does not make sense into an empty head" msgstr "" -"Nicht vorzuspulende Version kann nicht in einem leeren Zweig verwendet " +"Nicht vorzuspulender Commit kann nicht in einem leeren Branch verwendet " "werden." -#: builtin/merge.c:1265 +#: builtin/merge.c:1226 +#, c-format +msgid "%s - not something we can merge" +msgstr "%s - nichts was wir zusammenführen können" + +#: builtin/merge.c:1277 #, c-format msgid "Commit %s has an untrusted GPG signature, allegedly by %s." msgstr "" -"Version %s hat eine nicht vertrauenswürdige GPG-Signatur, angeblich von %s." +"Commit %s hat eine nicht vertrauenswürdige GPG-Signatur, angeblich von %s." -#: builtin/merge.c:1268 +#: builtin/merge.c:1280 #, c-format msgid "Commit %s has a bad GPG signature allegedly by %s." -msgstr "Version %s hat eine ungültige GPG-Signatur, angeblich von %s." +msgstr "Commit %s hat eine ungültige GPG-Signatur, angeblich von %s." #. 'N' -#: builtin/merge.c:1271 +#: builtin/merge.c:1283 #, c-format msgid "Commit %s does not have a GPG signature." -msgstr "Version %s hat keine GPG-Signatur." +msgstr "Commit %s hat keine GPG-Signatur." -#: builtin/merge.c:1274 +#: builtin/merge.c:1286 #, c-format msgid "Commit %s has a good GPG signature by %s\n" -msgstr "Version %s hat eine gültige GPG-Signatur von %s\n" +msgstr "Commit %s hat eine gültige GPG-Signatur von %s\n" -#: builtin/merge.c:1358 +#: builtin/merge.c:1370 #, c-format msgid "Updating %s..%s\n" msgstr "Aktualisiere %s..%s\n" -#: builtin/merge.c:1397 +#: builtin/merge.c:1409 #, c-format msgid "Trying really trivial in-index merge...\n" -msgstr "Probiere wirklich triviale \"in-index\"-Zusammenführung...\n" +msgstr "Probiere wirklich trivialen \"in-index\"-Merge...\n" -#: builtin/merge.c:1404 +#: builtin/merge.c:1416 #, c-format msgid "Nope.\n" msgstr "Nein.\n" -#: builtin/merge.c:1436 +#: builtin/merge.c:1448 msgid "Not possible to fast-forward, aborting." msgstr "Vorspulen nicht möglich, breche ab." -#: builtin/merge.c:1459 builtin/merge.c:1538 +#: builtin/merge.c:1471 builtin/merge.c:1550 #, c-format msgid "Rewinding the tree to pristine...\n" -msgstr "Rücklauf des Zweiges bis zum Ursprung...\n" +msgstr "Rücklauf des Verzeichnisses bis zum Ursprung...\n" -#: builtin/merge.c:1463 +#: builtin/merge.c:1475 #, c-format msgid "Trying merge strategy %s...\n" -msgstr "Probiere Zusammenführungsstrategie %s...\n" +msgstr "Probiere Merge-Strategie %s...\n" -#: builtin/merge.c:1529 +#: builtin/merge.c:1541 #, c-format msgid "No merge strategy handled the merge.\n" -msgstr "Keine Zusammenführungsstrategie behandelt diese Zusammenführung.\n" +msgstr "Keine Merge-Strategie behandelt diesen Merge.\n" -#: builtin/merge.c:1531 +#: builtin/merge.c:1543 #, c-format msgid "Merge with strategy %s failed.\n" -msgstr "Zusammenführung mit Strategie %s fehlgeschlagen.\n" +msgstr "Merge mit Strategie %s fehlgeschlagen.\n" -#: builtin/merge.c:1540 +#: builtin/merge.c:1552 #, c-format msgid "Using the %s to prepare resolving by hand.\n" msgstr "Benutzen Sie \"%s\" um die Auflösung per Hand vorzubereiten.\n" -#: builtin/merge.c:1552 +#: builtin/merge.c:1564 #, 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" +"Automatischer Merge abgeschlossen; halte, wie gewünscht, vor dem Commit an\n" #: builtin/merge-base.c:26 msgid "git merge-base [-a|--all] ..." -msgstr "git merge-base [-a|--all] ..." +msgstr "git merge-base [-a|--all] ..." #: builtin/merge-base.c:27 msgid "git merge-base [-a|--all] --octopus ..." -msgstr "git merge-base [-a|--all] --octopus ..." +msgstr "git merge-base [-a|--all] --octopus ..." #: builtin/merge-base.c:28 msgid "git merge-base --independent ..." -msgstr "git merge-base --independent ..." +msgstr "git merge-base --independent ..." #: builtin/merge-base.c:29 msgid "git merge-base --is-ancestor " -msgstr "git merge-base --is-ancestor " +msgstr "git merge-base --is-ancestor " #: builtin/merge-base.c:98 msgid "output all common ancestors" -msgstr "Ausgabe aller gemeinsamen Vorfahren" +msgstr "Ausgabe aller gemeinsamen Vorgänger-Commits" #: 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" +msgstr "findet Vorgänger-Commits für einen einzelnen n-Wege-Merge" #: builtin/merge-base.c:100 msgid "list revs not reachable from others" -msgstr "listet Versionen auf, die nicht durch Andere erreichbar sind" +msgstr "listet Commits 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?" +msgstr "ist der Erste ein Vorgänger-Commit von dem Anderen?" #: builtin/merge-file.c:8 msgid "" @@ -6715,7 +6952,7 @@ msgstr "sendet Ergebnisse zur Standard-Ausgabe" #: builtin/merge-file.c:34 msgid "use a diff3 based merge" -msgstr "verwendet eine diff3 basierte Zusammenführung" +msgstr "verwendet einen diff3 basierten Merge" #: builtin/merge-file.c:35 msgid "for conflicts, use our version" @@ -6755,7 +6992,7 @@ 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" +msgstr "erlaubt die Erstellung von mehr als einem \"Tree\"-Objekt" #: builtin/mv.c:14 msgid "git mv [options] ... " @@ -6789,7 +7026,7 @@ msgstr "kann Verzeichnis nicht über Datei verschieben" #: builtin/mv.c:128 #, c-format msgid "Huh? %.*s is in index?" -msgstr "Huh? %.*s ist in der Bereitstellung?" +msgstr "Huh? %.*s ist zum Commit vorgemerkt?" #: builtin/mv.c:140 msgid "source directory is empty" @@ -6831,47 +7068,51 @@ msgstr "Benenne %s nach %s um\n" msgid "renaming '%s' failed" msgstr "Umbenennung von '%s' fehlgeschlagen" -#: builtin/name-rev.c:175 +#: builtin/name-rev.c:259 msgid "git name-rev [options] ..." -msgstr "git name-rev [Optionen] ..." +msgstr "git name-rev [Optionen] ..." -#: builtin/name-rev.c:176 +#: builtin/name-rev.c:260 msgid "git name-rev [options] --all" msgstr "git name-rev [Optionen] --all" -#: builtin/name-rev.c:177 +#: builtin/name-rev.c:261 msgid "git name-rev [options] --stdin" msgstr "git name-rev [Optionen] --stdin" -#: builtin/name-rev.c:229 +#: builtin/name-rev.c:313 msgid "print only names (no SHA-1)" msgstr "zeigt nur Namen an (keine SHA-1)" -#: builtin/name-rev.c:230 +#: builtin/name-rev.c:314 msgid "only use tags to name the commits" -msgstr "verwendet nur Markierungen um die Versionen zu benennen" +msgstr "verwendet nur Tags um die Commits zu benennen" -#: builtin/name-rev.c:232 +#: builtin/name-rev.c:316 msgid "only use refs matching " msgstr "verwendet nur Referenzen die entsprechen" -#: builtin/name-rev.c:234 +#: builtin/name-rev.c:318 msgid "list all commits reachable from all refs" -msgstr "listet alle Versionen auf, die von allen Referenzen erreichbar sind" +msgstr "listet alle Commits auf, die von allen Referenzen erreichbar sind" -#: builtin/name-rev.c:235 +#: builtin/name-rev.c:319 msgid "read from stdin" msgstr "liest von der Standard-Eingabe" -#: builtin/name-rev.c:236 +#: builtin/name-rev.c:320 msgid "allow to print `undefined` names" msgstr "erlaubt Ausgabe von `undefinierten` Namen" -#: builtin/notes.c:26 +#: builtin/name-rev.c:326 +msgid "dereference tags in the input (internal use)" +msgstr "dereferenziert Tags in der Eingabe (interne Verwendung)" + +#: builtin/notes.c:24 msgid "git notes [--ref ] [list []]" msgstr "git notes [--ref ] [list []]" -#: builtin/notes.c:27 +#: builtin/notes.c:25 msgid "" "git notes [--ref ] add [-f] [-m | -F | (-c | -C) " "] []" @@ -6879,12 +7120,12 @@ msgstr "" "git notes [--ref ] add [-f] [-m | -F | (-" "c | -C) ] []" -#: builtin/notes.c:28 +#: builtin/notes.c:26 msgid "git notes [--ref ] copy [-f] " msgstr "" "git notes [--ref ] copy [-f] " -#: builtin/notes.c:29 +#: builtin/notes.c:27 msgid "" "git notes [--ref ] append [-m | -F | (-c | -C) " "] []" @@ -6892,223 +7133,201 @@ msgstr "" "git notes [--ref ] append [-m | -F | (-c " "| -C) ] []" -#: builtin/notes.c:30 +#: builtin/notes.c:28 msgid "git notes [--ref ] edit []" msgstr "git notes [--ref ] edit []" -#: builtin/notes.c:31 +#: builtin/notes.c:29 msgid "git notes [--ref ] show []" msgstr "git notes [--ref ] show []" -#: builtin/notes.c:32 +#: builtin/notes.c:30 msgid "" "git notes [--ref ] merge [-v | -q] [-s ] " msgstr "" "git notes [--ref ] merge [-v | -q] [-s ] " -#: builtin/notes.c:33 +#: builtin/notes.c:31 msgid "git notes merge --commit [-v | -q]" msgstr "git notes merge --commit [-v | -q]" -#: builtin/notes.c:34 +#: builtin/notes.c:32 msgid "git notes merge --abort [-v | -q]" msgstr "git notes merge --abort [-v | -q]" -#: builtin/notes.c:35 +#: builtin/notes.c:33 msgid "git notes [--ref ] remove [...]" msgstr "git notes [--ref ] remove [...]" -#: builtin/notes.c:36 +#: builtin/notes.c:34 msgid "git notes [--ref ] prune [-n | -v]" msgstr "git notes [--ref ] prune [-n | -v]" -#: builtin/notes.c:37 +#: builtin/notes.c:35 msgid "git notes [--ref ] get-ref" msgstr "git notes [--ref ] get-ref" -#: builtin/notes.c:42 +#: builtin/notes.c:40 msgid "git notes [list []]" msgstr "git notes [list []]" -#: builtin/notes.c:47 +#: builtin/notes.c:45 msgid "git notes add [] []" msgstr "git notes add [] []" -#: builtin/notes.c:52 +#: builtin/notes.c:50 msgid "git notes copy [] " msgstr "git notes copy [] " -#: builtin/notes.c:53 +#: builtin/notes.c:51 msgid "git notes copy --stdin [ ]..." msgstr "git notes copy --stdin [ ]..." -#: builtin/notes.c:58 +#: builtin/notes.c:56 msgid "git notes append [] []" msgstr "git notes append [] []" -#: builtin/notes.c:63 +#: builtin/notes.c:61 msgid "git notes edit []" msgstr "git notes edit []" -#: builtin/notes.c:68 +#: builtin/notes.c:66 msgid "git notes show []" msgstr "git notes show []" -#: builtin/notes.c:73 +#: builtin/notes.c:71 msgid "git notes merge [] " msgstr "git notes merge [] " -#: builtin/notes.c:74 +#: builtin/notes.c:72 msgid "git notes merge --commit []" msgstr "git notes merge --commit []" -#: builtin/notes.c:75 +#: builtin/notes.c:73 msgid "git notes merge --abort []" msgstr "git notes merge --abort []" -#: builtin/notes.c:80 +#: builtin/notes.c:78 msgid "git notes remove []" msgstr "git notes remove []" -#: builtin/notes.c:85 +#: builtin/notes.c:83 msgid "git notes prune []" msgstr "git notes prune []" -#: builtin/notes.c:90 +#: builtin/notes.c:88 msgid "git notes get-ref" msgstr "git notes get-ref" -#: builtin/notes.c:139 +#: builtin/notes.c:137 #, c-format msgid "unable to start 'show' for object '%s'" msgstr "konnte 'show' für Objekt '%s' nicht starten" -#: builtin/notes.c:143 +#: builtin/notes.c:141 msgid "could not read 'show' output" msgstr "Konnte Ausgabe von 'show' nicht lesen." -#: builtin/notes.c:151 +#: builtin/notes.c:149 #, c-format msgid "failed to finish 'show' for object '%s'" msgstr "konnte 'show' für Objekt '%s' nicht abschließen" -#: builtin/notes.c:169 builtin/tag.c:341 +#: builtin/notes.c:167 builtin/tag.c:341 #, c-format msgid "could not create file '%s'" msgstr "konnte Datei '%s' nicht erstellen" -#: builtin/notes.c:188 +#: builtin/notes.c:186 msgid "Please supply the note contents using either -m or -F option" msgstr "" "Bitte liefern Sie den Notiz-Inhalt unter Verwendung der Option -m oder -F." -#: builtin/notes.c:209 builtin/notes.c:972 +#: builtin/notes.c:207 builtin/notes.c:844 #, c-format msgid "Removing note for object %s\n" msgstr "Entferne Notiz für Objekt %s\n" -#: builtin/notes.c:214 +#: builtin/notes.c:212 msgid "unable to write note object" msgstr "Konnte Notiz-Objekt nicht schreiben" -#: builtin/notes.c:216 +#: builtin/notes.c:214 #, c-format msgid "The note contents has been left in %s" msgstr "Die Notiz-Inhalte wurden in %s belassen" -#: builtin/notes.c:250 builtin/tag.c:540 +#: builtin/notes.c:248 builtin/tag.c:540 #, c-format msgid "cannot read '%s'" msgstr "kann '%s' nicht lesen" -#: builtin/notes.c:252 builtin/tag.c:543 +#: builtin/notes.c:250 builtin/tag.c:543 #, c-format msgid "could not open or read '%s'" msgstr "konnte '%s' nicht öffnen oder lesen" -#: builtin/notes.c:271 builtin/notes.c:444 builtin/notes.c:446 -#: builtin/notes.c:506 builtin/notes.c:560 builtin/notes.c:643 -#: builtin/notes.c:648 builtin/notes.c:723 builtin/notes.c:765 -#: builtin/notes.c:967 builtin/tag.c:556 +#: builtin/notes.c:269 builtin/notes.c:316 builtin/notes.c:318 +#: builtin/notes.c:378 builtin/notes.c:432 builtin/notes.c:515 +#: builtin/notes.c:520 builtin/notes.c:595 builtin/notes.c:637 +#: builtin/notes.c:839 builtin/tag.c:556 #, c-format msgid "Failed to resolve '%s' as a valid ref." msgstr "Konnte '%s' nicht als gültige Referenz auflösen." -#: builtin/notes.c:274 +#: builtin/notes.c:272 #, c-format msgid "Failed to read object '%s'." msgstr "Fehler beim Lesen des Objektes '%s'." -#: builtin/notes.c:298 -msgid "Cannot commit uninitialized/unreferenced notes tree" -msgstr "Kann uninitialisierten/unreferenzierten Notiz-Baum nicht eintragen." - -#: builtin/notes.c:339 -#, c-format -msgid "Bad notes.rewriteMode value: '%s'" -msgstr "Ungültiger notes.rewriteMode Wert: '%s'" - -#: builtin/notes.c:349 -#, c-format -msgid "Refusing to rewrite notes in %s (outside of refs/notes/)" -msgstr "" -"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:376 -#, c-format -msgid "Bad %s value: '%s'" -msgstr "Ungültiger %s Wert: '%s'" - -#: builtin/notes.c:440 +#: builtin/notes.c:312 #, c-format msgid "Malformed input line: '%s'." msgstr "Fehlerhafte Eingabezeile: '%s'." -#: builtin/notes.c:455 +#: builtin/notes.c:327 #, c-format msgid "Failed to copy notes from '%s' to '%s'" msgstr "Fehler beim Kopieren der Notizen von '%s' nach '%s'" -#: builtin/notes.c:499 builtin/notes.c:553 builtin/notes.c:626 -#: builtin/notes.c:638 builtin/notes.c:711 builtin/notes.c:758 -#: builtin/notes.c:1032 +#: builtin/notes.c:371 builtin/notes.c:425 builtin/notes.c:498 +#: builtin/notes.c:510 builtin/notes.c:583 builtin/notes.c:630 +#: builtin/notes.c:904 msgid "too many parameters" msgstr "zu viele Parameter" -#: builtin/notes.c:512 builtin/notes.c:771 +#: builtin/notes.c:384 builtin/notes.c:643 #, c-format msgid "No note found for object %s." msgstr "Kein Notiz für Objekt %s gefunden." -#: builtin/notes.c:534 builtin/notes.c:691 +#: builtin/notes.c:406 builtin/notes.c:563 msgid "note contents as a string" msgstr "Notizinhalte als Zeichenkette" -#: builtin/notes.c:537 builtin/notes.c:694 +#: builtin/notes.c:409 builtin/notes.c:566 msgid "note contents in a file" msgstr "Notizinhalte in einer Datei" -#: builtin/notes.c:539 builtin/notes.c:542 builtin/notes.c:696 -#: builtin/notes.c:699 builtin/tag.c:474 +#: builtin/notes.c:411 builtin/notes.c:414 builtin/notes.c:568 +#: builtin/notes.c:571 builtin/tag.c:474 msgid "object" msgstr "Objekt" -#: builtin/notes.c:540 builtin/notes.c:697 +#: builtin/notes.c:412 builtin/notes.c:569 msgid "reuse and edit specified note object" msgstr "Wiederverwendung und Bearbeitung des angegebenen Notiz-Objektes" -#: builtin/notes.c:543 builtin/notes.c:700 +#: builtin/notes.c:415 builtin/notes.c:572 msgid "reuse specified note object" msgstr "Wiederverwendung des angegebenen Notiz-Objektes" -#: builtin/notes.c:545 builtin/notes.c:613 +#: builtin/notes.c:417 builtin/notes.c:485 msgid "replace existing notes" msgstr "ersetzt existierende Notizen" -#: builtin/notes.c:579 +#: builtin/notes.c:451 #, c-format msgid "" "Cannot add notes. Found existing notes for object %s. Use '-f' to overwrite " @@ -7117,26 +7336,26 @@ msgstr "" "Konnte Notizen nicht hinzufügen. Existierende Notizen für Objekt %s " "gefunden. Verwenden Sie '-f' um die existierenden Notizen zu überschreiben." -#: builtin/notes.c:584 builtin/notes.c:661 +#: builtin/notes.c:456 builtin/notes.c:533 #, c-format msgid "Overwriting existing notes for object %s\n" msgstr "Überschreibe existierende Notizen für Objekt %s\n" -#: builtin/notes.c:614 +#: builtin/notes.c:486 msgid "read objects from stdin" msgstr "liest Objekte von der Standard-Eingabe" -#: builtin/notes.c:616 +#: builtin/notes.c:488 msgid "load rewriting config for (implies --stdin)" msgstr "" "lädt Konfiguration für beim Umschreiben von Versionen (impliziert " "--stdin)" -#: builtin/notes.c:634 +#: builtin/notes.c:506 msgid "too few parameters" msgstr "zu wenig Parameter" -#: builtin/notes.c:655 +#: builtin/notes.c:527 #, c-format msgid "" "Cannot copy notes. Found existing notes for object %s. Use '-f' to overwrite " @@ -7145,12 +7364,12 @@ msgstr "" "Kann Notizen nicht kopieren. Existierende Notizen für Objekt %s gefunden. " "Verwenden Sie '-f' um die existierenden Notizen zu überschreiben." -#: builtin/notes.c:667 +#: builtin/notes.c:539 #, 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:716 +#: builtin/notes.c:588 #, c-format msgid "" "The -m/-F/-c/-C options have been deprecated for the 'edit' subcommand.\n" @@ -7159,15 +7378,15 @@ msgstr "" "Die Optionen -m/-F/-c/-C sind für das Unterkommando 'edit' veraltet.\n" "Bitte benutzen Sie stattdessen 'git notes add -f -m/-F/-c/-C'.\n" -#: builtin/notes.c:863 +#: builtin/notes.c:735 msgid "General options" msgstr "Allgemeine Optionen" -#: builtin/notes.c:865 +#: builtin/notes.c:737 msgid "Merge options" -msgstr "Optionen für Zusammenführung" +msgstr "Merge-Optionen" -#: builtin/notes.c:867 +#: builtin/notes.c:739 msgid "" "resolve notes conflicts using the given strategy (manual/ours/theirs/union/" "cat_sort_uniq)" @@ -7175,46 +7394,46 @@ msgstr "" "löst Konflikte bei Notizen mit der angegebenen Strategie auf (manual/ours/" "theirs/union/cat_sort_uniq)" -#: builtin/notes.c:869 +#: builtin/notes.c:741 msgid "Committing unmerged notes" msgstr "trägt nicht zusammengeführte Notizen ein" -#: builtin/notes.c:871 +#: builtin/notes.c:743 msgid "finalize notes merge by committing unmerged notes" msgstr "" -"schließt Zusammenführung von Notizen ab, in dem nicht zusammengeführte " -"Notizen eingetragen werden" +"schließt Merge von Notizen ab, in dem nicht zusammengeführte Notizen " +"committet werden" -#: builtin/notes.c:873 +#: builtin/notes.c:745 msgid "Aborting notes merge resolution" -msgstr "bricht Konfliktauflösung bei Zusammenführung von Notizen ab" +msgstr "bricht Konfliktauflösung beim Merge von Notizen ab" -#: builtin/notes.c:875 +#: builtin/notes.c:747 msgid "abort notes merge" -msgstr "bricht Zusammenführung von Notizen ab" +msgstr "bricht Merge von Notizen ab" -#: builtin/notes.c:970 +#: builtin/notes.c:842 #, c-format msgid "Object %s has no note\n" msgstr "Objekt %s hat keine Notiz\n" -#: builtin/notes.c:982 +#: builtin/notes.c:854 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:985 +#: builtin/notes.c:857 msgid "read object names from the standard input" msgstr "liest Objektnamen von der Standard-Eingabe" -#: builtin/notes.c:1066 +#: builtin/notes.c:938 msgid "notes_ref" msgstr "Notiz-Referenz" -#: builtin/notes.c:1067 +#: builtin/notes.c:939 msgid "use notes from " msgstr "verwendet Notizen von " -#: builtin/notes.c:1102 builtin/remote.c:1598 +#: builtin/notes.c:974 builtin/remote.c:1598 #, c-format msgid "Unknown subcommand: %s" msgstr "Unbekanntes Unterkommando: %s" @@ -7237,12 +7456,12 @@ msgstr "Fehler beim Komprimieren (%d)" #: builtin/pack-objects.c:2397 #, c-format msgid "unsupported index version %s" -msgstr "Nicht unterstützte Bereitstellungsversion %s" +msgstr "Nicht unterstützte Staging-Area-Version %s" #: builtin/pack-objects.c:2401 #, c-format msgid "bad index version '%s'" -msgstr "Ungültige Bereitstellungsversion '%s'" +msgstr "Ungültige Staging-Area-Version '%s'" #: builtin/pack-objects.c:2424 #, c-format @@ -7328,7 +7547,7 @@ 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" +msgstr "liest Argumente bezüglich Commits von der Standard-Eingabe" #: builtin/pack-objects.c:2483 msgid "limit the objects to those that are not yet packed" @@ -7341,8 +7560,7 @@ 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" +"schließt Objekte ein, die von Einträgen des Reflogs referenziert werden" #: builtin/pack-objects.c:2492 msgid "output pack to stdout" @@ -7350,8 +7568,7 @@ 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" +msgstr "schließt Tag-Objekte ein, die auf gepackte Objekte referenzieren" #: builtin/pack-objects.c:2496 msgid "keep unreachable objects" @@ -7379,7 +7596,7 @@ 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\")" +msgstr "verbirgt keine Commits mit künstlichen Vorgängern (\"grafts\")" #: builtin/pack-refs.c:6 msgid "git pack-refs [options]" @@ -7399,7 +7616,7 @@ msgstr "git prune-packed [-n|--dry-run] [-q|--quiet]" #: builtin/prune.c:12 msgid "git prune [-n] [-v] [--expire