From: Junio C Hamano Date: Thu, 27 Feb 2014 22:01:38 +0000 (-0800) Subject: Merge branch 'ks/tree-diff-walk' X-Git-Tag: v2.0.0-rc0~154 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/795dd116bb655f8aa8c206ecaf415527871cb7a6?hp=7146e66f0861c720f9b32dc9d80ab80495a33e43 Merge branch 'ks/tree-diff-walk' * ks/tree-diff-walk: tree-walk: finally switch over tree descriptors to contain a pre-parsed entry revision: convert to using diff_tree_sha1() line-log: convert to using diff_tree_sha1() tree-diff: convert diff_root_tree_sha1() to just call diff_tree_sha1 with old=NULL tree-diff: allow diff_tree_sha1 to accept NULL sha1 --- diff --git a/.gitignore b/.gitignore index b5f9defed3..dc600f9b36 100644 --- a/.gitignore +++ b/.gitignore @@ -182,6 +182,7 @@ /test-dump-cache-tree /test-scrap-cache-tree /test-genrandom +/test-hashmap /test-index-version /test-line-buffer /test-match-trees diff --git a/Documentation/RelNotes/1.8.5.4.txt b/Documentation/RelNotes/1.8.5.4.txt new file mode 100644 index 0000000000..d18c40389e --- /dev/null +++ b/Documentation/RelNotes/1.8.5.4.txt @@ -0,0 +1,48 @@ +Git v1.8.5.4 Release Notes +========================== + +Fixes since v1.8.5.3 +-------------------- + + * "git fetch --depth=0" was a no-op, and was silently ignored. + Diagnose it as an error. + + * Remote repository URL expressed in scp-style host:path notation are + parsed more carefully (e.g. "foo/bar:baz" is local, "[::1]:/~user" asks + to connect to user's home directory on host at address ::1. + + * SSL-related options were not passed correctly to underlying socket + layer in "git send-email". + + * "git commit -v" appends the patch to the log message before + editing, and then removes the patch when the editor returned + control. However, the patch was not stripped correctly when the + first modified path was a submodule. + + * "git mv A B/", when B does not exist as a directory, should error + out, but it didn't. + + * When we figure out how many file descriptors to allocate for + keeping packfiles open, a system with non-working getrlimit() could + cause us to die(), but because we make this call only to get a + rough estimate of how many is available and we do not even attempt + to use up all file descriptors available ourselves, it is nicer to + fall back to a reasonable low value rather than dying. + + * "git log --decorate" did not handle a tag pointed by another tag + nicely. + + * "git add -A" (no other arguments) in a totally empty working tree + used to emit an error. + + * There is no reason to have a hardcoded upper limit of the number of + parents for an octopus merge, created via the graft mechanism, but + there was. + + * The implementation of 'git stash $cmd "stash@{...}"' did not quote + the stash argument properly and left it split at IFS whitespace. + + * The documentation to "git pull" hinted there is an "-m" option + because it incorrectly shared the documentation with "git merge". + +Also contains typofixes, documentation updates and trivial code clean-ups. diff --git a/Documentation/RelNotes/1.8.5.5.txt b/Documentation/RelNotes/1.8.5.5.txt new file mode 100644 index 0000000000..9191ce948f --- /dev/null +++ b/Documentation/RelNotes/1.8.5.5.txt @@ -0,0 +1,37 @@ +Git v1.8.5.5 Release Notes +========================== + +Fixes since v1.8.5.4 +-------------------- + + * The pathspec matching code, while comparing two trees (e.g. "git + diff A B -- path1 path2") was too aggressive and failed to match + some paths when multiple pathspecs were involved. + + * "git repack --max-pack-size=8g" stopped being parsed correctly when + the command was reimplemented in C. + + * A recent update to "git send-email" broke platforms where + /etc/ssl/certs/ directory exists but cannot be used as SSL_ca_path + (e.g. Fedora rawhide). + + * A handful of bugs around interpreting $branch@{upstream} notation + and its lookalike, when $branch part has interesting characters, + e.g. "@", and ":", have been fixed. + + * "git clone" would fail to clone from a repository that has a ref + directly under "refs/", e.g. "refs/stash", because different + validation paths do different things on such a refname. Loosen the + client side's validation to allow such a ref. + + * "git log --left-right A...B" lost the "leftness" of commits + reachable from A when A is a tag as a side effect of a recent + bugfix. This is a regression in 1.8.4.x series. + + * "git merge-base --octopus" used to leave cleaning up suboptimal + result to the caller, but now it does the clean-up itself. + + * "git mv A B/", when B does not exist as a directory, should error + out, but it didn't. + +Also contains typofixes, documentation updates and trivial code clean-ups. diff --git a/Documentation/RelNotes/1.9.0.txt b/Documentation/RelNotes/1.9.0.txt new file mode 100644 index 0000000000..752d79127a --- /dev/null +++ b/Documentation/RelNotes/1.9.0.txt @@ -0,0 +1,345 @@ +Git v1.9.0 Release Notes +======================== + +Backward compatibility notes +---------------------------- + +"git submodule foreach $cmd $args" used to treat "$cmd $args" the same +way "ssh" did, concatenating them into a single string and letting the +shell unquote. Careless users who forget to sufficiently quote $args +get their argument split at $IFS whitespaces by the shell, and got +unexpected results due to this. Starting from this release, the +command line is passed directly to the shell, if it has an argument. + +Read-only support for experimental loose-object format, in which users +could optionally choose to write their loose objects for a short +while between v1.4.3 and v1.5.3 era, has been dropped. + +The meanings of the "--tags" option to "git fetch" has changed; the +command fetches tags _in addition to_ what is fetched by the same +command line without the option. + +The way "git push $there $what" interprets the $what part given on the +command line, when it does not have a colon that explicitly tells us +what ref at the $there repository is to be updated, has been enhanced. + +A handful of ancient commands that have long been deprecated are +finally gone (repo-config, tar-tree, lost-found, and peek-remote). + + +Backward compatibility notes (for Git 2.0.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, which 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. + +The default prefix for "git svn" will change in Git 2.0. For a long +time, "git svn" created its remote-tracking branches directly under +refs/remotes, but it will place them under refs/remotes/origin/ unless +it is told otherwise with its --prefix option. + + +Updates since v1.8.5 +-------------------- + +Foreign interfaces, subsystems and ports. + + * The HTTP transport, when talking GSS-Negotiate, uses "100 + Continue" response to avoid having to rewind and resend a large + payload, which may not be always doable. + + * Various bugfixes to remote-bzr and remote-hg (in contrib/). + + * The build procedure is aware of MirBSD now. + + * Various "git p4", "git svn" and "gitk" updates. + + +UI, Workflows & Features + + * Fetching from a shallowly-cloned repository used to be forbidden, + primarily because the codepaths involved were not carefully vetted + and we did not bother supporting such usage. This release attempts + to allow object transfer out of a shallowly-cloned repository in a + more controlled way (i.e. the receiver becomes a shallow repository + with a truncated history). + + * Just like we give a reasonable default for "less" via the LESS + environment variable, we now specify a reasonable default for "lv" + via the "LV" environment variable when spawning the pager. + + * Two-level configuration variable names in "branch.*" and "remote.*" + hierarchies, whose variables are predominantly three-level, were + not completed by hitting a in bash and zsh completions. + + * Fetching a 'frotz' branch with "git fetch", while a 'frotz/nitfol' + remote-tracking branch from an earlier fetch was still there, would + error out, primarily because the command was not told that it is + allowed to lose any information on our side. "git fetch --prune" + now can be used to remove 'frotz/nitfol' to make room for fetching and + storing the 'frotz' remote-tracking branch. + + * "diff.orderfile=" configuration variable can be used to + pretend as if the "-O" option were given from the command + line of "git diff", etc. + + * The negative pathspec syntax allows "git log -- . ':!dir'" to tell + us "I am interested in everything but 'dir' directory". + + * "git difftool" shows how many different paths there are in total, + and how many of them have been shown so far, to indicate progress. + + * "git push origin master" used to push our 'master' branch to update + the 'master' branch at the 'origin' repository. This has been + enhanced to use the same ref mapping "git push origin" would use to + determine what ref at the 'origin' to be updated with our 'master'. + For example, with this configuration + + [remote "origin"] + push = refs/heads/*:refs/review/* + + that would cause "git push origin" to push out our local branches + to corresponding refs under refs/review/ hierarchy at 'origin', + "git push origin master" would update 'refs/review/master' over + there. Alternatively, if push.default is set to 'upstream' and our + 'master' is set to integrate with 'topic' from the 'origin' branch, + running "git push origin" while on our 'master' would update their + 'topic' branch, and running "git push origin master" while on any + of our branches does the same. + + * "gitweb" learned to treat ref hierarchies other than refs/heads as + if they are additional branch namespaces (e.g. refs/changes/ in + Gerrit). + + * "git for-each-ref --format=..." learned a few formatting directives; + e.g. "%(color:red)%(HEAD)%(color:reset) %(refname:short) %(subject)". + + * The command string given to "git submodule foreach" is passed + directly to the shell, without being eval'ed. This is a backward + incompatible change that may break existing users. + + * "git log" and friends learned the "--exclude=" option, to + allow people to say "list history of all branches except those that + match this pattern" with "git log --exclude='*/*' --branches". + + * "git rev-parse --parseopt" learned a new "--stuck-long" option to + help scripts parse options with an optional parameter. + + * The "--tags" option to "git fetch" no longer tells the command to + fetch _only_ the tags. It instead fetches tags _in addition to_ + what are fetched by the same command line without the option. + + +Performance, Internal Implementation, etc. + + * When parsing a 40-hex string into the object name, the string is + checked to see if it can be interpreted as a ref so that a warning + can be given for ambiguity. The code kicked in even when the + core.warnambiguousrefs is set to false to squelch this warning, in + which case the cycles spent to look at the ref namespace were an + expensive no-op, as the result was discarded without being used. + + * The naming convention of the packfiles has been updated; it used to + be based on the enumeration of names of the objects that are + contained in the pack, but now it also depends on how the packed + result is represented---packing the same set of objects using + different settings (or delta order) would produce a pack with + different name. + + * "git diff --no-index" mode used to unnecessarily attempt to read + the index when there is one. + + * The deprecated parse-options macro OPT_BOOLEAN has been removed; + use OPT_BOOL or OPT_COUNTUP in new code. + + * A few duplicate implementations of prefix/suffix string comparison + functions have been unified to starts_with() and ends_with(). + + * The new PERLLIB_EXTRA makefile variable can be used to specify + additional directories Perl modules (e.g. the ones necessary to run + git-svn) are installed on the platform when building. + + * "git merge-base" learned the "--fork-point" mode, that implements + the same logic used in "git pull --rebase" to find a suitable fork + point out of the reflog entries for the remote-tracking branch the + work has been based on. "git rebase" has the same logic that can be + triggered with the "--fork-point" option. + + * A third-party "receive-pack" (the responder to "git push") can + advertise the "no-thin" capability to tell "git push" not to use + the thin-pack optimization. Our receive-pack has always been + capable of accepting and fattening a thin-pack, and will continue + not to ask "git push" to use a non-thin pack. + + +Also contains various documentation updates and code clean-ups. + + +Fixes since v1.8.5 +------------------ + +Unless otherwise noted, all the fixes since v1.8.5 in the maintenance +track are contained in this release (see the maintenance releases' notes +for details). + + * The pathspec matching code, while comparing two trees (e.g. "git + diff A B -- path1 path2") was too aggressive and failed to match + some paths when multiple pathspecs were involved. + + * "git repack --max-pack-size=8g" stopped being parsed correctly when + the command was reimplemented in C. + + * An earlier update in v1.8.4.x to "git rev-list --objects" with + negative ref had a performance regression. + (merge 200abe7 jk/mark-edges-uninteresting later to maint). + + * A recent update to "git send-email" broke platforms where + /etc/ssl/certs/ directory exists but cannot be used as SSL_ca_path + (e.g. Fedora rawhide). + + * A handful of bugs around interpreting $branch@{upstream} notation + and its lookalike, when $branch part has interesting characters, + e.g. "@", and ":", have been fixed. + + * "git clone" would fail to clone from a repository that has a ref + directly under "refs/", e.g. "refs/stash", because different + validation paths do different things on such a refname. Loosen the + client side's validation to allow such a ref. + + * "git log --left-right A...B" lost the "leftness" of commits + reachable from A when A is a tag as a side effect of a recent + bugfix. This is a regression in 1.8.4.x series. + + * documentations to "git pull" hinted there is an "-m" option because + it incorrectly shared the documentation with "git merge". + + * "git diff A B submod" and "git diff A B submod/" ought to have done + the same for a submodule "submod", but didn't. + + * "git clone $origin foo\bar\baz" on Windows failed to create the + leading directories (i.e. a moral-equivalent of "mkdir -p"). + + * "submodule.*.update=checkout", when propagated from .gitmodules to + .git/config, turned into a "submodule.*.update=none", which did not + make much sense. + (merge efa8fd7 fp/submodule-checkout-mode later to maint). + + * The implementation of 'git stash $cmd "stash@{...}"' did not quote + the stash argument properly and left it split at IFS whitespace. + + * The "--[no-]informative-errors" options to "git daemon" were parsed + a bit too loosely, allowing any other string after these option + names. + + * There is no reason to have a hardcoded upper limit for the number of + parents of an octopus merge, created via the graft mechanism, but + there was. + + * The basic test used to leave unnecessary trash directories in the + t/ directory. + (merge 738a8be jk/test-framework-updates later to maint). + + * "git merge-base --octopus" used to leave cleaning up suboptimal + result to the caller, but now it does the clean-up itself. + + * A "gc" process running as a different user should be able to stop a + new "gc" process from starting, but it didn't. + + * An earlier "clean-up" introduced an unnecessary memory leak. + + * "git add -A" (no other arguments) in a totally empty working tree + used to emit an error. + + * "git log --decorate" did not handle a tag pointed by another tag + nicely. + + * When we figure out how many file descriptors to allocate for + keeping packfiles open, a system with non-working getrlimit() could + cause us to die(), but because we make this call only to get a + rough estimate of how many are available and we do not even attempt + to use up all available file descriptors ourselves, it is nicer to + fall back to a reasonable low value rather than dying. + + * read_sha1_file(), that is the workhorse to read the contents given + an object name, honoured object replacements, but there was no + corresponding mechanism to sha1_object_info() that was used to + obtain the metainfo (e.g. type & size) about the object. This led + callers to weird inconsistencies. + (merge 663a856 cc/replace-object-info later to maint). + + * "git cat-file --batch=", an admittedly useless command, did not + behave very well. + + * "git rev-parse -- " did not implement the usual + disambiguation rules the commands in the "git log" family used in + the same way. + + * "git mv A B/", when B does not exist as a directory, should error + out, but it didn't. + + * A workaround to an old bug in glibc prior to glibc 2.17 has been + retired; this would remove a side effect of the workaround that + corrupts system error messages in non-C locales. + + * SSL-related options were not passed correctly to underlying socket + layer in "git send-email". + + * "git commit -v" appends the patch to the log message before + editing, and then removes the patch when the editor returned + control. However, the patch was not stripped correctly when the + first modified path was a submodule. + + * "git fetch --depth=0" was a no-op, and was silently ignored. + Diagnose it as an error. + + * Remote repository URLs expressed in scp-style host:path notation are + parsed more carefully (e.g. "foo/bar:baz" is local, "[::1]:/~user" asks + to connect to user's home directory on host at address ::1. + + * "git diff -- ':(icase)makefile'" was unnecessarily rejected at the + command line parser. + + * "git cat-file --batch-check=ok" did not check the existence of + the named object. + + * "git am --abort" sometimes complained about not being able to write + a tree with an 0{40} object in it. + + * Two processes creating loose objects at the same time could have + failed unnecessarily when the name of their new objects started + with the same byte value, due to a race condition. diff --git a/Documentation/RelNotes/1.9.txt b/Documentation/RelNotes/1.9.txt deleted file mode 100644 index 43c7b682a6..0000000000 --- a/Documentation/RelNotes/1.9.txt +++ /dev/null @@ -1,372 +0,0 @@ -Git v1.9 Release Notes -====================== - -Backward compatibility notes ----------------------------- - -"git submodule foreach $cmd $args" used to treat "$cmd $args" the same -way "ssh" did, concatenating them into a single string and letting the -shell unquote. Careless users who forget to sufficiently quote $args -gets their argument split at $IFS whitespaces by the shell, and got -unexpected results due to this. Starting from this release, the -command line is passed directly to the shell, if it has an argument. - -Read-only support for experimental loose-object format, in which users -could optionally choose to write in their loose objects for a short -while between v1.4.3 to v1.5.3 era, has been dropped. - -The meanings of "--tags" option to "git fetch" has changed; the -command fetches tags _in addition to_ what are fetched by the same -command line without the option. - -The way "git push $there $what" interprets $what part given on the -command line, when it does not have a colon that explicitly tells us -what ref at the $there repository is to be updated, has been enhanced. - -A handful of ancient commands that have long been deprecated are -finally gone (repo-config, tar-tree, lost-found, and peek-remote). - - -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, which 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. - -The default prefix for "git svn" will change in Git 2.0. For a long -time, "git svn" created its remote-tracking branches directly under -refs/remotes, but it will place them under refs/remotes/origin/ unless -it is told otherwise with its --prefix option. - - -Updates since v1.8.5 --------------------- - -Foreign interfaces, subsystems and ports. - - * The HTTP transport, when talking GSS-Negotiate, uses "100 - Continue" response to avoid having to rewind and resend a large - payload, which may not be always doable. - - * Various bugfixes to remote-bzr and remote-hg (in contrib/). - - * The build procedure is aware of MirBSD now. - - * Various "git p4", "git svn" and "gitk" updates. - - -UI, Workflows & Features - - * Fetching from a shallowly-cloned repository used to be forbidden, - primarily because the codepaths involved were not carefully vetted - and we did not bother supporting such usage. This release attempts - to allow object transfer out of a shallowly-cloned repository in a - more controlled way (i.e. the receiver become a shallow repository - with a truncated history). - - * Just like we give a reasonable default for "less" via the LESS - environment variable, we now specify a reasonable default for "lv" - via the "LV" environment variable when spawning the pager. - - * Two-level configuration variable names in "branch.*" and "remote.*" - hierarchies, whose variables are predominantly three-level, were - not completed by hitting a in bash and zsh completions. - - * Fetching 'frotz' branch with "git fetch", while 'frotz/nitfol' - remote-tracking branch from an earlier fetch was still there, would - error out, primarily because the command was not told that it is - allowed to lose any information on our side. "git fetch --prune" - now can be used to remove 'frotz/nitfol' to make room to fetch and - store 'frotz' remote-tracking branch. - - * "diff.orderfile=" configuration variable can be used to - pretend as if the "-O" option were given from the command - line of "git diff", etc. - - * The negative pathspec syntax allows "git log -- . ':!dir'" to tell - us "I am interested in everything but 'dir' directory". - - * "git difftool" shows how many different paths there are in total, - and how many of them have been shown so far, to indicate progress. - - * "git push origin master" used to push our 'master' branch to update - the 'master' branch at the 'origin' repository. This has been - enhanced to use the same ref mapping "git push origin" would use to - determine what ref at the 'origin' to be updated with our 'master'. - For example, with this configuration - - [remote "origin"] - push = refs/heads/*:refs/review/* - - that would cause "git push origin" to push out our local branches - to corresponding refs under refs/review/ hierarchy at 'origin', - "git push origin master" would update 'refs/review/master' over - there. Alternatively, if push.default is set to 'upstream' and our - 'master' is set to integrate with 'topic' from the 'origin' branch, - running "git push origin" while on our 'master' would update their - 'topic' branch, and running "git push origin master" while on any - of our branches does the same. - - * "gitweb" learned to treat ref hierarchies other than refs/heads as - if they are additional branch namespaces (e.g. refs/changes/ in - Gerrit). - - * "git for-each-ref --format=..." learned a few formatting directives; - e.g. "%(color:red)%(HEAD)%(color:reset) %(refname:short) %(subject)". - - * The command string given to "git submodule foreach" is passed - directly to the shell, without being eval'ed. This is a backward - incompatible change that may break existing users. - - * "git log" and friends learned the "--exclude=" option, to - allow people to say "list history of all branches except those that - match this pattern" with "git log --exclude='*/*' --branches". - - * "git rev-parse --parseopt" learned a new "--stuck-long" option to - help scripts parse options with an optional parameter. - - * The "--tags" option to "git fetch" no longer tells the command to - fetch _only_ the tags. It instead fetches tags _in addition to_ - what are fetched by the same command line without the option. - - -Performance, Internal Implementation, etc. - - * When parsing a 40-hex string into the object name, the string is - checked to see if it can be interpreted as a ref so that a warning - can be given for ambiguity. The code kicked in even when the - core.warnambiguousrefs is set to false to squelch this warning, in - which case the cycles spent to look at the ref namespace were an - expensive no-op, as the result was discarded without being used. - - * The naming convention of the packfiles has been updated; it used to - be based on the enumeration of names of the objects that are - contained in the pack, but now it also depends on how the packed - result is represented---packing the same set of objects using - different settings (or delta order) would produce a pack with - different name. - - * "git diff --no-index" mode used to unnecessarily attempt to read - the index when there is one. - - * The deprecated parse-options macro OPT_BOOLEAN has been removed; - use OPT_BOOL or OPT_COUNTUP in new code. - - * A few duplicate implementations of prefix/suffix string comparison - functions have been unified to starts_with() and ends_with(). - - * The new PERLLIB_EXTRA makefile variable can be used to specify - additional directories Perl modules (e.g. the ones necessary to run - git-svn) are installed on the platform when building. - - * "git merge-base" learned the "--fork-point" mode, that implements - the same logic used in "git pull --rebase" to find a suitable fork - point out of the reflog entries for the remote-tracking branch the - work has been based on. "git rebase" has the same logic that can be - triggered with the "--fork-point" option. - - * A third-party "receive-pack" (the responder to "git push") can - advertise the "no-thin" capability to tell "git push" not to use - the thin-pack optimization. Our receive-pack has always been - capable of accepting and fattening a thin-pack, and will continue - not to ask "git push" to use a non-thin pack. - - -Also contains various documentation updates and code clean-ups. - - -Fixes since v1.8.5 ------------------- - -Unless otherwise noted, all the fixes since v1.8.5 in the maintenance -track are contained in this release (see the maintenance releases' notes -for details). - - * The pathspec matching code, while comparing two trees (e.g. "git - diff A B -- path1 path2") was too agrresive and failed to match - some paths when multiple pathspecs were involved. - (merge e4ddb05 as/tree-walk-fix-aggressive-short-cut later to maint). - - * "git repack --max-pack-size=8g" stopped being parsed correctly when - the command was reimplemented in C. - (merge b861e23 sb/repack-in-c later to maint). - - * An earlier update in v1.8.4.x to "git rev-list --objects" with - negative ref had performance regression. - (merge 200abe7 jk/mark-edges-uninteresting later to maint). - - * A recent update to "git send-email" broke platforms where - /etc/ssl/certs/ directory exists, but it cannot used as SSL_ca_path - (e.g. Fedora rawhide). - (merge 01645b7 rk/send-email-ssl-cert later to maint). - - * A handful of bugs around interpreting $branch@{upstream} notation - and its lookalike, when $branch part has interesting characters, - e.g. "@", and ":", have been fixed. - (merge 9892d5d jk/interpret-branch-name-fix later to maint). - - * "git clone" would fail to clone from a repository that has a ref - directly under "refs/", e.g. "refs/stash", because different - validation paths do different things on such a refname. Loosen the - client side's validation to allow such a ref. - (merge 4c22408 jk/allow-fetch-onelevel-refname later to maint). - - * "git log --left-right A...B" lost the "leftness" of commits - reachable from A when A is a tag as a side effect of a recent - bugfix. This is a regression in 1.8.4.x series. - (merge a743528 jc/revision-range-unpeel later to maint). - - * documentations to "git pull" hinted there is an "-m" option because - it incorrectly shared the documentation with "git merge". - (merge 08f19cf jc/maint-pull-docfix later to maint). - - * "git diff A B submod" and "git diff A B submod/" ought to have done - the same for a submodule "submod", but didn't. - - * "git clone $origin foo\bar\baz" on Windows failed to create the - leading directories (i.e. a moral-equivalent of "mkdir -p"). - - * "submodule.*.update=checkout", when propagated from .gitmodules to - .git/config, turned into a "submodule.*.update=none", which did not - make much sense. - (merge efa8fd7 fp/submodule-checkout-mode later to maint). - - * The implementation of 'git stash $cmd "stash@{...}"' did not quote - the stash argument properly and left it split at IFS whitespace. - (merge 2a07e43 ow/stash-with-ifs later to maint). - - * The "--[no-]informative-errors" options to "git daemon" were parsed - a bit too loosely, allowing any other string after these option - names. - (merge 82246b7 nd/daemon-informative-errors-typofix later to maint). - - * There is no reason to have a hardcoded upper limit of the number of - parents for an octopus merge, created via the graft mechanism, but - there was. - (merge e228c17 js/lift-parent-count-limit later to maint). - - * The basic test used to leave unnecessary trash directories in the - t/ directory. - (merge 738a8be jk/test-framework-updates later to maint). - - * "git merge-base --octopus" used to leave cleaning up suboptimal - result to the caller, but now it does the clean-up itself. - (merge 8f29299 bm/merge-base-octopus-dedup later to maint). - - * A "gc" process running as a different user should be able to stop a - new "gc" process from starting, but it didn't. - (merge ed7eda8 km/gc-eperm later to maint). - - * An earlier "clean-up" introduced an unnecessary memory leak. - (merge e1c1a32 jk/credential-plug-leak later to maint). - - * "git add -A" (no other arguments) in a totally empty working tree - used to emit an error. - (merge 64ed07c nd/add-empty-fix later to maint). - - * "git log --decorate" did not handle a tag pointed by another tag - nicely. - (merge 5e1361c bc/log-decoration later to maint). - - * When we figure out how many file descriptors to allocate for - keeping packfiles open, a system with non-working getrlimit() could - cause us to die(), but because we make this call only to get a - rough estimate of how many is available and we do not even attempt - to use up all file descriptors available ourselves, it is nicer to - fall back to a reasonable low value rather than dying. - (merge 491a8de jh/rlimit-nofile-fallback later to maint). - - * read_sha1_file(), that is the workhorse to read the contents given - an object name, honoured object replacements, but there was no - corresponding mechanism to sha1_object_info() that was used to - obtain the metainfo (e.g. type & size) about the object. This led - callers to weird inconsistencies. - (merge 663a856 cc/replace-object-info later to maint). - - * "git cat-file --batch=", an admittedly useless command, did not - behave very well. - (merge 6554dfa jk/cat-file-regression-fix later to maint). - - * "git rev-parse -- " did not implement the usual - disambiguation rules the commands in the "git log" family used in - the same way. - (merge 62f162f jk/rev-parse-double-dashes later to maint). - - * "git mv A B/", when B does not exist as a directory, should error - out, but it didn't. - (merge c57f628 mm/mv-file-to-no-such-dir-with-slash later to maint). - - * A workaround to an old bug in glibc prior to glibc 2.17 has been - retired; this would remove a side effect of the workaround that - corrupts system error messages in non-C locales. - - * SSL-related options were not passed correctly to underlying socket - layer in "git send-email". - (merge 5508f3e tr/send-email-ssl later to maint). - - * "git commit -v" appends the patch to the log message before - editing, and then removes the patch when the editor returned - control. However, the patch was not stripped correctly when the - first modified path was a submodule. - (merge 1a72cfd jl/commit-v-strip-marker later to maint). - - * "git fetch --depth=0" was a no-op, and was silently ignored. - Diagnose it as an error. - (merge 5594bca nd/transport-positive-depth-only later to maint). - - * Remote repository URL expressed in scp-style host:path notation are - parsed more carefully (e.g. "foo/bar:baz" is local, "[::1]:/~user" asks - to connect to user's home directory on host at address ::1. - (merge a2036d7 tb/clone-ssh-with-colon-for-port later to maint). - - * "git diff -- ':(icase)makefile'" was unnecessarily rejected at the - command line parser. - (merge 887c6c1 nd/magic-pathspec later to maint). - - * "git cat-file --batch-check=ok" did not check the existence of - the named object. - (merge 4ef8d1d sb/sha1-loose-object-info-check-existence later to maint). - - * "git am --abort" sometimes complained about not being able to write - a tree with an 0{40} object in it. - (merge 77b43ca jk/two-way-merge-corner-case-fix later to maint). - - * Two processes creating loose objects at the same time could have - failed unnecessarily when the name of their new objects started - with the same byte value, due to a race condition. - (merge b2476a6 jh/loose-object-dirs-creation-race later to maint). diff --git a/Documentation/config.txt b/Documentation/config.txt index 5f4d7939ed..7eec746950 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -992,6 +992,14 @@ commit.cleanup:: have to remove the help lines that begin with `#` in the commit log template yourself, if you do this). +commit.gpgsign:: + + A boolean to specify whether all commits should be GPG signed. + Use of this option when doing operations such as rebase can + result in a large number of commits being signed. It may be + convenient to use an agent to avoid typing your GPG passphrase + several times. + commit.status:: A boolean to enable/disable inclusion of status information in the commit message template when using an editor to prepare the commit @@ -1881,6 +1889,16 @@ pretty.:: Note that an alias with the same name as a built-in format will be silently ignored. +pull.ff:: + By default, Git does not create an extra merge commit when merging + a commit that is a descendant of the current commit. Instead, the + tip of the current branch is fast-forwarded. When set to `false`, + this variable tells Git to create an extra merge commit in such + a case (equivalent to giving the `--no-ff` option from the command + line). When set to `only`, only such fast-forward merges are + allowed (equivalent to giving the `--ff-only` option from the + command line). + pull.rebase:: When true, rebase branches on top of the fetched branch, instead of merging the default branch from the default remote when "git diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt index 49878570bf..bf3dac0cef 100644 --- a/Documentation/git-clone.txt +++ b/Documentation/git-clone.txt @@ -208,7 +208,7 @@ objects from the source repository into a pack in the cloned repository. --separate-git-dir=:: Instead of placing the cloned repository where it is supposed to be, place the cloned repository at the specified directory, - then make a filesytem-agnostic Git symbolic link to there. + then make a filesystem-agnostic Git symbolic link to there. The result is Git repository can be separated from working tree. diff --git a/Documentation/git-commit-tree.txt b/Documentation/git-commit-tree.txt index cafdc9642d..a469eab066 100644 --- a/Documentation/git-commit-tree.txt +++ b/Documentation/git-commit-tree.txt @@ -55,8 +55,13 @@ OPTIONS from the standard input. -S[]:: +--gpg-sign[=]:: GPG-sign commit. +--no-gpg-sign:: + Countermand `commit.gpgsign` configuration variable that is + set to force each and every commit to be signed. + Commit Information ------------------ diff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt index 1a7616c73a..7c42e9cabc 100644 --- a/Documentation/git-commit.txt +++ b/Documentation/git-commit.txt @@ -302,6 +302,10 @@ configuration variable documented in linkgit:git-config[1]. --gpg-sign[=]:: GPG-sign commit. +--no-gpg-sign:: + Countermand `commit.gpgsign` configuration variable that is + set to force each and every commit to be signed. + \--:: Do not interpret any more arguments as options. diff --git a/Documentation/git-diff.txt b/Documentation/git-diff.txt index 33fbd8c56f..56fb7e5322 100644 --- a/Documentation/git-diff.txt +++ b/Documentation/git-diff.txt @@ -44,7 +44,7 @@ two blob objects, or changes between two files on disk. commit relative to the named . Typically you would want comparison with the latest commit, so if you do not give , it defaults to HEAD. - If HEAD does not exist (e.g. unborned branches) and + If HEAD does not exist (e.g. unborn branches) and is not given, it shows all staged changes. --staged is a synonym of --cached. diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt index bfef8a0c62..21cb59a6d6 100644 --- a/Documentation/git-submodule.txt +++ b/Documentation/git-submodule.txt @@ -15,8 +15,8 @@ SYNOPSIS 'git submodule' [--quiet] init [--] [...] 'git submodule' [--quiet] deinit [-f|--force] [--] ... 'git submodule' [--quiet] update [--init] [--remote] [-N|--no-fetch] - [-f|--force] [--rebase] [--reference ] [--depth ] - [--merge] [--recursive] [--] [...] + [-f|--force] [--rebase|--merge|--checkout] [--reference ] + [--depth ] [--recursive] [--] [...] 'git submodule' [--quiet] summary [--cached|--files] [(-n|--summary-limit) ] [commit] [--] [...] 'git submodule' [--quiet] foreach [--recursive] @@ -155,13 +155,31 @@ it contains local modifications. update:: Update the registered submodules, i.e. clone missing submodules and - checkout the commit specified in the index of the containing repository. - This will make the submodules HEAD be detached unless `--rebase` or - `--merge` is specified or the key `submodule.$name.update` is set to - `rebase`, `merge` or `none`. `none` can be overridden by specifying - `--checkout`. Setting the key `submodule.$name.update` to `!command` - will cause `command` to be run. `command` can be any arbitrary shell - command that takes a single argument, namely the sha1 to update to. + checkout the commit specified in the index of the containing + repository. The update mode defaults to `checkout`, but can be + configured with the `submodule..update` setting or the + `--rebase`, `--merge`, or `--checkout` options. ++ +For updates that clone missing submodules, checkout-mode updates will +create submodules with detached HEADs; all other modes will create +submodules with a local branch named after `submodule..branch`. ++ +For updates that do not clone missing submodules, the submodule's HEAD +is only touched when the remote reference does not match the +submodule's HEAD (for none-mode updates, the submodule is never +touched). The remote reference is usually the gitlinked commit from +the superproject's tree, but with `--remote` it is the upstream +subproject's `submodule..branch`. This remote reference is +integrated with the submodule's HEAD using the specified update mode. +For checkout-mode updates, that will result in a detached HEAD. For +rebase- and merge-mode updates, the commit referenced by the +submodule's HEAD may change, but the symbolic reference will remain +unchanged (i.e. checked-out branches will still be checked-out +branches, and detached HEADs will still be detached HEADs). If none +of the builtin modes fit your needs, set `submodule..update` to +`!command` to configure a custom integration command. `command` can +be any arbitrary shell command that takes a single argument, namely +the sha1 to update to. + If the submodule is not yet initialized, and you just want to use the setting as stored in .gitmodules, you can automatically initialize the @@ -281,6 +299,16 @@ In order to ensure a current tracking branch state, `update --remote` fetches the submodule's remote repository before calculating the SHA-1. If you don't want to fetch, you should use `submodule update --remote --no-fetch`. ++ +Use this option to integrate changes from the upstream subproject with +your submodule's current HEAD. Alternatively, you can run `git pull` +from the submodule, which is equivalent except for the remote branch +name: `update --remote` uses the default upstream repository and +`submodule..branch`, while `git pull` uses the submodule's +`branch..merge`. Prefer `submodule..branch` if you want +to distribute the default upstream branch with the superproject and +`branch..merge` if you want a more native feel while working in +the submodule itself. -N:: --no-fetch:: diff --git a/Documentation/git-tag.txt b/Documentation/git-tag.txt index c418c44d40..404257df9f 100644 --- a/Documentation/git-tag.txt +++ b/Documentation/git-tag.txt @@ -103,8 +103,9 @@ OPTIONS + This option is only applicable when listing tags without annotation lines. ---contains :: - Only list tags which contain the specified commit. +--contains []:: + Only list tags which contain the specified commit (HEAD if not + specified). --points-at :: Only list tags of the given object. diff --git a/Documentation/git.txt b/Documentation/git.txt index 274d816b43..02bbc084b8 100644 --- a/Documentation/git.txt +++ b/Documentation/git.txt @@ -43,9 +43,16 @@ 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.5.3/git.html[documentation for release 1.8.5.3] +* link:v1.9.0/git.html[documentation for release 1.9.0] * release notes for + link:RelNotes/1.9.0.txt[1.9.0]. + +* link:v1.8.5.5/git.html[documentation for release 1.8.5.5] + +* release notes for + link:RelNotes/1.8.5.5.txt[1.8.5.5], + link:RelNotes/1.8.5.4.txt[1.8.5.4], link:RelNotes/1.8.5.3.txt[1.8.5.3], link:RelNotes/1.8.5.2.txt[1.8.5.2], link:RelNotes/1.8.5.1.txt[1.8.5.1], diff --git a/Documentation/gitcli.txt b/Documentation/gitcli.txt index 3f33ca5507..1c3e109cb3 100644 --- a/Documentation/gitcli.txt +++ b/Documentation/gitcli.txt @@ -28,7 +28,7 @@ arguments. Here are the rules: they can be disambiguated by placing `--` between them. E.g. `git diff -- HEAD` is, "I have a file called HEAD in my work tree. Please show changes between the version I staged in the index - and what I have in the work tree for that file". not "show difference + and what I have in the work tree for that file", not "show difference between the HEAD commit and the work tree as a whole". You can say `git diff HEAD --` to ask for the latter. diff --git a/Documentation/githooks.txt b/Documentation/githooks.txt index d48bf4d6fa..d954bf6ba8 100644 --- a/Documentation/githooks.txt +++ b/Documentation/githooks.txt @@ -251,7 +251,7 @@ three parameters: - the name of the ref being updated, - the old object name stored in the ref, - - and the new objectname to be stored in the ref. + - and the new object name to be stored in the ref. A zero exit from the update hook allows the ref to be updated. Exiting with a non-zero status prevents 'git-receive-pack' diff --git a/Documentation/gitmodules.txt b/Documentation/gitmodules.txt index 347a9f76ee..f539e3f66a 100644 --- a/Documentation/gitmodules.txt +++ b/Documentation/gitmodules.txt @@ -55,6 +55,10 @@ submodule..branch:: A remote branch name for tracking updates in the upstream submodule. If the option is not specified, it defaults to 'master'. See the `--remote` documentation in linkgit:git-submodule[1] for details. ++ +This branch name is also used for the local branch created by +non-checkout cloning updates. See the `update` documentation in +linkgit:git-submodule[1] for details. submodule..fetchRecurseSubmodules:: This option can be used to control recursive fetching of this diff --git a/Documentation/gitweb.conf.txt b/Documentation/gitweb.conf.txt index db4154f9d5..952f503afb 100644 --- a/Documentation/gitweb.conf.txt +++ b/Documentation/gitweb.conf.txt @@ -630,13 +630,13 @@ need to set this element to empty list i.e. `[]`. override:: If this field has a true value then the given feature is - overriddable, which means that it can be configured + overridable, which means that it can be configured (or enabled/disabled) on a per-repository basis. + Usually given "" is configurable via the `gitweb.` config variable in the per-repository Git configuration file. + -*Note* that no feature is overriddable by default. +*Note* that no feature is overridable by default. sub:: Internal detail of implementation. What is important is that diff --git a/Documentation/howto/maintain-git.txt b/Documentation/howto/maintain-git.txt index 33ae69c11f..ca4378740c 100644 --- a/Documentation/howto/maintain-git.txt +++ b/Documentation/howto/maintain-git.txt @@ -39,26 +39,26 @@ The policy on Integration is informally mentioned in "A Note from the maintainer" message, which is periodically posted to this mailing list after each feature release is made. - - Feature releases are numbered as vX.Y.Z and are meant to + - Feature releases are numbered as vX.Y.0 and are meant to contain bugfixes and enhancements in any area, including functionality, performance and usability, without regression. - One release cycle for a feature release is expected to last for eight to ten weeks. - - Maintenance releases are numbered as vX.Y.Z.W and are meant - to contain only bugfixes for the corresponding vX.Y.Z feature - release and earlier maintenance releases vX.Y.Z.V (V < W). + - Maintenance releases are numbered as vX.Y.Z and are meant + to contain only bugfixes for the corresponding vX.Y.0 feature + release and earlier maintenance releases vX.Y.W (W < Z). - 'master' branch is used to prepare for the next feature release. In other words, at some point, the tip of 'master' - branch is tagged with vX.Y.Z. + branch is tagged with vX.Y.0. - 'maint' branch is used to prepare for the next maintenance - release. After the feature release vX.Y.Z is made, the tip + release. After the feature release vX.Y.0 is made, the tip of 'maint' branch is set to that release, and bugfixes will accumulate on the branch, and at some point, the tip of the - branch is tagged with vX.Y.Z.1, vX.Y.Z.2, and so on. + branch is tagged with vX.Y.1, vX.Y.2, and so on. - 'next' branch is used to publish changes (both enhancements and fixes) that (1) have worthwhile goal, (2) are in a fairly @@ -86,6 +86,10 @@ this mailing list after each feature release is made. users are encouraged to test it so that regressions and bugs are found before new topics are merged to 'master'. +Note that before v1.9.0 release, the version numbers used to be +structured slightly differently. vX.Y.Z were feature releases while +vX.Y.Z.W were maintenance releases for vX.Y.Z. + A Typical Git Day ----------------- diff --git a/Documentation/technical/api-hash.txt b/Documentation/technical/api-hash.txt deleted file mode 100644 index e5061e0677..0000000000 --- a/Documentation/technical/api-hash.txt +++ /dev/null @@ -1,52 +0,0 @@ -hash API -======== - -The hash API is a collection of simple hash table functions. Users are expected -to implement their own hashing. - -Data Structures ---------------- - -`struct hash_table`:: - - The hash table structure. The `array` member points to the hash table - entries. The `size` member counts the total number of valid and invalid - entries in the table. The `nr` member keeps track of the number of - valid entries. - -`struct hash_table_entry`:: - - An opaque structure representing an entry in the hash table. The `hash` - member is the entry's hash key and the `ptr` member is the entry's - value. - -Functions ---------- - -`init_hash`:: - - Initialize the hash table. - -`free_hash`:: - - Release memory associated with the hash table. - -`insert_hash`:: - - Insert a pointer into the hash table. If an entry with that hash - already exists, a pointer to the existing entry's value is returned. - Otherwise NULL is returned. This allows callers to implement - chaining, etc. - -`lookup_hash`:: - - Lookup an entry in the hash table. If an entry with that hash exists - the entry's value is returned. Otherwise NULL is returned. - -`for_each_hash`:: - - Call a function for each entry in the hash table. The function is - expected to take the entry's value as its only argument and return an - int. If the function returns a negative int the loop is aborted - immediately. Otherwise, the return value is accumulated and the sum - returned upon completion of the loop. diff --git a/Documentation/technical/api-hashmap.txt b/Documentation/technical/api-hashmap.txt new file mode 100644 index 0000000000..42ca2347ed --- /dev/null +++ b/Documentation/technical/api-hashmap.txt @@ -0,0 +1,235 @@ +hashmap API +=========== + +The hashmap API is a generic implementation of hash-based key-value mappings. + +Data Structures +--------------- + +`struct hashmap`:: + + The hash table structure. ++ +The `size` member keeps track of the total number of entries. The `cmpfn` +member is a function used to compare two entries for equality. The `table` and +`tablesize` members store the hash table and its size, respectively. + +`struct hashmap_entry`:: + + An opaque structure representing an entry in the hash table, which must + be used as first member of user data structures. Ideally it should be + followed by an int-sized member to prevent unused memory on 64-bit + systems due to alignment. ++ +The `hash` member is the entry's hash code and the `next` member points to the +next entry in case of collisions (i.e. if multiple entries map to the same +bucket). + +`struct hashmap_iter`:: + + An iterator structure, to be used with hashmap_iter_* functions. + +Types +----- + +`int (*hashmap_cmp_fn)(const void *entry, const void *entry_or_key, const void *keydata)`:: + + User-supplied function to test two hashmap entries for equality. Shall + return 0 if the entries are equal. ++ +This function is always called with non-NULL `entry` / `entry_or_key` +parameters that have the same hash code. When looking up an entry, the `key` +and `keydata` parameters to hashmap_get and hashmap_remove are always passed +as second and third argument, respectively. Otherwise, `keydata` is NULL. + +Functions +--------- + +`unsigned int strhash(const char *buf)`:: +`unsigned int strihash(const char *buf)`:: +`unsigned int memhash(const void *buf, size_t len)`:: +`unsigned int memihash(const void *buf, size_t len)`:: + + Ready-to-use hash functions for strings, using the FNV-1 algorithm (see + http://www.isthe.com/chongo/tech/comp/fnv). ++ +`strhash` and `strihash` take 0-terminated strings, while `memhash` and +`memihash` operate on arbitrary-length memory. ++ +`strihash` and `memihash` are case insensitive versions. + +`void hashmap_init(struct hashmap *map, hashmap_cmp_fn equals_function, size_t initial_size)`:: + + Initializes a hashmap structure. ++ +`map` is the hashmap to initialize. ++ +The `equals_function` can be specified to compare two entries for equality. +If NULL, entries are considered equal if their hash codes are equal. ++ +If the total number of entries is known in advance, the `initial_size` +parameter may be used to preallocate a sufficiently large table and thus +prevent expensive resizing. If 0, the table is dynamically resized. + +`void hashmap_free(struct hashmap *map, int free_entries)`:: + + Frees a hashmap structure and allocated memory. ++ +`map` is the hashmap to free. ++ +If `free_entries` is true, each hashmap_entry in the map is freed as well +(using stdlib's free()). + +`void hashmap_entry_init(void *entry, unsigned int hash)`:: + + Initializes a hashmap_entry structure. ++ +`entry` points to the entry to initialize. ++ +`hash` is the hash code of the entry. + +`void *hashmap_get(const struct hashmap *map, const void *key, const void *keydata)`:: + + Returns the hashmap entry for the specified key, or NULL if not found. ++ +`map` is the hashmap structure. ++ +`key` is a hashmap_entry structure (or user data structure that starts with +hashmap_entry) that has at least been initialized with the proper hash code +(via `hashmap_entry_init`). ++ +If an entry with matching hash code is found, `key` and `keydata` are passed +to `hashmap_cmp_fn` to decide whether the entry matches the key. + +`void *hashmap_get_next(const struct hashmap *map, const void *entry)`:: + + Returns the next equal hashmap entry, or NULL if not found. This can be + used to iterate over duplicate entries (see `hashmap_add`). ++ +`map` is the hashmap structure. ++ +`entry` is the hashmap_entry to start the search from, obtained via a previous +call to `hashmap_get` or `hashmap_get_next`. + +`void hashmap_add(struct hashmap *map, void *entry)`:: + + Adds a hashmap entry. This allows to add duplicate entries (i.e. + separate values with the same key according to hashmap_cmp_fn). ++ +`map` is the hashmap structure. ++ +`entry` is the entry to add. + +`void *hashmap_put(struct hashmap *map, void *entry)`:: + + Adds or replaces a hashmap entry. If the hashmap contains duplicate + entries equal to the specified entry, only one of them will be replaced. ++ +`map` is the hashmap structure. ++ +`entry` is the entry to add or replace. ++ +Returns the replaced entry, or NULL if not found (i.e. the entry was added). + +`void *hashmap_remove(struct hashmap *map, const void *key, const void *keydata)`:: + + Removes a hashmap entry matching the specified key. If the hashmap + contains duplicate entries equal to the specified key, only one of + them will be removed. ++ +`map` is the hashmap structure. ++ +`key` is a hashmap_entry structure (or user data structure that starts with +hashmap_entry) that has at least been initialized with the proper hash code +(via `hashmap_entry_init`). ++ +If an entry with matching hash code is found, `key` and `keydata` are +passed to `hashmap_cmp_fn` to decide whether the entry matches the key. ++ +Returns the removed entry, or NULL if not found. + +`void hashmap_iter_init(struct hashmap *map, struct hashmap_iter *iter)`:: +`void *hashmap_iter_next(struct hashmap_iter *iter)`:: +`void *hashmap_iter_first(struct hashmap *map, struct hashmap_iter *iter)`:: + + Used to iterate over all entries of a hashmap. ++ +`hashmap_iter_init` initializes a `hashmap_iter` structure. ++ +`hashmap_iter_next` returns the next hashmap_entry, or NULL if there are no +more entries. ++ +`hashmap_iter_first` is a combination of both (i.e. initializes the iterator +and returns the first entry, if any). + +Usage example +------------- + +Here's a simple usage example that maps long keys to double values. +[source,c] +------------ +struct hashmap map; + +struct long2double { + struct hashmap_entry ent; /* must be the first member! */ + long key; + double value; +}; + +static int long2double_cmp(const struct long2double *e1, const struct long2double *e2, const void *unused) +{ + return !(e1->key == e2->key); +} + +void long2double_init(void) +{ + hashmap_init(&map, (hashmap_cmp_fn) long2double_cmp, 0); +} + +void long2double_free(void) +{ + hashmap_free(&map, 1); +} + +static struct long2double *find_entry(long key) +{ + struct long2double k; + hashmap_entry_init(&k, memhash(&key, sizeof(long))); + k.key = key; + return hashmap_get(&map, &k, NULL); +} + +double get_value(long key) +{ + struct long2double *e = find_entry(key); + return e ? e->value : 0; +} + +void set_value(long key, double value) +{ + struct long2double *e = find_entry(key); + if (!e) { + e = malloc(sizeof(struct long2double)); + hashmap_entry_init(e, memhash(&key, sizeof(long))); + e->key = key; + hashmap_add(&map, e); + } + e->value = value; +} +------------ + +Using variable-sized keys +------------------------- + +The `hashmap_entry_get` and `hashmap_entry_remove` functions expect an ordinary +`hashmap_entry` structure as key to find the correct entry. If the key data is +variable-sized (e.g. a FLEX_ARRAY string) or quite large, it is undesirable +to create a full-fledged entry structure on the heap and copy all the key data +into the structure. + +In this case, the `keydata` parameter can be used to pass +variable-sized key data directly to the comparison function, and the `key` +parameter can be a stripped-down, fixed size entry structure allocated on the +stack. + +See test-hashmap.c for an example using arbitrary-length strings as keys. diff --git a/Documentation/user-manual.txt b/Documentation/user-manual.txt index 248dcabd50..d4f9804462 100644 --- a/Documentation/user-manual.txt +++ b/Documentation/user-manual.txt @@ -3795,7 +3795,7 @@ like so: $ git update-index filename ------------------------------------------------- -but to avoid common mistakes with filename globbing etc, the command +but to avoid common mistakes with filename globbing etc., the command will not normally add totally new entries or remove old entries, i.e. it will normally just update existing cache entries. diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index 38b939b636..2b97352dd3 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -1,7 +1,7 @@ #!/bin/sh GVF=GIT-VERSION-FILE -DEF_VER=v1.9-rc2 +DEF_VER=v1.9.0 LF=' ' diff --git a/Makefile b/Makefile index dddaf4f287..c3213bd54b 100644 --- a/Makefile +++ b/Makefile @@ -555,6 +555,7 @@ TEST_PROGRAMS_NEED_X += test-date TEST_PROGRAMS_NEED_X += test-delta TEST_PROGRAMS_NEED_X += test-dump-cache-tree TEST_PROGRAMS_NEED_X += test-genrandom +TEST_PROGRAMS_NEED_X += test-hashmap TEST_PROGRAMS_NEED_X += test-index-version TEST_PROGRAMS_NEED_X += test-line-buffer TEST_PROGRAMS_NEED_X += test-match-trees @@ -671,7 +672,7 @@ LIB_H += git-compat-util.h LIB_H += gpg-interface.h LIB_H += graph.h LIB_H += grep.h -LIB_H += hash.h +LIB_H += hashmap.h LIB_H += help.h LIB_H += http.h LIB_H += kwset.h @@ -802,7 +803,7 @@ LIB_OBJS += gettext.o LIB_OBJS += gpg-interface.o LIB_OBJS += graph.o LIB_OBJS += grep.o -LIB_OBJS += hash.o +LIB_OBJS += hashmap.o LIB_OBJS += help.o LIB_OBJS += hex.o LIB_OBJS += ident.o diff --git a/RelNotes b/RelNotes index c300119d96..bb52cf9476 120000 --- a/RelNotes +++ b/RelNotes @@ -1 +1 @@ -Documentation/RelNotes/1.9.txt \ No newline at end of file +Documentation/RelNotes/1.9.0.txt \ No newline at end of file diff --git a/bisect.c b/bisect.c index 37200b41f1..8448d27877 100644 --- a/bisect.c +++ b/bisect.c @@ -685,7 +685,6 @@ static void mark_expected_rev(char *bisect_rev_hex) static int bisect_checkout(char *bisect_rev_hex, int no_checkout) { - int res; mark_expected_rev(bisect_rev_hex); @@ -696,6 +695,7 @@ static int bisect_checkout(char *bisect_rev_hex, int no_checkout) die("update-ref --no-deref HEAD failed on %s", bisect_rev_hex); } else { + int res; res = run_command_v_opt(argv_checkout, RUN_GIT_CMD); if (res) exit(res); diff --git a/builtin/add.c b/builtin/add.c index 2a2722fa10..672adc01ff 100644 --- a/builtin/add.c +++ b/builtin/add.c @@ -208,8 +208,7 @@ static char *prune_directory(struct dir_struct *dir, struct pathspec *pathspec, i = dir->nr; while (--i >= 0) { struct dir_entry *entry = *src++; - if (match_pathspec_depth(pathspec, entry->name, entry->len, - prefix, seen)) + if (dir_path_match(entry, pathspec, prefix, seen)) *dst++ = entry; else if (flag & WARN_IMPLICIT_DOT) /* diff --git a/builtin/apply.c b/builtin/apply.c index b0d0986226..a7e72d57ab 100644 --- a/builtin/apply.c +++ b/builtin/apply.c @@ -1943,13 +1943,7 @@ static int parse_chunk(char *buffer, unsigned long size, struct patch *patch) size - offset - hdrsize, patch); if (!patchsize) { - static const char *binhdr[] = { - "Binary files ", - "Files ", - NULL, - }; static const char git_binary[] = "GIT binary patch\n"; - int i; int hd = hdrsize + offset; unsigned long llen = linelen(buffer + hd, size - hd); @@ -1965,6 +1959,12 @@ static int parse_chunk(char *buffer, unsigned long size, struct patch *patch) patchsize = 0; } else if (!memcmp(" differ\n", buffer + hd + llen - 8, 8)) { + static const char *binhdr[] = { + "Binary files ", + "Files ", + NULL, + }; + int i; for (i = 0; binhdr[i]; i++) { int len = strlen(binhdr[i]); if (len < size - hd && diff --git a/builtin/blame.c b/builtin/blame.c index e44a6bb30a..967a7c6bbd 100644 --- a/builtin/blame.c +++ b/builtin/blame.c @@ -1580,14 +1580,14 @@ static const char *format_time(unsigned long time, const char *tz_str, int show_raw_time) { static char time_buf[128]; - const char *time_str; - int time_len; - int tz; if (show_raw_time) { snprintf(time_buf, sizeof(time_buf), "%lu %s", time, tz_str); } else { + const char *time_str; + int time_len; + int tz; tz = atoi(tz_str); time_str = show_date(time, tz, blame_date_mode); time_len = strlen(time_str); diff --git a/builtin/checkout.c b/builtin/checkout.c index 5df3837e31..ada51fa70f 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -297,8 +297,7 @@ static int checkout_paths(const struct checkout_opts *opts, * match_pathspec() for _all_ entries when * opts->source_tree != NULL. */ - if (match_pathspec_depth(&opts->pathspec, ce->name, ce_namelen(ce), - 0, ps_matched)) + if (ce_path_match(ce, &opts->pathspec, ps_matched)) ce->ce_flags |= CE_MATCHED; } diff --git a/builtin/clean.c b/builtin/clean.c index 2f26297142..114d7bf879 100644 --- a/builtin/clean.c +++ b/builtin/clean.c @@ -154,7 +154,7 @@ static int remove_dirs(struct strbuf *path, const char *prefix, int force_flag, DIR *dir; struct strbuf quoted = STRBUF_INIT; struct dirent *e; - int res = 0, ret = 0, gone = 1, original_len = path->len, len, i; + int res = 0, ret = 0, gone = 1, original_len = path->len, len; unsigned char submodule_head[20]; struct string_list dels = STRING_LIST_INIT_DUP; @@ -242,6 +242,7 @@ static int remove_dirs(struct strbuf *path, const char *prefix, int force_flag, } if (!*dir_gone && !quiet) { + int i; for (i = 0; i < dels.nr; i++) printf(dry_run ? _(msg_would_remove) : _(msg_remove), dels.items[i].string); } @@ -933,36 +934,18 @@ int cmd_clean(int argc, const char **argv, const char *prefix) for (i = 0; i < dir.nr; i++) { struct dir_entry *ent = dir.entries[i]; - int len, pos; int matches = 0; - const struct cache_entry *ce; struct stat st; const char *rel; - /* - * Remove the '/' at the end that directory - * walking adds for directory entries. - */ - len = ent->len; - if (len && ent->name[len-1] == '/') - len--; - pos = cache_name_pos(ent->name, len); - if (0 <= pos) - continue; /* exact match */ - pos = -pos - 1; - if (pos < active_nr) { - ce = active_cache[pos]; - if (ce_namelen(ce) == len && - !memcmp(ce->name, ent->name, len)) - continue; /* Yup, this one exists unmerged */ - } + if (!cache_name_is_other(ent->name, ent->len)) + continue; if (lstat(ent->name, &st)) die_errno("Cannot lstat '%s'", ent->name); if (pathspec.nr) - matches = match_pathspec_depth(&pathspec, ent->name, - len, 0, NULL); + matches = dir_path_match(ent, &pathspec, 0, NULL); if (S_ISDIR(st.st_mode)) { if (remove_directories || (matches == MATCHED_EXACTLY)) { diff --git a/builtin/commit-tree.c b/builtin/commit-tree.c index f641ff2a89..987a4c3d73 100644 --- a/builtin/commit-tree.c +++ b/builtin/commit-tree.c @@ -12,6 +12,8 @@ static const char commit_tree_usage[] = "git commit-tree [(-p )...] [-S[]] [-m ] [-F ] object.sha1; @@ -31,6 +33,10 @@ static int commit_tree_config(const char *var, const char *value, void *cb) int status = git_gpg_config(var, value, NULL); if (status) return status; + if (!strcmp(var, "commit.gpgsign")) { + sign_commit = git_config_bool(var, value) ? "" : NULL; + return 0; + } return git_default_config(var, value, cb); } @@ -41,7 +47,6 @@ int cmd_commit_tree(int argc, const char **argv, const char *prefix) unsigned char tree_sha1[20]; unsigned char commit_sha1[20]; struct strbuf buffer = STRBUF_INIT; - const char *sign_commit = NULL; git_config(commit_tree_config, NULL); @@ -66,6 +71,11 @@ int cmd_commit_tree(int argc, const char **argv, const char *prefix) continue; } + if (!strcmp(arg, "--no-gpg-sign")) { + sign_commit = NULL; + continue; + } + if (!strcmp(arg, "-m")) { if (argc <= ++i) usage(commit_tree_usage); diff --git a/builtin/commit.c b/builtin/commit.c index 3767478c6d..3783bcadcd 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -234,7 +234,7 @@ static int list_paths(struct string_list *list, const char *with_tree, if (ce->ce_flags & CE_UPDATE) continue; - if (!match_pathspec_depth(pattern, ce->name, ce_namelen(ce), 0, m)) + if (!ce_path_match(ce, pattern, m)) continue; item = string_list_insert(list, ce->name); if (ce_skip_worktree(ce)) @@ -307,7 +307,6 @@ static char *prepare_index(int argc, const char **argv, const char *prefix, int fd; struct string_list partial; struct pathspec pathspec; - char *old_index_env = NULL; int refresh_flags = REFRESH_QUIET; if (is_status) @@ -320,6 +319,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix, die(_("index file corrupt")); if (interactive) { + char *old_index_env = NULL; fd = hold_locked_index(&index_lock, 1); refresh_cache_or_die(refresh_flags); @@ -600,12 +600,10 @@ static int prepare_to_commit(const char *index_file, const char *prefix, { struct stat statbuf; struct strbuf committer_ident = STRBUF_INIT; - int commitable, saved_color_setting; + int commitable; struct strbuf sb = STRBUF_INIT; - char *buffer; const char *hook_arg1 = NULL; const char *hook_arg2 = NULL; - int ident_shown = 0; int clean_message_contents = (cleanup_mode != CLEANUP_NONE); int old_display_comment_prefix; @@ -649,6 +647,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix, logfile); hook_arg1 = "message"; } else if (use_message) { + char *buffer; buffer = strstr(use_message_buffer, "\n\n"); if (!use_editor && (!buffer || buffer[2] == '\0')) die(_("commit has empty message")); @@ -753,6 +752,8 @@ static int prepare_to_commit(const char *index_file, const char *prefix, /* This checks if committer ident is explicitly given */ strbuf_addstr(&committer_ident, git_committer_info(IDENT_STRICT)); if (use_editor && include_status) { + int ident_shown = 0; + int saved_color_setting; char *ai_tmp, *ci_tmp; if (whence != FROM_COMMIT) status_printf_ln(s, GIT_COLOR_NORMAL, @@ -1406,6 +1407,10 @@ static int git_commit_config(const char *k, const char *v, void *cb) } if (!strcmp(k, "commit.cleanup")) return git_config_string(&cleanup_arg, k, v); + if (!strcmp(k, "commit.gpgsign")) { + sign_commit = git_config_bool(k, v) ? "" : NULL; + return 0; + } status = git_gpg_config(k, v, NULL); if (status) @@ -1510,7 +1515,6 @@ int cmd_commit(int argc, const char **argv, const char *prefix) struct ref_lock *ref_lock; struct commit_list *parents = NULL, **pptr = &parents; struct stat statbuf; - int allow_fast_forward = 1; struct commit *current_head = NULL; struct commit_extra_header *extra = NULL; @@ -1558,6 +1562,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix) } else if (whence == FROM_MERGE) { struct strbuf m = STRBUF_INIT; FILE *fp; + int allow_fast_forward = 1; if (!reflog_msg) reflog_msg = "commit (merge)"; diff --git a/builtin/describe.c b/builtin/describe.c index 7db43dae1b..dadd999c41 100644 --- a/builtin/describe.c +++ b/builtin/describe.c @@ -6,7 +6,7 @@ #include "exec_cmd.h" #include "parse-options.h" #include "diff.h" -#include "hash.h" +#include "hashmap.h" #include "argv-array.h" #define SEEN (1u << 0) @@ -25,7 +25,7 @@ static int longformat; static int first_parent; static int abbrev = -1; /* unspecified */ static int max_candidates = 10; -static struct hash_table names; +static struct hashmap names; static int have_util; static const char *pattern; static int always; @@ -37,7 +37,7 @@ static const char *diff_index_args[] = { }; struct commit_name { - struct commit_name *next; + struct hashmap_entry entry; unsigned char peeled[20]; struct tag *tag; unsigned prio:2; /* annotated tag = 2, tag = 1, head = 0 */ @@ -50,6 +50,12 @@ static const char *prio_names[] = { "head", "lightweight", "annotated", }; +static int commit_name_cmp(const struct commit_name *cn1, + const struct commit_name *cn2, const void *peeled) +{ + return hashcmp(cn1->peeled, peeled ? peeled : cn2->peeled); +} + static inline unsigned int hash_sha1(const unsigned char *sha1) { unsigned int hash; @@ -59,21 +65,9 @@ static inline unsigned int hash_sha1(const unsigned char *sha1) static inline struct commit_name *find_commit_name(const unsigned char *peeled) { - struct commit_name *n = lookup_hash(hash_sha1(peeled), &names); - while (n && !!hashcmp(peeled, n->peeled)) - n = n->next; - return n; -} - -static int set_util(void *chain, void *data) -{ - struct commit_name *n; - for (n = chain; n; n = n->next) { - struct commit *c = lookup_commit_reference_gently(n->peeled, 1); - if (c) - c->util = n; - } - return 0; + struct commit_name key; + hashmap_entry_init(&key, hash_sha1(peeled)); + return hashmap_get(&names, &key, peeled); } static int replace_name(struct commit_name *e, @@ -118,16 +112,10 @@ static void add_to_known_names(const char *path, struct tag *tag = NULL; if (replace_name(e, prio, sha1, &tag)) { if (!e) { - void **pos; e = xmalloc(sizeof(struct commit_name)); hashcpy(e->peeled, peeled); - pos = insert_hash(hash_sha1(peeled), e, &names); - if (pos) { - e->next = *pos; - *pos = e; - } else { - e->next = NULL; - } + hashmap_entry_init(e, hash_sha1(peeled)); + hashmap_add(&names, e); e->path = NULL; } e->tag = tag; @@ -292,7 +280,14 @@ static void describe(const char *arg, int last_one) fprintf(stderr, _("searching to describe %s\n"), arg); if (!have_util) { - for_each_hash(&names, set_util, NULL); + struct hashmap_iter iter; + struct commit *c; + struct commit_name *n = hashmap_iter_first(&names, &iter); + for (; n; n = hashmap_iter_next(&iter)) { + c = lookup_commit_reference_gently(n->peeled, 1); + if (c) + c->util = n; + } have_util = 1; } @@ -463,9 +458,9 @@ int cmd_describe(int argc, const char **argv, const char *prefix) return cmd_name_rev(args.argc, args.argv, prefix); } - init_hash(&names); + hashmap_init(&names, (hashmap_cmp_fn) commit_name_cmp, 0); for_each_rawref(get_name, NULL); - if (!names.nr && !always) + if (!names.size && !always) die(_("No names found, cannot describe anything.")); if (argc == 0) { diff --git a/builtin/fetch.c b/builtin/fetch.c index 025bc3e38d..55f457c04f 100644 --- a/builtin/fetch.c +++ b/builtin/fetch.c @@ -1026,7 +1026,6 @@ static int fetch_multiple(struct string_list *list) static int fetch_one(struct remote *remote, int argc, const char **argv) { - int i; static const char **refs = NULL; struct refspec *refspec; int ref_nr = 0; @@ -1050,6 +1049,7 @@ static int fetch_one(struct remote *remote, int argc, const char **argv) if (argc > 0) { int j = 0; + int i; refs = xcalloc(argc + 1, sizeof(const char *)); for (i = 0; i < argc; i++) { if (!strcmp(argv[i], "tag")) { diff --git a/builtin/gc.c b/builtin/gc.c index c19545d49e..5bbb5e3cc6 100644 --- a/builtin/gc.c +++ b/builtin/gc.c @@ -188,13 +188,12 @@ static int need_to_gc(void) 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; + int fd; if (pidfile) /* already locked */ @@ -206,6 +205,8 @@ static const char *lock_repo_for_gc(int force, pid_t* ret_pid) fd = hold_lock_file_for_update(&lock, git_path("gc.pid"), LOCK_DIE_ON_ERROR); if (!force) { + static char locking_host[128]; + int should_exit; fp = fopen(git_path("gc.pid"), "r"); memset(locking_host, 0, sizeof(locking_host)); should_exit = diff --git a/builtin/grep.c b/builtin/grep.c index 63f86032d9..69ac2d8797 100644 --- a/builtin/grep.c +++ b/builtin/grep.c @@ -379,7 +379,7 @@ static int grep_cache(struct grep_opt *opt, const struct pathspec *pathspec, int const struct cache_entry *ce = active_cache[nr]; if (!S_ISREG(ce->ce_mode)) continue; - if (!match_pathspec_depth(pathspec, ce->name, ce_namelen(ce), 0, NULL)) + if (!ce_path_match(ce, pathspec, NULL)) continue; /* * If CE_VALID is on, we assume worktree file and its cache entry @@ -524,9 +524,7 @@ static int grep_directory(struct grep_opt *opt, const struct pathspec *pathspec, fill_directory(&dir, pathspec); for (i = 0; i < dir.nr; i++) { - const char *name = dir.entries[i]->name; - int namelen = strlen(name); - if (!match_pathspec_depth(pathspec, name, namelen, 0, NULL)) + if (!dir_path_match(dir.entries[i], pathspec, 0, NULL)) continue; hit |= grep_file(opt, dir.entries[i]->name); if (hit && opt->status_only) diff --git a/builtin/ls-files.c b/builtin/ls-files.c index e1cf6d8547..47c38808a2 100644 --- a/builtin/ls-files.c +++ b/builtin/ls-files.c @@ -64,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_depth(&pathspec, ent->name, ent->len, len, ps_matched)) + if (!dir_path_match(ent, &pathspec, len, ps_matched)) return; fputs(tag, stdout); @@ -139,7 +139,9 @@ 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_depth(&pathspec, ce->name, ce_namelen(ce), len, ps_matched)) + if (!match_pathspec(&pathspec, ce->name, ce_namelen(ce), + len, ps_matched, + S_ISDIR(ce->ce_mode) || S_ISGITLINK(ce->ce_mode))) return; if (tag && *tag && show_valid_bit && @@ -195,7 +197,8 @@ static void show_ru_info(void) len = strlen(path); if (len < max_prefix_len) continue; /* outside of the prefix */ - if (!match_pathspec_depth(&pathspec, path, len, max_prefix_len, ps_matched)) + if (!match_pathspec(&pathspec, path, len, + max_prefix_len, ps_matched, 0)) continue; /* uninterested */ for (i = 0; i < 3; i++) { if (!ui->mode[i]) diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c index 65ec931846..51184dfa2e 100644 --- a/builtin/ls-tree.c +++ b/builtin/ls-tree.c @@ -171,7 +171,7 @@ int cmd_ls_tree(int argc, const char **argv, const char *prefix) * 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() + * match_pathspec() or tree_entry_interesting() */ parse_pathspec(&pathspec, PATHSPEC_GLOB | PATHSPEC_ICASE, PATHSPEC_PREFER_CWD, diff --git a/builtin/merge.c b/builtin/merge.c index e576a7fdc6..f0cf1205fa 100644 --- a/builtin/merge.c +++ b/builtin/merge.c @@ -597,6 +597,9 @@ static int git_merge_config(const char *k, const char *v, void *cb) } else if (!strcmp(k, "merge.defaulttoupstream")) { default_to_upstream = git_config_bool(k, v); return 0; + } else if (!strcmp(k, "commit.gpgsign")) { + sign_commit = git_config_bool(k, v) ? "" : NULL; + return 0; } status = fmt_merge_msg_config(k, v, cb); diff --git a/builtin/repack.c b/builtin/repack.c index 6284846d82..bb2314c9cb 100644 --- a/builtin/repack.c +++ b/builtin/repack.c @@ -258,7 +258,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix) for_each_string_list_item(item, &names) { for (ext = 0; ext < 2; ext++) { char *fname, *fname_old; - fname = mkpathdup("%s/%s%s", packdir, + fname = mkpathdup("%s/pack-%s%s", packdir, item->string, exts[ext]); if (!file_exists(fname)) { free(fname); @@ -335,7 +335,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix) for_each_string_list_item(item, &names) { for (ext = 0; ext < 2; ext++) { char *fname; - fname = mkpath("%s/old-pack-%s%s", + fname = mkpath("%s/old-%s%s", packdir, item->string, exts[ext]); diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c index aaeb611a97..45901df371 100644 --- a/builtin/rev-parse.c +++ b/builtin/rev-parse.c @@ -547,15 +547,17 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix) continue; } if (!strcmp(arg, "--default")) { - def = argv[i+1]; - i++; + def = argv[++i]; + if (!def) + die("--default requires an argument"); continue; } if (!strcmp(arg, "--prefix")) { - prefix = argv[i+1]; + prefix = argv[++i]; + if (!prefix) + die("--prefix requires an argument"); startup_info->prefix = prefix; output_prefix = 1; - i++; continue; } if (!strcmp(arg, "--revs-only")) { @@ -738,9 +740,12 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix) continue; } if (!strcmp(arg, "--resolve-git-dir")) { - const char *gitdir = resolve_gitdir(argv[i+1]); + const char *gitdir = argv[++i]; if (!gitdir) - die("not a gitdir '%s'", argv[i+1]); + die("--resolve-git-dir requires an argument"); + gitdir = resolve_gitdir(gitdir); + if (!gitdir) + die("not a gitdir '%s'", argv[i]); puts(gitdir); continue; } diff --git a/builtin/rm.c b/builtin/rm.c index 3a0e0eaab7..960634dd0c 100644 --- a/builtin/rm.c +++ b/builtin/rm.c @@ -308,10 +308,10 @@ int cmd_rm(int argc, const char **argv, const char *prefix) for (i = 0; i < active_nr; i++) { const struct cache_entry *ce = active_cache[i]; - if (!match_pathspec_depth(&pathspec, ce->name, ce_namelen(ce), 0, seen)) + if (!ce_path_match(ce, &pathspec, seen)) continue; ALLOC_GROW(list.entry, list.nr + 1, list.alloc); - list.entry[list.nr].name = ce->name; + list.entry[list.nr].name = xstrdup(ce->name); list.entry[list.nr].is_submodule = S_ISGITLINK(ce->ce_mode); if (list.entry[list.nr++].is_submodule && !is_staging_gitmodules_ok()) diff --git a/builtin/update-index.c b/builtin/update-index.c index e3a10d706d..d12ad95f3e 100644 --- a/builtin/update-index.c +++ b/builtin/update-index.c @@ -12,6 +12,7 @@ #include "resolve-undo.h" #include "parse-options.h" #include "pathspec.h" +#include "dir.h" /* * Default to not allowing changes to the list of files. The @@ -274,36 +275,32 @@ static void chmod_path(int flip, const char *path) die("git update-index: cannot chmod %cx '%s'", flip, path); } -static void update_one(const char *path, const char *prefix, int prefix_length) +static void update_one(const char *path) { - const char *p = prefix_path(prefix, prefix_length, path); - if (!verify_path(p)) { + if (!verify_path(path)) { fprintf(stderr, "Ignoring path %s\n", path); - goto free_return; + return; } if (mark_valid_only) { - if (mark_ce_flags(p, CE_VALID, mark_valid_only == MARK_FLAG)) + if (mark_ce_flags(path, CE_VALID, mark_valid_only == MARK_FLAG)) die("Unable to mark file %s", path); - goto free_return; + return; } if (mark_skip_worktree_only) { - if (mark_ce_flags(p, CE_SKIP_WORKTREE, mark_skip_worktree_only == MARK_FLAG)) + if (mark_ce_flags(path, CE_SKIP_WORKTREE, mark_skip_worktree_only == MARK_FLAG)) die("Unable to mark file %s", path); - goto free_return; + return; } if (force_remove) { - if (remove_file_from_cache(p)) + if (remove_file_from_cache(path)) die("git update-index: unable to remove %s", path); report("remove '%s'", path); - goto free_return; + return; } - if (process_path(p)) + if (process_path(path)) die("Unable to process path %s", path); report("add '%s'", path); - free_return: - if (p < path || p > path + strlen(path)) - free((char *)p); } static void read_index_info(int line_termination) @@ -563,8 +560,9 @@ static int do_reupdate(int ac, const char **av, const struct cache_entry *ce = active_cache[pos]; struct cache_entry *old = NULL; int save_nr; + char *path; - if (ce_stage(ce) || !ce_path_match(ce, &pathspec)) + if (ce_stage(ce) || !ce_path_match(ce, &pathspec, NULL)) continue; if (has_head) old = read_one_ent(NULL, head_sha1, @@ -579,7 +577,9 @@ static int do_reupdate(int ac, const char **av, * or worse yet 'allow_replace', active_nr may decrease. */ save_nr = active_nr; - update_one(ce->name + prefix_length, prefix, prefix_length); + path = xstrdup(ce->name); + update_one(path); + free(path); if (save_nr != active_nr) goto redo; } @@ -836,11 +836,10 @@ int cmd_update_index(int argc, const char **argv, const char *prefix) setup_work_tree(); p = prefix_path(prefix, prefix_length, path); - update_one(p, NULL, 0); + update_one(p); if (set_executable_bit) chmod_path(set_executable_bit, p); - if (p < path || p > path + strlen(path)) - free((char *)p); + free((char *)p); ctx.argc--; ctx.argv++; break; @@ -879,11 +878,10 @@ int cmd_update_index(int argc, const char **argv, const char *prefix) strbuf_swap(&buf, &nbuf); } p = prefix_path(prefix, prefix_length, buf.buf); - update_one(p, NULL, 0); + update_one(p); if (set_executable_bit) chmod_path(set_executable_bit, p); - if (p < buf.buf || p > buf.buf + buf.len) - free((char *)p); + free((char *)p); } strbuf_release(&nbuf); strbuf_release(&buf); diff --git a/cache.h b/cache.h index dc040fb1aa..5994f7a203 100644 --- a/cache.h +++ b/cache.h @@ -3,7 +3,7 @@ #include "git-compat-util.h" #include "strbuf.h" -#include "hash.h" +#include "hashmap.h" #include "advice.h" #include "gettext.h" #include "convert.h" @@ -130,12 +130,12 @@ struct stat_data { }; struct cache_entry { + struct hashmap_entry ent; struct stat_data ce_stat_data; unsigned int ce_mode; unsigned int ce_flags; unsigned int ce_namelen; unsigned char sha1[20]; - struct cache_entry *next; char name[FLEX_ARRAY]; /* more */ }; @@ -159,7 +159,6 @@ struct cache_entry { #define CE_ADDED (1 << 19) #define CE_HASHED (1 << 20) -#define CE_UNHASHED (1 << 21) #define CE_WT_REMOVE (1 << 22) /* remove in work directory */ #define CE_CONFLICTED (1 << 23) @@ -195,17 +194,18 @@ 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! */ -#define CE_STATE_MASK (CE_HASHED | CE_UNHASHED) static inline void copy_cache_entry(struct cache_entry *dst, const struct cache_entry *src) { - unsigned int state = dst->ce_flags & CE_STATE_MASK; + unsigned int state = dst->ce_flags & CE_HASHED; /* Don't copy hash chain and name */ - memcpy(dst, src, offsetof(struct cache_entry, next)); + memcpy(&dst->ce_stat_data, &src->ce_stat_data, + offsetof(struct cache_entry, name) - + offsetof(struct cache_entry, ce_stat_data)); /* Restore the hash state */ - dst->ce_flags = (dst->ce_flags & ~CE_STATE_MASK) | state; + dst->ce_flags = (dst->ce_flags & ~CE_HASHED) | state; } static inline unsigned create_ce_flags(unsigned stage) @@ -277,8 +277,8 @@ struct index_state { struct cache_time timestamp; unsigned name_hash_initialized : 1, initialized : 1; - struct hash_table name_hash; - struct hash_table dir_hash; + struct hashmap name_hash; + struct hashmap dir_hash; }; extern struct index_state the_index; @@ -316,7 +316,6 @@ extern void free_name_hash(struct index_state *istate); #define ce_modified(ce, st, options) ie_modified(&the_index, (ce), (st), (options)) #define cache_dir_exists(name, namelen) index_dir_exists(&the_index, (name), (namelen)) #define cache_file_exists(name, namelen, igncase) index_file_exists(&the_index, (name), (namelen), (igncase)) -#define cache_name_exists(name, namelen, igncase) index_name_exists(&the_index, (name), (namelen), (igncase)) #define cache_name_is_other(name, namelen) index_name_is_other(&the_index, (name), (namelen)) #define resolve_undo_clear() resolve_undo_clear_index(&the_index) #define unmerge_cache_entry_at(at) unmerge_index_entry_at(&the_index, at) @@ -467,7 +466,6 @@ extern int unmerged_index(const struct index_state *); extern int verify_path(const char *path); extern struct cache_entry *index_dir_exists(struct index_state *istate, const char *name, int namelen); extern struct cache_entry *index_file_exists(struct index_state *istate, const char *name, int namelen, int igncase); -extern struct cache_entry *index_name_exists(struct index_state *istate, const char *name, int namelen, int igncase); extern int index_name_pos(const struct index_state *, const char *name, int namelen); #define ADD_CACHE_OK_TO_ADD 1 /* Ok to add */ #define ADD_CACHE_OK_TO_REPLACE 2 /* Ok to replace file/directory */ @@ -487,7 +485,7 @@ extern int remove_file_from_index(struct index_state *, const char *path); #define ADD_CACHE_IMPLICIT_DOT 32 /* internal to "git add -u/-A" */ extern int add_to_index(struct index_state *, const char *path, struct stat *, int flags); extern int add_file_to_index(struct index_state *, const char *path, int flags); -extern struct cache_entry *make_cache_entry(unsigned int mode, const unsigned char *sha1, const char *path, int stage, int refresh); +extern struct cache_entry *make_cache_entry(unsigned int mode, const unsigned char *sha1, const char *path, int stage, unsigned int refresh_options); extern int ce_same_name(const struct cache_entry *a, const struct cache_entry *b); extern int index_name_is_other(const struct index_state *, const char *, int); extern void *read_blob_data_from_index(struct index_state *, const char *, unsigned long *); @@ -498,11 +496,13 @@ extern void *read_blob_data_from_index(struct index_state *, const char *, unsig #define CE_MATCH_RACY_IS_DIRTY 02 /* do stat comparison even if CE_SKIP_WORKTREE is true */ #define CE_MATCH_IGNORE_SKIP_WORKTREE 04 +/* ignore non-existent files during stat update */ +#define CE_MATCH_IGNORE_MISSING 0x08 +/* enable stat refresh */ +#define CE_MATCH_REFRESH 0x10 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); -extern int ce_path_match(const struct cache_entry *ce, const struct pathspec *pathspec); - #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); diff --git a/config.c b/config.c index d969a5aefc..314d8ee740 100644 --- a/config.c +++ b/config.c @@ -84,8 +84,12 @@ static int handle_path_include(const char *path, struct config_include_data *inc { int ret = 0; struct strbuf buf = STRBUF_INIT; - char *expanded = expand_user_path(path); + char *expanded; + if (!path) + return config_error_nonbool("include.path"); + + expanded = expand_user_path(path); if (!expanded) return error("Could not expand include path '%s'", path); path = expanded; diff --git a/diff-lib.c b/diff-lib.c index 346cac651d..2eddc66bbd 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -11,6 +11,7 @@ #include "unpack-trees.h" #include "refs.h" #include "submodule.h" +#include "dir.h" /* * diff-files @@ -108,7 +109,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option) if (diff_can_quit_early(&revs->diffopt)) break; - if (!ce_path_match(ce, &revs->prune_data)) + if (!ce_path_match(ce, &revs->prune_data, NULL)) continue; if (ce_stage(ce)) { @@ -438,7 +439,7 @@ static int oneway_diff(const struct cache_entry * const *src, if (tree == o->df_conflict_entry) tree = NULL; - if (ce_path_match(idx ? idx : tree, &revs->prune_data)) { + if (ce_path_match(idx ? idx : tree, &revs->prune_data, NULL)) { do_oneway_diff(o, idx, tree); if (diff_can_quit_early(&revs->diffopt)) { o->exiting_early = 1; diff --git a/diff.c b/diff.c index 8e4a6a9105..e8006666d8 100644 --- a/diff.c +++ b/diff.c @@ -4697,6 +4697,38 @@ static int diff_filespec_is_identical(struct diff_filespec *one, return !memcmp(one->data, two->data, one->size); } +static int diff_filespec_check_stat_unmatch(struct diff_filepair *p) +{ + if (p->done_skip_stat_unmatch) + return p->skip_stat_unmatch_result; + + p->done_skip_stat_unmatch = 1; + p->skip_stat_unmatch_result = 0; + /* + * 1. Entries that come from stat info dirtiness + * always have both sides (iow, not create/delete), + * one side of the object name is unknown, with + * the same mode and size. Keep the ones that + * do not match these criteria. They have real + * differences. + * + * 2. At this point, the file is known to be modified, + * with the same mode and size, and the object + * name of one side is unknown. Need to inspect + * the identical contents. + */ + if (!DIFF_FILE_VALID(p->one) || /* (1) */ + !DIFF_FILE_VALID(p->two) || + (p->one->sha1_valid && p->two->sha1_valid) || + (p->one->mode != p->two->mode) || + diff_populate_filespec(p->one, 1) || + diff_populate_filespec(p->two, 1) || + (p->one->size != p->two->size) || + !diff_filespec_is_identical(p->one, p->two)) /* (2) */ + p->skip_stat_unmatch_result = 1; + return p->skip_stat_unmatch_result; +} + static void diffcore_skip_stat_unmatch(struct diff_options *diffopt) { int i; @@ -4707,27 +4739,7 @@ static void diffcore_skip_stat_unmatch(struct diff_options *diffopt) for (i = 0; i < q->nr; i++) { struct diff_filepair *p = q->queue[i]; - /* - * 1. Entries that come from stat info dirtiness - * always have both sides (iow, not create/delete), - * one side of the object name is unknown, with - * the same mode and size. Keep the ones that - * do not match these criteria. They have real - * differences. - * - * 2. At this point, the file is known to be modified, - * with the same mode and size, and the object - * name of one side is unknown. Need to inspect - * the identical contents. - */ - if (!DIFF_FILE_VALID(p->one) || /* (1) */ - !DIFF_FILE_VALID(p->two) || - (p->one->sha1_valid && p->two->sha1_valid) || - (p->one->mode != p->two->mode) || - diff_populate_filespec(p->one, 1) || - diff_populate_filespec(p->two, 1) || - (p->one->size != p->two->size) || - !diff_filespec_is_identical(p->one, p->two)) /* (2) */ + if (diff_filespec_check_stat_unmatch(p)) diff_q(&outq, p); else { /* @@ -4890,6 +4902,7 @@ void diff_change(struct diff_options *options, unsigned old_dirty_submodule, unsigned new_dirty_submodule) { struct diff_filespec *one, *two; + struct diff_filepair *p; if (S_ISGITLINK(old_mode) && S_ISGITLINK(new_mode) && is_submodule_ignored(concatpath, options)) @@ -4916,10 +4929,16 @@ void diff_change(struct diff_options *options, fill_filespec(two, new_sha1, new_sha1_valid, new_mode); one->dirty_submodule = old_dirty_submodule; two->dirty_submodule = new_dirty_submodule; + p = diff_queue(&diff_queued_diff, one, two); - diff_queue(&diff_queued_diff, one, two); - if (!DIFF_OPT_TST(options, DIFF_FROM_CONTENTS)) - DIFF_OPT_SET(options, HAS_CHANGES); + if (DIFF_OPT_TST(options, DIFF_FROM_CONTENTS)) + return; + + if (DIFF_OPT_TST(options, QUICK) && options->skip_stat_unmatch && + !diff_filespec_check_stat_unmatch(p)) + return; + + DIFF_OPT_SET(options, HAS_CHANGES); } struct diff_filepair *diff_unmerge(struct diff_options *options, const char *path) diff --git a/diffcore-rename.c b/diffcore-rename.c index 6c7a72fbe7..9b4f068eb3 100644 --- a/diffcore-rename.c +++ b/diffcore-rename.c @@ -4,7 +4,7 @@ #include "cache.h" #include "diff.h" #include "diffcore.h" -#include "hash.h" +#include "hashmap.h" #include "progress.h" /* Table of rename/copy destinations */ @@ -243,137 +243,82 @@ static int score_compare(const void *a_, const void *b_) } struct file_similarity { - int src_dst, index; + struct hashmap_entry entry; + int index; struct diff_filespec *filespec; - struct file_similarity *next; }; -static int find_identical_files(struct file_similarity *src, - struct file_similarity *dst, +static unsigned int hash_filespec(struct diff_filespec *filespec) +{ + unsigned int hash; + if (!filespec->sha1_valid) { + if (diff_populate_filespec(filespec, 0)) + return 0; + hash_sha1_file(filespec->data, filespec->size, "blob", filespec->sha1); + } + memcpy(&hash, filespec->sha1, sizeof(hash)); + return hash; +} + +static int find_identical_files(struct hashmap *srcs, + int dst_index, struct diff_options *options) { int renames = 0; + struct diff_filespec *target = rename_dst[dst_index].two; + struct file_similarity *p, *best, dst; + int i = 100, best_score = -1; + /* - * Walk over all the destinations ... + * Find the best source match for specified destination. */ - do { - struct diff_filespec *target = dst->filespec; - struct file_similarity *p, *best; - int i = 100, best_score = -1; - - /* - * .. to find the best source match - */ - best = NULL; - for (p = src; p; p = p->next) { - int score; - struct diff_filespec *source = p->filespec; - - /* False hash collision? */ - if (hashcmp(source->sha1, target->sha1)) - continue; - /* Non-regular files? If so, the modes must match! */ - if (!S_ISREG(source->mode) || !S_ISREG(target->mode)) { - if (source->mode != target->mode) - continue; - } - /* Give higher scores to sources that haven't been used already */ - score = !source->rename_used; - if (source->rename_used && options->detect_rename != DIFF_DETECT_COPY) + best = NULL; + hashmap_entry_init(&dst, hash_filespec(target)); + for (p = hashmap_get(srcs, &dst, NULL); p; p = hashmap_get_next(srcs, p)) { + int score; + struct diff_filespec *source = p->filespec; + + /* False hash collision? */ + if (hashcmp(source->sha1, target->sha1)) + continue; + /* Non-regular files? If so, the modes must match! */ + if (!S_ISREG(source->mode) || !S_ISREG(target->mode)) { + if (source->mode != target->mode) continue; - score += basename_same(source, target); - if (score > best_score) { - best = p; - best_score = score; - if (score == 2) - break; - } - - /* Too many identical alternatives? Pick one */ - if (!--i) - break; } - if (best) { - record_rename_pair(dst->index, best->index, MAX_SCORE); - renames++; + /* Give higher scores to sources that haven't been used already */ + score = !source->rename_used; + if (source->rename_used && options->detect_rename != DIFF_DETECT_COPY) + continue; + score += basename_same(source, target); + if (score > best_score) { + best = p; + best_score = score; + if (score == 2) + break; } - } while ((dst = dst->next) != NULL); - return renames; -} -static void free_similarity_list(struct file_similarity *p) -{ - while (p) { - struct file_similarity *entry = p; - p = p->next; - free(entry); + /* Too many identical alternatives? Pick one */ + if (!--i) + break; } -} - -static int find_same_files(void *ptr, void *data) -{ - int ret; - struct file_similarity *p = ptr; - struct file_similarity *src = NULL, *dst = NULL; - struct diff_options *options = data; - - /* Split the hash list up into sources and destinations */ - do { - struct file_similarity *entry = p; - p = p->next; - if (entry->src_dst < 0) { - entry->next = src; - src = entry; - } else { - entry->next = dst; - dst = entry; - } - } while (p); - - /* - * If we have both sources *and* destinations, see if - * we can match them up - */ - ret = (src && dst) ? find_identical_files(src, dst, options) : 0; - - /* Free the hashes and return the number of renames found */ - free_similarity_list(src); - free_similarity_list(dst); - return ret; -} - -static unsigned int hash_filespec(struct diff_filespec *filespec) -{ - unsigned int hash; - if (!filespec->sha1_valid) { - if (diff_populate_filespec(filespec, 0)) - return 0; - hash_sha1_file(filespec->data, filespec->size, "blob", filespec->sha1); + if (best) { + record_rename_pair(dst_index, best->index, MAX_SCORE); + renames++; } - memcpy(&hash, filespec->sha1, sizeof(hash)); - return hash; + return renames; } -static void insert_file_table(struct hash_table *table, int src_dst, int index, struct diff_filespec *filespec) +static void insert_file_table(struct hashmap *table, int index, struct diff_filespec *filespec) { - void **pos; - unsigned int hash; struct file_similarity *entry = xmalloc(sizeof(*entry)); - entry->src_dst = src_dst; entry->index = index; entry->filespec = filespec; - entry->next = NULL; - - hash = hash_filespec(filespec); - pos = insert_hash(hash, entry, table); - /* We already had an entry there? */ - if (pos) { - entry->next = *pos; - *pos = entry; - } + hashmap_entry_init(entry, hash_filespec(filespec)); + hashmap_add(table, entry); } /* @@ -385,24 +330,22 @@ static void insert_file_table(struct hash_table *table, int src_dst, int index, */ static int find_exact_renames(struct diff_options *options) { - int i; - struct hash_table file_table; + int i, renames = 0; + struct hashmap file_table; - init_hash(&file_table); - preallocate_hash(&file_table, rename_src_nr + rename_dst_nr); + /* Add all sources to the hash table */ + hashmap_init(&file_table, NULL, rename_src_nr); for (i = 0; i < rename_src_nr; i++) - insert_file_table(&file_table, -1, i, rename_src[i].p->one); + insert_file_table(&file_table, i, rename_src[i].p->one); + /* Walk the destinations and find best source match */ for (i = 0; i < rename_dst_nr; i++) - insert_file_table(&file_table, 1, i, rename_dst[i].two); - - /* Find the renames */ - i = for_each_hash(&file_table, find_same_files, options); + renames += find_identical_files(&file_table, i, options); - /* .. and free the hash data structure */ - free_hash(&file_table); + /* Free the hash data structure and entries */ + hashmap_free(&file_table, 1); - return i; + return renames; } #define NUM_CANDIDATE_PER_DST 4 diff --git a/diffcore.h b/diffcore.h index 79de8cf28d..1315cfd4ef 100644 --- a/diffcore.h +++ b/diffcore.h @@ -68,6 +68,8 @@ struct diff_filepair { unsigned broken_pair : 1; unsigned renamed_pair : 1; unsigned is_unmerged : 1; + unsigned done_skip_stat_unmatch : 1; + unsigned skip_stat_unmatch_result : 1; }; #define DIFF_PAIR_UNMERGED(p) ((p)->is_unmerged) diff --git a/dir.c b/dir.c index b35b6330f8..98bb50fbab 100644 --- a/dir.c +++ b/dir.c @@ -195,6 +195,9 @@ int within_depth(const char *name, int namelen, return 1; } +#define DO_MATCH_EXCLUDE 1 +#define DO_MATCH_DIRECTORY 2 + /* * Does 'match' match the given name? * A match is found if @@ -208,7 +211,7 @@ int within_depth(const char *name, int namelen, * It returns 0 when there is no match. */ static int match_pathspec_item(const struct pathspec_item *item, int prefix, - const char *name, int namelen) + const char *name, int namelen, unsigned flags) { /* name/namelen has prefix cut off by caller */ const char *match = item->match + prefix; @@ -218,7 +221,7 @@ static int match_pathspec_item(const struct pathspec_item *item, int prefix, * The normal call pattern is: * 1. prefix = common_prefix_len(ps); * 2. prune something, or fill_directory - * 3. match_pathspec_depth() + * 3. match_pathspec() * * '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 @@ -257,7 +260,11 @@ static int match_pathspec_item(const struct pathspec_item *item, int prefix, if (match[matchlen-1] == '/' || name[matchlen] == '/') return MATCHED_RECURSIVELY; - } + } else if ((flags & DO_MATCH_DIRECTORY) && + match[matchlen - 1] == '/' && + namelen == matchlen - 1 && + !ps_strncmp(item, match, name, namelen)) + return MATCHED_EXACTLY; if (item->nowildcard_len < item->len && !git_fnmatch(item, match, name, @@ -282,12 +289,12 @@ static int match_pathspec_item(const struct pathspec_item *item, int prefix, * pathspec did not match any names, which could indicate that the * user mistyped the nth pathspec. */ -static int match_pathspec_depth_1(const struct pathspec *ps, - const char *name, int namelen, - int prefix, char *seen, - int exclude) +static int do_match_pathspec(const struct pathspec *ps, + const char *name, int namelen, + int prefix, char *seen, + unsigned flags) { - int i, retval = 0; + int i, retval = 0, exclude = flags & DO_MATCH_EXCLUDE; GUARD_PATHSPEC(ps, PATHSPEC_FROMTOP | @@ -327,7 +334,8 @@ static int match_pathspec_depth_1(const struct pathspec *ps, */ if (seen && ps->items[i].magic & PATHSPEC_EXCLUDE) seen[i] = MATCHED_FNMATCH; - how = match_pathspec_item(ps->items+i, prefix, name, namelen); + how = match_pathspec_item(ps->items+i, prefix, name, + namelen, flags); if (ps->recursive && (ps->magic & PATHSPEC_MAXDEPTH) && ps->max_depth != -1 && @@ -350,15 +358,19 @@ static int match_pathspec_depth_1(const struct pathspec *ps, return retval; } -int match_pathspec_depth(const struct pathspec *ps, - const char *name, int namelen, - int prefix, char *seen) +int match_pathspec(const struct pathspec *ps, + const char *name, int namelen, + int prefix, char *seen, int is_dir) { int positive, negative; - positive = match_pathspec_depth_1(ps, name, namelen, prefix, seen, 0); + unsigned flags = is_dir ? DO_MATCH_DIRECTORY : 0; + positive = do_match_pathspec(ps, name, namelen, + prefix, seen, flags); if (!(ps->magic & PATHSPEC_EXCLUDE) || !positive) return positive; - negative = match_pathspec_depth_1(ps, name, namelen, prefix, seen, 1); + negative = do_match_pathspec(ps, name, namelen, + prefix, seen, + flags | DO_MATCH_EXCLUDE); return negative ? 0 : positive; } diff --git a/dir.h b/dir.h index 9b7e4e77d8..55e53456af 100644 --- a/dir.h +++ b/dir.h @@ -132,9 +132,9 @@ struct dir_struct { 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 match_pathspec(const struct pathspec *pathspec, + const char *name, int namelen, + int prefix, char *seen, int is_dir); extern int within_depth(const char *name, int namelen, int depth, int max_depth); extern int fill_directory(struct dir_struct *dir, const struct pathspec *pathspec); @@ -205,4 +205,22 @@ extern int git_fnmatch(const struct pathspec_item *item, const char *pattern, const char *string, int prefix); +static inline int ce_path_match(const struct cache_entry *ce, + const struct pathspec *pathspec, + char *seen) +{ + return match_pathspec(pathspec, ce->name, ce_namelen(ce), 0, seen, + S_ISDIR(ce->ce_mode) || S_ISGITLINK(ce->ce_mode)); +} + +static inline int dir_path_match(const struct dir_entry *ent, + const struct pathspec *pathspec, + int prefix, char *seen) +{ + int has_trailing_dir = ent->len && ent->name[ent->len - 1] == '/'; + int len = has_trailing_dir ? ent->len - 1 : ent->len; + return match_pathspec(pathspec, ent->name, len, prefix, seen, + has_trailing_dir); +} + #endif diff --git a/git-compat-util.h b/git-compat-util.h index cbd86c37f5..614a5e95bd 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -480,9 +480,15 @@ extern FILE *git_fopen(const char*, const char*); #endif #ifdef SNPRINTF_RETURNS_BOGUS +#ifdef snprintf +#undef snprintf +#endif #define snprintf git_snprintf extern int git_snprintf(char *str, size_t maxsize, const char *format, ...); +#ifdef vsnprintf +#undef vsnprintf +#endif #define vsnprintf git_vsnprintf extern int git_vsnprintf(char *str, size_t maxsize, const char *format, va_list ap); diff --git a/git-pull.sh b/git-pull.sh index 0a5aa2c821..def7cc0e23 100755 --- a/git-pull.sh +++ b/git-pull.sh @@ -4,7 +4,7 @@ # # Fetch one or more remote refs and merge it/them into the current HEAD. -USAGE='[-n | --no-stat] [--[no-]commit] [--[no-]squash] [--[no-]ff] [--[no-]rebase|--rebase=preserve] [-s strategy]... [] ...' +USAGE='[-n | --no-stat] [--[no-]commit] [--[no-]squash] [--[no-]ff|--ff-only] [--[no-]rebase|--rebase=preserve] [-s strategy]... [] ...' LONG_USAGE='Fetch one or more remote refs and integrate it/them with the current HEAD.' SUBDIRECTORY_OK=Yes OPTIONS_SPEC= @@ -52,6 +52,21 @@ if test -z "$rebase" then rebase=$(bool_or_string_config pull.rebase) fi + +# Setup default fast-forward options via `pull.ff` +pull_ff=$(git config pull.ff) +case "$pull_ff" in +false) + no_ff=--no-ff + break + ;; +only) + ff_only=--ff-only + break + ;; +esac + + dry_run= while : do diff --git a/git-submodule.sh b/git-submodule.sh index 4a30087768..a33f68d27c 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -241,6 +241,15 @@ module_name() # # Clone a submodule # +# $1 = submodule path +# $2 = submodule name +# $3 = URL to clone +# $4 = reference repository to reuse (empty for independent) +# $5 = depth argument for shallow clones (empty for deep) +# $6 = (remote-tracking) starting point for the local branch (empty for HEAD) +# $7 = local branch to create (empty for a detached HEAD, unless $6 is +# also empty, in which case the local branch is left unchanged) +# # Prior to calling, cmd_update checks that a possibly existing # path is not a git repository. # Likewise, cmd_add checks that path does not exist at all, @@ -253,6 +262,8 @@ module_clone() url=$3 reference="$4" depth="$5" + start_point="$6" + local_branch="$7" quiet= if test -n "$GIT_QUIET" then @@ -306,7 +317,16 @@ module_clone() echo "gitdir: $rel/$a" >"$sm_path/.git" rel=$(echo $a | sed -e 's|[^/][^/]*|..|g') - (clear_local_git_env; cd "$sm_path" && GIT_WORK_TREE=. git config core.worktree "$rel/$b") + ( + clear_local_git_env + cd "$sm_path" && + GIT_WORK_TREE=. git config core.worktree "$rel/$b" && + # ash fails to wordsplit ${local_branch:+-B "$local_branch"...} + case "$local_branch" in + '') git checkout -f -q ${start_point:+"$start_point"} ;; + ?*) git checkout -f -q -B "$local_branch" ${start_point:+"$start_point"} ;; + esac + ) || die "$(eval_gettext "Unable to setup cloned submodule '\$sm_path'")" } isnumber() @@ -469,16 +489,15 @@ Use -f if you really want to add it." >&2 echo "$(eval_gettext "Reactivating local git directory for submodule '\$sm_name'.")" fi fi - module_clone "$sm_path" "$sm_name" "$realrepo" "$reference" "$depth" || exit - ( - clear_local_git_env - cd "$sm_path" && - # ash fails to wordsplit ${branch:+-b "$branch"...} - case "$branch" in - '') git checkout -f -q ;; - ?*) git checkout -f -q -B "$branch" "origin/$branch" ;; - esac - ) || die "$(eval_gettext "Unable to checkout submodule '\$sm_path'")" + if test -n "$branch" + then + start_point="origin/$branch" + local_branch="$branch" + else + start_point="" + local_branch="" + fi + module_clone "$sm_path" "$sm_name" "$realrepo" "$reference" "$depth" "$start_point" "$local_branch" || exit fi git config submodule."$sm_name".url "$realrepo" @@ -799,32 +818,35 @@ cmd_update() fi name=$(module_name "$sm_path") || exit url=$(git config submodule."$name".url) - branch=$(get_submodule_config "$name" branch master) + config_branch=$(get_submodule_config "$name" branch) + branch="${config_branch:-master}" + local_branch="$branch" if ! test -z "$update" then update_module=$update else update_module=$(git config submodule."$name".update) - case "$update_module" in - '') - ;; # Unset update mode - checkout | rebase | merge | none) - ;; # Known update modes - !*) - ;; # Custom update command - *) - die "$(eval_gettext "Invalid update mode '$update_module' for submodule '$name'")" - ;; - esac + if test -z "$update_module" + then + update_module="checkout" + fi fi displaypath=$(relative_path "$prefix$sm_path") - if test "$update_module" = "none" - then + case "$update_module" in + none) echo "Skipping submodule '$displaypath'" continue - fi + ;; + checkout) + local_branch="" + ;; + rebase | merge | !*) + ;; + *) + die "$(eval_gettext "Invalid update mode '$update_module' for submodule '$name'")" + esac if test -z "$url" then @@ -838,7 +860,8 @@ Maybe you want to use 'update --init'?")" if ! test -d "$sm_path"/.git -o -f "$sm_path"/.git then - module_clone "$sm_path" "$name" "$url" "$reference" "$depth" || exit + start_point="origin/${branch}" + module_clone "$sm_path" "$name" "$url" "$reference" "$depth" "$start_point" "$local_branch" || exit cloned_modules="$cloned_modules;$name" subsha1= else @@ -884,11 +907,16 @@ Maybe you want to use 'update --init'?")" case ";$cloned_modules;" in *";$name;"*) # then there is no local change to integrate - update_module= ;; + update_module='!git reset --hard -q' esac must_die_on_failure= case "$update_module" in + checkout) + command="git checkout $subforce -q" + die_msg="$(eval_gettext "Unable to checkout '\$sha1' in submodule path '\$displaypath'")" + say_msg="$(eval_gettext "Submodule path '\$displaypath': checked out '\$sha1'")" + ;; rebase) command="git rebase" die_msg="$(eval_gettext "Unable to rebase '\$sha1' in submodule path '\$displaypath'")" @@ -908,10 +936,7 @@ Maybe you want to use 'update --init'?")" must_die_on_failure=yes ;; *) - command="git checkout $subforce -q" - die_msg="$(eval_gettext "Unable to checkout '\$sha1' in submodule path '\$displaypath'")" - say_msg="$(eval_gettext "Submodule path '\$displaypath': checked out '\$sha1'")" - ;; + die "$(eval_gettext "Invalid update mode '$update_module' for submodule '$name'")" esac if (clear_local_git_env; cd "$sm_path" && $command "$sha1") diff --git a/hash.c b/hash.c deleted file mode 100644 index 749ecfe484..0000000000 --- a/hash.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Some generic hashing helpers. - */ -#include "cache.h" -#include "hash.h" - -/* - * Look up a hash entry in the hash table. Return the pointer to - * the existing entry, or the empty slot if none existed. The caller - * can then look at the (*ptr) to see whether it existed or not. - */ -static struct hash_table_entry *lookup_hash_entry(unsigned int hash, const struct hash_table *table) -{ - unsigned int size = table->size, nr = hash % size; - struct hash_table_entry *array = table->array; - - while (array[nr].ptr) { - if (array[nr].hash == hash) - break; - nr++; - if (nr >= size) - nr = 0; - } - return array + nr; -} - - -/* - * Insert a new hash entry pointer into the table. - * - * If that hash entry already existed, return the pointer to - * the existing entry (and the caller can create a list of the - * pointers or do anything else). If it didn't exist, return - * NULL (and the caller knows the pointer has been inserted). - */ -static void **insert_hash_entry(unsigned int hash, void *ptr, struct hash_table *table) -{ - struct hash_table_entry *entry = lookup_hash_entry(hash, table); - - if (!entry->ptr) { - entry->ptr = ptr; - entry->hash = hash; - table->nr++; - return NULL; - } - return &entry->ptr; -} - -static void grow_hash_table(struct hash_table *table) -{ - unsigned int i; - unsigned int old_size = table->size, new_size; - struct hash_table_entry *old_array = table->array, *new_array; - - new_size = alloc_nr(old_size); - new_array = xcalloc(sizeof(struct hash_table_entry), new_size); - table->size = new_size; - table->array = new_array; - table->nr = 0; - for (i = 0; i < old_size; i++) { - unsigned int hash = old_array[i].hash; - void *ptr = old_array[i].ptr; - if (ptr) - insert_hash_entry(hash, ptr, table); - } - free(old_array); -} - -void *lookup_hash(unsigned int hash, const struct hash_table *table) -{ - if (!table->array) - return NULL; - return lookup_hash_entry(hash, table)->ptr; -} - -void **insert_hash(unsigned int hash, void *ptr, struct hash_table *table) -{ - unsigned int nr = table->nr; - if (nr >= table->size/2) - grow_hash_table(table); - return insert_hash_entry(hash, ptr, table); -} - -int for_each_hash(const struct hash_table *table, int (*fn)(void *, void *), void *data) -{ - int sum = 0; - unsigned int i; - unsigned int size = table->size; - struct hash_table_entry *array = table->array; - - for (i = 0; i < size; i++) { - void *ptr = array->ptr; - array++; - if (ptr) { - int val = fn(ptr, data); - if (val < 0) - return val; - sum += val; - } - } - return sum; -} - -void free_hash(struct hash_table *table) -{ - free(table->array); - table->array = NULL; - table->size = 0; - table->nr = 0; -} diff --git a/hash.h b/hash.h deleted file mode 100644 index 1d43ac0ba0..0000000000 --- a/hash.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef HASH_H -#define HASH_H - -/* - * These are some simple generic hash table helper functions. - * Not necessarily suitable for all users, but good for things - * where you want to just keep track of a list of things, and - * have a good hash to use on them. - * - * It keeps the hash table at roughly 50-75% free, so the memory - * cost of the hash table itself is roughly - * - * 3 * 2*sizeof(void *) * nr_of_objects - * - * bytes. - * - * FIXME: on 64-bit architectures, we waste memory. It would be - * good to have just 32-bit pointers, requiring a special allocator - * for hashed entries or something. - */ -struct hash_table_entry { - unsigned int hash; - void *ptr; -}; - -struct hash_table { - unsigned int size, nr; - struct hash_table_entry *array; -}; - -extern void *lookup_hash(unsigned int hash, const struct hash_table *table); -extern void **insert_hash(unsigned int hash, void *ptr, struct hash_table *table); -extern int for_each_hash(const struct hash_table *table, int (*fn)(void *, void *), void *data); -extern void free_hash(struct hash_table *table); - -static inline void init_hash(struct hash_table *table) -{ - table->size = 0; - table->nr = 0; - table->array = NULL; -} - -static inline void preallocate_hash(struct hash_table *table, unsigned int elts) -{ - assert(table->size == 0 && table->nr == 0 && table->array == NULL); - table->size = elts * 2; - table->array = xcalloc(sizeof(struct hash_table_entry), table->size); -} - -#endif diff --git a/hashmap.c b/hashmap.c new file mode 100644 index 0000000000..d1b8056d8d --- /dev/null +++ b/hashmap.c @@ -0,0 +1,228 @@ +/* + * Generic implementation of hash-based key value mappings. + */ +#include "cache.h" +#include "hashmap.h" + +#define FNV32_BASE ((unsigned int) 0x811c9dc5) +#define FNV32_PRIME ((unsigned int) 0x01000193) + +unsigned int strhash(const char *str) +{ + unsigned int c, hash = FNV32_BASE; + while ((c = (unsigned char) *str++)) + hash = (hash * FNV32_PRIME) ^ c; + return hash; +} + +unsigned int strihash(const char *str) +{ + unsigned int c, hash = FNV32_BASE; + while ((c = (unsigned char) *str++)) { + if (c >= 'a' && c <= 'z') + c -= 'a' - 'A'; + hash = (hash * FNV32_PRIME) ^ c; + } + return hash; +} + +unsigned int memhash(const void *buf, size_t len) +{ + unsigned int hash = FNV32_BASE; + unsigned char *ucbuf = (unsigned char *) buf; + while (len--) { + unsigned int c = *ucbuf++; + hash = (hash * FNV32_PRIME) ^ c; + } + return hash; +} + +unsigned int memihash(const void *buf, size_t len) +{ + unsigned int hash = FNV32_BASE; + unsigned char *ucbuf = (unsigned char *) buf; + while (len--) { + unsigned int c = *ucbuf++; + if (c >= 'a' && c <= 'z') + c -= 'a' - 'A'; + hash = (hash * FNV32_PRIME) ^ c; + } + return hash; +} + +#define HASHMAP_INITIAL_SIZE 64 +/* grow / shrink by 2^2 */ +#define HASHMAP_RESIZE_BITS 2 +/* load factor in percent */ +#define HASHMAP_LOAD_FACTOR 80 + +static void alloc_table(struct hashmap *map, unsigned int size) +{ + map->tablesize = size; + map->table = xcalloc(size, sizeof(struct hashmap_entry *)); + + /* calculate resize thresholds for new size */ + map->grow_at = (unsigned int) ((uint64_t) size * HASHMAP_LOAD_FACTOR / 100); + if (size <= HASHMAP_INITIAL_SIZE) + map->shrink_at = 0; + else + /* + * The shrink-threshold must be slightly smaller than + * (grow-threshold / resize-factor) to prevent erratic resizing, + * thus we divide by (resize-factor + 1). + */ + map->shrink_at = map->grow_at / ((1 << HASHMAP_RESIZE_BITS) + 1); +} + +static inline int entry_equals(const struct hashmap *map, + const struct hashmap_entry *e1, const struct hashmap_entry *e2, + const void *keydata) +{ + return (e1 == e2) || (e1->hash == e2->hash && !map->cmpfn(e1, e2, keydata)); +} + +static inline unsigned int bucket(const struct hashmap *map, + const struct hashmap_entry *key) +{ + return key->hash & (map->tablesize - 1); +} + +static void rehash(struct hashmap *map, unsigned int newsize) +{ + unsigned int i, oldsize = map->tablesize; + struct hashmap_entry **oldtable = map->table; + + alloc_table(map, newsize); + for (i = 0; i < oldsize; i++) { + struct hashmap_entry *e = oldtable[i]; + while (e) { + struct hashmap_entry *next = e->next; + unsigned int b = bucket(map, e); + e->next = map->table[b]; + map->table[b] = e; + e = next; + } + } + free(oldtable); +} + +static inline struct hashmap_entry **find_entry_ptr(const struct hashmap *map, + const struct hashmap_entry *key, const void *keydata) +{ + struct hashmap_entry **e = &map->table[bucket(map, key)]; + while (*e && !entry_equals(map, *e, key, keydata)) + e = &(*e)->next; + return e; +} + +static int always_equal(const void *unused1, const void *unused2, const void *unused3) +{ + return 0; +} + +void hashmap_init(struct hashmap *map, hashmap_cmp_fn equals_function, + size_t initial_size) +{ + unsigned int size = HASHMAP_INITIAL_SIZE; + map->size = 0; + map->cmpfn = equals_function ? equals_function : always_equal; + + /* calculate initial table size and allocate the table */ + initial_size = (unsigned int) ((uint64_t) initial_size * 100 + / HASHMAP_LOAD_FACTOR); + while (initial_size > size) + size <<= HASHMAP_RESIZE_BITS; + alloc_table(map, size); +} + +void hashmap_free(struct hashmap *map, int free_entries) +{ + if (!map || !map->table) + return; + if (free_entries) { + struct hashmap_iter iter; + struct hashmap_entry *e; + hashmap_iter_init(map, &iter); + while ((e = hashmap_iter_next(&iter))) + free(e); + } + free(map->table); + memset(map, 0, sizeof(*map)); +} + +void *hashmap_get(const struct hashmap *map, const void *key, const void *keydata) +{ + return *find_entry_ptr(map, key, keydata); +} + +void *hashmap_get_next(const struct hashmap *map, const void *entry) +{ + struct hashmap_entry *e = ((struct hashmap_entry *) entry)->next; + for (; e; e = e->next) + if (entry_equals(map, entry, e, NULL)) + return e; + return NULL; +} + +void hashmap_add(struct hashmap *map, void *entry) +{ + unsigned int b = bucket(map, entry); + + /* add entry */ + ((struct hashmap_entry *) entry)->next = map->table[b]; + map->table[b] = entry; + + /* fix size and rehash if appropriate */ + map->size++; + if (map->size > map->grow_at) + rehash(map, map->tablesize << HASHMAP_RESIZE_BITS); +} + +void *hashmap_remove(struct hashmap *map, const void *key, const void *keydata) +{ + struct hashmap_entry *old; + struct hashmap_entry **e = find_entry_ptr(map, key, keydata); + if (!*e) + return NULL; + + /* remove existing entry */ + old = *e; + *e = old->next; + old->next = NULL; + + /* fix size and rehash if appropriate */ + map->size--; + if (map->size < map->shrink_at) + rehash(map, map->tablesize >> HASHMAP_RESIZE_BITS); + return old; +} + +void *hashmap_put(struct hashmap *map, void *entry) +{ + struct hashmap_entry *old = hashmap_remove(map, entry, NULL); + hashmap_add(map, entry); + return old; +} + +void hashmap_iter_init(struct hashmap *map, struct hashmap_iter *iter) +{ + iter->map = map; + iter->tablepos = 0; + iter->next = NULL; +} + +void *hashmap_iter_next(struct hashmap_iter *iter) +{ + struct hashmap_entry *current = iter->next; + for (;;) { + if (current) { + iter->next = current->next; + return current; + } + + if (iter->tablepos >= iter->map->tablesize) + return NULL; + + current = iter->map->table[iter->tablepos++]; + } +} diff --git a/hashmap.h b/hashmap.h new file mode 100644 index 0000000000..a816ad47b1 --- /dev/null +++ b/hashmap.h @@ -0,0 +1,71 @@ +#ifndef HASHMAP_H +#define HASHMAP_H + +/* + * Generic implementation of hash-based key-value mappings. + * See Documentation/technical/api-hashmap.txt. + */ + +/* FNV-1 functions */ + +extern unsigned int strhash(const char *buf); +extern unsigned int strihash(const char *buf); +extern unsigned int memhash(const void *buf, size_t len); +extern unsigned int memihash(const void *buf, size_t len); + +/* data structures */ + +struct hashmap_entry { + struct hashmap_entry *next; + unsigned int hash; +}; + +typedef int (*hashmap_cmp_fn)(const void *entry, const void *entry_or_key, + const void *keydata); + +struct hashmap { + struct hashmap_entry **table; + hashmap_cmp_fn cmpfn; + unsigned int size, tablesize, grow_at, shrink_at; +}; + +struct hashmap_iter { + struct hashmap *map; + struct hashmap_entry *next; + unsigned int tablepos; +}; + +/* hashmap functions */ + +extern void hashmap_init(struct hashmap *map, hashmap_cmp_fn equals_function, + size_t initial_size); +extern void hashmap_free(struct hashmap *map, int free_entries); + +/* hashmap_entry functions */ + +static inline void hashmap_entry_init(void *entry, unsigned int hash) +{ + struct hashmap_entry *e = entry; + e->hash = hash; + e->next = NULL; +} +extern void *hashmap_get(const struct hashmap *map, const void *key, + const void *keydata); +extern void *hashmap_get_next(const struct hashmap *map, const void *entry); +extern void hashmap_add(struct hashmap *map, void *entry); +extern void *hashmap_put(struct hashmap *map, void *entry); +extern void *hashmap_remove(struct hashmap *map, const void *key, + const void *keydata); + +/* hashmap_iter functions */ + +extern void hashmap_iter_init(struct hashmap *map, struct hashmap_iter *iter); +extern void *hashmap_iter_next(struct hashmap_iter *iter); +static inline void *hashmap_iter_first(struct hashmap *map, + struct hashmap_iter *iter) +{ + hashmap_iter_init(map, iter); + return hashmap_iter_next(iter); +} + +#endif diff --git a/merge-recursive.c b/merge-recursive.c index 8400a8e937..4177092942 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -201,7 +201,9 @@ static int add_cacheinfo(unsigned int mode, const unsigned char *sha1, const char *path, int stage, int refresh, int options) { struct cache_entry *ce; - ce = make_cache_entry(mode, sha1 ? sha1 : null_sha1, path, stage, refresh); + ce = make_cache_entry(mode, sha1 ? sha1 : null_sha1, path, stage, + (refresh ? (CE_MATCH_REFRESH | + CE_MATCH_IGNORE_MISSING) : 0 )); if (!ce) return error(_("addinfo_cache failed for path '%s'"), path); return add_cache_entry(ce, options); diff --git a/name-hash.c b/name-hash.c index e5b6e1ad23..97444d0201 100644 --- a/name-hash.c +++ b/name-hash.c @@ -8,49 +8,28 @@ #define NO_THE_INDEX_COMPATIBILITY_MACROS #include "cache.h" -/* - * This removes bit 5 if bit 6 is set. - * - * That will make US-ASCII characters hash to their upper-case - * equivalent. We could easily do this one whole word at a time, - * but that's for future worries. - */ -static inline unsigned char icase_hash(unsigned char c) -{ - return c & ~((c & 0x40) >> 1); -} - -static unsigned int hash_name(const char *name, int namelen) -{ - unsigned int hash = 0x123; - - while (namelen--) { - unsigned char c = *name++; - c = icase_hash(c); - hash = hash*101 + c; - } - return hash; -} - struct dir_entry { - struct dir_entry *next; + struct hashmap_entry ent; struct dir_entry *parent; struct cache_entry *ce; int nr; unsigned int namelen; }; +static int dir_entry_cmp(const struct dir_entry *e1, + const struct dir_entry *e2, const char *name) +{ + return e1->namelen != e2->namelen || strncasecmp(e1->ce->name, + name ? name : e2->ce->name, e1->namelen); +} + static struct dir_entry *find_dir_entry(struct index_state *istate, const char *name, unsigned int namelen) { - unsigned int hash = hash_name(name, namelen); - struct dir_entry *dir; - - for (dir = lookup_hash(hash, &istate->dir_hash); dir; dir = dir->next) - if (dir->namelen == namelen && - !strncasecmp(dir->ce->name, name, namelen)) - return dir; - return NULL; + struct dir_entry key; + hashmap_entry_init(&key, memihash(name, namelen)); + key.namelen = namelen; + return hashmap_get(&istate->dir_hash, &key, name); } static struct dir_entry *hash_dir_entry(struct index_state *istate, @@ -84,18 +63,11 @@ static struct dir_entry *hash_dir_entry(struct index_state *istate, dir = find_dir_entry(istate, ce->name, namelen); if (!dir) { /* not found, create it and add to hash table */ - void **pdir; - unsigned int hash = hash_name(ce->name, namelen); - dir = xcalloc(1, sizeof(struct dir_entry)); + hashmap_entry_init(dir, memihash(ce->name, namelen)); dir->namelen = namelen; dir->ce = ce; - - pdir = insert_hash(hash, dir, &istate->dir_hash); - if (pdir) { - dir->next = *pdir; - *pdir = dir; - } + hashmap_add(&istate->dir_hash, dir); /* recursively add missing parent directories */ dir->parent = hash_dir_entry(istate, ce, namelen); @@ -114,45 +86,50 @@ static void add_dir_entry(struct index_state *istate, struct cache_entry *ce) static void remove_dir_entry(struct index_state *istate, struct cache_entry *ce) { /* - * Release reference to the directory entry (and parents if 0). - * - * Note: we do not remove / free the entry because there's no - * hash.[ch]::remove_hash and dir->next may point to other entries - * that are still valid, so we must not free the memory. + * Release reference to the directory entry. If 0, remove and continue + * with parent directory. */ struct dir_entry *dir = hash_dir_entry(istate, ce, ce_namelen(ce)); - while (dir && dir->nr && !(--dir->nr)) - dir = dir->parent; + while (dir && !(--dir->nr)) { + struct dir_entry *parent = dir->parent; + hashmap_remove(&istate->dir_hash, dir, NULL); + free(dir); + dir = parent; + } } static void hash_index_entry(struct index_state *istate, struct cache_entry *ce) { - void **pos; - unsigned int hash; - if (ce->ce_flags & CE_HASHED) return; ce->ce_flags |= CE_HASHED; - ce->next = NULL; - hash = hash_name(ce->name, ce_namelen(ce)); - pos = insert_hash(hash, ce, &istate->name_hash); - if (pos) { - ce->next = *pos; - *pos = ce; - } + hashmap_entry_init(ce, memihash(ce->name, ce_namelen(ce))); + hashmap_add(&istate->name_hash, ce); - if (ignore_case && !(ce->ce_flags & CE_UNHASHED)) + if (ignore_case) add_dir_entry(istate, ce); } +static int cache_entry_cmp(const struct cache_entry *ce1, + const struct cache_entry *ce2, const void *remove) +{ + /* + * For remove_name_hash, find the exact entry (pointer equality); for + * index_file_exists, find all entries with matching hash code and + * decide whether the entry matches in same_name. + */ + return remove ? !(ce1 == ce2) : 0; +} + static void lazy_init_name_hash(struct index_state *istate) { int nr; if (istate->name_hash_initialized) return; - if (istate->cache_nr) - preallocate_hash(&istate->name_hash, istate->cache_nr); + hashmap_init(&istate->name_hash, (hashmap_cmp_fn) cache_entry_cmp, + istate->cache_nr); + hashmap_init(&istate->dir_hash, (hashmap_cmp_fn) dir_entry_cmp, 0); for (nr = 0; nr < istate->cache_nr; nr++) hash_index_entry(istate, istate->cache[nr]); istate->name_hash_initialized = 1; @@ -160,31 +137,19 @@ static void lazy_init_name_hash(struct index_state *istate) void add_name_hash(struct index_state *istate, struct cache_entry *ce) { - /* if already hashed, add reference to directory entries */ - if (ignore_case && (ce->ce_flags & CE_STATE_MASK) == CE_STATE_MASK) - add_dir_entry(istate, ce); - - ce->ce_flags &= ~CE_UNHASHED; if (istate->name_hash_initialized) hash_index_entry(istate, ce); } -/* - * We don't actually *remove* it, we can just mark it invalid so that - * we won't find it in lookups. - * - * Not only would we have to search the lists (simple enough), but - * we'd also have to rehash other hash buckets in case this makes the - * hash bucket empty (common). So it's much better to just mark - * it. - */ void remove_name_hash(struct index_state *istate, struct cache_entry *ce) { - /* if already hashed, release reference to directory entries */ - if (ignore_case && (ce->ce_flags & CE_STATE_MASK) == CE_HASHED) - remove_dir_entry(istate, ce); + if (!istate->name_hash_initialized || !(ce->ce_flags & CE_HASHED)) + return; + ce->ce_flags &= ~CE_HASHED; + hashmap_remove(&istate->name_hash, ce, ce); - ce->ce_flags |= CE_UNHASHED; + if (ignore_case) + remove_dir_entry(istate, ce); } static int slow_same_name(const char *name1, int len1, const char *name2, int len2) @@ -247,49 +212,27 @@ struct cache_entry *index_dir_exists(struct index_state *istate, const char *nam struct cache_entry *index_file_exists(struct index_state *istate, const char *name, int namelen, int icase) { - unsigned int hash = hash_name(name, namelen); struct cache_entry *ce; + struct hashmap_entry key; lazy_init_name_hash(istate); - ce = lookup_hash(hash, &istate->name_hash); + hashmap_entry_init(&key, memihash(name, namelen)); + ce = hashmap_get(&istate->name_hash, &key, NULL); while (ce) { - if (!(ce->ce_flags & CE_UNHASHED)) { - if (same_name(ce, name, namelen, icase)) - return ce; - } - ce = ce->next; + if (same_name(ce, name, namelen, icase)) + return ce; + ce = hashmap_get_next(&istate->name_hash, ce); } return NULL; } -struct cache_entry *index_name_exists(struct index_state *istate, const char *name, int namelen, int icase) -{ - if (namelen > 0 && name[namelen - 1] == '/') - return index_dir_exists(istate, name, namelen - 1); - return index_file_exists(istate, name, namelen, icase); -} - -static int free_dir_entry(void *entry, void *unused) -{ - struct dir_entry *dir = entry; - while (dir) { - struct dir_entry *next = dir->next; - free(dir); - dir = next; - } - return 0; -} - void free_name_hash(struct index_state *istate) { if (!istate->name_hash_initialized) return; istate->name_hash_initialized = 0; - if (ignore_case) - /* free directory entries */ - for_each_hash(&istate->dir_hash, free_dir_entry, NULL); - free_hash(&istate->name_hash); - free_hash(&istate->dir_hash); + hashmap_free(&istate->name_hash, 0); + hashmap_free(&istate->dir_hash, 1); } diff --git a/path.c b/path.c index 24594c4112..f9c5062427 100644 --- a/path.c +++ b/path.c @@ -265,12 +265,12 @@ static struct passwd *getpw_str(const char *username, size_t len) char *expand_user_path(const char *path) { struct strbuf user_path = STRBUF_INIT; - const char *first_slash = strchrnul(path, '/'); const char *to_copy = path; if (path == NULL) goto return_null; if (path[0] == '~') { + const char *first_slash = strchrnul(path, '/'); const char *username = path + 1; size_t username_len = first_slash - username; if (username_len == 0) { diff --git a/pathspec.c b/pathspec.c index 6cb9fd3014..8043099955 100644 --- a/pathspec.c +++ b/pathspec.c @@ -33,7 +33,7 @@ void add_pathspec_matches_against_index(const struct pathspec *pathspec, return; for (i = 0; i < active_nr; i++) { const struct cache_entry *ce = active_cache[i]; - match_pathspec_depth(pathspec, ce->name, ce_namelen(ce), 0, seen); + ce_path_match(ce, pathspec, seen); } } diff --git a/po/de.po b/po/de.po index c0bbb65bf6..b777ef4803 100644 --- a/po/de.po +++ b/po/de.po @@ -5,9 +5,9 @@ # msgid "" msgstr "" -"Project-Id-Version: git 1.8.5\n" +"Project-Id-Version: git 1.9\n" "Report-Msgid-Bugs-To: Git Mailing List \n" -"POT-Creation-Date: 2013-11-02 08:06+0800\n" +"POT-Creation-Date: 2014-02-01 08:06+0800\n" "PO-Revision-Date: 2013-07-28 18:42+0200\n" "Last-Translator: Ralf Thielow \n" "Language-Team: German <>\n" @@ -57,7 +57,7 @@ msgstr "" msgid "git archive --remote [--exec ] --list" msgstr "git archive --remote [--exec ] --list" -#: archive.c:242 builtin/add.c:240 builtin/add.c:556 builtin/rm.c:328 +#: archive.c:242 builtin/add.c:240 builtin/add.c:559 builtin/rm.c:328 #, c-format msgid "pathspec '%s' did not match any files" msgstr "Pfadspezifikation '%s' stimmt mit keinen Dateien überein" @@ -78,8 +78,8 @@ msgstr "Präfix" msgid "prepend prefix to each pathname in the archive" msgstr "stellt einen Präfix vor jeden Pfadnamen in dem Archiv" -#: archive.c:330 builtin/archive.c:88 builtin/blame.c:2264 -#: builtin/blame.c:2265 builtin/config.c:58 builtin/fast-export.c:680 +#: archive.c:330 builtin/archive.c:88 builtin/blame.c:2265 +#: builtin/blame.c:2266 builtin/config.c:58 builtin/fast-export.c:680 #: builtin/fast-export.c:682 builtin/grep.c:716 builtin/hash-object.c:77 #: builtin/ls-files.c:486 builtin/ls-files.c:489 builtin/notes.c:408 #: builtin/notes.c:565 builtin/read-tree.c:108 parse-options.h:154 @@ -268,64 +268,64 @@ msgstr "Fehler beim Sperren der Referenz zur Aktualisierung." msgid "Failed to write ref" msgstr "Fehler beim Schreiben der Referenz." -#: bundle.c:36 +#: bundle.c:37 #, c-format msgid "'%s' does not look like a v2 bundle file" msgstr "'%s' sieht nicht wie eine v2 Paketdatei aus" -#: bundle.c:63 +#: bundle.c:64 #, c-format msgid "unrecognized header: %s%s (%d)" msgstr "nicht erkannter Kopfbereich: %s%s (%d)" -#: bundle.c:89 builtin/commit.c:706 +#: bundle.c:90 builtin/commit.c:706 #, c-format msgid "could not open '%s'" msgstr "Konnte '%s' nicht öffnen" -#: bundle.c:140 +#: bundle.c:141 msgid "Repository lacks these prerequisite commits:" msgstr "Dem Repository fehlen folgende vorausgesetzte Commits:" -#: bundle.c:164 sequencer.c:662 sequencer.c:1112 builtin/log.c:332 -#: builtin/log.c:821 builtin/log.c:1418 builtin/log.c:1644 builtin/merge.c:364 +#: bundle.c:165 sequencer.c:662 sequencer.c:1112 builtin/log.c:332 +#: builtin/log.c:821 builtin/log.c:1418 builtin/log.c:1644 builtin/merge.c:357 #: builtin/shortlog.c:158 msgid "revision walk setup failed" msgstr "Einrichtung des Revisionsgangs fehlgeschlagen" -#: bundle.c:186 +#: bundle.c:187 #, c-format msgid "The bundle contains this ref:" msgid_plural "The bundle contains these %d refs:" msgstr[0] "Das Paket enthält diese Referenz:" msgstr[1] "Das Paket enthält diese %d Referenzen:" -#: bundle.c:193 +#: bundle.c:194 msgid "The bundle records a complete history." msgstr "Das Paket speichert eine komplette Historie." -#: bundle.c:195 +#: bundle.c:196 #, c-format msgid "The bundle requires this ref:" msgid_plural "The bundle requires these %d refs:" msgstr[0] "Das Paket benötigt diese Referenz:" msgstr[1] "Das Paket benötigt diese %d Referenzen:" -#: bundle.c:294 +#: bundle.c:296 msgid "rev-list died" msgstr "\"rev-list\" abgebrochen" -#: bundle.c:300 builtin/log.c:1329 builtin/shortlog.c:261 +#: bundle.c:302 builtin/log.c:1329 builtin/shortlog.c:261 #, c-format msgid "unrecognized argument: %s" msgstr "nicht erkanntes Argument: %s" -#: bundle.c:335 +#: bundle.c:337 #, c-format msgid "ref '%s' is excluded by the rev-list options" msgstr "Referenz '%s' wird durch \"rev-list\" Optionen ausgeschlossen" -#: bundle.c:380 +#: bundle.c:382 msgid "Refusing to create empty bundle." msgstr "Erstellung eines leeren Pakets zurückgewiesen." @@ -360,16 +360,16 @@ msgstr "%s %s ist kein Commit!" msgid "memory exhausted" msgstr "Speicher verbraucht" -#: connected.c:60 +#: connected.c:70 msgid "Could not run 'git rev-list'" msgstr "Konnte 'git rev-list' nicht ausführen" -#: connected.c:80 +#: connected.c:90 #, c-format msgid "failed write to rev-list: %s" msgstr "Fehler beim Schreiben nach rev-list: %s" -#: connected.c:88 +#: connected.c:98 #, c-format msgid "failed to close rev-list's stdin: %s" msgstr "Fehler beim Schließen von rev-list's Standard-Eingabe: %s" @@ -441,23 +441,28 @@ msgid_plural "%lu years ago" msgstr[0] "vor %lu Jahr" msgstr[1] "vor %lu Jahren" -#: diff.c:112 +#: diffcore-order.c:24 +#, c-format +msgid "failed to read orderfile '%s'" +msgstr "Fehler beim Lesen der Reihenfolgedatei '%s'." + +#: diff.c:113 #, c-format msgid " Failed to parse dirstat cut-off percentage '%s'\n" msgstr "" " Fehler beim Parsen des abgeschnittenen \"dirstat\" Prozentsatzes '%s'\n" -#: diff.c:117 +#: diff.c:118 #, c-format msgid " Unknown dirstat parameter '%s'\n" msgstr " Unbekannter \"dirstat\" Parameter '%s'\n" -#: diff.c:210 +#: diff.c:213 #, c-format msgid "Unknown value for 'diff.submodule' config variable: '%s'" msgstr "Unbekannter Wert in Konfigurationsvariable 'diff.dirstat': '%s'" -#: diff.c:260 +#: diff.c:263 #, c-format msgid "" "Found errors in 'diff.dirstat' config variable:\n" @@ -466,7 +471,7 @@ msgstr "" "Fehler in 'diff.dirstat' Konfigurationsvariable gefunden:\n" "%s" -#: diff.c:3490 +#: diff.c:3509 #, c-format msgid "" "Failed to parse --dirstat/-X option parameter:\n" @@ -475,7 +480,7 @@ msgstr "" "Fehler beim Parsen des --dirstat/-X Optionsparameters:\n" "%s" -#: diff.c:3504 +#: diff.c:3523 #, c-format msgid "Failed to parse --submodule option parameter: '%s'" msgstr "Fehler beim Parsen des --submodule Optionsparameters: '%s'" @@ -586,7 +591,7 @@ msgid "failed to read the cache" msgstr "Lesen des Zwischenspeichers fehlgeschlagen" #: merge.c:110 builtin/checkout.c:358 builtin/checkout.c:559 -#: builtin/clone.c:655 +#: builtin/clone.c:661 msgid "unable to write new index file" msgstr "Konnte neue Staging-Area-Datei nicht schreiben." @@ -635,7 +640,7 @@ msgstr "kann Objekt %s '%s' nicht lesen" msgid "blob expected for %s '%s'" msgstr "Blob erwartet für %s '%s'" -#: merge-recursive.c:774 builtin/clone.c:311 +#: merge-recursive.c:774 builtin/clone.c:317 #, c-format msgid "failed to open '%s'" msgstr "Fehler beim Öffnen von '%s'" @@ -685,7 +690,7 @@ msgstr "" msgid "rename" msgstr "umbenennen" -#: merge-recursive.c:1082 +#: merge-recursive.c:1082 wt-status.c:283 msgid "renamed" msgstr "umbenannt" @@ -750,7 +755,7 @@ msgstr "Objekt %s ist kein Blob" msgid "modify" msgstr "ändern" -#: merge-recursive.c:1565 +#: merge-recursive.c:1565 wt-status.c:281 msgid "modified" msgstr "geändert" @@ -772,7 +777,7 @@ msgstr "%s ausgelassen (Ergebnis des Merges existiert bereits)" msgid "Auto-merging %s" msgstr "automatischer Merge von %s" -#: merge-recursive.c:1634 git-submodule.sh:1125 +#: merge-recursive.c:1634 git-submodule.sh:1148 msgid "submodule" msgstr "Submodul" @@ -844,7 +849,7 @@ msgstr "Merge hat keinen Commit zurückgegeben" msgid "Could not parse object '%s'" msgstr "Konnte Objekt '%s' nicht parsen." -#: merge-recursive.c:2010 builtin/merge.c:672 +#: merge-recursive.c:2010 builtin/merge.c:665 msgid "Unable to write index." msgstr "Konnte Staging-Area nicht schreiben." @@ -901,47 +906,50 @@ msgstr " %s" msgid "-NUM" msgstr "-NUM" -#: pathspec.c:118 +#: pathspec.c:133 msgid "global 'glob' and 'noglob' pathspec settings are incompatible" -msgstr "Globale Einstellungen zur Pfadspezifikation 'glob' und 'noglob' sind inkompatibel." +msgstr "" +"Globale Einstellungen zur Pfadspezifikation 'glob' und 'noglob' sind " +"inkompatibel." -#: pathspec.c:128 +#: pathspec.c:143 msgid "" "global 'literal' pathspec setting is incompatible with all other global " "pathspec settings" -msgstr "Globale Einstellung zur Pfadspezifikation 'literal' ist inkompatibel\n" +msgstr "" +"Globale Einstellung zur Pfadspezifikation 'literal' ist inkompatibel\n" "mit allen anderen Optionen." -#: pathspec.c:158 +#: pathspec.c:177 msgid "invalid parameter for pathspec magic 'prefix'" msgstr "ungültiger Parameter für Pfadspezifikationsangabe 'prefix'" -#: pathspec.c:164 +#: pathspec.c:183 #, c-format msgid "Invalid pathspec magic '%.*s' in '%s'" msgstr "ungültige Pfadspezifikationsangabe '%.*s' in '%s'" -#: pathspec.c:168 +#: pathspec.c:187 #, c-format msgid "Missing ')' at the end of pathspec magic in '%s'" msgstr "Fehlendes ')' am Ende der Pfadspezifikationsangabe in '%s'" -#: pathspec.c:186 +#: pathspec.c:205 #, c-format msgid "Unimplemented pathspec magic '%c' in '%s'" msgstr "nicht unterstützte Pfadspezifikationsangabe '%c' in '%s'" -#: pathspec.c:211 +#: pathspec.c:230 #, c-format msgid "%s: 'literal' and 'glob' are incompatible" msgstr "%s: 'literal' und 'glob' sind inkompatibel" -#: pathspec.c:222 +#: pathspec.c:241 #, c-format msgid "%s: '%s' is outside repository" msgstr "%s: '%s' liegt außerhalb des Repositories" -#: pathspec.c:278 +#: pathspec.c:291 #, c-format msgid "Pathspec '%s' is in submodule '%.*s'" msgstr "Pfadspezifikation '%s' befindet sich in Submodul '%.*s'" @@ -951,42 +959,75 @@ msgstr "Pfadspezifikation '%s' befindet sich in Submodul '%.*s'" #. * name. E.g. when add--interactive dies when running #. * "checkout -p" #. -#: pathspec.c:340 +#: pathspec.c:353 #, c-format msgid "%s: pathspec magic not supported by this command: %s" -msgstr "%s: Pfadspezifikationsangabe wird von diesem Kommando nicht unterstützt: %s" +msgstr "" +"%s: Pfadspezifikationsangabe wird von diesem Kommando nicht unterstützt: %s" -#: pathspec.c:415 +#: pathspec.c:433 #, c-format msgid "pathspec '%s' is beyond a symbolic link" msgstr "Pfadspezifikation '%s' ist hinter einem symbolischen Verweis" -#: remote.c:1833 +#: pathspec.c:442 +msgid "" +"There is nothing to exclude from by :(exclude) patterns.\n" +"Perhaps you forgot to add either ':/' or '.' ?" +msgstr "" +":(exclude) Muster, aber keine anderen Pfadspezifikationen angegeben.\n" +"Vielleicht haben Sie vergessen entweder ':/' oder '.' hinzuzufügen?" + +#: remote.c:753 +#, c-format +msgid "Cannot fetch both %s and %s to %s" +msgstr "Kann 'fetch' nicht für sowohl %s als auch %s nach %s ausführen." + +#: remote.c:757 +#, c-format +msgid "%s usually tracks %s, not %s" +msgstr "%s folgt üblicherweise %s, nicht %s" + +#: remote.c:761 +#, c-format +msgid "%s tracks both %s and %s" +msgstr "%s folgt sowohl %s als auch %s" + +#. +#. * This last possibility doesn't occur because +#. * FETCH_HEAD_IGNORE entries always appear at +#. * the end of the list. +#. +#: remote.c:769 +msgid "Internal error" +msgstr "Interner Fehler" + +#: remote.c:1871 #, c-format msgid "Your branch is based on '%s', but the upstream is gone.\n" msgstr "Ihr Branch basiert auf '%s', aber Upstream-Branch wurde entfernt.\n" -#: remote.c:1837 +#: remote.c:1875 msgid " (use \"git branch --unset-upstream\" to fixup)\n" msgstr " (benutzen Sie \"git branch --unset-upstream\" zum Beheben)\n" -#: remote.c:1840 +#: remote.c:1878 #, c-format msgid "Your branch is up-to-date with '%s'.\n" msgstr "Ihr Branch ist auf dem selben Stand wie '%s'.\n" -#: remote.c:1844 +#: remote.c:1882 #, 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 Branch ist vor '%s' um %d Commit.\n" msgstr[1] "Ihr Branch ist vor '%s' um %d Commits.\n" -#: remote.c:1850 +#: remote.c:1888 msgid " (use \"git push\" to publish your local commits)\n" msgstr " (benutzen Sie \"git push\" um lokale Commits zu publizieren)\n" -#: remote.c:1853 +#: remote.c:1891 #, c-format msgid "Your branch is behind '%s' by %d commit, and can be fast-forwarded.\n" msgid_plural "" @@ -996,12 +1037,12 @@ msgstr[0] "" msgstr[1] "" "Ihr Branch ist zu '%s' um %d Commits hinterher, und kann vorgespult werden.\n" -#: remote.c:1861 +#: remote.c:1899 msgid " (use \"git pull\" to update your local branch)\n" msgstr "" " (benutzen Sie \"git pull\" um Ihren lokalen Branch zu aktualisieren)\n" -#: remote.c:1864 +#: remote.c:1902 #, c-format msgid "" "Your branch and '%s' have diverged,\n" @@ -1016,7 +1057,7 @@ msgstr[1] "" "Ihr Branch und '%s' sind divergiert,\n" "und haben jeweils %d und %d unterschiedliche Commits.\n" -#: remote.c:1874 +#: remote.c:1912 msgid " (use \"git pull\" to merge the remote branch into yours)\n" msgstr "" " (benutzen Sie \"git pull\" um Ihren Branch mit dem Remote-Branch " @@ -1031,14 +1072,14 @@ msgstr "Öffnen von /dev/null fehlgeschlagen" 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 +#: sequencer.c:206 builtin/merge.c:783 builtin/merge.c:896 +#: builtin/merge.c:1006 builtin/merge.c:1016 #, c-format msgid "Could not open '%s' for writing" msgstr "Konnte '%s' nicht zum Schreiben öffnen." -#: sequencer.c:208 builtin/merge.c:350 builtin/merge.c:793 -#: builtin/merge.c:1015 builtin/merge.c:1028 +#: sequencer.c:208 builtin/merge.c:343 builtin/merge.c:786 +#: builtin/merge.c:1008 builtin/merge.c:1021 #, c-format msgid "Could not write to '%s'" msgstr "Konnte nicht nach '%s' schreiben." @@ -1280,7 +1321,7 @@ msgstr "Kann nicht als allerersten Commit einen Revert ausführen." msgid "Can't cherry-pick into empty head" msgstr "Kann nicht als allerersten Commit einen Cherry-Pick ausführen." -#: sha1_name.c:440 +#: sha1_name.c:439 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" @@ -1305,28 +1346,29 @@ msgstr "" "indem Sie \"git config advice.objectNameWarning false\"\n" "ausführen." -#: sha1_name.c:1112 +#: sha1_name.c:1070 msgid "HEAD does not point to a branch" msgstr "HEAD zeigt auf keinen Branch" -#: sha1_name.c:1115 +#: sha1_name.c:1073 #, c-format msgid "No such branch: '%s'" msgstr "Kein solcher Branch '%s'" -#: sha1_name.c:1117 +#: sha1_name.c:1075 #, c-format msgid "No upstream configured for branch '%s'" msgstr "Kein Upstream-Branch für Branch '%s' konfiguriert." -#: sha1_name.c:1121 +#: sha1_name.c:1079 #, c-format msgid "Upstream branch '%s' not stored as a remote-tracking branch" msgstr "Upstream-Branch '%s' ist nicht als Remote-Tracking-Branch gespeichert" #: submodule.c:64 submodule.c:98 msgid "Cannot change unmerged .gitmodules, resolve merge conflicts first" -msgstr "Kann nicht zusammengeführte .gitmodules-Datei nicht ändern, lösen\n" +msgstr "" +"Kann nicht zusammengeführte .gitmodules-Datei nicht ändern, lösen\n" "Sie zuerst die Konflikte auf" #: submodule.c:68 submodule.c:102 @@ -1428,245 +1470,237 @@ msgstr "konnte aktuellen Benutzer nicht in Passwort-Datei finden: %s" msgid "no such user" msgstr "kein solcher Benutzer" -#: wt-status.c:146 +#: wt-status.c:150 msgid "Unmerged paths:" msgstr "Nicht zusammengeführte Pfade:" -#: wt-status.c:173 wt-status.c:200 +#: wt-status.c:177 wt-status.c:204 #, c-format msgid " (use \"git reset %s ...\" to unstage)" msgstr "" " (benutzen Sie \"git reset %s ...\" zum Entfernen aus der Staging-" "Area)" -#: wt-status.c:175 wt-status.c:202 +#: wt-status.c:179 wt-status.c:206 msgid " (use \"git rm --cached ...\" to unstage)" msgstr "" " (benutzen Sie \"git rm --cached ...\" zum Entfernen aus der Staging-" "Area)" -#: wt-status.c:179 +#: wt-status.c:183 msgid " (use \"git add ...\" to mark resolution)" msgstr "" " (benutzen Sie \"git add/rm ...\" um die Auflösung zu markieren)" -#: wt-status.c:181 wt-status.c:185 +#: wt-status.c:185 wt-status.c:189 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:183 +#: wt-status.c:187 msgid " (use \"git rm ...\" to mark resolution)" msgstr "" " (benutzen Sie \"git add/rm ...\" um die Auflösung zu markieren)" -#: wt-status.c:194 +#: wt-status.c:198 msgid "Changes to be committed:" msgstr "zum Commit vorgemerkte Änderungen:" -#: wt-status.c:212 +#: wt-status.c:216 msgid "Changes not staged for commit:" msgstr "Änderungen, die nicht zum Commit vorgemerkt sind:" -#: wt-status.c:216 +#: wt-status.c:220 msgid " (use \"git add ...\" to update what will be committed)" msgstr "" " (benutzen Sie \"git add ...\" um die Änderungen zum Commit " "vorzumerken)" -#: wt-status.c:218 +#: wt-status.c:222 msgid " (use \"git add/rm ...\" to update what will be committed)" msgstr "" " (benutzen Sie \"git add/rm ...\" um die Änderungen zum Commit " "vorzumerken)" -#: wt-status.c:219 +#: wt-status.c:223 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:221 +#: wt-status.c:225 msgid " (commit or discard the untracked or modified content in submodules)" msgstr "" " (committen oder verwerfen Sie den unbeobachteten oder geänderten Inhalt in " "den Submodulen)" -#: wt-status.c:233 +#: wt-status.c:237 #, c-format msgid " (use \"git %s ...\" to include in what will be committed)" msgstr "" " (benutzen Sie \"git %s ...\" um die Änderungen zum Commit " "vorzumerken)" -#: wt-status.c:250 +#: wt-status.c:254 msgid "bug" msgstr "Fehler" -#: wt-status.c:255 +#: wt-status.c:259 msgid "both deleted:" msgstr "beide gelöscht:" -#: wt-status.c:256 +#: wt-status.c:260 msgid "added by us:" msgstr "von uns hinzugefügt:" -#: wt-status.c:257 +#: wt-status.c:261 msgid "deleted by them:" msgstr "von denen gelöscht:" -#: wt-status.c:258 +#: wt-status.c:262 msgid "added by them:" msgstr "von denen hinzugefügt:" -#: wt-status.c:259 +#: wt-status.c:263 msgid "deleted by us:" msgstr "von uns gelöscht:" -#: wt-status.c:260 +#: wt-status.c:264 msgid "both added:" msgstr "von beiden hinzugefügt:" -#: wt-status.c:261 +#: wt-status.c:265 msgid "both modified:" msgstr "von beiden geändert:" -#: wt-status.c:291 -msgid "new commits, " -msgstr "neue Commits, " - -#: wt-status.c:293 -msgid "modified content, " -msgstr "geänderter Inhalt, " - -#: wt-status.c:295 -msgid "untracked content, " -msgstr "unbeobachteter Inhalt, " +#: wt-status.c:275 +msgid "new file" +msgstr "neue Datei" -#: wt-status.c:312 -#, c-format -msgid "new file: %s" -msgstr "neue Datei: %s" +#: wt-status.c:277 +msgid "copied" +msgstr "kopiert" -#: wt-status.c:315 -#, c-format -msgid "copied: %s -> %s" -msgstr "kopiert: %s -> %s" +#: wt-status.c:279 +msgid "deleted" +msgstr "gelöscht" -#: wt-status.c:318 -#, c-format -msgid "deleted: %s" -msgstr "gelöscht: %s" +#: wt-status.c:285 +msgid "typechange" +msgstr "Typänderung" -#: wt-status.c:321 -#, c-format -msgid "modified: %s" -msgstr "geändert: %s" +#: wt-status.c:287 +msgid "unknown" +msgstr "unbekannt" -#: wt-status.c:324 -#, c-format -msgid "renamed: %s -> %s" -msgstr "umbenannt: %s -> %s" +#: wt-status.c:289 +msgid "unmerged" +msgstr "nicht zusammengeführt" -#: wt-status.c:327 -#, c-format -msgid "typechange: %s" -msgstr "Typänderung: %s" +#: wt-status.c:336 +msgid "new commits, " +msgstr "neue Commits, " -#: wt-status.c:330 -#, c-format -msgid "unknown: %s" -msgstr "unbekannt: %s" +#: wt-status.c:338 +msgid "modified content, " +msgstr "geänderter Inhalt, " -#: wt-status.c:333 -#, c-format -msgid "unmerged: %s" -msgstr "nicht zusammengeführt: %s" +#: wt-status.c:340 +msgid "untracked content, " +msgstr "unbeobachteter Inhalt, " -#: wt-status.c:336 +#: wt-status.c:357 #, c-format msgid "bug: unhandled diff status %c" msgstr "Fehler: unbehandelter Differenz-Status %c" -#: wt-status.c:703 +#: wt-status.c:732 msgid "Submodules changed but not updated:" msgstr "Submodule geändert, aber nicht aktualisiert:" -#: wt-status.c:705 +#: wt-status.c:734 msgid "Submodule changes to be committed:" msgstr "Änderungen in Submodul zum Committen:" -#: wt-status.c:848 +#: wt-status.c:836 +msgid "" +"Do not touch the line above.\n" +"Everything below will be removed." +msgstr "" +"Ändern Sie nicht die obige Zeile.\n" +"Alles unterhalb von ihr wird entfernt." + +#: wt-status.c:899 msgid "You have unmerged paths." msgstr "Sie haben nicht zusammengeführte Pfade." -#: wt-status.c:851 +#: wt-status.c:902 msgid " (fix conflicts and run \"git commit\")" msgstr " (beheben Sie die Konflikte und führen Sie \"git commit\" aus)" -#: wt-status.c:854 +#: wt-status.c:905 msgid "All conflicts fixed but you are still merging." msgstr "Alle Konflikte sind behoben, aber Sie sind immer noch beim Merge." -#: wt-status.c:857 +#: wt-status.c:908 msgid " (use \"git commit\" to conclude merge)" msgstr " (benutzen Sie \"git commit\" um den Merge abzuschließen)" -#: wt-status.c:867 +#: wt-status.c:918 msgid "You are in the middle of an am session." msgstr "Eine \"am\"-Sitzung ist im Gange." -#: wt-status.c:870 +#: wt-status.c:921 msgid "The current patch is empty." msgstr "Der aktuelle Patch ist leer." -#: wt-status.c:874 +#: wt-status.c:925 msgid " (fix conflicts and then run \"git am --continue\")" msgstr "" " (beheben Sie die Konflikte und führen Sie dann \"git am --continue\" aus)" -#: wt-status.c:876 +#: wt-status.c:927 msgid " (use \"git am --skip\" to skip this patch)" msgstr " (benutzen Sie \"git am --skip\" um diesen Patch auszulassen)" -#: wt-status.c:878 +#: wt-status.c:929 msgid " (use \"git am --abort\" to restore the original branch)" msgstr "" " (benutzen Sie \"git am --abort\" um den ursprünglichen Branch " "wiederherzustellen)" -#: wt-status.c:938 wt-status.c:955 +#: wt-status.c:989 wt-status.c:1006 #, c-format msgid "You are currently rebasing branch '%s' on '%s'." msgstr "Sie sind gerade beim Rebase von Branch '%s' auf '%s'." -#: wt-status.c:943 wt-status.c:960 +#: wt-status.c:994 wt-status.c:1011 msgid "You are currently rebasing." msgstr "Sie sind gerade beim Rebase." -#: wt-status.c:946 +#: wt-status.c:997 msgid " (fix conflicts and then run \"git rebase --continue\")" msgstr "" " (beheben Sie die Konflikte und führen Sie dann \"git rebase --continue\" " "aus)" -#: wt-status.c:948 +#: wt-status.c:999 msgid " (use \"git rebase --skip\" to skip this patch)" msgstr " (benutzen Sie \"git rebase --skip\" um diesen Patch auszulassen)" -#: wt-status.c:950 +#: wt-status.c:1001 msgid " (use \"git rebase --abort\" to check out the original branch)" msgstr "" " (benutzen Sie \"git rebase --abort\" um den ursprünglichen Branch " "auszuchecken)" -#: wt-status.c:963 +#: wt-status.c:1014 msgid " (all conflicts fixed: run \"git rebase --continue\")" msgstr " (alle Konflikte behoben: führen Sie \"git rebase --continue\" aus)" -#: wt-status.c:967 +#: wt-status.c:1018 #, c-format msgid "" "You are currently splitting a commit while rebasing branch '%s' on '%s'." @@ -1674,129 +1708,129 @@ msgstr "" "Sie teilen gerade einen Commit auf, während ein Rebase von Branch '%s' auf " "'%s' im Gange ist." -#: wt-status.c:972 +#: wt-status.c:1023 msgid "You are currently splitting a commit during a rebase." msgstr "Sie teilen gerade einen Commit während eines Rebase auf." -#: wt-status.c:975 +#: wt-status.c:1026 msgid " (Once your working directory is clean, run \"git rebase --continue\")" msgstr "" " (Sobald Ihr Arbeitsverzeichnis unverändert ist, führen Sie \"git rebase --" "continue\" aus)" -#: wt-status.c:979 +#: wt-status.c:1030 #, c-format msgid "You are currently editing a commit while rebasing branch '%s' on '%s'." msgstr "" "Sie editieren gerade einen Commit während eines Rebase von Branch '%s' auf " "'%s'." -#: wt-status.c:984 +#: wt-status.c:1035 msgid "You are currently editing a commit during a rebase." msgstr "Sie editieren gerade einen Commit während eines Rebase." -#: wt-status.c:987 +#: wt-status.c:1038 msgid " (use \"git commit --amend\" to amend the current commit)" msgstr "" " (benutzen Sie \"git commit --amend\" um den aktuellen Commit nachzubessern)" -#: wt-status.c:989 +#: wt-status.c:1040 msgid "" " (use \"git rebase --continue\" once you are satisfied with your changes)" msgstr "" " (benutzen Sie \"git rebase --continue\" sobald Ihre Änderungen " "abgeschlossen sind)" -#: wt-status.c:999 +#: wt-status.c:1050 #, c-format msgid "You are currently cherry-picking commit %s." msgstr "Sie führen gerade \"cherry-pick\" von Commit %s aus." -#: wt-status.c:1004 +#: wt-status.c:1055 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:1007 +#: wt-status.c:1058 msgid " (all conflicts fixed: run \"git cherry-pick --continue\")" msgstr "" " (alle Konflikte behoben: führen Sie \"git cherry-pick --continue\" aus)" -#: wt-status.c:1009 +#: wt-status.c:1060 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:1018 +#: wt-status.c:1069 #, c-format msgid "You are currently reverting commit %s." msgstr "Sie sind gerade an einem Revert von Commit '%s'." -#: wt-status.c:1023 +#: wt-status.c:1074 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:1026 +#: wt-status.c:1077 msgid " (all conflicts fixed: run \"git revert --continue\")" msgstr " (alle Konflikte behoben: führen Sie \"git revert --continue\" aus)" -#: wt-status.c:1028 +#: wt-status.c:1079 msgid " (use \"git revert --abort\" to cancel the revert operation)" msgstr "" " (benutzen Sie \"git revert --abort\" um die Revert-Operation abzubrechen)" -#: wt-status.c:1039 +#: wt-status.c:1090 #, c-format msgid "You are currently bisecting, started from branch '%s'." msgstr "Sie sind gerade bei einer binären Suche, gestartet von Branch '%s'." -#: wt-status.c:1043 +#: wt-status.c:1094 msgid "You are currently bisecting." msgstr "Sie sind gerade bei einer binären Suche." -#: wt-status.c:1046 +#: wt-status.c:1097 msgid " (use \"git bisect reset\" to get back to the original branch)" msgstr "" " (benutzen Sie \"git bisect reset\" um zum ursprünglichen Branch " "zurückzukehren)" -#: wt-status.c:1221 +#: wt-status.c:1272 msgid "On branch " msgstr "Auf Branch " -#: wt-status.c:1228 +#: wt-status.c:1279 msgid "rebase in progress; onto " msgstr "Rebase im Gange; auf " -#: wt-status.c:1235 +#: wt-status.c:1286 msgid "HEAD detached at " msgstr "HEAD losgelöst bei " -#: wt-status.c:1237 +#: wt-status.c:1288 msgid "HEAD detached from " msgstr "HEAD losgelöst von " -#: wt-status.c:1240 +#: wt-status.c:1291 msgid "Not currently on any branch." msgstr "Im Moment auf keinem Branch." -#: wt-status.c:1257 +#: wt-status.c:1308 msgid "Initial commit" msgstr "Initialer Commit" -#: wt-status.c:1271 +#: wt-status.c:1322 msgid "Untracked files" msgstr "Unbeobachtete Dateien" -#: wt-status.c:1273 +#: wt-status.c:1324 msgid "Ignored files" msgstr "Ignorierte Dateien" -#: wt-status.c:1277 +#: wt-status.c:1328 #, c-format msgid "" "It took %.2f seconds to enumerate untracked files. 'status -uno'\n" @@ -1807,32 +1841,32 @@ 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:1283 +#: wt-status.c:1334 #, c-format msgid "Untracked files not listed%s" msgstr "Unbeobachtete Dateien nicht aufgelistet%s" -#: wt-status.c:1285 +#: wt-status.c:1336 msgid " (use -u option to show untracked files)" msgstr " (benutzen Sie die Option -u um unbeobachteten Dateien anzuzeigen)" -#: wt-status.c:1291 +#: wt-status.c:1342 msgid "No changes" msgstr "Keine Änderungen" -#: wt-status.c:1296 +#: wt-status.c:1347 #, c-format msgid "no changes added to commit (use \"git add\" and/or \"git commit -a\")\n" msgstr "" "keine Änderungen zum Commit vorgemerkt (benutzen Sie \"git add\" und/oder " "\"git commit -a\")\n" -#: wt-status.c:1299 +#: wt-status.c:1350 #, c-format msgid "no changes added to commit\n" msgstr "keine Änderungen zum Commit vorgemerkt\n" -#: wt-status.c:1302 +#: wt-status.c:1353 #, c-format msgid "" "nothing added to commit but untracked files present (use \"git add\" to " @@ -1841,60 +1875,60 @@ msgstr "" "nichts zum Commit vorgemerkt, aber es gibt unbeobachtete Dateien (benutzen " "Sie \"git add\" zum Beobachten)\n" -#: wt-status.c:1305 +#: wt-status.c:1356 #, c-format msgid "nothing added to commit but untracked files present\n" msgstr "nichts zum Commit vorgemerkt, aber es gibt unbeobachtete Dateien\n" -#: wt-status.c:1308 +#: wt-status.c:1359 #, c-format msgid "nothing to commit (create/copy files and use \"git add\" to track)\n" msgstr "" "nichts zu committen (Erstellen/Kopieren Sie Dateien und benutzen Sie \"git " "add\" zum Beobachten)\n" -#: wt-status.c:1311 wt-status.c:1316 +#: wt-status.c:1362 wt-status.c:1367 #, c-format msgid "nothing to commit\n" msgstr "nichts zu committen\n" -#: wt-status.c:1314 +#: wt-status.c:1365 #, c-format msgid "nothing to commit (use -u to show untracked files)\n" msgstr "" "nichts zu committen (benutzen Sie die Option -u, um unbeobachtete Dateien " "anzuzeigen)\n" -#: wt-status.c:1318 +#: wt-status.c:1369 #, c-format msgid "nothing to commit, working directory clean\n" msgstr "nichts zu committen, Arbeitsverzeichnis unverändert\n" -#: wt-status.c:1427 +#: wt-status.c:1478 msgid "HEAD (no branch)" msgstr "HEAD (kein Branch)" -#: wt-status.c:1433 +#: wt-status.c:1484 msgid "Initial commit on " msgstr "Initialer Commit auf " -#: wt-status.c:1463 +#: wt-status.c:1514 msgid "gone" msgstr "entfernt" -#: wt-status.c:1465 +#: wt-status.c:1516 msgid "behind " msgstr "hinterher " -#: wt-status.c:1468 wt-status.c:1471 +#: wt-status.c:1519 wt-status.c:1522 msgid "ahead " msgstr "voraus " -#: wt-status.c:1473 +#: wt-status.c:1524 msgid ", behind " msgstr ", hinterher " -#: compat/precompose_utf8.c:55 builtin/clone.c:350 +#: compat/precompose_utf8.c:55 builtin/clone.c:356 #, c-format msgid "failed to unlink '%s'" msgstr "Konnte '%s' nicht entfernen." @@ -2027,15 +2061,15 @@ msgstr "" "Die folgenden Pfade werden durch eine Ihrer \".gitignore\" Dateien " "ignoriert:\n" -#: builtin/add.c:354 builtin/clean.c:875 builtin/fetch.c:92 builtin/mv.c:66 -#: builtin/prune-packed.c:73 builtin/push.c:459 builtin/remote.c:1253 +#: builtin/add.c:354 builtin/clean.c:875 builtin/fetch.c:93 builtin/mv.c:70 +#: builtin/prune-packed.c:77 builtin/push.c:506 builtin/remote.c:1344 #: builtin/rm.c:269 msgid "dry run" msgstr "Probelauf" #: builtin/add.c:355 builtin/apply.c:4410 builtin/check-ignore.c:19 #: builtin/commit.c:1249 builtin/count-objects.c:95 builtin/fsck.c:612 -#: builtin/log.c:1592 builtin/mv.c:65 builtin/read-tree.c:113 +#: builtin/log.c:1592 builtin/mv.c:69 builtin/read-tree.c:113 msgid "be verbose" msgstr "erweiterte Ausgaben" @@ -2120,11 +2154,11 @@ msgid "Maybe you wanted to say 'git add .'?\n" msgstr "Wollten Sie vielleicht 'git add .' sagen?\n" #: builtin/add.c:492 builtin/check-ignore.c:172 builtin/clean.c:919 -#: builtin/commit.c:320 builtin/mv.c:86 builtin/reset.c:224 builtin/rm.c:299 +#: builtin/commit.c:320 builtin/mv.c:90 builtin/reset.c:224 builtin/rm.c:299 msgid "index file corrupt" msgstr "Staging-Area-Datei beschädigt" -#: builtin/add.c:589 builtin/apply.c:4506 builtin/mv.c:259 builtin/rm.c:432 +#: builtin/add.c:592 builtin/apply.c:4506 builtin/mv.c:270 builtin/rm.c:432 msgid "Unable to write new index file" msgstr "Konnte neue Staging-Area-Datei nicht schreiben." @@ -2463,7 +2497,7 @@ msgid "unable to read index file" msgstr "Konnte Staging-Area-Datei nicht lesen" #: builtin/apply.c:4357 builtin/apply.c:4360 builtin/clone.c:90 -#: builtin/fetch.c:77 +#: builtin/fetch.c:78 msgid "path" msgstr "Pfad" @@ -2678,96 +2712,96 @@ msgstr "git blame [Optionen] [rev-opts] [rev] [--] Datei" msgid "[rev-opts] are documented in git-rev-list(1)" msgstr "[rev-opts] sind dokumentiert in git-rev-list(1)" -#: builtin/blame.c:2248 +#: builtin/blame.c:2249 msgid "Show blame entries as we find them, incrementally" msgstr "Zeigt \"blame\"-Einträge schrittweise, während wir sie generieren" -#: builtin/blame.c:2249 +#: builtin/blame.c:2250 msgid "Show blank SHA-1 for boundary commits (Default: off)" msgstr "Zeigt leere SHA-1 für Grenz-Commits (Standard: aus)" -#: builtin/blame.c:2250 +#: builtin/blame.c:2251 msgid "Do not treat root commits as boundaries (Default: off)" msgstr "Behandelt Ursprungs-Commit nicht als Grenzen (Standard: aus)" -#: builtin/blame.c:2251 +#: builtin/blame.c:2252 msgid "Show work cost statistics" msgstr "Zeigt Statistiken zum Arbeitsaufwand" -#: builtin/blame.c:2252 +#: builtin/blame.c:2253 msgid "Show output score for blame entries" msgstr "Zeigt Ausgabebewertung für \"blame\"-Einträge" -#: builtin/blame.c:2253 +#: builtin/blame.c:2254 msgid "Show original filename (Default: auto)" msgstr "Zeigt ursprünglichen Dateinamen (Standard: auto)" -#: builtin/blame.c:2254 +#: builtin/blame.c:2255 msgid "Show original linenumber (Default: off)" msgstr "Zeigt ursprüngliche Zeilennummer (Standard: aus)" -#: builtin/blame.c:2255 +#: builtin/blame.c:2256 msgid "Show in a format designed for machine consumption" msgstr "Anzeige in einem Format für maschinelle Auswertung" -#: builtin/blame.c:2256 +#: builtin/blame.c:2257 msgid "Show porcelain format with per-line commit information" msgstr "" "Anzeige in Format für Fremdprogramme mit Commit-Informationen pro Zeile" -#: builtin/blame.c:2257 +#: builtin/blame.c:2258 msgid "Use the same output mode as git-annotate (Default: off)" msgstr "Benutzt den gleichen Ausgabemodus wie \"git-annotate\" (Standard: aus)" -#: builtin/blame.c:2258 +#: builtin/blame.c:2259 msgid "Show raw timestamp (Default: off)" msgstr "Zeigt unbearbeiteten Zeitstempel (Standard: aus)" -#: builtin/blame.c:2259 +#: builtin/blame.c:2260 msgid "Show long commit SHA1 (Default: off)" msgstr "Zeigt langen Commit-SHA1 (Standard: aus)" -#: builtin/blame.c:2260 +#: builtin/blame.c:2261 msgid "Suppress author name and timestamp (Default: off)" msgstr "Unterdrückt den Namen des Autors und den Zeitstempel (Standard: aus)" -#: builtin/blame.c:2261 +#: builtin/blame.c:2262 msgid "Show author email instead of name (Default: off)" msgstr "Zeigt anstatt des Namens die Email-Adresse des Autors (Standard: aus)" -#: builtin/blame.c:2262 +#: builtin/blame.c:2263 msgid "Ignore whitespace differences" msgstr "Ignoriert Unterschiede im Whitespace" -#: builtin/blame.c:2263 +#: builtin/blame.c:2264 msgid "Spend extra cycles to find better match" msgstr "arbeite länger, um bessere Übereinstimmungen zu finden" -#: builtin/blame.c:2264 +#: builtin/blame.c:2265 msgid "Use revisions from instead of calling git-rev-list" msgstr "Benutzt Commits von anstatt \"git-rev-list\" aufzurufen" -#: builtin/blame.c:2265 +#: builtin/blame.c:2266 msgid "Use 's contents as the final image" msgstr "Benutzt Inhalte der en als entgültiges Abbild" -#: builtin/blame.c:2266 builtin/blame.c:2267 +#: builtin/blame.c:2267 builtin/blame.c:2268 msgid "score" msgstr "Bewertung" -#: builtin/blame.c:2266 +#: builtin/blame.c:2267 msgid "Find line copies within and across files" msgstr "Findet kopierte Zeilen innerhalb oder zwischen Dateien" -#: builtin/blame.c:2267 +#: builtin/blame.c:2268 msgid "Find line movements within and across files" msgstr "Findet verschobene Zeilen innerhalb oder zwischen Dateien" -#: builtin/blame.c:2268 +#: builtin/blame.c:2269 msgid "n,m" msgstr "n,m" -#: builtin/blame.c:2268 +#: builtin/blame.c:2269 msgid "Process only line range n,m, counting from 1" msgstr "Verarbeitet nur Zeilen im Bereich n,m, gezählt von 1" @@ -2873,252 +2907,252 @@ msgstr "Branch %s entfernt (war %s).\n" msgid "branch '%s' does not point at a commit" msgstr "Branch '%s' zeigt auf keinen Commit" -#: builtin/branch.c:453 +#: builtin/branch.c:454 #, c-format msgid "[%s: gone]" msgstr "[%s: entfernt]" -#: builtin/branch.c:456 +#: builtin/branch.c:459 #, c-format msgid "[%s]" msgstr "[%s]" -#: builtin/branch.c:459 +#: builtin/branch.c:464 #, c-format msgid "[%s: behind %d]" msgstr "[%s: %d hinterher]" -#: builtin/branch.c:461 +#: builtin/branch.c:466 #, c-format msgid "[behind %d]" msgstr "[%d hinterher]" -#: builtin/branch.c:465 +#: builtin/branch.c:470 #, c-format msgid "[%s: ahead %d]" msgstr "[%s: %d voraus]" -#: builtin/branch.c:467 +#: builtin/branch.c:472 #, c-format msgid "[ahead %d]" msgstr "[%d voraus]" -#: builtin/branch.c:470 +#: builtin/branch.c:475 #, c-format msgid "[%s: ahead %d, behind %d]" msgstr "[%s: %d voraus, %d hinterher]" -#: builtin/branch.c:473 +#: builtin/branch.c:478 #, c-format msgid "[ahead %d, behind %d]" msgstr "[%d voraus, %d hinterher]" -#: builtin/branch.c:496 +#: builtin/branch.c:502 msgid " **** invalid ref ****" msgstr " **** ungültige Referenz ****" -#: builtin/branch.c:588 +#: builtin/branch.c:594 #, c-format msgid "(no branch, rebasing %s)" msgstr "(kein Branch, Rebase von Branch %s im Gange)" -#: builtin/branch.c:591 +#: builtin/branch.c:597 #, c-format msgid "(no branch, bisect started on %s)" msgstr "(kein Branch, binäre Suche begonnen bei %s)" -#: builtin/branch.c:594 +#: builtin/branch.c:600 #, c-format msgid "(detached from %s)" msgstr "(losgelöst von %s)" -#: builtin/branch.c:597 +#: builtin/branch.c:603 msgid "(no branch)" msgstr "(kein Branch)" -#: builtin/branch.c:643 +#: builtin/branch.c:649 #, c-format msgid "object '%s' does not point to a commit" msgstr "Objekt '%s' zeigt auf keinen Commit" -#: builtin/branch.c:675 +#: builtin/branch.c:681 msgid "some refs could not be read" msgstr "Konnte einige Referenzen nicht lesen" -#: builtin/branch.c:688 +#: builtin/branch.c:694 msgid "cannot rename the current branch while not on any." msgstr "" "Kann aktuellen Branch nicht umbenennen, solange Sie sich auf keinem befinden." -#: builtin/branch.c:698 +#: builtin/branch.c:704 #, c-format msgid "Invalid branch name: '%s'" msgstr "Ungültiger Branchname: '%s'" -#: builtin/branch.c:713 +#: builtin/branch.c:719 msgid "Branch rename failed" msgstr "Umbenennung des Branches fehlgeschlagen" -#: builtin/branch.c:717 +#: builtin/branch.c:723 #, c-format msgid "Renamed a misnamed branch '%s' away" msgstr "falsch benannten Branch '%s' umbenannt" -#: builtin/branch.c:721 +#: builtin/branch.c:727 #, c-format msgid "Branch renamed to %s, but HEAD is not updated!" msgstr "Branch umbenannt zu %s, aber HEAD ist nicht aktualisiert!" -#: builtin/branch.c:728 +#: builtin/branch.c:734 msgid "Branch is renamed, but update of config-file failed" msgstr "" "Branch ist umbenannt, aber die Aktualisierung der Konfigurationsdatei ist " "fehlgeschlagen." -#: builtin/branch.c:743 +#: builtin/branch.c:749 #, c-format msgid "malformed object name %s" msgstr "Missgebildeter Objektname %s" -#: builtin/branch.c:767 +#: builtin/branch.c:773 #, c-format msgid "could not write branch description template: %s" msgstr "Konnte Beschreibungsvorlage für Branch nicht schreiben: %s" -#: builtin/branch.c:797 +#: builtin/branch.c:803 msgid "Generic options" msgstr "Allgemeine Optionen" -#: builtin/branch.c:799 +#: builtin/branch.c:805 msgid "show hash and subject, give twice for upstream branch" msgstr "Zeigt Hash und Betreff; -vv: zusätzlich Upstream-Branch" -#: builtin/branch.c:800 +#: builtin/branch.c:806 msgid "suppress informational messages" msgstr "unterdrückt Informationsmeldungen" -#: builtin/branch.c:801 +#: builtin/branch.c:807 msgid "set up tracking mode (see git-pull(1))" msgstr "stellt den Übernahmemodus ein (siehe git-pull(1))" -#: builtin/branch.c:803 +#: builtin/branch.c:809 msgid "change upstream info" msgstr "ändert Informationen zum Upstream-Branch" -#: builtin/branch.c:807 +#: builtin/branch.c:813 msgid "use colored output" msgstr "verwendet farbliche Ausgaben" -#: builtin/branch.c:808 +#: builtin/branch.c:814 msgid "act on remote-tracking branches" msgstr "wirkt auf Remote-Tracking-Branches" -#: builtin/branch.c:811 builtin/branch.c:817 builtin/branch.c:838 -#: builtin/branch.c:844 builtin/commit.c:1460 builtin/commit.c:1461 +#: builtin/branch.c:817 builtin/branch.c:823 builtin/branch.c:844 +#: builtin/branch.c:850 builtin/commit.c:1460 builtin/commit.c:1461 #: builtin/commit.c:1462 builtin/commit.c:1463 builtin/tag.c:468 msgid "commit" msgstr "Commit" -#: builtin/branch.c:812 builtin/branch.c:818 +#: builtin/branch.c:818 builtin/branch.c:824 msgid "print only branches that contain the commit" msgstr "gibt nur Branches aus, welche diesen Commit beinhalten" -#: builtin/branch.c:824 +#: builtin/branch.c:830 msgid "Specific git-branch actions:" msgstr "spezifische Aktionen für \"git-branch\":" -#: builtin/branch.c:825 +#: builtin/branch.c:831 msgid "list both remote-tracking and local branches" msgstr "listet Remote-Tracking und lokale Branches auf" -#: builtin/branch.c:827 +#: builtin/branch.c:833 msgid "delete fully merged branch" msgstr "entfernt vollständig zusammengeführten Branch" -#: builtin/branch.c:828 +#: builtin/branch.c:834 msgid "delete branch (even if not merged)" msgstr "löscht Branch (auch wenn nicht zusammengeführt)" -#: builtin/branch.c:829 +#: builtin/branch.c:835 msgid "move/rename a branch and its reflog" msgstr "verschiebt/benennt einen Branch und dessen Reflog um" -#: builtin/branch.c:830 +#: builtin/branch.c:836 msgid "move/rename a branch, even if target exists" msgstr "" "verschiebt/benennt einen Branch um, auch wenn das Ziel bereits existiert" -#: builtin/branch.c:831 +#: builtin/branch.c:837 msgid "list branch names" msgstr "listet Branchnamen auf" -#: builtin/branch.c:832 +#: builtin/branch.c:838 msgid "create the branch's reflog" msgstr "erzeugt das Reflog des Branches" -#: builtin/branch.c:834 +#: builtin/branch.c:840 msgid "edit the description for the branch" msgstr "bearbeitet die Beschreibung für den Branch" -#: builtin/branch.c:835 +#: builtin/branch.c:841 msgid "force creation (when already exists)" msgstr "erzeuge auch, wenn der Branch bereits existiert" -#: builtin/branch.c:838 +#: builtin/branch.c:844 msgid "print only not merged branches" msgstr "gibt nur Branches aus, die nicht zusammengeführt sind" -#: builtin/branch.c:844 +#: builtin/branch.c:850 msgid "print only merged branches" msgstr "gibt nur Branches aus, die zusammengeführt sind" -#: builtin/branch.c:848 +#: builtin/branch.c:854 msgid "list branches in columns" msgstr "listet Branches in Spalten auf" -#: builtin/branch.c:861 +#: builtin/branch.c:867 msgid "Failed to resolve HEAD as a valid ref." msgstr "Konnte HEAD nicht als gültige Referenz auflösen." -#: builtin/branch.c:866 builtin/clone.c:629 +#: builtin/branch.c:872 builtin/clone.c:635 msgid "HEAD not found below refs/heads!" msgstr "HEAD wurde nicht unter \"refs/heads\" gefunden!" -#: builtin/branch.c:890 +#: builtin/branch.c:896 msgid "--column and --verbose are incompatible" msgstr "Die Optionen --column und --verbose sind inkompatibel." -#: builtin/branch.c:896 builtin/branch.c:935 +#: builtin/branch.c:902 builtin/branch.c:941 msgid "branch name required" msgstr "Branchname erforderlich" -#: builtin/branch.c:911 +#: builtin/branch.c:917 msgid "Cannot give description to detached HEAD" msgstr "zu losgelöstem HEAD kann keine Beschreibung hinterlegt werden" -#: builtin/branch.c:916 +#: builtin/branch.c:922 msgid "cannot edit description of more than one branch" msgstr "Beschreibung von mehr als einem Branch kann nicht bearbeitet werden" -#: builtin/branch.c:923 +#: builtin/branch.c:929 #, c-format msgid "No commit on branch '%s' yet." msgstr "Noch kein Commit in Branch '%s'." -#: builtin/branch.c:926 +#: builtin/branch.c:932 #, c-format msgid "No branch named '%s'." msgstr "Branch '%s' nicht vorhanden." -#: builtin/branch.c:941 +#: builtin/branch.c:947 msgid "too many branches for a rename operation" msgstr "zu viele Branches für eine Umbenennen-Operation angegeben" -#: builtin/branch.c:946 +#: builtin/branch.c:952 msgid "too many branches to set new upstream" msgstr "zu viele Branches angegeben um Upstream-Branch zu setzen" -#: builtin/branch.c:950 +#: builtin/branch.c:956 #, c-format msgid "" "could not set upstream of HEAD to %s when it does not point to any branch." @@ -3126,43 +3160,43 @@ msgstr "" "Konnte keinen neuen Upstream-Branch von HEAD zu %s setzen, da dieser auf\n" "keinen Branch zeigt." -#: builtin/branch.c:953 builtin/branch.c:975 builtin/branch.c:997 +#: builtin/branch.c:959 builtin/branch.c:981 builtin/branch.c:1002 #, c-format msgid "no such branch '%s'" msgstr "Kein solcher Branch '%s'" -#: builtin/branch.c:957 +#: builtin/branch.c:963 #, c-format msgid "branch '%s' does not exist" msgstr "Branch '%s' existiert nicht" -#: builtin/branch.c:969 +#: builtin/branch.c:975 msgid "too many branches to unset upstream" msgstr "" "zu viele Branches angegeben um Konfiguration zu Upstream-Branch zu entfernen" -#: builtin/branch.c:973 +#: builtin/branch.c:979 msgid "could not unset upstream of HEAD when it does not point to any branch." msgstr "" "Konnte Konfiguration zu Upstream-Branch von HEAD nicht entfernen, da dieser\n" "auf keinen Branch zeigt." -#: builtin/branch.c:979 +#: builtin/branch.c:985 #, c-format msgid "Branch '%s' has no upstream information" msgstr "Branch '%s' hat keinen Upstream-Branch gesetzt" -#: builtin/branch.c:994 +#: builtin/branch.c:999 msgid "it does not make sense to create 'HEAD' manually" msgstr "'HEAD' darf nicht manuell erstellt werden" -#: builtin/branch.c:1000 +#: builtin/branch.c:1005 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 " "Branchnamen verwendet werden." -#: builtin/branch.c:1003 +#: builtin/branch.c:1008 #, c-format msgid "" "The --set-upstream flag is deprecated and will be removed. Consider using --" @@ -3171,7 +3205,7 @@ msgstr "" "Die --set-upstream Option ist veraltet und wird entfernt. Benutzen Sie --" "track oder --set-upstream-to\n" -#: builtin/branch.c:1020 +#: builtin/branch.c:1025 #, c-format msgid "" "\n" @@ -3182,12 +3216,12 @@ msgstr "" "Wenn Sie wollten, dass '%s' den Branch '%s' als Upstream-Branch hat, führen " "Sie aus:\n" -#: builtin/branch.c:1021 +#: builtin/branch.c:1026 #, c-format msgid " git branch -d %s\n" msgstr " git branch -d %s\n" -#: builtin/branch.c:1022 +#: builtin/branch.c:1027 #, c-format msgid " git branch --set-upstream-to %s\n" msgstr " git branch --set-upstream-to %s\n" @@ -3205,45 +3239,45 @@ msgstr "Um ein Paket zu erstellen wird ein Repository benötigt." msgid "Need a repository to unbundle." msgstr "Zum Entpacken wird ein Repository benötigt." -#: builtin/cat-file.c:312 +#: builtin/cat-file.c:328 msgid "git cat-file (-t|-s|-e|-p||--textconv) " msgstr "git cat-file (-t|-s|-e|-p||--textconv) " -#: builtin/cat-file.c:313 +#: builtin/cat-file.c:329 msgid "git cat-file (--batch|--batch-check) < " msgstr "git cat-file (--batch|--batch-check) < " -#: builtin/cat-file.c:350 +#: builtin/cat-file.c:366 msgid " can be one of: blob, tree, commit, tag" msgstr " kann sein: blob, tree, commit, tag" -#: builtin/cat-file.c:351 +#: builtin/cat-file.c:367 msgid "show object type" msgstr "zeigt Objektart" -#: builtin/cat-file.c:352 +#: builtin/cat-file.c:368 msgid "show object size" msgstr "zeigt Objektgröße" -#: builtin/cat-file.c:354 +#: builtin/cat-file.c:370 msgid "exit with zero when there's no error" msgstr "beendet mit Rückgabewert 0, wenn kein Fehler aufgetreten ist" -#: builtin/cat-file.c:355 +#: builtin/cat-file.c:371 msgid "pretty-print object's content" msgstr "ansprechende Anzeige des Objektinhaltes" -#: builtin/cat-file.c:357 +#: builtin/cat-file.c:373 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:359 +#: builtin/cat-file.c:375 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:362 +#: builtin/cat-file.c:378 msgid "show info about objects fed from the standard input" msgstr "" "Anzeige von Informationen über Objekte, gelesen von der Standard-Eingabe" @@ -3273,7 +3307,7 @@ msgstr "liest Dateinamen von der Standard-Eingabe" msgid "terminate input and output records by a NUL character" msgstr "schließt Einträge von Ein- und Ausgabe mit NUL-Zeichen ab" -#: builtin/check-ignore.c:18 builtin/checkout.c:1090 builtin/gc.c:259 +#: builtin/check-ignore.c:18 builtin/checkout.c:1090 builtin/gc.c:260 msgid "suppress progress reporting" msgstr "unterdrückt Fortschrittsanzeige" @@ -3569,7 +3603,7 @@ msgid "Cannot switch branch to a non-commit '%s'" msgstr "Kann Branch nicht zu Nicht-Commit '%s' wechseln" #: builtin/checkout.c:1091 builtin/checkout.c:1093 builtin/clone.c:88 -#: builtin/remote.c:169 builtin/remote.c:171 +#: builtin/remote.c:159 builtin/remote.c:161 msgid "branch" msgstr "Branch" @@ -3617,11 +3651,11 @@ msgstr "erzwingt Auschecken (verwirft lokale Änderungen)" msgid "perform a 3-way merge with the new branch" msgstr "führt einen 3-Wege-Merge mit dem neuen Branch aus" -#: builtin/checkout.c:1106 builtin/merge.c:232 +#: builtin/checkout.c:1106 builtin/merge.c:225 msgid "update ignored files (default)" msgstr "aktualisiert ignorierte Dateien (Standard)" -#: builtin/checkout.c:1107 builtin/log.c:1228 parse-options.h:251 +#: builtin/checkout.c:1107 builtin/log.c:1228 parse-options.h:248 msgid "style" msgstr "Stil" @@ -3820,7 +3854,7 @@ msgid "remove whole directories" msgstr "löscht ganze Verzeichnisse" #: builtin/clean.c:880 builtin/describe.c:420 builtin/grep.c:718 -#: builtin/ls-files.c:483 builtin/name-rev.c:315 builtin/show-ref.c:185 +#: builtin/ls-files.c:483 builtin/name-rev.c:314 builtin/show-ref.c:185 msgid "pattern" msgstr "Muster" @@ -3860,8 +3894,8 @@ msgstr "" msgid "git clone [options] [--] []" msgstr "git clone [Optionen] [--] []" -#: builtin/clone.c:64 builtin/fetch.c:96 builtin/merge.c:229 -#: builtin/push.c:474 +#: builtin/clone.c:64 builtin/fetch.c:97 builtin/merge.c:222 +#: builtin/push.c:521 msgid "force progress reporting" msgstr "erzwingt Fortschrittsanzeige" @@ -3921,13 +3955,13 @@ msgstr "checkt aus, anstatt HEAD des Remote-Repositories" msgid "path to git-upload-pack on the remote" msgstr "Pfad zu \"git-upload-pack\" auf der Gegenseite" -#: builtin/clone.c:92 builtin/fetch.c:97 builtin/grep.c:663 +#: builtin/clone.c:92 builtin/fetch.c:98 builtin/grep.c:663 msgid "depth" msgstr "Tiefe" #: builtin/clone.c:93 msgid "create a shallow clone of that depth" -msgstr "erstellt einen flachen Klon mit dieser Tiefe" +msgstr "erstellt einen Klon mit unvollständiger Historie (shallow) in dieser Tiefe" #: builtin/clone.c:95 msgid "clone only one branch, HEAD or --branch" @@ -3954,42 +3988,52 @@ msgstr "setzt Konfiguration innerhalb des neuen Repositories" msgid "reference repository '%s' is not a local repository." msgstr "Referenziertes Repository '%s' ist kein lokales Repository." -#: builtin/clone.c:315 +#: builtin/clone.c:256 +#, c-format +msgid "reference repository '%s' is shallow" +msgstr "Referenziertes Repository '%s' hat eine unvollständige Historie (shallow)." + +#: builtin/clone.c:259 +#, c-format +msgid "reference repository '%s' is grafted" +msgstr "Referenziertes Repository '%s' ist mit künstlichen Vorgängern (\"grafts\") eingehängt." + +#: builtin/clone.c:321 #, c-format msgid "failed to create directory '%s'" msgstr "Fehler beim Erstellen von Verzeichnis '%s'" -#: builtin/clone.c:317 builtin/diff.c:77 +#: builtin/clone.c:323 builtin/diff.c:83 #, c-format msgid "failed to stat '%s'" msgstr "Konnte '%s' nicht lesen" -#: builtin/clone.c:319 +#: builtin/clone.c:325 #, c-format msgid "%s exists and is not a directory" msgstr "%s existiert und ist kein Verzeichnis" -#: builtin/clone.c:333 +#: builtin/clone.c:339 #, c-format msgid "failed to stat %s\n" msgstr "Konnte %s nicht lesen\n" -#: builtin/clone.c:355 +#: builtin/clone.c:361 #, c-format msgid "failed to create link '%s'" msgstr "Konnte Verweis '%s' nicht erstellen" -#: builtin/clone.c:359 +#: builtin/clone.c:365 #, c-format msgid "failed to copy file to '%s'" msgstr "Konnte Datei nicht nach '%s' kopieren" -#: builtin/clone.c:382 builtin/clone.c:559 +#: builtin/clone.c:388 builtin/clone.c:565 #, c-format msgid "done.\n" msgstr "Fertig.\n" -#: builtin/clone.c:395 +#: builtin/clone.c:401 msgid "" "Clone succeeded, but checkout failed.\n" "You can inspect what was checked out with 'git status'\n" @@ -3999,103 +4043,113 @@ 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:474 +#: builtin/clone.c:480 #, c-format msgid "Could not find remote branch %s to clone." msgstr "Konnte zu klonenden Remote-Branch %s nicht finden." -#: builtin/clone.c:554 +#: builtin/clone.c:560 #, c-format msgid "Checking connectivity... " msgstr "Prüfe Konnektivität... " -#: builtin/clone.c:557 +#: builtin/clone.c:563 msgid "remote did not send all necessary objects" msgstr "Remote-Repository hat nicht alle erforderlichen Objekte gesendet." -#: builtin/clone.c:620 +#: builtin/clone.c:626 msgid "remote HEAD refers to nonexistent ref, unable to checkout.\n" msgstr "" "Externer HEAD bezieht sich auf eine nicht existierende Referenz und kann " "nicht ausgecheckt werden.\n" -#: builtin/clone.c:651 +#: builtin/clone.c:657 msgid "unable to checkout working tree" msgstr "Arbeitsverzeichnis konnte nicht ausgecheckt werden" -#: builtin/clone.c:759 +#: builtin/clone.c:765 msgid "Too many arguments." msgstr "Zu viele Argumente." -#: builtin/clone.c:763 +#: builtin/clone.c:769 msgid "You must specify a repository to clone." msgstr "Sie müssen ein Repository zum Klonen angeben." -#: builtin/clone.c:774 +#: builtin/clone.c:780 #, c-format msgid "--bare and --origin %s options are incompatible." msgstr "Die Optionen --bare und --origin %s sind inkompatibel." -#: builtin/clone.c:777 +#: builtin/clone.c:783 msgid "--bare and --separate-git-dir are incompatible." msgstr "Die Optionen --bare und --separate-git-dir sind inkompatibel." -#: builtin/clone.c:790 +#: builtin/clone.c:796 #, c-format msgid "repository '%s' does not exist" msgstr "Repository '%s' existiert nicht." -#: builtin/clone.c:795 +#: builtin/clone.c:802 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:797 +#: builtin/clone.c:805 +msgid "source repository is shallow, ignoring --local" +msgstr "Quelle ist ein Repository mit unvollständiger Historie (shallow)," +"ignoriere --local" + +#: builtin/clone.c:810 msgid "--local is ignored" msgstr "--local wird ignoriert" -#: builtin/clone.c:807 +#: builtin/clone.c:814 builtin/fetch.c:1119 +#, c-format +msgid "depth %s is not a positive number" +msgstr "Tiefe %s ist keine positive Zahl" + +#: builtin/clone.c:824 #, 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:817 +#: builtin/clone.c:834 #, c-format msgid "working tree '%s' already exists." msgstr "Arbeitsverzeichnis '%s' existiert bereits." -#: builtin/clone.c:830 builtin/clone.c:842 +#: builtin/clone.c:847 builtin/clone.c:859 #, c-format msgid "could not create leading directories of '%s'" msgstr "Konnte führende Verzeichnisse von '%s' nicht erstellen." -#: builtin/clone.c:833 +#: builtin/clone.c:850 #, c-format msgid "could not create work tree dir '%s'." msgstr "Konnte Arbeitsverzeichnis '%s' nicht erstellen." -#: builtin/clone.c:852 +#: builtin/clone.c:869 #, c-format msgid "Cloning into bare repository '%s'...\n" msgstr "Klone in Bare-Repository '%s'...\n" -#: builtin/clone.c:854 +#: builtin/clone.c:871 #, c-format msgid "Cloning into '%s'...\n" msgstr "Klone nach '%s'...\n" -#: builtin/clone.c:888 +#: builtin/clone.c:906 #, c-format msgid "Don't know how to clone %s" msgstr "Weiß nicht wie %s zu klonen ist." -#: builtin/clone.c:939 builtin/clone.c:947 +#: builtin/clone.c:957 builtin/clone.c:965 #, c-format msgid "Remote branch %s not found in upstream %s" msgstr "Remote-Branch %s nicht im Upstream-Repository %s gefunden" -#: builtin/clone.c:950 +#: builtin/clone.c:968 msgid "You appear to have cloned an empty repository." msgstr "Sie scheinen ein leeres Repository geklont zu haben." @@ -4464,7 +4518,7 @@ msgstr "zeigt Status im Kurzformat" msgid "show branch information" msgstr "zeigt Branchinformationen" -#: builtin/commit.c:1255 builtin/commit.c:1486 builtin/push.c:460 +#: builtin/commit.c:1255 builtin/commit.c:1486 builtin/push.c:507 msgid "machine-readable output" msgstr "maschinenlesbare Ausgabe" @@ -4547,7 +4601,7 @@ msgstr "Autor" msgid "override author for commit" msgstr "überschreibt Autor eines Commits" -#: builtin/commit.c:1458 builtin/gc.c:260 +#: builtin/commit.c:1458 builtin/gc.c:261 msgid "date" msgstr "Datum" @@ -4555,7 +4609,7 @@ msgstr "Datum" msgid "override date for commit" msgstr "überschreibt Datum eines Commits" -#: builtin/commit.c:1459 builtin/merge.c:223 builtin/notes.c:405 +#: builtin/commit.c:1459 builtin/merge.c:216 builtin/notes.c:405 #: builtin/notes.c:562 builtin/tag.c:455 msgid "message" msgstr "Beschreibung" @@ -4613,11 +4667,11 @@ msgstr "" msgid "include status in commit message template" msgstr "fügt Status in die Commit-Beschreibungsvorlage ein" -#: builtin/commit.c:1470 builtin/merge.c:230 builtin/tag.c:461 +#: builtin/commit.c:1470 builtin/merge.c:223 builtin/tag.c:461 msgid "key id" msgstr "Schlüssel-ID" -#: builtin/commit.c:1471 builtin/merge.c:231 +#: builtin/commit.c:1471 builtin/merge.c:224 msgid "GPG sign commit" msgstr "signiert Commit mit GPG" @@ -4674,7 +4728,7 @@ msgstr "erlaubt Aufzeichnung einer Änderung mit einer leeren Beschreibung" msgid "could not parse HEAD commit" msgstr "Konnte Commit von HEAD nicht analysieren." -#: builtin/commit.c:1567 builtin/merge.c:525 +#: builtin/commit.c:1567 builtin/merge.c:518 #, c-format msgid "could not open '%s' for reading" msgstr "Konnte '%s' nicht zum Lesen öffnen." @@ -4693,29 +4747,29 @@ msgstr "Konnte MERGE_MODE nicht lesen" msgid "could not read commit message: %s" msgstr "Konnte Commit-Beschreibung nicht lesen: %s" -#: builtin/commit.c:1614 +#: builtin/commit.c:1611 #, c-format msgid "Aborting commit; you did not edit the message.\n" msgstr "Commit abgebrochen; Sie haben die Beschreibung nicht editiert.\n" -#: builtin/commit.c:1619 +#: builtin/commit.c:1616 #, c-format msgid "Aborting commit due to empty commit message.\n" msgstr "Commit aufgrund leerer Beschreibung abgebrochen.\n" -#: builtin/commit.c:1634 builtin/merge.c:861 builtin/merge.c:886 +#: builtin/commit.c:1631 builtin/merge.c:854 builtin/merge.c:879 msgid "failed to write commit object" msgstr "Fehler beim Schreiben des Commit-Objektes." -#: builtin/commit.c:1655 +#: builtin/commit.c:1652 msgid "cannot lock HEAD ref" msgstr "Kann Referenz von HEAD nicht sperren." -#: builtin/commit.c:1659 +#: builtin/commit.c:1656 msgid "cannot update HEAD ref" msgstr "Kann Referenz von HEAD nicht aktualisieren." -#: builtin/commit.c:1670 +#: builtin/commit.c:1667 msgid "" "Repository has been updated, but unable to write\n" "new_index file. Check that disk is not full or quota is\n" @@ -4978,7 +5032,7 @@ msgstr "betrachtet die jüngsten Tags (Standard: 10)" msgid "only consider tags matching " msgstr "betrachtet nur Tags die entsprechen" -#: builtin/describe.c:423 builtin/name-rev.c:322 +#: builtin/describe.c:423 builtin/name-rev.c:321 msgid "show abbreviated commit object as fallback" msgstr "zeigt gekürztes Commit-Objekt, wenn sonst nichts zutrifft" @@ -5004,31 +5058,31 @@ msgstr "Keine Namen gefunden, kann nichts beschreiben." msgid "--dirty is incompatible with commit-ishes" msgstr "Die Option --dirty kann nicht mit Commits verwendet werden." -#: builtin/diff.c:79 +#: builtin/diff.c:85 #, c-format msgid "'%s': not a regular file or symlink" msgstr "'%s': keine reguläre Datei oder symbolischer Verweis" -#: builtin/diff.c:230 +#: builtin/diff.c:236 #, c-format msgid "invalid option: %s" msgstr "Ungültige Option: %s" -#: builtin/diff.c:307 +#: builtin/diff.c:357 msgid "Not a git repository" msgstr "Kein Git-Repository" -#: builtin/diff.c:350 +#: builtin/diff.c:400 #, c-format msgid "invalid object '%s' given." msgstr "Objekt '%s' ist ungültig." -#: builtin/diff.c:359 +#: builtin/diff.c:409 #, c-format msgid "more than two blobs given: '%s'" msgstr "Mehr als zwei Blobs angegeben: '%s'" -#: builtin/diff.c:366 +#: builtin/diff.c:416 #, c-format msgid "unhandled object '%s' given." msgstr "unbehandeltes Objekt '%s' angegeben" @@ -5089,147 +5143,157 @@ msgstr "git fetch --multiple [] [( | )...]" msgid "git fetch --all []" msgstr "git fetch --all []" -#: builtin/fetch.c:74 +#: builtin/fetch.c:75 msgid "fetch from all remotes" msgstr "fordert von allen Remote-Repositories an" -#: builtin/fetch.c:76 +#: builtin/fetch.c:77 msgid "append to .git/FETCH_HEAD instead of overwriting" msgstr "hängt an .git/FETCH_HEAD an, anstatt zu überschreiben" -#: builtin/fetch.c:78 +#: builtin/fetch.c:79 msgid "path to upload pack on remote end" msgstr "Pfad des Programms zum Hochladen von Paketen auf der Gegenseite" -#: builtin/fetch.c:79 +#: builtin/fetch.c:80 msgid "force overwrite of local branch" msgstr "erzwingt das Überschreiben von lokalen Branches" -#: builtin/fetch.c:81 +#: builtin/fetch.c:82 msgid "fetch from multiple remotes" msgstr "fordert von mehreren Remote-Repositories an" -#: builtin/fetch.c:83 +#: builtin/fetch.c:84 msgid "fetch all tags and associated objects" msgstr "fordert alle Tags und verbundene Objekte an" -#: builtin/fetch.c:85 +#: builtin/fetch.c:86 msgid "do not fetch all tags (--no-tags)" msgstr "fordert nicht alle Tags an (--no-tags)" -#: builtin/fetch.c:87 +#: builtin/fetch.c:88 msgid "prune remote-tracking branches no longer on remote" msgstr "" "entfernt Remote-Tracking-Branches, die sich nicht mehr im Remote-Repository " "befinden" -#: builtin/fetch.c:88 +#: builtin/fetch.c:89 msgid "on-demand" msgstr "bei-Bedarf" -#: builtin/fetch.c:89 +#: builtin/fetch.c:90 msgid "control recursive fetching of submodules" msgstr "kontrolliert rekursive Anforderungen von Submodulen" -#: builtin/fetch.c:93 +#: builtin/fetch.c:94 msgid "keep downloaded pack" msgstr "behält heruntergeladenes Paket" -#: builtin/fetch.c:95 +#: builtin/fetch.c:96 msgid "allow updating of HEAD ref" msgstr "erlaubt Aktualisierung der \"HEAD\"-Referenz" -#: builtin/fetch.c:98 +#: builtin/fetch.c:99 msgid "deepen history of shallow clone" -msgstr "vertieft die Historie eines flachen Klons" +msgstr "vertieft die Historie eines Klons mit unvollständiger Historie (shallow)" -#: builtin/fetch.c:100 +#: builtin/fetch.c:101 msgid "convert to a complete repository" msgstr "konvertiert zu einem vollständigen Repository" -#: builtin/fetch.c:102 builtin/log.c:1197 +#: builtin/fetch.c:103 builtin/log.c:1197 msgid "dir" msgstr "Verzeichnis" -#: builtin/fetch.c:103 +#: builtin/fetch.c:104 msgid "prepend this to submodule path output" msgstr "stellt dies an die Ausgabe der Submodul-Pfade voran" -#: builtin/fetch.c:106 +#: builtin/fetch.c:107 msgid "default mode for recursion" msgstr "Standard-Modus für Rekursion" -#: builtin/fetch.c:236 +#: builtin/fetch.c:109 +msgid "accept refs that update .git/shallow" +msgstr "akzeptiert Referenzen die .git/shallow aktualisieren" + +#: builtin/fetch.c:347 msgid "Couldn't find remote ref HEAD" msgstr "Konnte Remote-Referenz von HEAD nicht finden." -#: builtin/fetch.c:290 +#: builtin/fetch.c:411 #, c-format msgid "object %s not found" msgstr "Objekt %s nicht gefunden" -#: builtin/fetch.c:295 +#: builtin/fetch.c:416 msgid "[up to date]" msgstr "[aktuell]" -#: builtin/fetch.c:309 +#: builtin/fetch.c:430 #, c-format msgid "! %-*s %-*s -> %s (can't fetch in current branch)" msgstr "" "! %-*s %-*s -> %s (kann \"fetch\" im aktuellen Branch nicht ausführen)" -#: builtin/fetch.c:310 builtin/fetch.c:396 +#: builtin/fetch.c:431 builtin/fetch.c:517 msgid "[rejected]" msgstr "[zurückgewiesen]" -#: builtin/fetch.c:321 +#: builtin/fetch.c:442 msgid "[tag update]" msgstr "[Tag Aktualisierung]" -#: builtin/fetch.c:323 builtin/fetch.c:358 builtin/fetch.c:376 +#: builtin/fetch.c:444 builtin/fetch.c:479 builtin/fetch.c:497 msgid " (unable to update local ref)" msgstr " (kann lokale Referenz nicht aktualisieren)" -#: builtin/fetch.c:341 +#: builtin/fetch.c:462 msgid "[new tag]" msgstr "[neues Tag]" -#: builtin/fetch.c:344 +#: builtin/fetch.c:465 msgid "[new branch]" msgstr "[neuer Branch]" -#: builtin/fetch.c:347 +#: builtin/fetch.c:468 msgid "[new ref]" msgstr "[neue Referenz]" -#: builtin/fetch.c:392 +#: builtin/fetch.c:513 msgid "unable to update local ref" msgstr "kann lokale Referenz nicht aktualisieren" -#: builtin/fetch.c:392 +#: builtin/fetch.c:513 msgid "forced update" msgstr "Aktualisierung erzwungen" -#: builtin/fetch.c:398 +#: builtin/fetch.c:519 msgid "(non-fast-forward)" msgstr "(kein Vorspulen)" -#: builtin/fetch.c:429 builtin/fetch.c:735 +#: builtin/fetch.c:552 builtin/fetch.c:785 #, c-format msgid "cannot open %s: %s\n" msgstr "kann %s nicht öffnen: %s\n" -#: builtin/fetch.c:438 +#: builtin/fetch.c:561 #, c-format msgid "%s did not send all necessary objects\n" msgstr "%s hat nicht alle erforderlichen Objekte gesendet\n" -#: builtin/fetch.c:537 +#: builtin/fetch.c:579 +#, c-format +msgid "reject %s because shallow roots are not allowed to be updated" +msgstr "%s wurde zurückgewiesen, da Ursprungs-Commits von Repositories" +"mit unvollständiger Historie (shallow) nicht aktualisiert werden dürfen." + +#: builtin/fetch.c:667 builtin/fetch.c:750 #, c-format msgid "From %.*s\n" msgstr "Von %.*s\n" -#: builtin/fetch.c:548 +#: builtin/fetch.c:678 #, c-format msgid "" "some local refs could not be updated; try running\n" @@ -5238,57 +5302,57 @@ msgstr "" "Einige lokale Referenzen konnten nicht aktualisiert werden; versuchen Sie\n" "'git remote prune %s' um jeden älteren, widersprüchlichen Branch zu löschen." -#: builtin/fetch.c:598 +#: builtin/fetch.c:730 #, c-format msgid " (%s will become dangling)" msgstr " (%s wird unreferenziert)" -#: builtin/fetch.c:599 +#: builtin/fetch.c:731 #, c-format msgid " (%s has become dangling)" msgstr " (%s wurde unreferenziert)" -#: builtin/fetch.c:606 +#: builtin/fetch.c:755 msgid "[deleted]" msgstr "[gelöscht]" -#: builtin/fetch.c:607 builtin/remote.c:1055 +#: builtin/fetch.c:756 builtin/remote.c:1050 msgid "(none)" msgstr "(nichts)" -#: builtin/fetch.c:725 +#: builtin/fetch.c:775 #, c-format msgid "Refusing to fetch into current branch %s of non-bare repository" msgstr "" "Der \"fetch\" in den aktuellen Branch %s von einem nicht-Bare-Repository " "wurde verweigert." -#: builtin/fetch.c:744 +#: builtin/fetch.c:794 #, 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:747 +#: builtin/fetch.c:797 #, c-format msgid "Option \"%s\" is ignored for %s\n" msgstr "Option \"%s\" wird ignoriert für %s\n" -#: builtin/fetch.c:801 +#: builtin/fetch.c:853 #, c-format msgid "Don't know how to fetch from %s" msgstr "Weiß nicht wie von %s angefordert wird." -#: builtin/fetch.c:976 +#: builtin/fetch.c:1015 #, c-format msgid "Fetching %s\n" msgstr "Fordere an von %s\n" -#: builtin/fetch.c:978 builtin/remote.c:100 +#: builtin/fetch.c:1017 builtin/remote.c:90 #, c-format msgid "Could not fetch %s" msgstr "Konnte nicht von %s anfordern" -#: builtin/fetch.c:997 +#: builtin/fetch.c:1036 msgid "" "No remote repository specified. Please, specify either a URL or a\n" "remote name from which new revisions should be fetched." @@ -5297,35 +5361,35 @@ msgstr "" "oder den Namen des Remote-Repositories an, von welchem neue\n" "Commits angefordert werden sollen." -#: builtin/fetch.c:1020 +#: builtin/fetch.c:1059 msgid "You need to specify a tag name." msgstr "Sie müssen den Namen des Tags angeben." -#: builtin/fetch.c:1068 +#: builtin/fetch.c:1107 msgid "--depth and --unshallow cannot be used together" msgstr "" "Die Optionen --depth und --unshallow können nicht gemeinsam verwendet werden." -#: builtin/fetch.c:1070 +#: builtin/fetch.c:1109 msgid "--unshallow on a complete repository does not make sense" msgstr "" -"Die Option --unshallow kann nicht in einem vollständigen Repository " +"Die Option --unshallow kann nicht in einem Repository mit unvollständiger Historie " "verwendet werden." -#: builtin/fetch.c:1089 +#: builtin/fetch.c:1132 msgid "fetch --all does not take a repository argument" msgstr "fetch --all akzeptiert kein Repository als Argument" -#: builtin/fetch.c:1091 +#: builtin/fetch.c:1134 msgid "fetch --all does not make sense with refspecs" msgstr "fetch --all kann nicht mit Refspecs verwendet werden." -#: builtin/fetch.c:1102 +#: builtin/fetch.c:1145 #, c-format msgid "No such remote or remote group: %s" msgstr "Kein Remote-Repository (einzeln oder Gruppe): %s" -#: builtin/fetch.c:1110 +#: builtin/fetch.c:1153 msgid "Fetching a group and specifying refspecs does not make sense" msgstr "" "Das Abholen einer Gruppe von Remote-Repositories kann nicht mit der Angabe\n" @@ -5337,8 +5401,9 @@ 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:702 -#: builtin/merge.c:203 builtin/show-branch.c:655 builtin/show-ref.c:178 -#: builtin/tag.c:446 parse-options.h:135 parse-options.h:245 +#: builtin/merge.c:196 builtin/repack.c:160 builtin/repack.c:164 +#: builtin/show-branch.c:654 builtin/show-ref.c:178 builtin/tag.c:446 +#: parse-options.h:135 parse-options.h:242 msgid "n" msgstr "Anzahl" @@ -5362,43 +5427,43 @@ msgstr "verwendet als Beschreibungsanfang" msgid "file to read from" msgstr "Datei zum Einlesen" -#: builtin/for-each-ref.c:995 +#: builtin/for-each-ref.c:1063 msgid "git for-each-ref [options] []" msgstr "git for-each-ref [Optionen] []" -#: builtin/for-each-ref.c:1010 +#: builtin/for-each-ref.c:1078 msgid "quote placeholders suitably for shells" msgstr "formatiert Platzhalter als Shell-String" -#: builtin/for-each-ref.c:1012 +#: builtin/for-each-ref.c:1080 msgid "quote placeholders suitably for perl" msgstr "formatiert Platzhalter als Perl-String" -#: builtin/for-each-ref.c:1014 +#: builtin/for-each-ref.c:1082 msgid "quote placeholders suitably for python" msgstr "formatiert Platzhalter als Python-String" -#: builtin/for-each-ref.c:1016 +#: builtin/for-each-ref.c:1084 msgid "quote placeholders suitably for tcl" msgstr "formatiert Platzhalter als TCL-String" -#: builtin/for-each-ref.c:1019 +#: builtin/for-each-ref.c:1087 msgid "show only matched refs" msgstr "zeigt nur passende Referenzen" -#: builtin/for-each-ref.c:1020 +#: builtin/for-each-ref.c:1088 builtin/replace.c:177 msgid "format" msgstr "Format" -#: builtin/for-each-ref.c:1020 +#: builtin/for-each-ref.c:1088 msgid "format to use for the output" msgstr "für die Ausgabe zu verwendendes Format" -#: builtin/for-each-ref.c:1021 +#: builtin/for-each-ref.c:1089 msgid "key" msgstr "Schüssel" -#: builtin/for-each-ref.c:1022 +#: builtin/for-each-ref.c:1090 msgid "field name to sort on" msgstr "sortiere nach diesem Feld" @@ -5442,42 +5507,43 @@ msgstr "aktiviert genauere Prüfung" msgid "write dangling objects in .git/lost-found" msgstr "schreibt unreferenzierte Objekte nach .git/lost-found" -#: builtin/fsck.c:623 builtin/prune.c:134 +#: builtin/fsck.c:623 builtin/prune.c:144 msgid "show progress" msgstr "zeigt Fortschrittsanzeige" -#: builtin/gc.c:23 +#: builtin/gc.c:24 msgid "git gc [options]" msgstr "git gc [Optionen]" -#: builtin/gc.c:79 +#: builtin/gc.c:80 #, c-format msgid "Invalid %s: '%s'" msgstr "Ungültiger %s: '%s'" -#: builtin/gc.c:106 +#: builtin/gc.c:107 #, c-format msgid "insanely long object directory %.*s" msgstr "zu langes Objekt-Verzeichnis %.*s" -#: builtin/gc.c:261 +#: builtin/gc.c:262 msgid "prune unreferenced objects" msgstr "entfernt unreferenzierte Objekte" -#: builtin/gc.c:263 +#: builtin/gc.c:264 msgid "be more thorough (increased runtime)" msgstr "mehr Gründlichkeit (erhöht Laufzeit)" -#: builtin/gc.c:264 +#: builtin/gc.c:265 msgid "enable auto-gc mode" msgstr "aktiviert \"auto-gc\" Modus" -#: builtin/gc.c:265 +#: builtin/gc.c:266 msgid "force running gc even if there may be another gc running" -msgstr "erzwingt Ausführung von \"git gc\" selbst wenn ein anderes\n" +msgstr "" +"erzwingt Ausführung von \"git gc\" selbst wenn ein anderes\n" "\"git gc\" bereits ausgeführt wird" -#: builtin/gc.c:305 +#: builtin/gc.c:306 #, c-format msgid "" "Auto packing the repository for optimum performance. You may also\n" @@ -5488,7 +5554,7 @@ msgstr "" "Siehe \"git help gc\" für weitere Informationen.\n" #. be quiet on --auto -#: builtin/gc.c:315 +#: builtin/gc.c:316 #, c-format msgid "" "gc is already running on machine '%s' pid % (use --force if not)" @@ -5496,7 +5562,7 @@ msgstr "" "\"git gc\" wird bereits auf Maschine '%s' pid % ausgeführt\n" "(benutzen Sie --force falls nicht)" -#: builtin/gc.c:340 +#: builtin/gc.c:341 msgid "" "There are too many unreachable loose objects; run 'git prune' to remove them." msgstr "" @@ -5845,57 +5911,57 @@ msgstr "" "'%s': Kommando für unterstützten Handbuchbetrachter.\n" "Sie könnten stattdessen 'man..path' benutzen." -#: builtin/help.c:349 +#: builtin/help.c:353 #, c-format msgid "'%s': unknown man viewer." msgstr "'%s': unbekannter Handbuch-Betrachter." -#: builtin/help.c:366 +#: builtin/help.c:370 msgid "no man viewer handled the request" msgstr "kein Handbuch-Betrachter konnte mit dieser Anfrage umgehen" -#: builtin/help.c:374 +#: builtin/help.c:378 msgid "no info viewer handled the request" msgstr "kein Informations-Betrachter konnte mit dieser Anfrage umgehen" -#: builtin/help.c:420 +#: builtin/help.c:424 msgid "Defining attributes per path" msgstr "Definition von Attributen pro Pfad" -#: builtin/help.c:421 +#: builtin/help.c:425 msgid "A Git glossary" msgstr "Ein Git-Glossar" -#: builtin/help.c:422 +#: builtin/help.c:426 msgid "Specifies intentionally untracked files to ignore" msgstr "Spezifikation von bewusst ignorierten, unbeobachteten Dateien" -#: builtin/help.c:423 +#: builtin/help.c:427 msgid "Defining submodule properties" msgstr "Definition von Submodul-Eigenschaften" -#: builtin/help.c:424 +#: builtin/help.c:428 msgid "Specifying revisions and ranges for Git" msgstr "Spezifikation von Commits und Bereichen für Git" -#: builtin/help.c:425 +#: builtin/help.c:429 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:426 +#: builtin/help.c:430 msgid "An overview of recommended workflows with Git" msgstr "Eine Übersicht über empfohlene Arbeitsabläufe mit Git" -#: builtin/help.c:438 +#: builtin/help.c:442 msgid "The common Git guides are:\n" msgstr "Die allgemein verwendeten Git-Anleitungen sind:\n" -#: builtin/help.c:460 builtin/help.c:476 +#: builtin/help.c:463 builtin/help.c:480 #, c-format msgid "usage: %s%s" msgstr "Verwendung: %s%s" -#: builtin/help.c:492 +#: builtin/help.c:496 #, c-format msgid "`git %s' is aliased to `%s'" msgstr "für `git %s' wurde der Alias `%s' angelegt" @@ -6305,21 +6371,21 @@ msgstr "Berechtigungen" msgid "specify that the git repository is to be shared amongst several users" msgstr "gibt an, dass das Git-Repository mit mehreren Benutzern geteilt wird" -#: builtin/init-db.c:493 builtin/prune-packed.c:75 builtin/repack.c:155 +#: builtin/init-db.c:493 builtin/prune-packed.c:79 builtin/repack.c:155 msgid "be quiet" msgstr "weniger Ausgaben" -#: builtin/init-db.c:522 builtin/init-db.c:529 +#: builtin/init-db.c:525 builtin/init-db.c:530 #, c-format msgid "cannot mkdir %s" msgstr "kann Verzeichnis %s nicht erstellen" -#: builtin/init-db.c:533 +#: builtin/init-db.c:534 #, c-format msgid "cannot chdir to %s" msgstr "kann nicht in Verzeichnis %s wechseln" -#: builtin/init-db.c:555 +#: builtin/init-db.c:556 #, c-format msgid "" "%s (or --work-tree=) not allowed without specifying %s (or --git-" @@ -6328,11 +6394,11 @@ msgstr "" "%s (oder --work-tree=) nicht erlaubt ohne Spezifizierung von %s " "(oder --git-dir=)" -#: builtin/init-db.c:579 +#: builtin/init-db.c:580 msgid "Cannot access current working directory" msgstr "Kann nicht auf aktuelles Arbeitsverzeichnis zugreifen." -#: builtin/init-db.c:586 +#: builtin/init-db.c:587 #, c-format msgid "Cannot access work tree '%s'" msgstr "Kann nicht auf Arbeitsverzeichnis '%s' zugreifen." @@ -6768,153 +6834,153 @@ msgstr "Verfügbare Strategien sind:" msgid "Available custom strategies are:" msgstr "Verfügbare benutzerdefinierte Strategien sind:" -#: builtin/merge.c:198 +#: builtin/merge.c:191 msgid "do not show a diffstat at the end of the merge" msgstr "zeigt keine Zusammenfassung der Unterschiede am Schluss des Merges an" -#: builtin/merge.c:201 +#: builtin/merge.c:194 msgid "show a diffstat at the end of the merge" msgstr "zeigt eine Zusammenfassung der Unterschiede am Schluss des Merges an" -#: builtin/merge.c:202 +#: builtin/merge.c:195 msgid "(synonym to --stat)" msgstr "(Synonym für --stat)" -#: builtin/merge.c:204 +#: builtin/merge.c:197 msgid "add (at most ) entries from shortlog to merge commit message" msgstr "" "fügt (höchstens ) Einträge von \"shortlog\" zur Beschreibung des Merge-" "Commits hinzu" -#: builtin/merge.c:207 +#: builtin/merge.c:200 msgid "create a single commit instead of doing a merge" msgstr "erzeugt einen einzelnen Commit anstatt eines Merges" -#: builtin/merge.c:209 +#: builtin/merge.c:202 msgid "perform a commit if the merge succeeds (default)" msgstr "führt einen Commit durch, wenn der Merge erfolgreich war (Standard)" -#: builtin/merge.c:211 +#: builtin/merge.c:204 msgid "edit message before committing" msgstr "Bearbeitung der Beschreibung vor dem Commit" -#: builtin/merge.c:212 +#: builtin/merge.c:205 msgid "allow fast-forward (default)" msgstr "erlaubt Vorspulen (Standard)" -#: builtin/merge.c:214 +#: builtin/merge.c:207 msgid "abort if fast-forward is not possible" msgstr "bricht ab, wenn kein Vorspulen möglich ist" -#: builtin/merge.c:218 +#: builtin/merge.c:211 msgid "Verify that the named commit has a valid GPG signature" msgstr "überprüft den genannten Commit auf eine gültige GPG-Signatur" -#: builtin/merge.c:219 builtin/notes.c:738 builtin/revert.c:89 +#: builtin/merge.c:212 builtin/notes.c:738 builtin/revert.c:89 msgid "strategy" msgstr "Strategie" -#: builtin/merge.c:220 +#: builtin/merge.c:213 msgid "merge strategy to use" msgstr "zu verwendende Merge-Strategie" -#: builtin/merge.c:221 +#: builtin/merge.c:214 msgid "option=value" msgstr "Option=Wert" -#: builtin/merge.c:222 +#: builtin/merge.c:215 msgid "option for selected merge strategy" msgstr "Option für ausgewählte Merge-Strategie" -#: builtin/merge.c:224 +#: builtin/merge.c:217 msgid "merge commit message (for a non-fast-forward merge)" msgstr "" "führt Commit-Beschreibung zusammen (für einen Merge, der kein Vorspulen war)" -#: builtin/merge.c:228 +#: builtin/merge.c:221 msgid "abort the current in-progress merge" msgstr "bricht den sich im Gange befindlichen Merge ab" -#: builtin/merge.c:257 +#: builtin/merge.c:250 msgid "could not run stash." msgstr "Konnte \"stash\" nicht ausführen." -#: builtin/merge.c:262 +#: builtin/merge.c:255 msgid "stash failed" msgstr "\"stash\" fehlgeschlagen" -#: builtin/merge.c:267 +#: builtin/merge.c:260 #, c-format msgid "not a valid object: %s" msgstr "kein gültiges Objekt: %s" -#: builtin/merge.c:286 builtin/merge.c:303 +#: builtin/merge.c:279 builtin/merge.c:296 msgid "read-tree failed" msgstr "read-tree fehlgeschlagen" -#: builtin/merge.c:333 +#: builtin/merge.c:326 msgid " (nothing to squash)" msgstr " (nichts zu quetschen)" -#: builtin/merge.c:346 +#: builtin/merge.c:339 #, c-format msgid "Squash commit -- not updating HEAD\n" msgstr "Quetsche Commit -- HEAD wird nicht aktualisiert\n" -#: builtin/merge.c:378 +#: builtin/merge.c:371 msgid "Writing SQUASH_MSG" msgstr "Schreibe SQUASH_MSG" -#: builtin/merge.c:380 +#: builtin/merge.c:373 msgid "Finishing SQUASH_MSG" msgstr "Schließe SQUASH_MSG ab" -#: builtin/merge.c:403 +#: builtin/merge.c:396 #, c-format msgid "No merge message -- not updating HEAD\n" msgstr "Keine Merge-Commit-Beschreibung -- HEAD wird nicht aktualisiert\n" -#: builtin/merge.c:453 +#: builtin/merge.c:446 #, c-format msgid "'%s' does not point to a commit" msgstr "'%s' zeigt auf keinen Commit" -#: builtin/merge.c:565 +#: builtin/merge.c:558 #, c-format msgid "Bad branch.%s.mergeoptions string: %s" msgstr "Ungültiger branch.%s.mergeoptions String: %s" -#: builtin/merge.c:657 +#: builtin/merge.c:650 msgid "git write-tree failed to write a tree" msgstr "\"git write-tree\" schlug beim Schreiben eines \"Tree\"-Objektes fehl" -#: builtin/merge.c:685 +#: builtin/merge.c:678 msgid "Not handling anything other than two heads merge." msgstr "Es wird nur der Merge von zwei Branches behandelt." -#: builtin/merge.c:699 +#: builtin/merge.c:692 #, c-format msgid "Unknown option for merge-recursive: -X%s" msgstr "Unbekannte Option für merge-recursive: -X%s" -#: builtin/merge.c:713 +#: builtin/merge.c:706 #, c-format msgid "unable to write %s" msgstr "konnte %s nicht schreiben" -#: builtin/merge.c:802 +#: builtin/merge.c:795 #, c-format msgid "Could not read from '%s'" msgstr "konnte nicht von '%s' lesen" -#: builtin/merge.c:811 +#: builtin/merge.c:804 #, c-format msgid "Not committing merge; use 'git commit' to complete the merge.\n" msgstr "" "Merge wurde nicht committet; benutzen Sie 'git commit' um den Merge " "abzuschließen.\n" -#: builtin/merge.c:817 +#: builtin/merge.c:810 #, c-format msgid "" "Please enter a commit message to explain why this merge is necessary,\n" @@ -6930,50 +6996,50 @@ msgstr "" "Zeilen beginnend mit '%c' werden ignoriert, und eine leere Beschreibung\n" "bricht den Commit ab.\n" -#: builtin/merge.c:841 +#: builtin/merge.c:834 msgid "Empty commit message." msgstr "Leere Commit-Beschreibung" -#: builtin/merge.c:853 +#: builtin/merge.c:846 #, c-format msgid "Wonderful.\n" msgstr "Wunderbar.\n" -#: builtin/merge.c:918 +#: builtin/merge.c:911 #, c-format msgid "Automatic merge failed; fix conflicts and then commit the result.\n" msgstr "" "Automatischer Merge fehlgeschlagen; beheben Sie die Konflikte und committen " "Sie dann das Ergebnis.\n" -#: builtin/merge.c:934 +#: builtin/merge.c:927 #, c-format msgid "'%s' is not a commit" msgstr "'%s' ist kein Commit" -#: builtin/merge.c:975 +#: builtin/merge.c:968 msgid "No current branch." msgstr "Sie befinden sich auf keinem Branch." -#: builtin/merge.c:977 +#: builtin/merge.c:970 msgid "No remote for the current branch." msgstr "Kein Remote-Repository für den aktuellen Branch." -#: builtin/merge.c:979 +#: builtin/merge.c:972 msgid "No default upstream defined for the current branch." msgstr "" "Es ist kein Standard-Upstream-Branch für den aktuellen Branch definiert." -#: builtin/merge.c:984 +#: builtin/merge.c:977 #, c-format msgid "No remote-tracking branch for %s from %s" msgstr "Kein Remote-Tracking-Branch für %s von %s" -#: builtin/merge.c:1140 +#: builtin/merge.c:1133 msgid "There is no merge to abort (MERGE_HEAD missing)." msgstr "Es gibt keinen Merge zum Abbrechen (vermisse MERGE_HEAD)" -#: builtin/merge.c:1156 git-pull.sh:31 +#: builtin/merge.c:1149 git-pull.sh:31 msgid "" "You have not concluded your merge (MERGE_HEAD exists).\n" "Please, commit your changes before you can merge." @@ -6981,11 +7047,11 @@ msgstr "" "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:1159 git-pull.sh:34 +#: builtin/merge.c:1152 git-pull.sh:34 msgid "You have not concluded your merge (MERGE_HEAD exists)." msgstr "Sie haben Ihren Merge nicht abgeschlossen (MERGE_HEAD existiert)." -#: builtin/merge.c:1163 +#: builtin/merge.c:1156 msgid "" "You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists).\n" "Please, commit your changes before you can merge." @@ -6993,143 +7059,151 @@ msgstr "" "Sie haben \"cherry-pick\" nicht abgeschlossen (CHERRY_PICK_HEAD existiert).\n" "Bitte committen Sie Ihre Änderungen, bevor Sie \"merge\" ausführen können." -#: builtin/merge.c:1166 +#: builtin/merge.c:1159 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:1175 +#: builtin/merge.c:1168 msgid "You cannot combine --squash with --no-ff." msgstr "Sie können --squash nicht mit --no-ff kombinieren." -#: builtin/merge.c:1184 +#: builtin/merge.c:1177 msgid "No commit specified and merge.defaultToUpstream not set." msgstr "Kein Commit angegeben und merge.defaultToUpstream ist nicht gesetzt." -#: builtin/merge.c:1216 +#: builtin/merge.c:1209 msgid "Can merge only exactly one commit into empty head" msgstr "Kann nur exakt einen Commit in einem leeren Branch zusammenführen." -#: builtin/merge.c:1219 +#: builtin/merge.c:1212 msgid "Squash commit into empty head not supported yet" msgstr "" "Bin auf einem Commit, der noch geboren wird; kann \"squash\" nicht ausführen." -#: builtin/merge.c:1221 +#: builtin/merge.c:1214 msgid "Non-fast-forward commit does not make sense into an empty head" msgstr "" "Nicht vorzuspulender Commit kann nicht in einem leeren Branch verwendet " "werden." -#: builtin/merge.c:1226 +#: builtin/merge.c:1219 #, c-format msgid "%s - not something we can merge" msgstr "%s - nichts was wir zusammenführen können" -#: builtin/merge.c:1277 +#: builtin/merge.c:1270 #, c-format msgid "Commit %s has an untrusted GPG signature, allegedly by %s." msgstr "" "Commit %s hat eine nicht vertrauenswürdige GPG-Signatur, angeblich von %s." -#: builtin/merge.c:1280 +#: builtin/merge.c:1273 #, c-format msgid "Commit %s has a bad GPG signature allegedly by %s." msgstr "Commit %s hat eine ungültige GPG-Signatur, angeblich von %s." #. 'N' -#: builtin/merge.c:1283 +#: builtin/merge.c:1276 #, c-format msgid "Commit %s does not have a GPG signature." msgstr "Commit %s hat keine GPG-Signatur." -#: builtin/merge.c:1286 +#: builtin/merge.c:1279 #, c-format msgid "Commit %s has a good GPG signature by %s\n" msgstr "Commit %s hat eine gültige GPG-Signatur von %s\n" -#: builtin/merge.c:1370 +#: builtin/merge.c:1363 #, c-format msgid "Updating %s..%s\n" msgstr "Aktualisiere %s..%s\n" -#: builtin/merge.c:1409 +#: builtin/merge.c:1402 #, c-format msgid "Trying really trivial in-index merge...\n" msgstr "Probiere wirklich trivialen \"in-index\"-Merge...\n" -#: builtin/merge.c:1416 +#: builtin/merge.c:1409 #, c-format msgid "Nope.\n" msgstr "Nein.\n" -#: builtin/merge.c:1448 +#: builtin/merge.c:1441 msgid "Not possible to fast-forward, aborting." msgstr "Vorspulen nicht möglich, breche ab." -#: builtin/merge.c:1471 builtin/merge.c:1550 +#: builtin/merge.c:1464 builtin/merge.c:1543 #, c-format msgid "Rewinding the tree to pristine...\n" msgstr "Rücklauf des Verzeichnisses bis zum Ursprung...\n" -#: builtin/merge.c:1475 +#: builtin/merge.c:1468 #, c-format msgid "Trying merge strategy %s...\n" msgstr "Probiere Merge-Strategie %s...\n" -#: builtin/merge.c:1541 +#: builtin/merge.c:1534 #, c-format msgid "No merge strategy handled the merge.\n" msgstr "Keine Merge-Strategie behandelt diesen Merge.\n" -#: builtin/merge.c:1543 +#: builtin/merge.c:1536 #, c-format msgid "Merge with strategy %s failed.\n" msgstr "Merge mit Strategie %s fehlgeschlagen.\n" -#: builtin/merge.c:1552 +#: builtin/merge.c:1545 #, 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:1564 +#: builtin/merge.c:1557 #, c-format msgid "Automatic merge went well; stopped before committing as requested\n" msgstr "" "Automatischer Merge abgeschlossen; halte, wie gewünscht, vor dem Commit an\n" -#: builtin/merge-base.c:26 +#: builtin/merge-base.c:29 msgid "git merge-base [-a|--all] ..." msgstr "git merge-base [-a|--all] ..." -#: builtin/merge-base.c:27 +#: builtin/merge-base.c:30 msgid "git merge-base [-a|--all] --octopus ..." msgstr "git merge-base [-a|--all] --octopus ..." -#: builtin/merge-base.c:28 +#: builtin/merge-base.c:31 msgid "git merge-base --independent ..." msgstr "git merge-base --independent ..." -#: builtin/merge-base.c:29 +#: builtin/merge-base.c:32 msgid "git merge-base --is-ancestor " msgstr "git merge-base --is-ancestor " -#: builtin/merge-base.c:98 +#: builtin/merge-base.c:33 +msgid "git merge-base --fork-point []" +msgstr "git merge-base --fork-point []" + +#: builtin/merge-base.c:214 msgid "output all common ancestors" msgstr "Ausgabe aller gemeinsamen Vorgänger-Commits" -#: builtin/merge-base.c:99 +#: builtin/merge-base.c:216 msgid "find ancestors for a single n-way merge" msgstr "findet Vorgänger-Commits für einen einzelnen n-Wege-Merge" -#: builtin/merge-base.c:100 +#: builtin/merge-base.c:218 msgid "list revs not reachable from others" msgstr "listet Commits auf, die nicht durch Andere erreichbar sind" -#: builtin/merge-base.c:102 +#: builtin/merge-base.c:220 msgid "is the first one ancestor of the other?" msgstr "ist der Erste ein Vorgänger-Commit von dem Anderen?" +#: builtin/merge-base.c:222 +msgid "find where forked from reflog of " +msgstr "findet wo von Reflog von abgespalten wurde" + #: builtin/merge-file.c:8 msgid "" "git merge-file [options] [-L name1 [-L orig [-L name2]]] file1 orig_file " @@ -7190,124 +7264,129 @@ msgstr "erlaubt die Erstellung von mehr als einem \"Tree\"-Objekt" msgid "git mv [options] ... " msgstr "git mv [Optionen] ... " -#: builtin/mv.c:67 +#: builtin/mv.c:71 msgid "force move/rename even if target exists" msgstr "erzwingt Verschieben/Umbenennen, auch wenn das Ziel existiert" -#: builtin/mv.c:68 +#: builtin/mv.c:72 msgid "skip move/rename errors" msgstr "überspringt Fehler beim Verschieben oder Umbenennen" -#: builtin/mv.c:113 +#: builtin/mv.c:122 #, c-format msgid "Checking rename of '%s' to '%s'\n" msgstr "Prüfe Umbenennung von '%s' nach '%s'\n" -#: builtin/mv.c:117 +#: builtin/mv.c:126 msgid "bad source" msgstr "ungültige Quelle" -#: builtin/mv.c:120 +#: builtin/mv.c:129 msgid "can not move directory into itself" msgstr "kann Verzeichnis nicht in sich selbst verschieben" -#: builtin/mv.c:123 +#: builtin/mv.c:132 msgid "cannot move directory over file" msgstr "kann Verzeichnis nicht über Datei verschieben" -#: builtin/mv.c:129 +#: builtin/mv.c:138 #, c-format msgid "Huh? Directory %s is in index and no submodule?" msgstr "Huh? Verzeichnis %s ist zum Commit vorgemerkt und kein Submodul?" -#: builtin/mv.c:131 builtin/rm.c:318 +#: builtin/mv.c:140 builtin/rm.c:318 msgid "Please, stage your changes to .gitmodules or stash them to proceed" msgstr "" -"Bitte merken Sie Ihre Änderungen in .gitmodules zum Commit vor oder benutzen\n" +"Bitte merken Sie Ihre Änderungen in .gitmodules zum Commit vor oder " +"benutzen\n" "Sie \"stash\" um fortzufahren." -#: builtin/mv.c:147 +#: builtin/mv.c:156 #, c-format msgid "Huh? %.*s is in index?" msgstr "Huh? %.*s ist zum Commit vorgemerkt?" -#: builtin/mv.c:159 +#: builtin/mv.c:168 msgid "source directory is empty" msgstr "Quellverzeichnis ist leer" -#: builtin/mv.c:191 +#: builtin/mv.c:200 msgid "not under version control" msgstr "nicht unter Versionskontrolle" -#: builtin/mv.c:193 +#: builtin/mv.c:202 msgid "destination exists" msgstr "Ziel existiert bereits" -#: builtin/mv.c:201 +#: builtin/mv.c:210 #, c-format msgid "overwriting '%s'" msgstr "überschreibe '%s'" -#: builtin/mv.c:204 +#: builtin/mv.c:213 msgid "Cannot overwrite" msgstr "Kann nicht überschreiben" -#: builtin/mv.c:207 +#: builtin/mv.c:216 msgid "multiple sources for the same target" msgstr "mehrere Quellen für das selbe Ziel" -#: builtin/mv.c:222 +#: builtin/mv.c:218 +msgid "destination directory does not exist" +msgstr "Zielverzeichnis existiert nicht" + +#: builtin/mv.c:233 #, c-format msgid "%s, source=%s, destination=%s" msgstr "%s, Quelle=%s, Ziel=%s" -#: builtin/mv.c:232 +#: builtin/mv.c:243 #, c-format msgid "Renaming %s to %s\n" msgstr "Benenne %s nach %s um\n" -#: builtin/mv.c:235 builtin/remote.c:731 builtin/repack.c:330 +#: builtin/mv.c:246 builtin/remote.c:726 builtin/repack.c:328 #, c-format msgid "renaming '%s' failed" msgstr "Umbenennung von '%s' fehlgeschlagen" -#: builtin/name-rev.c:259 +#: builtin/name-rev.c:258 msgid "git name-rev [options] ..." msgstr "git name-rev [Optionen] ..." -#: builtin/name-rev.c:260 +#: builtin/name-rev.c:259 msgid "git name-rev [options] --all" msgstr "git name-rev [Optionen] --all" -#: builtin/name-rev.c:261 +#: builtin/name-rev.c:260 msgid "git name-rev [options] --stdin" msgstr "git name-rev [Optionen] --stdin" -#: builtin/name-rev.c:313 +#: builtin/name-rev.c:312 msgid "print only names (no SHA-1)" msgstr "zeigt nur Namen an (keine SHA-1)" -#: builtin/name-rev.c:314 +#: builtin/name-rev.c:313 msgid "only use tags to name the commits" msgstr "verwendet nur Tags um die Commits zu benennen" -#: builtin/name-rev.c:316 +#: builtin/name-rev.c:315 msgid "only use refs matching " msgstr "verwendet nur Referenzen die entsprechen" -#: builtin/name-rev.c:318 +#: builtin/name-rev.c:317 msgid "list all commits reachable from all refs" msgstr "listet alle Commits auf, die von allen Referenzen erreichbar sind" -#: builtin/name-rev.c:319 +#: builtin/name-rev.c:318 msgid "read from stdin" msgstr "liest von der Standard-Eingabe" -#: builtin/name-rev.c:320 +#: builtin/name-rev.c:319 msgid "allow to print `undefined` names (default)" msgstr "erlaubt Ausgabe von `undefinierten` Namen (Standard)" -#: builtin/name-rev.c:326 +#: builtin/name-rev.c:325 msgid "dereference tags in the input (internal use)" msgstr "dereferenziert Tags in der Eingabe (interne Verwendung)" @@ -7636,7 +7715,7 @@ msgstr "Notiz-Referenz" msgid "use notes from " msgstr "verwendet Notizen von " -#: builtin/notes.c:974 builtin/remote.c:1598 +#: builtin/notes.c:974 builtin/remote.c:1593 #, c-format msgid "Unknown subcommand: %s" msgstr "Unbekanntes Unterkommando: %s" @@ -7656,150 +7735,150 @@ msgstr "" msgid "deflate error (%d)" msgstr "Fehler beim Komprimieren (%d)" -#: builtin/pack-objects.c:2398 +#: builtin/pack-objects.c:2396 #, c-format msgid "unsupported index version %s" msgstr "Nicht unterstützte Staging-Area-Version %s" -#: builtin/pack-objects.c:2402 +#: builtin/pack-objects.c:2400 #, c-format msgid "bad index version '%s'" msgstr "Ungültige Staging-Area-Version '%s'" -#: builtin/pack-objects.c:2425 +#: builtin/pack-objects.c:2423 #, c-format msgid "option %s does not accept negative form" msgstr "Option %s akzeptiert keine negative Form" -#: builtin/pack-objects.c:2429 +#: builtin/pack-objects.c:2427 #, c-format msgid "unable to parse value '%s' for option %s" msgstr "konnte Wert '%s' für Option %s nicht parsen" -#: builtin/pack-objects.c:2448 +#: builtin/pack-objects.c:2446 msgid "do not show progress meter" msgstr "zeigt keine Fortschrittsanzeige" -#: builtin/pack-objects.c:2450 +#: builtin/pack-objects.c:2448 msgid "show progress meter" msgstr "zeigt Fortschrittsanzeige" -#: builtin/pack-objects.c:2452 +#: builtin/pack-objects.c:2450 msgid "show progress meter during object writing phase" msgstr "zeigt Forschrittsanzeige während der Phase des Schreibens der Objekte" -#: builtin/pack-objects.c:2455 +#: builtin/pack-objects.c:2453 msgid "similar to --all-progress when progress meter is shown" msgstr "ähnlich zu --all-progress wenn Fortschrittsanzeige darstellt wird" -#: builtin/pack-objects.c:2456 +#: builtin/pack-objects.c:2454 msgid "version[,offset]" msgstr "version[,offset]" -#: builtin/pack-objects.c:2457 +#: builtin/pack-objects.c:2455 msgid "write the pack index file in the specified idx format version" msgstr "" "schreibt die Index-Datei des Paketes in der angegebenen Indexformat-Version" -#: builtin/pack-objects.c:2460 +#: builtin/pack-objects.c:2458 msgid "maximum size of each output pack file" msgstr "maximale Größe für jede ausgegebene Paketdatei" -#: builtin/pack-objects.c:2462 +#: builtin/pack-objects.c:2460 msgid "ignore borrowed objects from alternate object store" msgstr "ignoriert geliehene Objekte von alternativem Objektspeicher" -#: builtin/pack-objects.c:2464 +#: builtin/pack-objects.c:2462 msgid "ignore packed objects" msgstr "ignoriert gepackte Objekte" -#: builtin/pack-objects.c:2466 +#: builtin/pack-objects.c:2464 msgid "limit pack window by objects" msgstr "begrenzt Paketfenster durch Objekte" -#: builtin/pack-objects.c:2468 +#: builtin/pack-objects.c:2466 msgid "limit pack window by memory in addition to object limit" msgstr "begrenzt Paketfenster, zusätzlich zur Objektbegrenzung, durch Speicher" -#: builtin/pack-objects.c:2470 +#: builtin/pack-objects.c:2468 msgid "maximum length of delta chain allowed in the resulting pack" msgstr "" "maximale Länge der erlaubten Differenzverkettung im resultierenden Paket" -#: builtin/pack-objects.c:2472 +#: builtin/pack-objects.c:2470 msgid "reuse existing deltas" msgstr "verwendet existierende Unterschiede wieder" -#: builtin/pack-objects.c:2474 +#: builtin/pack-objects.c:2472 msgid "reuse existing objects" msgstr "verwendet existierende Objekte wieder" -#: builtin/pack-objects.c:2476 +#: builtin/pack-objects.c:2474 msgid "use OFS_DELTA objects" msgstr "verwendet OFS_DELTA Objekte" -#: builtin/pack-objects.c:2478 +#: builtin/pack-objects.c:2476 msgid "use threads when searching for best delta matches" msgstr "" "verwendet Threads bei der Suche nach den besten Übereinstimmungen bei " "Unterschieden" -#: builtin/pack-objects.c:2480 +#: builtin/pack-objects.c:2478 msgid "do not create an empty pack output" msgstr "erzeugt keine leeren Pakete" -#: builtin/pack-objects.c:2482 +#: builtin/pack-objects.c:2480 msgid "read revision arguments from standard input" msgstr "liest Argumente bezüglich Commits von der Standard-Eingabe" -#: builtin/pack-objects.c:2484 +#: builtin/pack-objects.c:2482 msgid "limit the objects to those that are not yet packed" msgstr "begrenzt die Objekte zu solchen, die noch nicht gepackt wurden" -#: builtin/pack-objects.c:2487 +#: builtin/pack-objects.c:2485 msgid "include objects reachable from any reference" msgstr "schließt Objekte ein, die von jeder Referenz erreichbar sind" -#: builtin/pack-objects.c:2490 +#: builtin/pack-objects.c:2488 msgid "include objects referred by reflog entries" msgstr "" "schließt Objekte ein, die von Einträgen des Reflogs referenziert werden" -#: builtin/pack-objects.c:2493 +#: builtin/pack-objects.c:2491 msgid "output pack to stdout" msgstr "schreibt Paket in die Standard-Ausgabe" -#: builtin/pack-objects.c:2495 +#: builtin/pack-objects.c:2493 msgid "include tag objects that refer to objects to be packed" msgstr "schließt Tag-Objekte ein, die auf gepackte Objekte referenzieren" -#: builtin/pack-objects.c:2497 +#: builtin/pack-objects.c:2495 msgid "keep unreachable objects" msgstr "behält nicht erreichbare Objekte" -#: builtin/pack-objects.c:2498 parse-options.h:143 +#: builtin/pack-objects.c:2496 parse-options.h:143 msgid "time" msgstr "Zeit" -#: builtin/pack-objects.c:2499 +#: builtin/pack-objects.c:2497 msgid "unpack unreachable objects newer than