From: Junio C Hamano Date: Wed, 25 Apr 2018 04:29:06 +0000 (+0900) Subject: Merge branch 'jm/mem-pool' X-Git-Tag: v2.18.0-rc0~107 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/cac7a2ba7be9354cfc02e14b50d35c4e9cf2b4d7?hp=065feab4ebc8e160ab025ff351d724aeda3623ad Merge branch 'jm/mem-pool' An reusable "memory pool" implementation has been extracted from fast-import.c, which in turn has become the first user of the mem-pool API. * jm/mem-pool: mem-pool: move reusable parts of memory pool into its own file fast-import: introduce mem_pool type fast-import: rename mem_pool type to mp_block --- diff --git a/Documentation/RelNotes/2.18.0.txt b/Documentation/RelNotes/2.18.0.txt new file mode 100644 index 0000000000..5f16516734 --- /dev/null +++ b/Documentation/RelNotes/2.18.0.txt @@ -0,0 +1,122 @@ +Git 2.18 Release Notes +====================== + +Updates since v2.17 +------------------- + +UI, Workflows & Features + + * Rename detection logic in "diff" family that is used in "merge" has + learned to guess when all of x/a, x/b and x/c have moved to z/a, + z/b and z/c, it is likely that x/d added in the meantime would also + want to move to z/d by taking the hint that the entire directory + 'x' moved to 'z'. A bug causing dirty files involved in a rename + to be overwritten during merge has also been fixed as part of this + work. + + * "git filter-branch" learned to use a different exit code to allow + the callers to tell the case where there was no new commits to + rewrite from other error cases. + + * When built with more recent cURL, GIT_SSL_VERSION can now specify + "tlsv1.3" as its value. + + +Performance, Internal Implementation, Development Support etc. + + * A "git fetch" from a repository with insane number of refs into a + repository that is already up-to-date still wasted too many cycles + making many lstat(2) calls to see if these objects at the tips + exist as loose objects locally. These lstat(2) calls are optimized + away by enumerating all loose objects beforehand. + It is unknown if the new strategy negatively affects existing use + cases, fetching into a repository with many loose objects from a + repository with small number of refs. + + * Git can be built to use either v1 or v2 of the PCRE library, and so + far, the build-time configuration USE_LIBPCRE=YesPlease instructed + the build procedure to use v1, but now it means v2. USE_LIBPCRE1 + and USE_LIBPCRE2 can be used to explicitly choose which version to + use, as before. + + * The build procedure learned to optionally use symbolic links + (instead of hardlinks and copies) to install "git-foo" for built-in + commands, whose binaries are all identical. + + * Conversion from uchar[20] to struct object_id continues. + + * The way "git worktree prune" worked internally has been simplified, + by assuming how "git worktree move" moves an existing worktree to a + different place. + + * Code clean-up for the "repository" abstraction. + (merge 00a3da2a13 nd/remove-ignore-env-field later to maint). + + * Code to find the length to uniquely abbreviate object names based + on packfile content, which is a relatively recent addtion, has been + optimized to use the same fan-out table. + + * The mechanism to use parse-options API to automate the command line + completion continues to get extended and polished. + + * Copies of old scripted Porcelain commands in contrib/examples/ have + been removed. + + * Some tests that rely on the exact hardcoded values of object names + have been updated in preparation for hash function migration. + + * Perf-test update. + + * Test helper update. + + * The effort continues to refactor the internal global data structure + to make it possible to open multiple repositories, work with and + then close them, + + * Small test-helper programs have been consolidated into a single + binary. + +Also contains various documentation updates and code clean-ups. + + +Fixes since v2.17 +----------------- + + * "git shortlog cruft" aborted with a BUG message when run outside a + Git repository. The command has been taught to complain about + extra and unwanted arguments on its command line instead in such a + case. + (merge 4aa0161e83 ma/shortlog-revparse later to maint). + + * "git stash push -u -- " gave an unnecessary and confusing + error message when there was no tracked files that match the + , which has been fixed. + (merge 353278687e tg/stash-untracked-with-pathspec-fix later to maint). + + * "git tag --contains no-such-commit" gave a full list of options + after giving an error message. + (merge 3bb0923f06 ps/contains-id-error-message later to maint). + + * "diff-highlight" filter (in contrib/) learned to undertand "git log + --graph" output better. + (merge 4551fbba14 jk/diff-highlight-graph-fix later to maint). + + * when refs that do not point at committish are given, "git + filter-branch" gave a misleading error messages. This has been + corrected. + (merge f78ab355e7 yk/filter-branch-non-committish-refs later to maint). + + * "git submodule status" misbehaved on a submodule that has been + removed from the working tree. + (merge 74b6bda32f rs/status-with-removed-submodule later to maint). + + * When credential helper exits very quickly without reading its + input, it used to cause Git to die with SIGPIPE, which has been + fixed. + (merge a0d51e8d0e eb/cred-helper-ignore-sigpipe later to maint). + + * Other minor doc, test and build updates and code cleanups. + (merge 248f66ed8e nd/trace-with-env later to maint). + (merge 14ced5562c ys/bisect-object-id-missing-conversion-fix later to maint). + (merge 5988eb631a ab/doc-hash-brokenness later to maint). + (merge a4d4e32a70 pk/test-avoid-pipe-hiding-exit-status later to maint). diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches index a1d0feca36..945f8edb46 100644 --- a/Documentation/SubmittingPatches +++ b/Documentation/SubmittingPatches @@ -260,8 +260,8 @@ that starts with `-----BEGIN PGP SIGNED MESSAGE-----`. That is not a text/plain, it's something else. Send your patch with "To:" set to the mailing list, with "cc:" listing -people who are involved in the area you are touching (the output from -`git blame $path` and `git shortlog --no-merges $path` would help to +people who are involved in the area you are touching (the `git +contacts` command in `contrib/contacts/` can help to identify them), to solicit comments and reviews. :1: footnote:[The current maintainer: gitster@pobox.com] diff --git a/Documentation/config.txt b/Documentation/config.txt index ce9102cea8..2659153cb3 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -1957,6 +1957,7 @@ http.sslVersion:: - tlsv1.0 - tlsv1.1 - tlsv1.2 + - tlsv1.3 + Can be overridden by the `GIT_SSL_VERSION` environment variable. @@ -3364,7 +3365,7 @@ uploadpack.packObjectsHook:: stdout. uploadpack.allowFilter:: - If this option is set, `upload-pack` will advertise partial + If this option is set, `upload-pack` will support partial clone and partial fetch object filtering. + Note that this configuration variable is ignored if it is seen in the diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt index e3a44f03cd..f466600972 100644 --- a/Documentation/diff-options.txt +++ b/Documentation/diff-options.txt @@ -568,7 +568,7 @@ the normal order. -- + Patterns have the same syntax and semantics as patterns used for -fnmantch(3) without the FNM_PATHNAME flag, except a pathname also +fnmatch(3) without the FNM_PATHNAME flag, except a pathname also matches a pattern if removing any number of the final pathname components matches the pattern. For example, the pattern "`foo*bar`" matches "`fooasdfbar`" and "`foo/bar/baz/asdf`" but not "`foobarx`". @@ -592,7 +592,7 @@ endif::git-format-patch[] Treat all files as text. --ignore-cr-at-eol:: - Ignore carrige-return at the end of line when doing a comparison. + Ignore carriage-return at the end of line when doing a comparison. --ignore-space-at-eol:: Ignore changes in whitespace at EOL. diff --git a/Documentation/git-bisect.txt b/Documentation/git-bisect.txt index 4a1417bdcd..4b45d837a7 100644 --- a/Documentation/git-bisect.txt +++ b/Documentation/git-bisect.txt @@ -165,8 +165,8 @@ To get a reminder of the currently used terms, use git bisect terms ------------------------------------------------ -You can get just the old (respectively new) term with `git bisect term ---term-old` or `git bisect term --term-good`. +You can get just the old (respectively new) term with `git bisect terms +--term-old` or `git bisect terms --term-good`. If you would like to use your own terms instead of "bad"/"good" or "new"/"old", you can choose any names you like (except existing bisect diff --git a/Documentation/git-fetch-pack.txt b/Documentation/git-fetch-pack.txt index f7ebe36a7b..c975884793 100644 --- a/Documentation/git-fetch-pack.txt +++ b/Documentation/git-fetch-pack.txt @@ -88,7 +88,7 @@ be in a separate packet, and the list must end with a flush packet. infinite even if there is an ancestor-chain that long. --shallow-since=:: - Deepen or shorten the history of a shallow'repository to + Deepen or shorten the history of a shallow repository to include all reachable commits after . --shallow-exclude=:: diff --git a/Documentation/git-filter-branch.txt b/Documentation/git-filter-branch.txt index 3a52e4dce3..b634043183 100644 --- a/Documentation/git-filter-branch.txt +++ b/Documentation/git-filter-branch.txt @@ -222,6 +222,14 @@ this purpose, they are instead rewritten to point at the nearest ancestor that was not excluded. +EXIT STATUS +----------- + +On success, the exit status is `0`. If the filter can't find any commits to +rewrite, the exit status is `2`. On any other error, the exit status may be +any other non-zero value. + + Examples -------- diff --git a/Documentation/git-for-each-ref.txt b/Documentation/git-for-each-ref.txt index dffa14a795..085d177d97 100644 --- a/Documentation/git-for-each-ref.txt +++ b/Documentation/git-for-each-ref.txt @@ -121,7 +121,7 @@ refname:: stripping with positive , or it becomes the full refname if stripping with negative . Neither is an error. + -`strip` can be used as a synomym to `lstrip`. +`strip` can be used as a synonym to `lstrip`. objecttype:: The type of the object (`blob`, `tree`, `commit`, `tag`). diff --git a/Documentation/git-gc.txt b/Documentation/git-gc.txt index 571b5a7e3c..3126e0dd00 100644 --- a/Documentation/git-gc.txt +++ b/Documentation/git-gc.txt @@ -15,8 +15,9 @@ DESCRIPTION ----------- Runs a number of housekeeping tasks within the current repository, such as compressing file revisions (to reduce disk space and increase -performance) and removing unreachable objects which may have been -created from prior invocations of 'git add'. +performance), removing unreachable objects which may have been +created from prior invocations of 'git add', packing refs, pruning +reflog, rerere metadata or stale working trees. Users are encouraged to run this task on a regular basis within each repository to maintain good disk space utilization and good @@ -45,20 +46,25 @@ OPTIONS With this option, 'git gc' checks whether any housekeeping is required; if not, it exits without performing any work. Some git commands run `git gc --auto` after performing - operations that could create many loose objects. + operations that could create many loose objects. Housekeeping + is required if there are too many loose objects or too many + packs in the repository. + -Housekeeping is required if there are too many loose objects or -too many packs in the repository. If the number of loose objects -exceeds the value of the `gc.auto` configuration variable, then -all loose objects are combined into a single pack using -`git repack -d -l`. Setting the value of `gc.auto` to 0 -disables automatic packing of loose objects. +If the number of loose objects exceeds the value of the `gc.auto` +configuration variable, then all loose objects are combined into a +single pack using `git repack -d -l`. Setting the value of `gc.auto` +to 0 disables automatic packing of loose objects. + If the number of packs exceeds the value of `gc.autoPackLimit`, then existing packs (except those marked with a `.keep` file) are consolidated into a single pack by using the `-A` option of 'git repack'. Setting `gc.autoPackLimit` to 0 disables automatic consolidation of packs. ++ +If houskeeping is required due to many loose objects or packs, all +other housekeeping tasks (e.g. rerere, working trees, reflog...) will +be performed as well. + --prune=:: Prune loose objects older than date (default is 2 weeks ago, @@ -133,6 +139,10 @@ The optional configuration variable `gc.pruneExpire` controls how old the unreferenced loose objects have to be before they are pruned. The default is "2 weeks ago". +Optional configuration variable `gc.worktreePruneExpire` controls how +old a stale working tree should be before `git worktree prune` deletes +it. Default is "3 months ago". + Notes ----- diff --git a/Documentation/git-mktree.txt b/Documentation/git-mktree.txt index c3616e7711..27fe2b32e1 100644 --- a/Documentation/git-mktree.txt +++ b/Documentation/git-mktree.txt @@ -14,7 +14,7 @@ SYNOPSIS DESCRIPTION ----------- Reads standard input in non-recursive `ls-tree` output format, and creates -a tree object. The order of the tree entries is normalised by mktree so +a tree object. The order of the tree entries is normalized by mktree so pre-sorting the input is not required. The object name of the tree object built is written to the standard output. diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt index 3277ca1432..dd852068b1 100644 --- a/Documentation/git-rebase.txt +++ b/Documentation/git-rebase.txt @@ -364,9 +364,10 @@ default is `--no-fork-point`, otherwise the default is `--fork-point`. Incompatible with the --interactive option. --signoff:: - This flag is passed to 'git am' to sign off all the rebased - commits (see linkgit:git-am[1]). Incompatible with the - --interactive option. + Add a Signed-off-by: trailer to all the rebased commits. Note + that if `--interactive` is given then only commits marked to be + picked, edited or reworded will have the trailer added. Incompatible + with the `--preserve-merges` option. -i:: --interactive:: diff --git a/Documentation/git-send-email.txt b/Documentation/git-send-email.txt index 71ef97ba9b..60cf96f4c1 100644 --- a/Documentation/git-send-email.txt +++ b/Documentation/git-send-email.txt @@ -255,7 +255,7 @@ must be used for each option. --batch-size=:: Some email servers (e.g. smtp.163.com) limit the number emails to be - sent per session (connection) and this will lead to a faliure when + sent per session (connection) and this will lead to a failure when sending many messages. With this option, send-email will disconnect after sending $ messages and wait for a few seconds (see --relogin-delay) and reconnect, to work around such a limit. You may want to @@ -473,16 +473,7 @@ edit ~/.gitconfig to specify your account settings: If you have multifactor authentication setup on your gmail account, you will need to generate an app-specific password for use with 'git send-email'. Visit -https://security.google.com/settings/security/apppasswords to setup an -app-specific password. Once setup, you can store it with the credentials -helper: - - $ git credential fill - protocol=smtp - host=smtp.gmail.com - username=youname@gmail.com - password=app-password - +https://security.google.com/settings/security/apppasswords to create it. Once your commits are ready to be sent to the mailing list, run the following commands: @@ -491,6 +482,11 @@ following commands: $ edit outgoing/0000-* $ git send-email outgoing/* +The first time you run it, you will be prompted for your credentials. Enter the +app-specific or your regular password as appropriate. If you have credential +helper configured (see linkgit:git-credential[1]), the password will be saved in +the credential store so you won't have to type it the next time. + Note: the following perl modules are required Net::SMTP::SSL, MIME::Base64 and Authen::SASL diff --git a/Documentation/git-shortlog.txt b/Documentation/git-shortlog.txt index ee6c5476c1..5e35ea18ac 100644 --- a/Documentation/git-shortlog.txt +++ b/Documentation/git-shortlog.txt @@ -8,8 +8,8 @@ git-shortlog - Summarize 'git log' output SYNOPSIS -------- [verse] -git log --pretty=short | 'git shortlog' [] 'git shortlog' [] [] [[\--] ...] +git log --pretty=short | 'git shortlog' [] DESCRIPTION ----------- diff --git a/Documentation/git-stash.txt b/Documentation/git-stash.txt index 056dfb8661..7ef8c47911 100644 --- a/Documentation/git-stash.txt +++ b/Documentation/git-stash.txt @@ -14,7 +14,7 @@ SYNOPSIS 'git stash' ( pop | apply ) [--index] [-q|--quiet] [] 'git stash' branch [] 'git stash' [push [-p|--patch] [-k|--[no-]keep-index] [-q|--quiet] - [-u|--include-untracked] [-a|--all] [-m|--message ]] + [-u|--include-untracked] [-a|--all] [-m|--message ] [--] [...]] 'git stash' clear 'git stash' create [] diff --git a/Documentation/git-status.txt b/Documentation/git-status.txt index 6c230c0c72..c16e27e63d 100644 --- a/Documentation/git-status.txt +++ b/Documentation/git-status.txt @@ -113,7 +113,7 @@ The possible options are: - 'matching' - Shows ignored files and directories matching an ignore pattern. + -When 'matching' mode is specified, paths that explicity match an +When 'matching' mode is specified, paths that explicitly match an ignored pattern are shown. If a directory matches an ignore pattern, then it is shown, but not paths contained in the ignored directory. If a directory does not match an ignore pattern, but all contents are diff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt index 636e09048e..d59379ee23 100644 --- a/Documentation/git-svn.txt +++ b/Documentation/git-svn.txt @@ -635,7 +635,8 @@ config key: svn.findcopiesharder -A:: --authors-file=:: - Syntax is compatible with the file used by 'git cvsimport': + Syntax is compatible with the file used by 'git cvsimport' but + an empty email address can be supplied with '<>': + ------------------------------------------------------------------------ loginname = Joe User @@ -654,8 +655,14 @@ config key: svn.authorsfile If this option is specified, for each SVN committer name that does not exist in the authors file, the given file is executed with the committer name as the first argument. The program is - expected to return a single line of the form "Name ", - which will be treated as if included in the authors file. + expected to return a single line of the form "Name " or + "Name <>", which will be treated as if included in the authors + file. ++ +Due to historical reasons a relative 'filename' is first searched +relative to the current directory for 'init' and 'clone' and relative +to the root of the working tree for 'fetch'. If 'filename' is +not found, it is searched like any other command in '$PATH'. + [verse] config key: svn.authorsProg diff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt index e7eb24ab85..2755ca90e3 100644 --- a/Documentation/git-worktree.txt +++ b/Documentation/git-worktree.txt @@ -27,11 +27,12 @@ out more than one branch at a time. With `git worktree add` a new working tree is associated with the repository. This new working tree is called a "linked working tree" as opposed to the "main working tree" prepared by "git init" or "git clone". A repository has one main working tree (if it's not a -bare repository) and zero or more linked working trees. +bare repository) and zero or more linked working trees. When you are done +with a linked working tree, remove it with `git worktree remove`. -When you are done with a linked working tree you can simply delete it. -The working tree's administrative files in the repository (see -"DETAILS" below) will eventually be removed automatically (see +If a working tree is deleted without using `git worktree remove`, then +its associated administrative files, which reside in the repository +(see "DETAILS" below), will eventually be removed automatically (see `gc.worktreePruneExpire` in linkgit:git-config[1]), or you can run `git worktree prune` in the main or any linked working tree to clean up any stale administrative files. @@ -106,7 +107,7 @@ OPTIONS By default, `add` refuses to create a new working tree when `` is a branch name and is already checked out by another working tree and `remove` refuses to remove an unclean - working tree. This option overrides that safeguard. + working tree. This option overrides these safeguards. -b :: -B :: @@ -232,7 +233,7 @@ The worktree list command has two output formats. The default format shows the details on a single line with columns. For example: ------------ -S git worktree list +$ git worktree list /path/to/bare-source (bare) /path/to/linked-worktree abcd1234 [master] /path/to/other-linked-worktree 1234abc (detached HEAD) @@ -247,7 +248,7 @@ if the value is true. An empty line indicates the end of a worktree. For example: ------------ -S git worktree list --porcelain +$ git worktree list --porcelain worktree /path/to/bare-source bare @@ -278,8 +279,7 @@ $ pushd ../temp # ... hack hack hack ... $ git commit -a -m 'emergency fix for boss' $ popd -$ rm -rf ../temp -$ git worktree prune +$ git worktree remove ../temp ------------ BUGS diff --git a/Documentation/gitrepository-layout.txt b/Documentation/gitrepository-layout.txt index c60bcad44a..e85148f05e 100644 --- a/Documentation/gitrepository-layout.txt +++ b/Documentation/gitrepository-layout.txt @@ -275,11 +275,6 @@ worktrees//locked:: or manually by `git worktree prune`. The file may contain a string explaining why the repository is locked. -worktrees//link:: - If this file exists, it is a hard link to the linked .git - file. It is used to detect if the linked repository is - manually removed. - SEE ALSO -------- linkgit:git-init[1], diff --git a/Documentation/howto/recover-corrupted-object-harder.txt b/Documentation/howto/recover-corrupted-object-harder.txt index 9c4cd0915f..8994e2559e 100644 --- a/Documentation/howto/recover-corrupted-object-harder.txt +++ b/Documentation/howto/recover-corrupted-object-harder.txt @@ -80,7 +80,7 @@ valid pack like: # now add our object data cat object >>tmp.pack # and then append the pack trailer - /path/to/git.git/test-sha1 -b trailer + /path/to/git.git/t/helper/test-tool sha1 -b trailer cat trailer >>tmp.pack ------------ diff --git a/Documentation/technical/api-directory-listing.txt b/Documentation/technical/api-directory-listing.txt index 7fae00f44f..4f44ca24f6 100644 --- a/Documentation/technical/api-directory-listing.txt +++ b/Documentation/technical/api-directory-listing.txt @@ -53,7 +53,7 @@ The notable options are: not be returned even if all of its contents are ignored. In this case, the contents are returned as individual entries. + -If this is set, files and directories that explicity match an ignore +If this is set, files and directories that explicitly match an ignore pattern are reported. Implicity ignored directories (directories that do not match an ignore pattern, but whose contents are all ignored) are not reported, instead all of the contents are reported. diff --git a/Documentation/technical/api-object-access.txt b/Documentation/technical/api-object-access.txt index a1162e5bcd..5b29622d00 100644 --- a/Documentation/technical/api-object-access.txt +++ b/Documentation/technical/api-object-access.txt @@ -1,7 +1,7 @@ object access API ================= -Talk about and family, things like +Talk about and family, things like * read_sha1_file() * read_object_with_reference() diff --git a/Documentation/technical/hash-function-transition.txt b/Documentation/technical/hash-function-transition.txt index 417ba491d0..4ab6cd1012 100644 --- a/Documentation/technical/hash-function-transition.txt +++ b/Documentation/technical/hash-function-transition.txt @@ -28,11 +28,30 @@ advantages: address stored content. Over time some flaws in SHA-1 have been discovered by security -researchers. https://shattered.io demonstrated a practical SHA-1 hash -collision. As a result, SHA-1 cannot be considered cryptographically -secure any more. This impacts the communication of hash values because -we cannot trust that a given hash value represents the known good -version of content that the speaker intended. +researchers. On 23 February 2017 the SHAttered attack +(https://shattered.io) demonstrated a practical SHA-1 hash collision. + +Git v2.13.0 and later subsequently moved to a hardened SHA-1 +implementation by default, which isn't vulnerable to the SHAttered +attack. + +Thus Git has in effect already migrated to a new hash that isn't SHA-1 +and doesn't share its vulnerabilities, its new hash function just +happens to produce exactly the same output for all known inputs, +except two PDFs published by the SHAttered researchers, and the new +implementation (written by those researchers) claims to detect future +cryptanalytic collision attacks. + +Regardless, it's considered prudent to move past any variant of SHA-1 +to a new hash. There's no guarantee that future attacks on SHA-1 won't +be published in the future, and those attacks may not have viable +mitigations. + +If SHA-1 and its variants were to be truly broken, Git's hash function +could not be considered cryptographically secure any more. This would +impact the communication of hash values because we could not trust +that a given hash value represented the known good version of content +that the speaker intended. SHA-1 still possesses the other properties such as fast object lookup and safe error checking, but other hash functions are equally suitable @@ -116,10 +135,15 @@ Documentation/technical/repository-version.txt) with extensions objectFormat = newhash compatObjectFormat = sha1 -Specifying a repository format extension ensures that versions of Git -not aware of NewHash do not try to operate on these repositories, -instead producing an error message: +The combination of setting `core.repositoryFormatVersion=1` and +populating `extensions.*` ensures that all versions of Git later than +`v0.99.9l` will die instead of trying to operate on the NewHash +repository, instead producing an error message. + # Between v0.99.9l and v2.7.0 + $ git status + fatal: Expected git repo version <= 0, found 1 + # After v2.7.0 $ git status fatal: unknown repository extensions found: objectformat diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index b4fb7d9a39..12ff59c2c7 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -1,7 +1,7 @@ #!/bin/sh GVF=GIT-VERSION-FILE -DEF_VER=v2.17.0-rc1 +DEF_VER=v2.17.GIT LF=' ' diff --git a/Makefile b/Makefile index ddbe878813..50da82b016 100644 --- a/Makefile +++ b/Makefile @@ -29,10 +29,10 @@ all:: # Perl-compatible regular expressions instead of standard or extended # POSIX regular expressions. # -# Currently USE_LIBPCRE is a synonym for USE_LIBPCRE1, define -# USE_LIBPCRE2 instead if you'd like to use version 2 of the PCRE -# library. The USE_LIBPCRE flag will likely be changed to mean v2 by -# default in future releases. +# USE_LIBPCRE is a synonym for USE_LIBPCRE2, define USE_LIBPCRE1 +# instead if you'd like to use the legacy version 1 of the PCRE +# library. Support for version 1 will likely be removed in some future +# release of Git, as upstream has all but abandoned it. # # When using USE_LIBPCRE1, define NO_LIBPCRE1_JIT if the PCRE v1 # library is compiled without --enable-jit. We will auto-detect @@ -335,6 +335,13 @@ all:: # when hardlinking a file to another name and unlinking the original file right # away (some NTFS drivers seem to zero the contents in that scenario). # +# Define INSTALL_SYMLINKS if you prefer to have everything that can be +# symlinked between bin/ and libexec/ to use relative symlinks between +# the two. This option overrides NO_CROSS_DIRECTORY_HARDLINKS and +# NO_INSTALL_HARDLINKS which will also use symlinking by indirection +# within the same directory in some cases, INSTALL_SYMLINKS will +# always symlink to the final target directly. +# # Define NO_CROSS_DIRECTORY_HARDLINKS if you plan to distribute the installed # programs as a tar, where bin/ and libexec/ might be on different file systems. # @@ -474,8 +481,7 @@ ARFLAGS = rcs # This can help installing the suite in a relocatable way. prefix = $(HOME) -bindir_relative = bin -bindir = $(prefix)/$(bindir_relative) +bindir = $(prefix)/bin mandir = $(prefix)/share/man infodir = $(prefix)/share/info gitexecdir = libexec/git-core @@ -492,8 +498,10 @@ lib = lib # DESTDIR = pathsep = : +bindir_relative = $(patsubst $(prefix)/%,%,$(bindir)) mandir_relative = $(patsubst $(prefix)/%,%,$(mandir)) infodir_relative = $(patsubst $(prefix)/%,%,$(infodir)) +gitexecdir_relative = $(patsubst $(prefix)/%,%,$(gitexecdir)) htmldir_relative = $(patsubst $(prefix)/%,%,$(htmldir)) export prefix bindir sharedir sysconfdir gitwebdir perllibdir localedir @@ -546,6 +554,7 @@ SCRIPT_PERL = SCRIPT_PYTHON = SCRIPT_SH = SCRIPT_LIB = +TEST_BUILTINS_OBJS = TEST_PROGRAMS_NEED_X = # Having this variable in your environment would break pipelines because @@ -651,47 +660,49 @@ X = PROGRAMS += $(patsubst %.o,git-%$X,$(PROGRAM_OBJS)) -TEST_PROGRAMS_NEED_X += test-chmtime -TEST_PROGRAMS_NEED_X += test-ctype -TEST_PROGRAMS_NEED_X += test-config -TEST_PROGRAMS_NEED_X += test-date -TEST_PROGRAMS_NEED_X += test-delta -TEST_PROGRAMS_NEED_X += test-drop-caches -TEST_PROGRAMS_NEED_X += test-dump-cache-tree +TEST_BUILTINS_OBJS += test-chmtime.o +TEST_BUILTINS_OBJS += test-config.o +TEST_BUILTINS_OBJS += test-ctype.o +TEST_BUILTINS_OBJS += test-date.o +TEST_BUILTINS_OBJS += test-delta.o +TEST_BUILTINS_OBJS += test-drop-caches.o +TEST_BUILTINS_OBJS += test-dump-cache-tree.o +TEST_BUILTINS_OBJS += test-dump-split-index.o +TEST_BUILTINS_OBJS += test-example-decorate.o +TEST_BUILTINS_OBJS += test-genrandom.o +TEST_BUILTINS_OBJS += test-hashmap.o +TEST_BUILTINS_OBJS += test-index-version.o +TEST_BUILTINS_OBJS += test-lazy-init-name-hash.o +TEST_BUILTINS_OBJS += test-match-trees.o +TEST_BUILTINS_OBJS += test-mergesort.o +TEST_BUILTINS_OBJS += test-mktemp.o +TEST_BUILTINS_OBJS += test-online-cpus.o +TEST_BUILTINS_OBJS += test-path-utils.o +TEST_BUILTINS_OBJS += test-prio-queue.o +TEST_BUILTINS_OBJS += test-read-cache.o +TEST_BUILTINS_OBJS += test-ref-store.o +TEST_BUILTINS_OBJS += test-regex.o +TEST_BUILTINS_OBJS += test-revision-walking.o +TEST_BUILTINS_OBJS += test-run-command.o +TEST_BUILTINS_OBJS += test-scrap-cache-tree.o +TEST_BUILTINS_OBJS += test-sha1-array.o +TEST_BUILTINS_OBJS += test-sha1.o +TEST_BUILTINS_OBJS += test-sigchain.o +TEST_BUILTINS_OBJS += test-strcmp-offset.o +TEST_BUILTINS_OBJS += test-string-list.o +TEST_BUILTINS_OBJS += test-submodule-config.o +TEST_BUILTINS_OBJS += test-subprocess.o +TEST_BUILTINS_OBJS += test-urlmatch-normalization.o +TEST_BUILTINS_OBJS += test-wildmatch.o +TEST_BUILTINS_OBJS += test-write-cache.o + TEST_PROGRAMS_NEED_X += test-dump-fsmonitor -TEST_PROGRAMS_NEED_X += test-dump-split-index TEST_PROGRAMS_NEED_X += test-dump-untracked-cache -TEST_PROGRAMS_NEED_X += test-example-decorate TEST_PROGRAMS_NEED_X += test-fake-ssh -TEST_PROGRAMS_NEED_X += test-genrandom -TEST_PROGRAMS_NEED_X += test-hashmap -TEST_PROGRAMS_NEED_X += test-index-version -TEST_PROGRAMS_NEED_X += test-lazy-init-name-hash TEST_PROGRAMS_NEED_X += test-line-buffer -TEST_PROGRAMS_NEED_X += test-match-trees -TEST_PROGRAMS_NEED_X += test-mergesort -TEST_PROGRAMS_NEED_X += test-mktemp -TEST_PROGRAMS_NEED_X += test-online-cpus TEST_PROGRAMS_NEED_X += test-parse-options -TEST_PROGRAMS_NEED_X += test-path-utils -TEST_PROGRAMS_NEED_X += test-prio-queue -TEST_PROGRAMS_NEED_X += test-read-cache -TEST_PROGRAMS_NEED_X += test-write-cache -TEST_PROGRAMS_NEED_X += test-ref-store -TEST_PROGRAMS_NEED_X += test-regex -TEST_PROGRAMS_NEED_X += test-revision-walking -TEST_PROGRAMS_NEED_X += test-run-command -TEST_PROGRAMS_NEED_X += test-scrap-cache-tree -TEST_PROGRAMS_NEED_X += test-sha1 -TEST_PROGRAMS_NEED_X += test-sha1-array -TEST_PROGRAMS_NEED_X += test-sigchain -TEST_PROGRAMS_NEED_X += test-strcmp-offset -TEST_PROGRAMS_NEED_X += test-string-list -TEST_PROGRAMS_NEED_X += test-submodule-config -TEST_PROGRAMS_NEED_X += test-subprocess TEST_PROGRAMS_NEED_X += test-svn-fe -TEST_PROGRAMS_NEED_X += test-urlmatch-normalization -TEST_PROGRAMS_NEED_X += test-wildmatch +TEST_PROGRAMS_NEED_X += test-tool TEST_PROGRAMS = $(patsubst %,t/helper/%$X,$(TEST_PROGRAMS_NEED_X)) @@ -772,6 +783,7 @@ LIB_OBJS += branch.o LIB_OBJS += bulk-checkin.o LIB_OBJS += bundle.o LIB_OBJS += cache-tree.o +LIB_OBJS += chdir-notify.o LIB_OBJS += checkout.o LIB_OBJS += color.o LIB_OBJS += column.o @@ -807,7 +819,7 @@ LIB_OBJS += ewah/bitmap.o LIB_OBJS += ewah/ewah_bitmap.o LIB_OBJS += ewah/ewah_io.o LIB_OBJS += ewah/ewah_rlw.o -LIB_OBJS += exec_cmd.o +LIB_OBJS += exec-cmd.o LIB_OBJS += fetch-object.o LIB_OBJS += fetch-pack.o LIB_OBJS += fsck.o @@ -878,7 +890,7 @@ LIB_OBJS += refs/packed-backend.o LIB_OBJS += refs/ref-cache.o LIB_OBJS += ref-filter.o LIB_OBJS += remote.o -LIB_OBJS += replace_object.o +LIB_OBJS += replace-object.o LIB_OBJS += repository.o LIB_OBJS += rerere.o LIB_OBJS += resolve-undo.o @@ -890,8 +902,8 @@ LIB_OBJS += server-info.o LIB_OBJS += setup.o LIB_OBJS += sha1-array.o LIB_OBJS += sha1-lookup.o -LIB_OBJS += sha1_file.o -LIB_OBJS += sha1_name.o +LIB_OBJS += sha1-file.o +LIB_OBJS += sha1-name.o LIB_OBJS += shallow.o LIB_OBJS += sideband.o LIB_OBJS += sigchain.o @@ -926,7 +938,7 @@ LIB_OBJS += walker.o LIB_OBJS += wildmatch.o LIB_OBJS += worktree.o LIB_OBJS += wrapper.o -LIB_OBJS += write_or_die.o +LIB_OBJS += write-or-die.o LIB_OBJS += ws.o LIB_OBJS += wt-status.o LIB_OBJS += xdiff-interface.o @@ -1171,13 +1183,18 @@ ifdef NO_LIBGEN_H COMPAT_OBJS += compat/basename.o endif -USE_LIBPCRE1 ?= $(USE_LIBPCRE) +USE_LIBPCRE2 ?= $(USE_LIBPCRE) -ifneq (,$(USE_LIBPCRE1)) - ifdef USE_LIBPCRE2 -$(error Only set USE_LIBPCRE1 (or its alias USE_LIBPCRE) or USE_LIBPCRE2, not both!) +ifneq (,$(USE_LIBPCRE2)) + ifdef USE_LIBPCRE1 +$(error Only set USE_LIBPCRE2 (or its alias USE_LIBPCRE) or USE_LIBPCRE1, not both!) endif + BASIC_CFLAGS += -DUSE_LIBPCRE2 + EXTLIBS += -lpcre2-8 +endif + +ifdef USE_LIBPCRE1 BASIC_CFLAGS += -DUSE_LIBPCRE1 EXTLIBS += -lpcre @@ -1186,11 +1203,6 @@ ifdef NO_LIBPCRE1_JIT endif endif -ifdef USE_LIBPCRE2 - BASIC_CFLAGS += -DUSE_LIBPCRE2 - EXTLIBS += -lpcre2-8 -endif - ifdef LIBPCREDIR BASIC_CFLAGS += -I$(LIBPCREDIR)/include EXTLIBS += -L$(LIBPCREDIR)/$(lib) $(CC_LD_DYNPATH)$(LIBPCREDIR)/$(lib) @@ -1742,6 +1754,7 @@ infodir_relative_SQ = $(subst ','\'',$(infodir_relative)) perllibdir_SQ = $(subst ','\'',$(perllibdir)) localedir_SQ = $(subst ','\'',$(localedir)) gitexecdir_SQ = $(subst ','\'',$(gitexecdir)) +gitexecdir_relative_SQ = $(subst ','\'',$(gitexecdir_relative)) template_dir_SQ = $(subst ','\'',$(template_dir)) htmldir_relative_SQ = $(subst ','\'',$(htmldir_relative)) prefix_SQ = $(subst ','\'',$(prefix)) @@ -2084,7 +2097,7 @@ VCSSVN_OBJS += vcs-svn/fast_export.o VCSSVN_OBJS += vcs-svn/svndiff.o VCSSVN_OBJS += vcs-svn/svndump.o -TEST_OBJS := $(patsubst %$X,%.o,$(TEST_PROGRAMS)) +TEST_OBJS := $(patsubst %$X,%.o,$(TEST_PROGRAMS)) $(patsubst %,t/helper/%,$(TEST_BUILTINS_OBJS)) OBJECTS := $(LIB_OBJS) $(BUILTIN_OBJS) $(PROGRAM_OBJS) $(TEST_OBJS) \ $(XDIFF_OBJS) \ $(VCSSVN_OBJS) \ @@ -2144,8 +2157,8 @@ else $(OBJECTS): $(LIB_H) endif -exec_cmd.sp exec_cmd.s exec_cmd.o: GIT-PREFIX -exec_cmd.sp exec_cmd.s exec_cmd.o: EXTRA_CPPFLAGS = \ +exec-cmd.sp exec-cmd.s exec-cmd.o: GIT-PREFIX +exec-cmd.sp exec-cmd.s exec-cmd.o: EXTRA_CPPFLAGS = \ '-DGIT_EXEC_PATH="$(gitexecdir_SQ)"' \ '-DBINDIR="$(bindir_relative_SQ)"' \ '-DPREFIX="$(prefix_SQ)"' @@ -2495,10 +2508,12 @@ t/helper/test-svn-fe$X: $(VCSSVN_LIB) .PRECIOUS: $(TEST_OBJS) +t/helper/test-tool$X: $(patsubst %,t/helper/%,$(TEST_BUILTINS_OBJS)) + t/helper/test-%$X: t/helper/test-%.o GIT-LDFLAGS $(GITLIBS) $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(filter %.a,$^) $(LIBS) -check-sha1:: t/helper/test-sha1$X +check-sha1:: t/helper/test-tool$X t/helper/test-sha1.sh SP_OBJ = $(patsubst %.o,%.sp,$(C_OBJ)) @@ -2607,35 +2622,44 @@ endif bindir=$$(cd '$(DESTDIR_SQ)$(bindir_SQ)' && pwd) && \ execdir=$$(cd '$(DESTDIR_SQ)$(gitexec_instdir_SQ)' && pwd) && \ + destdir_from_execdir_SQ=$$(echo '$(gitexecdir_relative_SQ)' | sed -e 's|[^/][^/]*|..|g') && \ { test "$$bindir/" = "$$execdir/" || \ for p in git$X $(filter $(install_bindir_programs),$(ALL_PROGRAMS)); do \ $(RM) "$$execdir/$$p" && \ - test -z "$(NO_INSTALL_HARDLINKS)$(NO_CROSS_DIRECTORY_HARDLINKS)" && \ - ln "$$bindir/$$p" "$$execdir/$$p" 2>/dev/null || \ - cp "$$bindir/$$p" "$$execdir/$$p" || exit; \ + test -n "$(INSTALL_SYMLINKS)" && \ + ln -s "$$destdir_from_execdir_SQ/$(bindir_relative_SQ)/$$p" "$$execdir/$$p" || \ + { test -z "$(NO_INSTALL_HARDLINKS)$(NO_CROSS_DIRECTORY_HARDLINKS)" && \ + ln "$$bindir/$$p" "$$execdir/$$p" 2>/dev/null || \ + cp "$$bindir/$$p" "$$execdir/$$p" || exit; } \ done; \ } && \ for p in $(filter $(install_bindir_programs),$(BUILT_INS)); do \ $(RM) "$$bindir/$$p" && \ - test -z "$(NO_INSTALL_HARDLINKS)" && \ - ln "$$bindir/git$X" "$$bindir/$$p" 2>/dev/null || \ - ln -s "git$X" "$$bindir/$$p" 2>/dev/null || \ - cp "$$bindir/git$X" "$$bindir/$$p" || exit; \ + test -n "$(INSTALL_SYMLINKS)" && \ + ln -s "git$X" "$$bindir/$$p" || \ + { test -z "$(NO_INSTALL_HARDLINKS)" && \ + ln "$$bindir/git$X" "$$bindir/$$p" 2>/dev/null || \ + ln -s "git$X" "$$bindir/$$p" 2>/dev/null || \ + cp "$$bindir/git$X" "$$bindir/$$p" || exit; } \ done && \ for p in $(BUILT_INS); do \ $(RM) "$$execdir/$$p" && \ - test -z "$(NO_INSTALL_HARDLINKS)" && \ - ln "$$execdir/git$X" "$$execdir/$$p" 2>/dev/null || \ - ln -s "git$X" "$$execdir/$$p" 2>/dev/null || \ - cp "$$execdir/git$X" "$$execdir/$$p" || exit; \ + test -n "$(INSTALL_SYMLINKS)" && \ + ln -s "$$destdir_from_execdir_SQ/$(bindir_relative_SQ)/git$X" "$$execdir/$$p" || \ + { test -z "$(NO_INSTALL_HARDLINKS)" && \ + ln "$$execdir/git$X" "$$execdir/$$p" 2>/dev/null || \ + ln -s "git$X" "$$execdir/$$p" 2>/dev/null || \ + cp "$$execdir/git$X" "$$execdir/$$p" || exit; } \ done && \ remote_curl_aliases="$(REMOTE_CURL_ALIASES)" && \ for p in $$remote_curl_aliases; do \ $(RM) "$$execdir/$$p" && \ - test -z "$(NO_INSTALL_HARDLINKS)" && \ - ln "$$execdir/git-remote-http$X" "$$execdir/$$p" 2>/dev/null || \ - ln -s "git-remote-http$X" "$$execdir/$$p" 2>/dev/null || \ - cp "$$execdir/git-remote-http$X" "$$execdir/$$p" || exit; \ + test -n "$(INSTALL_SYMLINKS)" && \ + ln -s "git-remote-http$X" "$$execdir/$$p" || \ + { test -z "$(NO_INSTALL_HARDLINKS)" && \ + ln "$$execdir/git-remote-http$X" "$$execdir/$$p" 2>/dev/null || \ + ln -s "git-remote-http$X" "$$execdir/$$p" 2>/dev/null || \ + cp "$$execdir/git-remote-http$X" "$$execdir/$$p" || exit; } \ done && \ ./check_bindir "z$$bindir" "z$$execdir" "$$bindir/git-add$X" diff --git a/RelNotes b/RelNotes index 7a6dc0603b..f6c58b347f 120000 --- a/RelNotes +++ b/RelNotes @@ -1 +1 @@ -Documentation/RelNotes/2.17.0.txt \ No newline at end of file +Documentation/RelNotes/2.18.0.txt \ No newline at end of file diff --git a/apply.c b/apply.c index 134dc7ba78..7e5792c996 100644 --- a/apply.c +++ b/apply.c @@ -3180,7 +3180,7 @@ static int apply_binary(struct apply_state *state, unsigned long size; char *result; - result = read_sha1_file(oid.hash, &type, &size); + result = read_object_file(&oid, &type, &size); if (!result) return error(_("the necessary postimage %s for " "'%s' cannot be read"), @@ -3242,7 +3242,7 @@ static int read_blob_object(struct strbuf *buf, const struct object_id *oid, uns unsigned long sz; char *result; - result = read_sha1_file(oid->hash, &type, &sz); + result = read_object_file(oid, &type, &sz); if (!result) return -1; /* XXX read_sha1_file NUL-terminates */ diff --git a/archive-tar.c b/archive-tar.c index c6ed96ee74..3563bcb9f2 100644 --- a/archive-tar.c +++ b/archive-tar.c @@ -111,7 +111,7 @@ static void write_trailer(void) * queues up writes, so that all our write(2) calls write exactly one * full block; pads writes to RECORDSIZE */ -static int stream_blocked(const unsigned char *sha1) +static int stream_blocked(const struct object_id *oid) { struct git_istream *st; enum object_type type; @@ -119,9 +119,9 @@ static int stream_blocked(const unsigned char *sha1) char buf[BLOCKSIZE]; ssize_t readlen; - st = open_istream(sha1, &type, &sz, NULL); + st = open_istream(oid, &type, &sz, NULL); if (!st) - return error("cannot stream blob %s", sha1_to_hex(sha1)); + return error("cannot stream blob %s", oid_to_hex(oid)); for (;;) { readlen = read_istream(st, buf, sizeof(buf)); if (readlen <= 0) @@ -218,7 +218,7 @@ static void prepare_header(struct archiver_args *args, } static void write_extended_header(struct archiver_args *args, - const unsigned char *sha1, + const struct object_id *oid, const void *buffer, unsigned long size) { struct ustar_header header; @@ -226,14 +226,14 @@ static void write_extended_header(struct archiver_args *args, memset(&header, 0, sizeof(header)); *header.typeflag = TYPEFLAG_EXT_HEADER; mode = 0100666; - xsnprintf(header.name, sizeof(header.name), "%s.paxheader", sha1_to_hex(sha1)); + xsnprintf(header.name, sizeof(header.name), "%s.paxheader", oid_to_hex(oid)); prepare_header(args, &header, mode, size); write_blocked(&header, sizeof(header)); write_blocked(buffer, size); } static int write_tar_entry(struct archiver_args *args, - const unsigned char *sha1, + const struct object_id *oid, const char *path, size_t pathlen, unsigned int mode) { @@ -257,7 +257,7 @@ static int write_tar_entry(struct archiver_args *args, mode = (mode | ((mode & 0100) ? 0777 : 0666)) & ~tar_umask; } else { return error("unsupported file mode: 0%o (SHA1: %s)", - mode, sha1_to_hex(sha1)); + mode, oid_to_hex(oid)); } if (pathlen > sizeof(header.name)) { size_t plen = get_path_prefix(path, pathlen, @@ -268,7 +268,7 @@ static int write_tar_entry(struct archiver_args *args, memcpy(header.name, path + plen + 1, rest); } else { xsnprintf(header.name, sizeof(header.name), "%s.data", - sha1_to_hex(sha1)); + oid_to_hex(oid)); strbuf_append_ext_header(&ext_header, "path", path, pathlen); } @@ -276,14 +276,14 @@ static int write_tar_entry(struct archiver_args *args, memcpy(header.name, path, pathlen); if (S_ISREG(mode) && !args->convert && - sha1_object_info(sha1, &size) == OBJ_BLOB && + oid_object_info(oid, &size) == OBJ_BLOB && size > big_file_threshold) buffer = NULL; else if (S_ISLNK(mode) || S_ISREG(mode)) { enum object_type type; - buffer = sha1_file_to_archive(args, path, sha1, old_mode, &type, &size); + buffer = object_file_to_archive(args, path, oid, old_mode, &type, &size); if (!buffer) - return error("cannot read %s", sha1_to_hex(sha1)); + return error("cannot read %s", oid_to_hex(oid)); } else { buffer = NULL; size = 0; @@ -292,7 +292,7 @@ static int write_tar_entry(struct archiver_args *args, if (S_ISLNK(mode)) { if (size > sizeof(header.linkname)) { xsnprintf(header.linkname, sizeof(header.linkname), - "see %s.paxheader", sha1_to_hex(sha1)); + "see %s.paxheader", oid_to_hex(oid)); strbuf_append_ext_header(&ext_header, "linkpath", buffer, size); } else @@ -308,7 +308,7 @@ static int write_tar_entry(struct archiver_args *args, prepare_header(args, &header, mode, size_in_header); if (ext_header.len > 0) { - write_extended_header(args, sha1, ext_header.buf, + write_extended_header(args, oid, ext_header.buf, ext_header.len); } strbuf_release(&ext_header); @@ -317,7 +317,7 @@ static int write_tar_entry(struct archiver_args *args, if (buffer) write_blocked(buffer, size); else - err = stream_blocked(sha1); + err = stream_blocked(oid); } free(buffer); return err; diff --git a/archive-zip.c b/archive-zip.c index e8913e5a26..6b20bce4d1 100644 --- a/archive-zip.c +++ b/archive-zip.c @@ -276,7 +276,7 @@ static int entry_is_binary(const char *path, const void *buffer, size_t size) #define STREAM_BUFFER_SIZE (1024 * 16) static int write_zip_entry(struct archiver_args *args, - const unsigned char *sha1, + const struct object_id *oid, const char *path, size_t pathlen, unsigned int mode) { @@ -314,7 +314,7 @@ static int write_zip_entry(struct archiver_args *args, if (pathlen > 0xffff) { return error("path too long (%d chars, SHA1: %s): %s", - (int)pathlen, sha1_to_hex(sha1), path); + (int)pathlen, oid_to_hex(oid), path); } if (S_ISDIR(mode) || S_ISGITLINK(mode)) { @@ -325,7 +325,7 @@ static int write_zip_entry(struct archiver_args *args, compressed_size = 0; buffer = NULL; } else if (S_ISREG(mode) || S_ISLNK(mode)) { - enum object_type type = sha1_object_info(sha1, &size); + enum object_type type = oid_object_info(oid, &size); method = 0; attr2 = S_ISLNK(mode) ? ((mode | 0777) << 16) : @@ -337,18 +337,18 @@ static int write_zip_entry(struct archiver_args *args, if (S_ISREG(mode) && type == OBJ_BLOB && !args->convert && size > big_file_threshold) { - stream = open_istream(sha1, &type, &size, NULL); + stream = open_istream(oid, &type, &size, NULL); if (!stream) return error("cannot stream blob %s", - sha1_to_hex(sha1)); + oid_to_hex(oid)); flags |= ZIP_STREAM; out = buffer = NULL; } else { - buffer = sha1_file_to_archive(args, path, sha1, mode, - &type, &size); + buffer = object_file_to_archive(args, path, oid, mode, + &type, &size); if (!buffer) return error("cannot read %s", - sha1_to_hex(sha1)); + oid_to_hex(oid)); crc = crc32(crc, buffer, size); is_binary = entry_is_binary(path_without_prefix, buffer, size); @@ -357,7 +357,7 @@ static int write_zip_entry(struct archiver_args *args, compressed_size = (method == 0) ? size : 0; } else { return error("unsupported file mode: 0%o (SHA1: %s)", mode, - sha1_to_hex(sha1)); + oid_to_hex(oid)); } if (creator_version > max_creator_version) diff --git a/archive.c b/archive.c index 0b7b62af0c..93ab175b0b 100644 --- a/archive.c +++ b/archive.c @@ -63,16 +63,16 @@ static void format_subst(const struct commit *commit, free(to_free); } -void *sha1_file_to_archive(const struct archiver_args *args, - const char *path, const unsigned char *sha1, - unsigned int mode, enum object_type *type, - unsigned long *sizep) +void *object_file_to_archive(const struct archiver_args *args, + const char *path, const struct object_id *oid, + unsigned int mode, enum object_type *type, + unsigned long *sizep) { void *buffer; const struct commit *commit = args->convert ? args->commit : NULL; path += args->baselen; - buffer = read_sha1_file(sha1, type, sizep); + buffer = read_object_file(oid, type, sizep); if (buffer && S_ISREG(mode)) { struct strbuf buf = STRBUF_INIT; size_t size = 0; @@ -121,7 +121,7 @@ static int check_attr_export_subst(const struct attr_check *check) return check && ATTR_TRUE(check->items[1].value); } -static int write_archive_entry(const unsigned char *sha1, const char *base, +static int write_archive_entry(const struct object_id *oid, const char *base, int baselen, const char *filename, unsigned mode, int stage, void *context) { @@ -153,7 +153,7 @@ static int write_archive_entry(const unsigned char *sha1, const char *base, if (S_ISDIR(mode) || S_ISGITLINK(mode)) { if (args->verbose) fprintf(stderr, "%.*s\n", (int)path.len, path.buf); - err = write_entry(args, sha1, path.buf, path.len, mode); + err = write_entry(args, oid, path.buf, path.len, mode); if (err) return err; return (S_ISDIR(mode) ? READ_TREE_RECURSIVE : 0); @@ -161,7 +161,7 @@ static int write_archive_entry(const unsigned char *sha1, const char *base, if (args->verbose) fprintf(stderr, "%.*s\n", (int)path.len, path.buf); - return write_entry(args, sha1, path.buf, path.len, mode); + return write_entry(args, oid, path.buf, path.len, mode); } static void queue_directory(const unsigned char *sha1, @@ -191,14 +191,14 @@ static int write_directory(struct archiver_context *c) d->path[d->len - 1] = '\0'; /* no trailing slash */ ret = write_directory(c) || - write_archive_entry(d->oid.hash, d->path, d->baselen, + write_archive_entry(&d->oid, d->path, d->baselen, d->path + d->baselen, d->mode, d->stage, c) != READ_TREE_RECURSIVE; free(d); return ret ? -1 : 0; } -static int queue_or_write_archive_entry(const unsigned char *sha1, +static int queue_or_write_archive_entry(const struct object_id *oid, struct strbuf *base, const char *filename, unsigned mode, int stage, void *context) { @@ -224,14 +224,14 @@ static int queue_or_write_archive_entry(const unsigned char *sha1, if (check_attr_export_ignore(check)) return 0; - queue_directory(sha1, base, filename, + queue_directory(oid->hash, base, filename, mode, stage, c); return READ_TREE_RECURSIVE; } if (write_directory(c)) return -1; - return write_archive_entry(sha1, base->buf, base->len, filename, mode, + return write_archive_entry(oid, base->buf, base->len, filename, mode, stage, context); } @@ -250,7 +250,7 @@ int write_archive_entries(struct archiver_args *args, len--; if (args->verbose) fprintf(stderr, "%.*s\n", (int)len, args->base); - err = write_entry(args, args->tree->object.oid.hash, args->base, + err = write_entry(args, &args->tree->object.oid, args->base, len, 040777); if (err) return err; @@ -303,7 +303,7 @@ static const struct archiver *lookup_archiver(const char *name) return NULL; } -static int reject_entry(const unsigned char *sha1, struct strbuf *base, +static int reject_entry(const struct object_id *oid, struct strbuf *base, const char *filename, unsigned mode, int stage, void *context) { @@ -397,8 +397,8 @@ static void parse_treeish_arg(const char **argv, unsigned int mode; int err; - err = get_tree_entry(tree->object.oid.hash, prefix, - tree_oid.hash, &mode); + err = get_tree_entry(&tree->object.oid, prefix, &tree_oid, + &mode); if (err || !S_ISDIR(mode)) die("current working directory is untracked"); diff --git a/archive.h b/archive.h index 62d1d82c1a..1f9954f7cd 100644 --- a/archive.h +++ b/archive.h @@ -31,7 +31,7 @@ extern void init_tar_archiver(void); extern void init_zip_archiver(void); typedef int (*write_archive_entry_fn_t)(struct archiver_args *args, - const unsigned char *sha1, + const struct object_id *oid, const char *path, size_t pathlen, unsigned int mode); @@ -39,9 +39,9 @@ extern int write_archive_entries(struct archiver_args *args, write_archive_entry extern int write_archive(int argc, const char **argv, const char *prefix, const char *name_hint, int remote); const char *archive_format_from_filename(const char *filename); -extern void *sha1_file_to_archive(const struct archiver_args *args, - const char *path, const unsigned char *sha1, - unsigned int mode, enum object_type *type, - unsigned long *sizep); +extern void *object_file_to_archive(const struct archiver_args *args, + const char *path, const struct object_id *oid, + unsigned int mode, enum object_type *type, + unsigned long *sizep); #endif /* ARCHIVE_H */ diff --git a/attr.c b/attr.c index dfc3a558d8..03a678fa9b 100644 --- a/attr.c +++ b/attr.c @@ -10,7 +10,7 @@ #define NO_THE_INDEX_COMPATIBILITY_MACROS #include "cache.h" #include "config.h" -#include "exec_cmd.h" +#include "exec-cmd.h" #include "attr.h" #include "dir.h" #include "utf8.h" diff --git a/bisect.c b/bisect.c index f6d05bd66f..a579b50884 100644 --- a/bisect.c +++ b/bisect.c @@ -132,7 +132,8 @@ static void show_list(const char *debug, int counted, int nr, unsigned flags = commit->object.flags; enum object_type type; unsigned long size; - char *buf = read_sha1_file(commit->object.oid.hash, &type, &size); + char *buf = read_object_file(&commit->object.oid, &type, + &size); const char *subject_start; int subject_len; @@ -144,10 +145,10 @@ static void show_list(const char *debug, int counted, int nr, fprintf(stderr, "%3d", weight(p)); else fprintf(stderr, "---"); - fprintf(stderr, " %.*s", 8, sha1_to_hex(commit->object.oid.hash)); + fprintf(stderr, " %.*s", 8, oid_to_hex(&commit->object.oid)); for (pp = commit->parents; pp; pp = pp->next) fprintf(stderr, " %.*s", 8, - sha1_to_hex(pp->item->object.oid.hash)); + oid_to_hex(&pp->item->object.oid)); subject_len = find_commit_subject(buf, &subject_start); if (subject_len) diff --git a/blame.c b/blame.c index 200e0ad9a2..78c9808bd1 100644 --- a/blame.c +++ b/blame.c @@ -80,8 +80,8 @@ static void verify_working_tree_path(struct commit *work_tree, const char *path) struct object_id blob_oid; unsigned mode; - if (!get_tree_entry(commit_oid->hash, path, blob_oid.hash, &mode) && - sha1_object_info(blob_oid.hash, NULL) == OBJ_BLOB) + if (!get_tree_entry(commit_oid, path, &blob_oid, &mode) && + oid_object_info(&blob_oid, NULL) == OBJ_BLOB) return; } @@ -297,8 +297,8 @@ static void fill_origin_blob(struct diff_options *opt, textconv_object(o->path, o->mode, &o->blob_oid, 1, &file->ptr, &file_size)) ; else - file->ptr = read_sha1_file(o->blob_oid.hash, &type, - &file_size); + file->ptr = read_object_file(&o->blob_oid, &type, + &file_size); file->size = file_size; if (!file->ptr) @@ -502,11 +502,9 @@ static int fill_blob_sha1_and_mode(struct blame_origin *origin) { if (!is_null_oid(&origin->blob_oid)) return 0; - if (get_tree_entry(origin->commit->object.oid.hash, - origin->path, - origin->blob_oid.hash, &origin->mode)) + if (get_tree_entry(&origin->commit->object.oid, origin->path, &origin->blob_oid, &origin->mode)) goto error_out; - if (sha1_object_info(origin->blob_oid.hash, NULL) != OBJ_BLOB) + if (oid_object_info(&origin->blob_oid, NULL) != OBJ_BLOB) goto error_out; return 0; error_out: @@ -1831,8 +1829,8 @@ void setup_scoreboard(struct blame_scoreboard *sb, const char *path, struct blam &sb->final_buf_size)) ; else - sb->final_buf = read_sha1_file(o->blob_oid.hash, &type, - &sb->final_buf_size); + sb->final_buf = read_object_file(&o->blob_oid, &type, + &sb->final_buf_size); if (!sb->final_buf) die(_("cannot read blob %s for path %s"), diff --git a/builtin/add.c b/builtin/add.c index 9ef7fb02d5..c9e2619a9a 100644 --- a/builtin/add.c +++ b/builtin/add.c @@ -9,7 +9,7 @@ #include "lockfile.h" #include "dir.h" #include "pathspec.h" -#include "exec_cmd.h" +#include "exec-cmd.h" #include "cache-tree.h" #include "run-command.h" #include "parse-options.h" diff --git a/builtin/am.c b/builtin/am.c index 1151b5c73a..d834f9e62b 100644 --- a/builtin/am.c +++ b/builtin/am.c @@ -6,7 +6,7 @@ #include "cache.h" #include "config.h" #include "builtin.h" -#include "exec_cmd.h" +#include "exec-cmd.h" #include "parse-options.h" #include "dir.h" #include "run-command.h" @@ -1550,7 +1550,7 @@ static int fall_back_threeway(const struct am_state *state, const char *index_pa discard_cache(); read_cache_from(index_path); - if (write_index_as_tree(orig_tree.hash, &the_index, index_path, 0, NULL)) + if (write_index_as_tree(&orig_tree, &the_index, index_path, 0, NULL)) return error(_("Repository lacks necessary blobs to fall back on 3-way merge.")); say(state, stdout, _("Using index info to reconstruct a base tree...")); @@ -1575,7 +1575,7 @@ static int fall_back_threeway(const struct am_state *state, const char *index_pa return error(_("Did you hand edit your patch?\n" "It does not apply to blobs recorded in its index.")); - if (write_index_as_tree(their_tree.hash, &the_index, index_path, 0, NULL)) + if (write_index_as_tree(&their_tree, &the_index, index_path, 0, NULL)) return error("could not write tree"); say(state, stdout, _("Falling back to patching base and 3-way merge...")); @@ -1626,7 +1626,7 @@ static void do_commit(const struct am_state *state) if (run_hook_le(NULL, "pre-applypatch", NULL)) exit(1); - if (write_cache_as_tree(tree.hash, 0, NULL)) + if (write_cache_as_tree(&tree, 0, NULL)) die(_("git write-tree failed to write a tree")); if (!get_oid_commit("HEAD", &parent)) { @@ -1862,7 +1862,7 @@ static void am_run(struct am_state *state, int resume) */ if (!state->rebasing) { am_destroy(state); - close_all_packs(); + close_all_packs(the_repository->objects); run_command_v_opt(argv_gc_auto, RUN_GIT_CMD); } } @@ -2004,7 +2004,7 @@ static int clean_index(const struct object_id *head, const struct object_id *rem if (fast_forward_to(head_tree, head_tree, 1)) return -1; - if (write_cache_as_tree(index.hash, 0, NULL)) + if (write_cache_as_tree(&index, 0, NULL)) return -1; index_tree = parse_tree_indirect(&index); diff --git a/builtin/blame.c b/builtin/blame.c index 9dcb367b90..db38c0b307 100644 --- a/builtin/blame.c +++ b/builtin/blame.c @@ -499,7 +499,7 @@ static int read_ancestry(const char *graft_file) static int update_auto_abbrev(int auto_abbrev, struct blame_origin *suspect) { - const char *uniq = find_unique_abbrev(suspect->commit->object.oid.hash, + const char *uniq = find_unique_abbrev(&suspect->commit->object.oid, auto_abbrev); int len = strlen(uniq); if (auto_abbrev < len) @@ -655,7 +655,7 @@ static int is_a_rev(const char *name) if (get_oid(name, &oid)) return 0; - return OBJ_NONE < sha1_object_info(oid.hash, NULL); + return OBJ_NONE < oid_object_info(&oid, NULL); } int cmd_blame(int argc, const char **argv, const char *prefix) @@ -729,6 +729,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix) for (;;) { switch (parse_options_step(&ctx, options, blame_opt_usage)) { case PARSE_OPT_HELP: + case PARSE_OPT_ERROR: exit(129); case PARSE_OPT_DONE: if (ctx.argv[0]) diff --git a/builtin/branch.c b/builtin/branch.c index 6d0cea9d4b..5bd2a0dd48 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -273,7 +273,7 @@ static int delete_branches(int argc, const char **argv, int force, int kinds, bname.buf, (flags & REF_ISBROKEN) ? "broken" : (flags & REF_ISSYMREF) ? target - : find_unique_abbrev(oid.hash, DEFAULT_ABBREV)); + : find_unique_abbrev(&oid, DEFAULT_ABBREV)); } delete_branch_config(bname.buf); diff --git a/builtin/cat-file.c b/builtin/cat-file.c index d90170f070..2c46d257cd 100644 --- a/builtin/cat-file.c +++ b/builtin/cat-file.c @@ -32,7 +32,7 @@ static int filter_object(const char *path, unsigned mode, { enum object_type type; - *buf = read_sha1_file(oid->hash, &type, size); + *buf = read_object_file(oid, &type, size); if (!*buf) return error(_("cannot read object %s '%s'"), oid_to_hex(oid), path); @@ -77,7 +77,7 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name, switch (opt) { case 't': oi.type_name = &sb; - if (sha1_object_info_extended(oid.hash, &oi, flags) < 0) + if (oid_object_info_extended(&oid, &oi, flags) < 0) die("git cat-file: could not get object info"); if (sb.len) { printf("%s\n", sb.buf); @@ -88,7 +88,7 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name, case 's': oi.sizep = &size; - if (sha1_object_info_extended(oid.hash, &oi, flags) < 0) + if (oid_object_info_extended(&oid, &oi, flags) < 0) die("git cat-file: could not get object info"); printf("%lu\n", size); return 0; @@ -116,7 +116,7 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name, /* else fallthrough */ case 'p': - type = sha1_object_info(oid.hash, NULL); + type = oid_object_info(&oid, NULL); if (type < 0) die("Not a valid object name %s", obj_name); @@ -130,7 +130,7 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name, if (type == OBJ_BLOB) return stream_blob_to_fd(1, &oid, NULL, 0); - buf = read_sha1_file(oid.hash, &type, &size); + buf = read_object_file(&oid, &type, &size); if (!buf) die("Cannot read object %s", obj_name); @@ -140,8 +140,9 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name, case 0: if (type_from_string(exp_type) == OBJ_BLOB) { struct object_id blob_oid; - if (sha1_object_info(oid.hash, NULL) == OBJ_TAG) { - char *buffer = read_sha1_file(oid.hash, &type, &size); + if (oid_object_info(&oid, NULL) == OBJ_TAG) { + char *buffer = read_object_file(&oid, &type, + &size); const char *target; if (!skip_prefix(buffer, "object ", &target) || get_oid_hex(target, &blob_oid)) @@ -150,7 +151,7 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name, } else oidcpy(&blob_oid, &oid); - if (sha1_object_info(blob_oid.hash, NULL) == OBJ_BLOB) + if (oid_object_info(&blob_oid, NULL) == OBJ_BLOB) return stream_blob_to_fd(1, &blob_oid, NULL, 0); /* * we attempted to dereference a tag to a blob @@ -159,7 +160,7 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name, * fall-back to the usual case. */ } - buf = read_object_with_reference(oid.hash, exp_type, &size, NULL); + buf = read_object_with_reference(&oid, exp_type, &size, NULL); break; default: @@ -304,8 +305,9 @@ static void print_object_or_die(struct batch_options *opt, struct expand_data *d enum object_type type; if (!textconv_object(data->rest, 0100644, oid, 1, &contents, &size)) - contents = read_sha1_file(oid->hash, &type, - &size); + contents = read_object_file(oid, + &type, + &size); if (!contents) die("could not convert '%s' %s", oid_to_hex(oid), data->rest); @@ -321,7 +323,7 @@ static void print_object_or_die(struct batch_options *opt, struct expand_data *d unsigned long size; void *contents; - contents = read_sha1_file(oid->hash, &type, &size); + contents = read_object_file(oid, &type, &size); if (!contents) die("object %s disappeared", oid_to_hex(oid)); if (type != data->type) @@ -340,8 +342,8 @@ static void batch_object_write(const char *obj_name, struct batch_options *opt, struct strbuf buf = STRBUF_INIT; if (!data->skip_object_info && - sha1_object_info_extended(data->oid.hash, &data->info, - OBJECT_INFO_LOOKUP_REPLACE) < 0) { + oid_object_info_extended(&data->oid, &data->info, + OBJECT_INFO_LOOKUP_REPLACE) < 0) { printf("%s missing\n", obj_name ? obj_name : oid_to_hex(&data->oid)); fflush(stdout); diff --git a/builtin/checkout.c b/builtin/checkout.c index d76e13c852..b49b582071 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -66,7 +66,7 @@ static int post_checkout_hook(struct commit *old_commit, struct commit *new_comm } -static int update_some(const unsigned char *sha1, struct strbuf *base, +static int update_some(const struct object_id *oid, struct strbuf *base, const char *pathname, unsigned mode, int stage, void *context) { int len; @@ -78,7 +78,7 @@ static int update_some(const unsigned char *sha1, struct strbuf *base, len = base->len + strlen(pathname); ce = xcalloc(1, cache_entry_size(len)); - hashcpy(ce->oid.hash, sha1); + oidcpy(&ce->oid, oid); memcpy(ce->name, base->buf, base->len); memcpy(ce->name + base->len, pathname, len - base->len); ce->ce_flags = create_ce_flags(0) | CE_UPDATE; @@ -405,10 +405,10 @@ static void describe_detached_head(const char *msg, struct commit *commit) pp_commit_easy(CMIT_FMT_ONELINE, commit, &sb); if (print_sha1_ellipsis()) { fprintf(stderr, "%s %s... %s\n", msg, - find_unique_abbrev(commit->object.oid.hash, DEFAULT_ABBREV), sb.buf); + find_unique_abbrev(&commit->object.oid, DEFAULT_ABBREV), sb.buf); } else { fprintf(stderr, "%s %s %s\n", msg, - find_unique_abbrev(commit->object.oid.hash, DEFAULT_ABBREV), sb.buf); + find_unique_abbrev(&commit->object.oid, DEFAULT_ABBREV), sb.buf); } strbuf_release(&sb); } @@ -720,7 +720,7 @@ static int add_pending_uninteresting_ref(const char *refname, static void describe_one_orphan(struct strbuf *sb, struct commit *commit) { strbuf_addstr(sb, " "); - strbuf_add_unique_abbrev(sb, commit->object.oid.hash, DEFAULT_ABBREV); + strbuf_add_unique_abbrev(sb, &commit->object.oid, DEFAULT_ABBREV); strbuf_addch(sb, ' '); if (!parse_commit(commit)) pp_commit_easy(CMIT_FMT_ONELINE, commit, sb); @@ -778,7 +778,7 @@ static void suggest_reattach(struct commit *commit, struct rev_info *revs) " git branch %s\n\n", /* Give ngettext() the count */ lost), - find_unique_abbrev(commit->object.oid.hash, DEFAULT_ABBREV)); + find_unique_abbrev(&commit->object.oid, DEFAULT_ABBREV)); } /* diff --git a/builtin/clone.c b/builtin/clone.c index 101c27a593..7df5932b85 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -27,6 +27,7 @@ #include "connected.h" #include "packfile.h" #include "list-objects-filter-options.h" +#include "object-store.h" /* * Overall FIXMEs: @@ -1217,7 +1218,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix) transport_disconnect(transport); if (option_dissociate) { - close_all_packs(); + close_all_packs(the_repository->objects); dissociate_from_references(); } diff --git a/builtin/commit-tree.c b/builtin/commit-tree.c index e5bdf57b1e..ecf42191da 100644 --- a/builtin/commit-tree.c +++ b/builtin/commit-tree.c @@ -58,7 +58,7 @@ int cmd_commit_tree(int argc, const char **argv, const char *prefix) usage(commit_tree_usage); if (get_oid_commit(argv[i], &oid)) die("Not a valid object name %s", argv[i]); - assert_sha1_type(oid.hash, OBJ_COMMIT); + assert_oid_type(&oid, OBJ_COMMIT); new_parent(lookup_commit(&oid), &parents); continue; } diff --git a/builtin/commit.c b/builtin/commit.c index 37fcb55ab0..5571d4a3e2 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -218,8 +218,7 @@ static int list_paths(struct string_list *list, const char *with_tree, if (with_tree) { char *max_prefix = common_prefix(pattern); - overlay_tree_on_index(&the_index, with_tree, - max_prefix ? max_prefix : prefix); + overlay_tree_on_index(&the_index, with_tree, max_prefix); free(max_prefix); } diff --git a/builtin/count-objects.c b/builtin/count-objects.c index 33343818c8..b054713e1a 100644 --- a/builtin/count-objects.c +++ b/builtin/count-objects.c @@ -7,10 +7,12 @@ #include "cache.h" #include "config.h" #include "dir.h" +#include "repository.h" #include "builtin.h" #include "parse-options.h" #include "quote.h" #include "packfile.h" +#include "object-store.h" static unsigned long garbage; static off_t size_garbage; @@ -120,9 +122,8 @@ int cmd_count_objects(int argc, const char **argv, const char *prefix) struct strbuf loose_buf = STRBUF_INIT; struct strbuf pack_buf = STRBUF_INIT; struct strbuf garbage_buf = STRBUF_INIT; - if (!packed_git) - prepare_packed_git(); - for (p = packed_git; p; p = p->next) { + + for (p = get_packed_git(the_repository); p; p = p->next) { if (!p->pack_local) continue; if (open_pack_index(p)) diff --git a/builtin/describe.c b/builtin/describe.c index e4869df7b4..b5afc45846 100644 --- a/builtin/describe.c +++ b/builtin/describe.c @@ -6,7 +6,7 @@ #include "blob.h" #include "refs.h" #include "builtin.h" -#include "exec_cmd.h" +#include "exec-cmd.h" #include "parse-options.h" #include "revision.h" #include "diff.h" @@ -285,7 +285,7 @@ static void append_name(struct commit_name *n, struct strbuf *dst) static void append_suffix(int depth, const struct object_id *oid, struct strbuf *dst) { - strbuf_addf(dst, "-%d-g%s", depth, find_unique_abbrev(oid->hash, abbrev)); + strbuf_addf(dst, "-%d-g%s", depth, find_unique_abbrev(oid, abbrev)); } static void describe_commit(struct object_id *oid, struct strbuf *dst) @@ -383,7 +383,7 @@ static void describe_commit(struct object_id *oid, struct strbuf *dst) if (!match_cnt) { struct object_id *cmit_oid = &cmit->object.oid; if (always) { - strbuf_add_unique_abbrev(dst, cmit_oid->hash, abbrev); + strbuf_add_unique_abbrev(dst, cmit_oid, abbrev); if (suffix) strbuf_addstr(dst, suffix); return; @@ -502,7 +502,7 @@ static void describe(const char *arg, int last_one) if (cmit) describe_commit(&oid, &sb); - else if (sha1_object_info(oid.hash, NULL) == OBJ_BLOB) + else if (oid_object_info(&oid, NULL) == OBJ_BLOB) describe_blob(oid, &sb); else die(_("%s is neither a commit nor blob"), arg); diff --git a/builtin/difftool.c b/builtin/difftool.c index bcc79d1888..aad0e073ee 100644 --- a/builtin/difftool.c +++ b/builtin/difftool.c @@ -15,7 +15,7 @@ #include "config.h" #include "builtin.h" #include "run-command.h" -#include "exec_cmd.h" +#include "exec-cmd.h" #include "parse-options.h" #include "argv-array.h" #include "strbuf.h" @@ -306,7 +306,7 @@ static char *get_symlink(const struct object_id *oid, const char *path) } else { enum object_type type; unsigned long size; - data = read_sha1_file(oid->hash, &type, &size); + data = read_object_file(oid, &type, &size); if (!data) die(_("could not read object %s for symlink %s"), oid_to_hex(oid), path); diff --git a/builtin/fast-export.c b/builtin/fast-export.c index 27b2cc138e..a15898d641 100644 --- a/builtin/fast-export.c +++ b/builtin/fast-export.c @@ -237,10 +237,10 @@ static void export_blob(const struct object_id *oid) object = (struct object *)lookup_blob(oid); eaten = 0; } else { - buf = read_sha1_file(oid->hash, &type, &size); + buf = read_object_file(oid, &type, &size); if (!buf) die ("Could not read blob %s", oid_to_hex(oid)); - if (check_sha1_signature(oid->hash, buf, size, type_name(type)) < 0) + if (check_object_signature(oid, buf, size, type_name(type)) < 0) die("sha1 mismatch in blob %s", oid_to_hex(oid)); object = parse_object_buffer(oid, type, size, buf, &eaten); } @@ -682,7 +682,7 @@ static void handle_tag(const char *name, struct tag *tag) return; } - buf = read_sha1_file(tag->object.oid.hash, &type, &size); + buf = read_object_file(&tag->object.oid, &type, &size); if (!buf) die ("Could not read tag %s", oid_to_hex(&tag->object.oid)); message = memmem(buf, size, "\n\n", 2); @@ -947,7 +947,7 @@ static void import_marks(char *input_file) if (last_idnum < mark) last_idnum = mark; - type = sha1_object_info(oid.hash, NULL); + type = oid_object_info(&oid, NULL); if (type < 0) die("object not found: %s", oid_to_hex(&oid)); diff --git a/builtin/fetch.c b/builtin/fetch.c index 6d73656a48..dcdfc66f09 100644 --- a/builtin/fetch.c +++ b/builtin/fetch.c @@ -637,7 +637,7 @@ static int update_local_ref(struct ref *ref, struct branch *current_branch = branch_get(NULL); const char *pretty_ref = prettify_refname(ref->name); - type = sha1_object_info(ref->new_oid.hash, NULL); + type = oid_object_info(&ref->new_oid, NULL); if (type < 0) die(_("object %s not found"), oid_to_hex(&ref->new_oid)); @@ -708,9 +708,9 @@ static int update_local_ref(struct ref *ref, if (in_merge_bases(current, updated)) { struct strbuf quickref = STRBUF_INIT; int r; - strbuf_add_unique_abbrev(&quickref, current->object.oid.hash, DEFAULT_ABBREV); + strbuf_add_unique_abbrev(&quickref, ¤t->object.oid, DEFAULT_ABBREV); strbuf_addstr(&quickref, ".."); - strbuf_add_unique_abbrev(&quickref, ref->new_oid.hash, DEFAULT_ABBREV); + strbuf_add_unique_abbrev(&quickref, &ref->new_oid, DEFAULT_ABBREV); if ((recurse_submodules != RECURSE_SUBMODULES_OFF) && (recurse_submodules != RECURSE_SUBMODULES_ON)) check_for_new_submodule_commits(&ref->new_oid); @@ -723,9 +723,9 @@ static int update_local_ref(struct ref *ref, } else if (force || ref->force) { struct strbuf quickref = STRBUF_INIT; int r; - strbuf_add_unique_abbrev(&quickref, current->object.oid.hash, DEFAULT_ABBREV); + strbuf_add_unique_abbrev(&quickref, ¤t->object.oid, DEFAULT_ABBREV); strbuf_addstr(&quickref, "..."); - strbuf_add_unique_abbrev(&quickref, ref->new_oid.hash, DEFAULT_ABBREV); + strbuf_add_unique_abbrev(&quickref, &ref->new_oid, DEFAULT_ABBREV); if ((recurse_submodules != RECURSE_SUBMODULES_OFF) && (recurse_submodules != RECURSE_SUBMODULES_ON)) check_for_new_submodule_commits(&ref->new_oid); @@ -1516,7 +1516,7 @@ int cmd_fetch(int argc, const char **argv, const char *prefix) string_list_clear(&list, 0); - close_all_packs(); + close_all_packs(the_repository->objects); argv_array_pushl(&argv_gc_auto, "gc", "--auto", NULL); if (verbosity < 0) diff --git a/builtin/fmt-merge-msg.c b/builtin/fmt-merge-msg.c index 8e8a15ea4a..bd680be687 100644 --- a/builtin/fmt-merge-msg.c +++ b/builtin/fmt-merge-msg.c @@ -485,10 +485,10 @@ static void fmt_merge_msg_sigs(struct strbuf *out) struct strbuf tagbuf = STRBUF_INIT; for (i = 0; i < origins.nr; i++) { - unsigned char *sha1 = origins.items[i].util; + struct object_id *oid = origins.items[i].util; enum object_type type; unsigned long size, len; - char *buf = read_sha1_file(sha1, &type, &size); + char *buf = read_object_file(oid, &type, &size); struct strbuf sig = STRBUF_INIT; if (!buf || type != OBJ_TAG) diff --git a/builtin/fsck.c b/builtin/fsck.c index ef78c6c00c..087360a675 100644 --- a/builtin/fsck.c +++ b/builtin/fsck.c @@ -1,5 +1,6 @@ #include "builtin.h" #include "cache.h" +#include "repository.h" #include "config.h" #include "commit.h" #include "tree.h" @@ -16,6 +17,7 @@ #include "streaming.h" #include "decorate.h" #include "packfile.h" +#include "object-store.h" #define REACHABLE 0x0001 #define SEEN 0x0002 @@ -65,7 +67,7 @@ static const char *printable_type(struct object *obj) const char *ret; if (obj->type == OBJ_NONE) { - enum object_type type = sha1_object_info(obj->oid.hash, NULL); + enum object_type type = oid_object_info(&obj->oid, NULL); if (type > 0) object_as_type(obj, type, 0); } @@ -513,7 +515,7 @@ static struct object *parse_loose_object(const struct object_id *oid, unsigned long size; int eaten; - if (read_loose_object(path, oid->hash, &type, &size, &contents) < 0) + if (read_loose_object(path, oid, &type, &size, &contents) < 0) return NULL; if (!contents && type != OBJ_BLOB) @@ -719,9 +721,12 @@ int cmd_fsck(int argc, const char **argv, const char *prefix) for_each_loose_object(mark_loose_for_connectivity, NULL, 0); for_each_packed_object(mark_packed_for_connectivity, NULL, 0); } else { + struct alternate_object_database *alt_odb_list; + fsck_object_dir(get_object_directory()); - prepare_alt_odb(); + prepare_alt_odb(the_repository); + alt_odb_list = the_repository->objects->alt_odb_list; for (alt = alt_odb_list; alt; alt = alt->next) fsck_object_dir(alt->path); @@ -730,10 +735,9 @@ int cmd_fsck(int argc, const char **argv, const char *prefix) uint32_t total = 0, count = 0; struct progress *progress = NULL; - prepare_packed_git(); - if (show_progress) { - for (p = packed_git; p; p = p->next) { + for (p = get_packed_git(the_repository); p; + p = p->next) { if (open_pack_index(p)) continue; total += p->num_objects; @@ -741,7 +745,8 @@ int cmd_fsck(int argc, const char **argv, const char *prefix) progress = start_progress(_("Checking objects"), total); } - for (p = packed_git; p; p = p->next) { + for (p = get_packed_git(the_repository); p; + p = p->next) { /* verify gives error messages itself */ if (verify_pack(p, fsck_obj_buffer, progress, count)) diff --git a/builtin/gc.c b/builtin/gc.c index f51e5a6500..3e67124eaa 100644 --- a/builtin/gc.c +++ b/builtin/gc.c @@ -11,6 +11,7 @@ */ #include "builtin.h" +#include "repository.h" #include "config.h" #include "tempfile.h" #include "lockfile.h" @@ -20,6 +21,7 @@ #include "argv-array.h" #include "commit.h" #include "packfile.h" +#include "object-store.h" #define FAILED_RUN "failed to run %s" @@ -172,8 +174,7 @@ static int too_many_packs(void) if (gc_auto_pack_limit <= 0) return 0; - prepare_packed_git(); - for (cnt = 0, p = packed_git; p; p = p->next) { + for (cnt = 0, p = get_packed_git(the_repository); p; p = p->next) { if (!p->pack_local) continue; if (p->pack_keep) @@ -479,7 +480,7 @@ int cmd_gc(int argc, const char **argv, const char *prefix) return error(FAILED_RUN, rerere.argv[0]); report_garbage = report_pack_garbage; - reprepare_packed_git(); + reprepare_packed_git(the_repository); if (pack_garbage.nr > 0) clean_pack_garbage(); diff --git a/builtin/grep.c b/builtin/grep.c index 789a89133a..5f32d2ce84 100644 --- a/builtin/grep.c +++ b/builtin/grep.c @@ -22,6 +22,7 @@ #include "pathspec.h" #include "submodule.h" #include "submodule-config.h" +#include "object-store.h" static char const * const grep_usage[] = { N_("git grep [] [-e] [...] [[--] ...]"), @@ -306,7 +307,7 @@ static void *lock_and_read_oid_file(const struct object_id *oid, enum object_typ void *data; grep_read_lock(); - data = read_sha1_file(oid->hash, type, size); + data = read_object_file(oid, type, size); grep_read_unlock(); return data; } @@ -439,7 +440,7 @@ static int grep_submodule(struct grep_opt *opt, struct repository *superproject, * object. */ grep_read_lock(); - add_to_alternates_memory(submodule.objectdir); + add_to_alternates_memory(submodule.objects->objectdir); grep_read_unlock(); if (oid) { @@ -452,7 +453,7 @@ static int grep_submodule(struct grep_opt *opt, struct repository *superproject, object = parse_object_or_die(oid, oid_to_hex(oid)); grep_read_lock(); - data = read_object_with_reference(object->oid.hash, tree_type, + data = read_object_with_reference(&object->oid, tree_type, &size, NULL); grep_read_unlock(); @@ -614,7 +615,7 @@ static int grep_object(struct grep_opt *opt, const struct pathspec *pathspec, int hit, len; grep_read_lock(); - data = read_object_with_reference(obj->oid.hash, tree_type, + data = read_object_with_reference(&obj->oid, tree_type, &size, NULL); grep_read_unlock(); diff --git a/builtin/hash-object.c b/builtin/hash-object.c index 526da5c185..a9a3a198c3 100644 --- a/builtin/hash-object.c +++ b/builtin/hash-object.c @@ -9,7 +9,7 @@ #include "blob.h" #include "quote.h" #include "parse-options.h" -#include "exec_cmd.h" +#include "exec-cmd.h" /* * This is to create corrupt objects for debugging and as such it diff --git a/builtin/help.c b/builtin/help.c index 598867cfea..2d51071429 100644 --- a/builtin/help.c +++ b/builtin/help.c @@ -4,7 +4,7 @@ #include "cache.h" #include "config.h" #include "builtin.h" -#include "exec_cmd.h" +#include "exec-cmd.h" #include "parse-options.h" #include "run-command.h" #include "column.h" diff --git a/builtin/index-pack.c b/builtin/index-pack.c index bda84a92ef..78e66b9986 100644 --- a/builtin/index-pack.c +++ b/builtin/index-pack.c @@ -9,10 +9,11 @@ #include "tree.h" #include "progress.h" #include "fsck.h" -#include "exec_cmd.h" +#include "exec-cmd.h" #include "streaming.h" #include "thread-utils.h" #include "packfile.h" +#include "object-store.h" static const char index_pack_usage[] = "git index-pack [-v] [-o ] [--keep | --keep=] [--verify] [--strict] ( | --stdin [--fix-thin] [])"; @@ -59,7 +60,7 @@ struct ofs_delta_entry { }; struct ref_delta_entry { - unsigned char sha1[20]; + struct object_id oid; int obj_no; }; @@ -222,7 +223,7 @@ static unsigned check_object(struct object *obj) if (!(obj->flags & FLAG_CHECKED)) { unsigned long size; - int type = sha1_object_info(obj->oid.hash, &size); + int type = oid_object_info(&obj->oid, &size); if (type <= 0) die(_("did not receive expected object %s"), oid_to_hex(&obj->oid)); @@ -672,18 +673,18 @@ static void find_ofs_delta_children(off_t offset, *last_index = last; } -static int compare_ref_delta_bases(const unsigned char *sha1, - const unsigned char *sha2, +static int compare_ref_delta_bases(const struct object_id *oid1, + const struct object_id *oid2, enum object_type type1, enum object_type type2) { int cmp = type1 - type2; if (cmp) return cmp; - return hashcmp(sha1, sha2); + return oidcmp(oid1, oid2); } -static int find_ref_delta(const unsigned char *sha1, enum object_type type) +static int find_ref_delta(const struct object_id *oid, enum object_type type) { int first = 0, last = nr_ref_deltas; @@ -692,7 +693,7 @@ static int find_ref_delta(const unsigned char *sha1, enum object_type type) struct ref_delta_entry *delta = &ref_deltas[next]; int cmp; - cmp = compare_ref_delta_bases(sha1, delta->sha1, + cmp = compare_ref_delta_bases(oid, &delta->oid, type, objects[delta->obj_no].type); if (!cmp) return next; @@ -705,11 +706,11 @@ static int find_ref_delta(const unsigned char *sha1, enum object_type type) return -first-1; } -static void find_ref_delta_children(const unsigned char *sha1, +static void find_ref_delta_children(const struct object_id *oid, int *first_index, int *last_index, enum object_type type) { - int first = find_ref_delta(sha1, type); + int first = find_ref_delta(oid, type); int last = first; int end = nr_ref_deltas - 1; @@ -718,9 +719,9 @@ static void find_ref_delta_children(const unsigned char *sha1, *last_index = -1; return; } - while (first > 0 && !hashcmp(ref_deltas[first - 1].sha1, sha1)) + while (first > 0 && !oidcmp(&ref_deltas[first - 1].oid, oid)) --first; - while (last < end && !hashcmp(ref_deltas[last + 1].sha1, sha1)) + while (last < end && !oidcmp(&ref_deltas[last + 1].oid, oid)) ++last; *first_index = first; *last_index = last; @@ -772,7 +773,7 @@ static int check_collison(struct object_entry *entry) memset(&data, 0, sizeof(data)); data.entry = entry; - data.st = open_istream(entry->idx.oid.hash, &type, &size, NULL); + data.st = open_istream(&entry->idx.oid, &type, &size, NULL); if (!data.st) return -1; if (size != entry->size || type != entry->type) @@ -811,12 +812,12 @@ static void sha1_object(const void *data, struct object_entry *obj_entry, enum object_type has_type; unsigned long has_size; read_lock(); - has_type = sha1_object_info(oid->hash, &has_size); + has_type = oid_object_info(oid, &has_size); if (has_type < 0) die(_("cannot read existing object info %s"), oid_to_hex(oid)); if (has_type != type || has_size != size) die(_("SHA1 COLLISION FOUND WITH %s !"), oid_to_hex(oid)); - has_data = read_sha1_file(oid->hash, &has_type, &has_size); + has_data = read_object_file(oid, &has_type, &has_size); read_unlock(); if (!data) data = new_data = get_data_from_pack(obj_entry); @@ -992,7 +993,7 @@ static struct base_data *find_unresolved_deltas_1(struct base_data *base, struct base_data *prev_base) { if (base->ref_last == -1 && base->ofs_last == -1) { - find_ref_delta_children(base->obj->idx.oid.hash, + find_ref_delta_children(&base->obj->idx.oid, &base->ref_first, &base->ref_last, OBJ_REF_DELTA); @@ -1076,7 +1077,7 @@ static int compare_ref_delta_entry(const void *a, const void *b) const struct ref_delta_entry *delta_a = a; const struct ref_delta_entry *delta_b = b; - return hashcmp(delta_a->sha1, delta_b->sha1); + return oidcmp(&delta_a->oid, &delta_b->oid); } static void resolve_base(struct object_entry *obj) @@ -1142,7 +1143,7 @@ static void parse_pack_objects(unsigned char *hash) ofs_delta++; } else if (obj->type == OBJ_REF_DELTA) { ALLOC_GROW(ref_deltas, nr_ref_deltas + 1, ref_deltas_alloc); - hashcpy(ref_deltas[nr_ref_deltas].sha1, ref_delta_oid.hash); + oidcpy(&ref_deltas[nr_ref_deltas].oid, &ref_delta_oid); ref_deltas[nr_ref_deltas].obj_no = i; nr_ref_deltas++; } else if (!data) { @@ -1374,14 +1375,15 @@ static void fix_unresolved_deltas(struct hashfile *f) if (objects[d->obj_no].real_type != OBJ_REF_DELTA) continue; - base_obj->data = read_sha1_file(d->sha1, &type, &base_obj->size); + base_obj->data = read_object_file(&d->oid, &type, + &base_obj->size); if (!base_obj->data) continue; - if (check_sha1_signature(d->sha1, base_obj->data, + if (check_object_signature(&d->oid, base_obj->data, base_obj->size, type_name(type))) - die(_("local object %s is corrupt"), sha1_to_hex(d->sha1)); - base_obj->obj = append_obj_to_pack(f, d->sha1, + die(_("local object %s is corrupt"), oid_to_hex(&d->oid)); + base_obj->obj = append_obj_to_pack(f, d->oid.hash, base_obj->data, base_obj->size, type); find_unresolved_deltas(base_obj); display_progress(progress, nr_resolved_deltas); @@ -1591,7 +1593,7 @@ static void read_idx_option(struct pack_idx_option *opts, const char *pack_name) /* * Get rid of the idx file as we do not need it anymore. * NEEDSWORK: extract this bit from free_pack_by_name() in - * sha1_file.c, perhaps? It shouldn't matter very much as we + * sha1-file.c, perhaps? It shouldn't matter very much as we * know we haven't installed this pack (hence we never have * read anything from it). */ diff --git a/builtin/init-db.c b/builtin/init-db.c index 68ff4ad75a..2542c5244e 100644 --- a/builtin/init-db.c +++ b/builtin/init-db.c @@ -7,7 +7,7 @@ #include "config.h" #include "refs.h" #include "builtin.h" -#include "exec_cmd.h" +#include "exec-cmd.h" #include "parse-options.h" #ifndef DEFAULT_GIT_TEMPLATE_DIR diff --git a/builtin/log.c b/builtin/log.c index 94ee177d56..71f68a3e4f 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -518,7 +518,7 @@ static int show_tag_object(const struct object_id *oid, struct rev_info *rev) { unsigned long size; enum object_type type; - char *buf = read_sha1_file(oid->hash, &type, &size); + char *buf = read_object_file(oid, &type, &size); int offset = 0; if (!buf) @@ -541,7 +541,7 @@ static int show_tag_object(const struct object_id *oid, struct rev_info *rev) return 0; } -static int show_tree_object(const unsigned char *sha1, +static int show_tree_object(const struct object_id *oid, struct strbuf *base, const char *pathname, unsigned mode, int stage, void *context) { @@ -1873,12 +1873,12 @@ static void print_commit(char sign, struct commit *commit, int verbose, { if (!verbose) { fprintf(file, "%c %s\n", sign, - find_unique_abbrev(commit->object.oid.hash, abbrev)); + find_unique_abbrev(&commit->object.oid, abbrev)); } else { struct strbuf buf = STRBUF_INIT; pp_commit_easy(CMIT_FMT_ONELINE, commit, &buf); fprintf(file, "%c %s %s\n", sign, - find_unique_abbrev(commit->object.oid.hash, abbrev), + find_unique_abbrev(&commit->object.oid, abbrev), buf.buf); strbuf_release(&buf); } diff --git a/builtin/ls-files.c b/builtin/ls-files.c index 2fc836e330..a71f6bd088 100644 --- a/builtin/ls-files.c +++ b/builtin/ls-files.c @@ -240,7 +240,7 @@ static void show_ce(struct repository *repo, struct dir_struct *dir, printf("%s%06o %s %d\t", tag, ce->ce_mode, - find_unique_abbrev(ce->oid.hash, abbrev), + find_unique_abbrev(&ce->oid, abbrev), ce_stage(ce)); } write_eolinfo(repo->index, ce, fullname); @@ -271,7 +271,7 @@ static void show_ru_info(const struct index_state *istate) if (!ui->mode[i]) continue; printf("%s%06o %s %d\t", tag_resolve_undo, ui->mode[i], - find_unique_abbrev(ui->sha1[i], abbrev), + find_unique_abbrev(&ui->oid[i], abbrev), i + 1); write_name(path); } diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c index ef965408e8..d44b4f9c27 100644 --- a/builtin/ls-tree.c +++ b/builtin/ls-tree.c @@ -60,7 +60,7 @@ static int show_recursive(const char *base, int baselen, const char *pathname) return 0; } -static int show_tree(const unsigned char *sha1, struct strbuf *base, +static int show_tree(const struct object_id *oid, struct strbuf *base, const char *pathname, unsigned mode, int stage, void *context) { int retval = 0; @@ -94,7 +94,7 @@ static int show_tree(const unsigned char *sha1, struct strbuf *base, char size_text[24]; if (!strcmp(type, blob_type)) { unsigned long size; - if (sha1_object_info(sha1, &size) == OBJ_BAD) + if (oid_object_info(oid, &size) == OBJ_BAD) xsnprintf(size_text, sizeof(size_text), "BAD"); else @@ -103,11 +103,11 @@ static int show_tree(const unsigned char *sha1, struct strbuf *base, } else xsnprintf(size_text, sizeof(size_text), "-"); printf("%06o %s %s %7s\t", mode, type, - find_unique_abbrev(sha1, abbrev), + find_unique_abbrev(oid, abbrev), size_text); } else printf("%06o %s %s\t", mode, type, - find_unique_abbrev(sha1, abbrev)); + find_unique_abbrev(oid, abbrev)); } baselen = base->len; strbuf_addstr(base, pathname); diff --git a/builtin/merge-tree.c b/builtin/merge-tree.c index d01ddecf66..bf01e05808 100644 --- a/builtin/merge-tree.c +++ b/builtin/merge-tree.c @@ -2,7 +2,7 @@ #include "tree-walk.h" #include "xdiff-interface.h" #include "blob.h" -#include "exec_cmd.h" +#include "exec-cmd.h" #include "merge-blobs.h" static const char merge_tree_usage[] = "git merge-tree "; @@ -60,7 +60,7 @@ static void *result(struct merge_list *entry, unsigned long *size) const char *path = entry->path; if (!entry->stage) - return read_sha1_file(entry->blob->object.oid.hash, &type, size); + return read_object_file(&entry->blob->object.oid, &type, size); base = NULL; if (entry->stage == 1) { base = entry->blob; @@ -82,7 +82,8 @@ static void *origin(struct merge_list *entry, unsigned long *size) enum object_type type; while (entry) { if (entry->stage == 2) - return read_sha1_file(entry->blob->object.oid.hash, &type, size); + return read_object_file(&entry->blob->object.oid, + &type, size); entry = entry->link; } return NULL; diff --git a/builtin/merge.c b/builtin/merge.c index ee050a47f3..9db5a2cf16 100644 --- a/builtin/merge.c +++ b/builtin/merge.c @@ -412,7 +412,7 @@ static void finish(struct commit *head_commit, * We ignore errors in 'gc --auto', since the * user should see them. */ - close_all_packs(); + close_all_packs(the_repository->objects); run_command_v_opt(argv_gc_auto, RUN_GIT_CMD); } } @@ -639,7 +639,7 @@ static int read_tree_trivial(struct object_id *common, struct object_id *head, static void write_tree_trivial(struct object_id *oid) { - if (write_cache_as_tree(oid->hash, 0, NULL)) + if (write_cache_as_tree(oid, 0, NULL)) die(_("git write-tree failed to write a tree")); } @@ -1324,7 +1324,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix) check_commit_signature(commit, &signature_check); - find_unique_abbrev_r(hex, commit->object.oid.hash, DEFAULT_ABBREV); + find_unique_abbrev_r(hex, &commit->object.oid, DEFAULT_ABBREV); switch (signature_check.result) { case 'G': break; @@ -1417,9 +1417,9 @@ int cmd_merge(int argc, const char **argv, const char *prefix) if (verbosity >= 0) { printf(_("Updating %s..%s\n"), - find_unique_abbrev(head_commit->object.oid.hash, + find_unique_abbrev(&head_commit->object.oid, DEFAULT_ABBREV), - find_unique_abbrev(remoteheads->item->object.oid.hash, + find_unique_abbrev(&remoteheads->item->object.oid, DEFAULT_ABBREV)); } strbuf_addstr(&msg, "Fast-forward"); diff --git a/builtin/mktag.c b/builtin/mktag.c index beb552847b..9f5a50a8fd 100644 --- a/builtin/mktag.c +++ b/builtin/mktag.c @@ -18,17 +18,17 @@ /* * We refuse to tag something we can't verify. Just because. */ -static int verify_object(const unsigned char *sha1, const char *expected_type) +static int verify_object(const struct object_id *oid, const char *expected_type) { int ret = -1; enum object_type type; unsigned long size; - void *buffer = read_sha1_file(sha1, &type, &size); - const unsigned char *repl = lookup_replace_object(sha1); + void *buffer = read_object_file(oid, &type, &size); + const struct object_id *repl = lookup_replace_object(oid); if (buffer) { if (type == type_from_string(expected_type)) - ret = check_sha1_signature(repl, buffer, size, expected_type); + ret = check_object_signature(repl, buffer, size, expected_type); free(buffer); } return ret; @@ -38,8 +38,8 @@ static int verify_tag(char *buffer, unsigned long size) { int typelen; char type[20]; - unsigned char sha1[20]; - const char *object, *type_line, *tag_line, *tagger_line, *lb, *rb; + struct object_id oid; + const char *object, *type_line, *tag_line, *tagger_line, *lb, *rb, *p; size_t len; if (size < 84) @@ -52,11 +52,11 @@ static int verify_tag(char *buffer, unsigned long size) if (memcmp(object, "object ", 7)) return error("char%d: does not start with \"object \"", 0); - if (get_sha1_hex(object + 7, sha1)) + if (parse_oid_hex(object + 7, &oid, &p)) return error("char%d: could not get SHA1 hash", 7); /* Verify type line */ - type_line = object + 48; + type_line = p + 1; if (memcmp(type_line - 1, "\ntype ", 6)) return error("char%d: could not find \"\\ntype \"", 47); @@ -80,8 +80,8 @@ static int verify_tag(char *buffer, unsigned long size) type[typelen] = 0; /* Verify that the object matches */ - if (verify_object(sha1, type)) - return error("char%d: could not verify object %s", 7, sha1_to_hex(sha1)); + if (verify_object(&oid, type)) + return error("char%d: could not verify object %s", 7, oid_to_hex(&oid)); /* Verify the tag-name: we don't allow control characters or spaces in it */ tag_line += 4; diff --git a/builtin/mktree.c b/builtin/mktree.c index f5f3c0eea1..263c530315 100644 --- a/builtin/mktree.c +++ b/builtin/mktree.c @@ -10,13 +10,13 @@ static struct treeent { unsigned mode; - unsigned char sha1[20]; + struct object_id oid; int len; char name[FLEX_ARRAY]; } **entries; static int alloc, used; -static void append_to_tree(unsigned mode, unsigned char *sha1, char *path) +static void append_to_tree(unsigned mode, struct object_id *oid, char *path) { struct treeent *ent; size_t len = strlen(path); @@ -26,7 +26,7 @@ static void append_to_tree(unsigned mode, unsigned char *sha1, char *path) FLEX_ALLOC_MEM(ent, name, path, len); ent->mode = mode; ent->len = len; - hashcpy(ent->sha1, sha1); + oidcpy(&ent->oid, oid); ALLOC_GROW(entries, used + 1, alloc); entries[used++] = ent; @@ -54,7 +54,7 @@ static void write_tree(struct object_id *oid) for (i = 0; i < used; i++) { struct treeent *ent = entries[i]; strbuf_addf(&buf, "%o %s%c", ent->mode, ent->name, '\0'); - strbuf_add(&buf, ent->sha1, 20); + strbuf_add(&buf, ent->oid.hash, the_hash_algo->rawsz); } write_object_file(buf.buf, buf.len, tree_type, oid); @@ -69,11 +69,12 @@ static const char *mktree_usage[] = { static void mktree_line(char *buf, size_t len, int nul_term_line, int allow_missing) { char *ptr, *ntr; + const char *p; unsigned mode; enum object_type mode_type; /* object type derived from mode */ enum object_type obj_type; /* object type derived from sha */ char *path, *to_free = NULL; - unsigned char sha1[20]; + struct object_id oid; ptr = buf; /* @@ -85,9 +86,8 @@ static void mktree_line(char *buf, size_t len, int nul_term_line, int allow_miss die("input format error: %s", buf); ptr = ntr + 1; /* type */ ntr = strchr(ptr, ' '); - if (!ntr || buf + len <= ntr + 40 || - ntr[41] != '\t' || - get_sha1_hex(ntr + 1, sha1)) + if (!ntr || parse_oid_hex(ntr + 1, &oid, &p) || + *p != '\t') die("input format error: %s", buf); /* It is perfectly normal if we do not have a commit from a submodule */ @@ -116,12 +116,12 @@ static void mktree_line(char *buf, size_t len, int nul_term_line, int allow_miss } /* Check the type of object identified by sha1 */ - obj_type = sha1_object_info(sha1, NULL); + obj_type = oid_object_info(&oid, NULL); if (obj_type < 0) { if (allow_missing) { ; /* no problem - missing objects are presumed to be of the right type */ } else { - die("entry '%s' object %s is unavailable", path, sha1_to_hex(sha1)); + die("entry '%s' object %s is unavailable", path, oid_to_hex(&oid)); } } else { if (obj_type != mode_type) { @@ -131,11 +131,11 @@ static void mktree_line(char *buf, size_t len, int nul_term_line, int allow_miss * because the new tree entry will never be correct. */ die("entry '%s' object %s is a %s but specified type was (%s)", - path, sha1_to_hex(sha1), type_name(obj_type), type_name(mode_type)); + path, oid_to_hex(&oid), type_name(obj_type), type_name(mode_type)); } } - append_to_tree(mode, sha1, path); + append_to_tree(mode, &oid, path); free(to_free); } diff --git a/builtin/name-rev.c b/builtin/name-rev.c index 9e088ebd11..387ddf85d2 100644 --- a/builtin/name-rev.c +++ b/builtin/name-rev.c @@ -328,7 +328,7 @@ static void show_name(const struct object *obj, else if (allow_undefined) printf("undefined\n"); else if (always) - printf("%s\n", find_unique_abbrev(oid->hash, DEFAULT_ABBREV)); + printf("%s\n", find_unique_abbrev(oid, DEFAULT_ABBREV)); else die("cannot describe '%s'", oid_to_hex(oid)); strbuf_release(&buf); diff --git a/builtin/notes.c b/builtin/notes.c index 6d2fda4a7d..e5bf80eef1 100644 --- a/builtin/notes.c +++ b/builtin/notes.c @@ -14,7 +14,7 @@ #include "blob.h" #include "pretty.h" #include "refs.h" -#include "exec_cmd.h" +#include "exec-cmd.h" #include "run-command.h" #include "parse-options.h" #include "string-list.h" @@ -118,11 +118,11 @@ static int list_each_note(const struct object_id *object_oid, return 0; } -static void copy_obj_to_fd(int fd, const unsigned char *sha1) +static void copy_obj_to_fd(int fd, const struct object_id *oid) { unsigned long size; enum object_type type; - char *buf = read_sha1_file(sha1, &type, &size); + char *buf = read_object_file(oid, &type, &size); if (buf) { if (size) write_or_die(fd, buf, size); @@ -162,7 +162,7 @@ static void write_commented_object(int fd, const struct object_id *object) } static void prepare_note_data(const struct object_id *object, struct note_data *d, - const unsigned char *old_note) + const struct object_id *old_note) { if (d->use_editor || !d->given) { int fd; @@ -253,7 +253,7 @@ static int parse_reuse_arg(const struct option *opt, const char *arg, int unset) if (get_oid(arg, &object)) die(_("failed to resolve '%s' as a valid ref."), arg); - if (!(buf = read_sha1_file(object.hash, &type, &len))) { + if (!(buf = read_object_file(&object, &type, &len))) { free(buf); die(_("failed to read object '%s'."), arg); } @@ -457,7 +457,7 @@ static int add(int argc, const char **argv, const char *prefix) oid_to_hex(&object)); } - prepare_note_data(&object, &d, note ? note->hash : NULL); + prepare_note_data(&object, &d, note); if (d.buf.len || allow_empty) { write_note_data(&d, &new_note); if (add_note(t, &object, &new_note, combine_notes_overwrite)) @@ -602,13 +602,13 @@ static int append_edit(int argc, const char **argv, const char *prefix) t = init_notes_check(argv[0], NOTES_INIT_WRITABLE); note = get_note(t, &object); - prepare_note_data(&object, &d, edit && note ? note->hash : NULL); + prepare_note_data(&object, &d, edit && note ? note : NULL); if (note && !edit) { /* Append buf to previous note contents */ unsigned long size; enum object_type type; - char *prev_buf = read_sha1_file(note->hash, &type, &size); + char *prev_buf = read_object_file(note, &type, &size); strbuf_grow(&d.buf, size + 1); if (d.buf.len && prev_buf && size) diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c index e9d3cfb9e3..4bdae5a1d8 100644 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@ -1,5 +1,6 @@ #include "builtin.h" #include "cache.h" +#include "repository.h" #include "config.h" #include "attr.h" #include "object.h" @@ -28,6 +29,7 @@ #include "argv-array.h" #include "list.h" #include "packfile.h" +#include "object-store.h" static const char *pack_usage[] = { N_("git pack-objects --stdout [...] [< | < ]"), @@ -122,11 +124,10 @@ static void *get_delta(struct object_entry *entry) void *buf, *base_buf, *delta_buf; enum object_type type; - buf = read_sha1_file(entry->idx.oid.hash, &type, &size); + buf = read_object_file(&entry->idx.oid, &type, &size); if (!buf) die("unable to read %s", oid_to_hex(&entry->idx.oid)); - base_buf = read_sha1_file(entry->delta->idx.oid.hash, &type, - &base_size); + base_buf = read_object_file(&entry->delta->idx.oid, &type, &base_size); if (!base_buf) die("unable to read %s", oid_to_hex(&entry->delta->idx.oid)); @@ -267,11 +268,10 @@ static unsigned long write_no_reuse_object(struct hashfile *f, struct object_ent if (!usable_delta) { if (entry->type == OBJ_BLOB && entry->size > big_file_threshold && - (st = open_istream(entry->idx.oid.hash, &type, &size, NULL)) != NULL) + (st = open_istream(&entry->idx.oid, &type, &size, NULL)) != NULL) buf = NULL; else { - buf = read_sha1_file(entry->idx.oid.hash, &type, - &size); + buf = read_object_file(&entry->idx.oid, &type, &size); if (!buf) die(_("unable to read %s"), oid_to_hex(&entry->idx.oid)); @@ -1025,8 +1025,7 @@ static int want_object_in_pack(const struct object_id *oid, if (want != -1) return want; } - - list_for_each(pos, &packed_git_mru) { + list_for_each(pos, get_packed_git_mru(the_repository)) { struct packed_git *p = list_entry(pos, struct packed_git, mru); off_t offset; @@ -1044,7 +1043,8 @@ static int want_object_in_pack(const struct object_id *oid, } want = want_found_object(exclude, p); if (!exclude && want > 0) - list_move(&p->mru, &packed_git_mru); + list_move(&p->mru, + get_packed_git_mru(the_repository)); if (want != -1) return want; } @@ -1190,7 +1190,7 @@ static struct pbase_tree_cache *pbase_tree_get(const struct object_id *oid) /* Did not find one. Either we got a bogus request or * we need to read and perhaps cache. */ - data = read_sha1_file(oid->hash, &type, &size); + data = read_object_file(oid, &type, &size); if (!data) return NULL; if (type != OBJ_TREE) { @@ -1351,7 +1351,7 @@ static void add_preferred_base(struct object_id *oid) if (window <= num_preferred_base++) return; - data = read_object_with_reference(oid->hash, tree_type, &size, tree_oid.hash); + data = read_object_with_reference(oid, tree_type, &size, &tree_oid); if (!data) return; @@ -1516,7 +1516,7 @@ static void check_object(struct object_entry *entry) unuse_pack(&w_curs); } - entry->type = sha1_object_info(entry->idx.oid.hash, &entry->size); + entry->type = oid_object_info(&entry->idx.oid, &entry->size); /* * The error condition is checked in prepare_pack(). This is * to permit a missing preferred base object to be ignored @@ -1578,8 +1578,7 @@ static void drop_reused_delta(struct object_entry *entry) * And if that fails, the error will be recorded in entry->type * and dealt with in prepare_pack(). */ - entry->type = sha1_object_info(entry->idx.oid.hash, - &entry->size); + entry->type = oid_object_info(&entry->idx.oid, &entry->size); } } @@ -1871,8 +1870,7 @@ static int try_delta(struct unpacked *trg, struct unpacked *src, /* Load data if not already done */ if (!trg->data) { read_lock(); - trg->data = read_sha1_file(trg_entry->idx.oid.hash, &type, - &sz); + trg->data = read_object_file(&trg_entry->idx.oid, &type, &sz); read_unlock(); if (!trg->data) die("object %s cannot be read", @@ -1885,8 +1883,7 @@ static int try_delta(struct unpacked *trg, struct unpacked *src, } if (!src->data) { read_lock(); - src->data = read_sha1_file(src_entry->idx.oid.hash, &type, - &sz); + src->data = read_object_file(&src_entry->idx.oid, &type, &sz); read_unlock(); if (!src->data) { if (src_entry->preferred_base) { @@ -2674,7 +2671,7 @@ static void add_objects_in_unpacked_packs(struct rev_info *revs) memset(&in_pack, 0, sizeof(in_pack)); - for (p = packed_git; p; p = p->next) { + for (p = get_packed_git(the_repository); p; p = p->next) { struct object_id oid; struct object *o; @@ -2709,7 +2706,7 @@ static void add_objects_in_unpacked_packs(struct rev_info *revs) static int add_loose_object(const struct object_id *oid, const char *path, void *data) { - enum object_type type = sha1_object_info(oid->hash, NULL); + enum object_type type = oid_object_info(oid, NULL); if (type < 0) { warning("loose object at %s could not be examined", path); @@ -2737,7 +2734,8 @@ static int has_sha1_pack_kept_or_nonlocal(const struct object_id *oid) static struct packed_git *last_found = (void *)1; struct packed_git *p; - p = (last_found != (void *)1) ? last_found : packed_git; + p = (last_found != (void *)1) ? last_found : + get_packed_git(the_repository); while (p) { if ((!p->pack_local || p->pack_keep) && @@ -2746,7 +2744,7 @@ static int has_sha1_pack_kept_or_nonlocal(const struct object_id *oid) return 1; } if (p == last_found) - p = packed_git; + p = get_packed_git(the_repository); else p = p->next; if (p == last_found) @@ -2782,7 +2780,7 @@ static void loosen_unused_packed_objects(struct rev_info *revs) uint32_t i; struct object_id oid; - for (p = packed_git; p; p = p->next) { + for (p = get_packed_git(the_repository); p; p = p->next) { if (!p->pack_local || p->pack_keep) continue; @@ -3150,10 +3148,9 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix) if (progress && all_progress_implied) progress = 2; - prepare_packed_git(); if (ignore_packed_keep) { struct packed_git *p; - for (p = packed_git; p; p = p->next) + for (p = get_packed_git(the_repository); p; p = p->next) if (p->pack_local && p->pack_keep) break; if (!p) /* no keep-able packs found */ @@ -3166,7 +3163,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix) * also covers non-local objects */ struct packed_git *p; - for (p = packed_git; p; p = p->next) { + for (p = get_packed_git(the_repository); p; p = p->next) { if (!p->pack_local) { have_non_local_packs = 1; break; diff --git a/builtin/pack-redundant.c b/builtin/pack-redundant.c index 991e1bb76f..354478a127 100644 --- a/builtin/pack-redundant.c +++ b/builtin/pack-redundant.c @@ -7,7 +7,9 @@ */ #include "builtin.h" +#include "repository.h" #include "packfile.h" +#include "object-store.h" #define BLKSIZE 512 @@ -571,7 +573,7 @@ static struct pack_list * add_pack(struct packed_git *p) static struct pack_list * add_pack_file(const char *filename) { - struct packed_git *p = packed_git; + struct packed_git *p = get_packed_git(the_repository); if (strlen(filename) < 40) die("Bad pack filename: %s", filename); @@ -586,7 +588,7 @@ static struct pack_list * add_pack_file(const char *filename) static void load_all(void) { - struct packed_git *p = packed_git; + struct packed_git *p = get_packed_git(the_repository); while (p) { add_pack(p); @@ -629,8 +631,6 @@ int cmd_pack_redundant(int argc, const char **argv, const char *prefix) break; } - prepare_packed_git(); - if (load_all_packs) load_all(); else diff --git a/builtin/prune.c b/builtin/prune.c index 4394d01c93..38ced18dad 100644 --- a/builtin/prune.c +++ b/builtin/prune.c @@ -50,7 +50,7 @@ static int prune_object(const struct object_id *oid, const char *fullpath, if (st.st_mtime > expire) return 0; if (show_only || verbose) { - enum object_type type = sha1_object_info(oid->hash, NULL); + enum object_type type = oid_object_info(oid, NULL); printf("%s %s\n", oid_to_hex(oid), (type > 0) ? type_name(type) : "unknown"); } diff --git a/builtin/pull.c b/builtin/pull.c index e32d6cd5b4..71aac5005e 100644 --- a/builtin/pull.c +++ b/builtin/pull.c @@ -9,7 +9,7 @@ #include "config.h" #include "builtin.h" #include "parse-options.h" -#include "exec_cmd.h" +#include "exec-cmd.h" #include "run-command.h" #include "sha1-array.h" #include "remote.h" diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c index 75e7f18ace..4b68a28e92 100644 --- a/builtin/receive-pack.c +++ b/builtin/receive-pack.c @@ -1,4 +1,5 @@ #include "builtin.h" +#include "repository.h" #include "config.h" #include "lockfile.h" #include "pack.h" @@ -6,7 +7,7 @@ #include "pkt-line.h" #include "sideband.h" #include "run-command.h" -#include "exec_cmd.h" +#include "exec-cmd.h" #include "commit.h" #include "object.h" #include "remote.h" @@ -1242,11 +1243,11 @@ static void check_aliased_update(struct command *cmd, struct string_list *list) rp_error("refusing inconsistent update between symref '%s' (%s..%s) and" " its target '%s' (%s..%s)", cmd->ref_name, - find_unique_abbrev(cmd->old_oid.hash, DEFAULT_ABBREV), - find_unique_abbrev(cmd->new_oid.hash, DEFAULT_ABBREV), + find_unique_abbrev(&cmd->old_oid, DEFAULT_ABBREV), + find_unique_abbrev(&cmd->new_oid, DEFAULT_ABBREV), dst_cmd->ref_name, - find_unique_abbrev(dst_cmd->old_oid.hash, DEFAULT_ABBREV), - find_unique_abbrev(dst_cmd->new_oid.hash, DEFAULT_ABBREV)); + find_unique_abbrev(&dst_cmd->old_oid, DEFAULT_ABBREV), + find_unique_abbrev(&dst_cmd->new_oid, DEFAULT_ABBREV)); cmd->error_string = dst_cmd->error_string = "inconsistent aliased update"; @@ -1778,7 +1779,7 @@ static const char *unpack(int err_fd, struct shallow_info *si) status = finish_command(&child); if (status) return "index-pack abnormal exit"; - reprepare_packed_git(); + reprepare_packed_git(the_repository); } return NULL; } @@ -2027,7 +2028,7 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix) proc.git_cmd = 1; proc.argv = argv_gc_auto; - close_all_packs(); + close_all_packs(the_repository->objects); if (!start_command(&proc)) { if (use_sideband) copy_to_sideband(proc.err, -1, NULL); diff --git a/builtin/reflog.c b/builtin/reflog.c index 4719a5354c..a89bd1dd25 100644 --- a/builtin/reflog.c +++ b/builtin/reflog.c @@ -75,7 +75,7 @@ static int tree_is_complete(const struct object_id *oid) if (!tree->buffer) { enum object_type type; unsigned long size; - void *data = read_sha1_file(oid->hash, &type, &size); + void *data = read_object_file(oid, &type, &size); if (!data) { tree->object.flags |= INCOMPLETE; return 0; diff --git a/builtin/replace.c b/builtin/replace.c index 482f12018f..935647be6b 100644 --- a/builtin/replace.c +++ b/builtin/replace.c @@ -53,8 +53,8 @@ static int show_reference(const char *refname, const struct object_id *oid, if (get_oid(refname, &object)) return error("Failed to resolve '%s' as a valid ref.", refname); - obj_type = sha1_object_info(object.hash, NULL); - repl_type = sha1_object_info(oid->hash, NULL); + obj_type = oid_object_info(&object, NULL); + repl_type = oid_object_info(oid, NULL); printf("%s (%s) -> %s (%s)\n", refname, type_name(obj_type), oid_to_hex(oid), type_name(repl_type)); @@ -162,8 +162,8 @@ static int replace_object_oid(const char *object_ref, struct ref_transaction *transaction; struct strbuf err = STRBUF_INIT; - obj_type = sha1_object_info(object->hash, NULL); - repl_type = sha1_object_info(repl->hash, NULL); + obj_type = oid_object_info(object, NULL); + repl_type = oid_object_info(repl, NULL); if (!force && obj_type != repl_type) die("Objects must be of the same type.\n" "'%s' points to a replaced object of type '%s'\n" @@ -290,7 +290,7 @@ static int edit_and_replace(const char *object_ref, int force, int raw) if (get_oid(object_ref, &old_oid) < 0) die("Not a valid object name: '%s'", object_ref); - type = sha1_object_info(old_oid.hash, NULL); + type = oid_object_info(&old_oid, NULL); if (type < 0) die("unable to get object type for %s", oid_to_hex(&old_oid)); diff --git a/builtin/reset.c b/builtin/reset.c index 5da0f75de9..7f1c3f02a3 100644 --- a/builtin/reset.c +++ b/builtin/reset.c @@ -109,7 +109,7 @@ static void print_new_head_line(struct commit *commit) struct strbuf buf = STRBUF_INIT; printf(_("HEAD is now at %s"), - find_unique_abbrev(commit->object.oid.hash, DEFAULT_ABBREV)); + find_unique_abbrev(&commit->object.oid, DEFAULT_ABBREV)); pp_commit_easy(CMIT_FMT_ONELINE, commit, &buf); if (buf.len > 0) diff --git a/builtin/rev-list.c b/builtin/rev-list.c index 6f5b9b0847..fadd3ec14c 100644 --- a/builtin/rev-list.c +++ b/builtin/rev-list.c @@ -108,7 +108,7 @@ static void show_commit(struct commit *commit, void *data) if (!revs->graph) fputs(get_revision_mark(revs, commit), stdout); if (revs->abbrev_commit && revs->abbrev) - fputs(find_unique_abbrev(commit->object.oid.hash, revs->abbrev), + fputs(find_unique_abbrev(&commit->object.oid, revs->abbrev), stdout); else fputs(oid_to_hex(&commit->object.oid), stdout); diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c index a1e680b5e9..36b2087782 100644 --- a/builtin/rev-parse.c +++ b/builtin/rev-parse.c @@ -159,7 +159,7 @@ static void show_rev(int type, const struct object_id *oid, const char *name) } } else if (abbrev) - show_with_type(type, find_unique_abbrev(oid->hash, abbrev)); + show_with_type(type, find_unique_abbrev(oid, abbrev)); else show_with_type(type, oid_to_hex(oid)); } diff --git a/builtin/rm.c b/builtin/rm.c index 4447bb4d0f..5b6fc7ee81 100644 --- a/builtin/rm.c +++ b/builtin/rm.c @@ -178,7 +178,7 @@ static int check_local_mod(struct object_id *head, int index_only) * way as changed from the HEAD. */ if (no_head - || get_tree_entry(head->hash, name, oid.hash, &mode) + || get_tree_entry(head, name, &oid, &mode) || ce->ce_mode != create_ce_mode(mode) || oidcmp(&ce->oid, &oid)) staged_changes = 1; diff --git a/builtin/shortlog.c b/builtin/shortlog.c index e29875b843..608d6ba77b 100644 --- a/builtin/shortlog.c +++ b/builtin/shortlog.c @@ -11,7 +11,8 @@ #include "parse-options.h" static char const * const shortlog_usage[] = { - N_("git shortlog [] [] [[--] [...]]"), + N_("git shortlog [] [] [[--] ...]"), + N_("git log --pretty=short | git shortlog []"), NULL }; @@ -283,6 +284,7 @@ int cmd_shortlog(int argc, const char **argv, const char *prefix) for (;;) { switch (parse_options_step(&ctx, options, shortlog_usage)) { case PARSE_OPT_HELP: + case PARSE_OPT_ERROR: exit(129); case PARSE_OPT_DONE: goto parse_done; @@ -292,6 +294,11 @@ int cmd_shortlog(int argc, const char **argv, const char *prefix) parse_done: argc = parse_options_end(&ctx); + if (nongit && argc > 1) { + error(_("too many arguments given outside repository")); + usage_with_options(shortlog_usage, options); + } + if (setup_revisions(argc, argv, &rev, NULL) != 1) { error(_("unrecognized argument: %s"), argv[1]); usage_with_options(shortlog_usage, options); diff --git a/builtin/show-branch.c b/builtin/show-branch.c index e8a4aa40cb..6c2148b71d 100644 --- a/builtin/show-branch.c +++ b/builtin/show-branch.c @@ -292,7 +292,7 @@ static void show_one_commit(struct commit *commit, int no_name) } else printf("[%s] ", - find_unique_abbrev(commit->object.oid.hash, + find_unique_abbrev(&commit->object.oid, DEFAULT_ABBREV)); } puts(pretty_str); diff --git a/builtin/show-ref.c b/builtin/show-ref.c index 41e5e71cad..f2eb1a7724 100644 --- a/builtin/show-ref.c +++ b/builtin/show-ref.c @@ -29,7 +29,7 @@ static void show_one(const char *refname, const struct object_id *oid) if (quiet) return; - hex = find_unique_abbrev(oid->hash, abbrev); + hex = find_unique_abbrev(oid, abbrev); if (hash_only) printf("%s\n", hex); else @@ -39,7 +39,7 @@ static void show_one(const char *refname, const struct object_id *oid) return; if (!peel_ref(refname, &peeled)) { - hex = find_unique_abbrev(peeled.hash, abbrev); + hex = find_unique_abbrev(&peeled, abbrev); printf("%s %s^{}\n", hex, refname); } } diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index ee020d4749..a404df3ea4 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -16,6 +16,7 @@ #include "revision.h" #include "diffcore.h" #include "diff.h" +#include "object-store.h" #define OPT_QUIET (1 << 0) #define OPT_CACHED (1 << 1) @@ -654,9 +655,13 @@ static void status_submodule(const char *path, const struct object_id *ce_oid, displaypath); } else if (!(flags & OPT_CACHED)) { struct object_id oid; + struct ref_store *refs = get_submodule_ref_store(path); - if (refs_head_ref(get_submodule_ref_store(path), - handle_submodule_head_ref, &oid)) + if (!refs) { + print_status(flags, '-', path, ce_oid, displaypath); + goto cleanup; + } + if (refs_head_ref(refs, handle_submodule_head_ref, &oid)) die(_("could not resolve HEAD ref inside the " "submodule '%s'"), path); @@ -1042,7 +1047,7 @@ static int module_deinit(int argc, const char **argv, const char *prefix) die(_("Use '--all' if you really want to deinitialize all submodules")); if (module_list_compute(argc, argv, prefix, &pathspec, &list) < 0) - BUG("module_list_compute should not choke on empty pathspec"); + return 1; info.prefix = prefix; if (quiet) diff --git a/builtin/tag.c b/builtin/tag.c index da186691ed..46a5c6a1da 100644 --- a/builtin/tag.c +++ b/builtin/tag.c @@ -99,7 +99,8 @@ static int delete_tag(const char *name, const char *ref, { if (delete_ref(NULL, ref, oid, 0)) return 1; - printf(_("Deleted tag '%s' (was %s)\n"), name, find_unique_abbrev(oid->hash, DEFAULT_ABBREV)); + printf(_("Deleted tag '%s' (was %s)\n"), name, + find_unique_abbrev(oid, DEFAULT_ABBREV)); return 0; } @@ -117,7 +118,7 @@ static int verify_tag(const char *name, const char *ref, return -1; if (format->format) - pretty_print_ref(name, oid->hash, format); + pretty_print_ref(name, oid, format); return 0; } @@ -167,7 +168,7 @@ static void write_tag_body(int fd, const struct object_id *oid) enum object_type type; char *buf, *sp; - buf = read_sha1_file(oid->hash, &type, &size); + buf = read_object_file(oid, &type, &size); if (!buf) return; /* skip header */ @@ -211,7 +212,7 @@ static void create_tag(const struct object_id *object, const char *tag, struct strbuf header = STRBUF_INIT; char *path = NULL; - type = sha1_object_info(object->hash, NULL); + type = oid_object_info(object, NULL); if (type <= OBJ_NONE) die(_("bad object type.")); @@ -293,17 +294,17 @@ static void create_reflog_msg(const struct object_id *oid, struct strbuf *sb) strbuf_addstr(sb, rla); } else { strbuf_addstr(sb, "tag: tagging "); - strbuf_add_unique_abbrev(sb, oid->hash, DEFAULT_ABBREV); + strbuf_add_unique_abbrev(sb, oid, DEFAULT_ABBREV); } strbuf_addstr(sb, " ("); - type = sha1_object_info(oid->hash, NULL); + type = oid_object_info(oid, NULL); switch (type) { default: strbuf_addstr(sb, "object of unknown type"); break; case OBJ_COMMIT: - if ((buf = read_sha1_file(oid->hash, &type, &size)) != NULL) { + if ((buf = read_object_file(oid, &type, &size)) != NULL) { subject_len = find_commit_subject(buf, &subject_start); strbuf_insert(sb, sb->len, subject_start, subject_len); } else { @@ -558,7 +559,8 @@ int cmd_tag(int argc, const char **argv, const char *prefix) die("%s", err.buf); ref_transaction_free(transaction); if (force && !is_null_oid(&prev) && oidcmp(&prev, &object)) - printf(_("Updated tag '%s' (was %s)\n"), tag, find_unique_abbrev(prev.hash, DEFAULT_ABBREV)); + printf(_("Updated tag '%s' (was %s)\n"), tag, + find_unique_abbrev(&prev, DEFAULT_ABBREV)); UNLEAK(buf); UNLEAK(ref); diff --git a/builtin/unpack-file.c b/builtin/unpack-file.c index 32e0155577..300eb59657 100644 --- a/builtin/unpack-file.c +++ b/builtin/unpack-file.c @@ -9,7 +9,7 @@ static char *create_temp_file(struct object_id *oid) unsigned long size; int fd; - buf = read_sha1_file(oid->hash, &type, &size); + buf = read_object_file(oid, &type, &size); if (!buf || type != OBJ_BLOB) die("unable to read blob object %s", oid_to_hex(oid)); diff --git a/builtin/unpack-objects.c b/builtin/unpack-objects.c index 6620feec68..b7755c6cc5 100644 --- a/builtin/unpack-objects.c +++ b/builtin/unpack-objects.c @@ -199,7 +199,7 @@ static int check_object(struct object *obj, int type, void *data, struct fsck_op if (!(obj->flags & FLAG_OPEN)) { unsigned long size; - int type = sha1_object_info(obj->oid.hash, &size); + int type = oid_object_info(&obj->oid, &size); if (type != obj->type || type <= 0) die("object of unexpected type"); obj->flags |= FLAG_WRITTEN; @@ -423,7 +423,7 @@ static void unpack_delta_entry(enum object_type type, unsigned long delta_size, if (resolve_against_held(nr, &base_oid, delta_data, delta_size)) return; - base = read_sha1_file(base_oid.hash, &type, &base_size); + base = read_object_file(&base_oid, &type, &base_size); if (!base) { error("failed to read delta-pack base object %s", oid_to_hex(&base_oid)); diff --git a/builtin/update-index.c b/builtin/update-index.c index 58d1c2d282..10d070a76f 100644 --- a/builtin/update-index.c +++ b/builtin/update-index.c @@ -592,7 +592,7 @@ static struct cache_entry *read_one_ent(const char *which, int size; struct cache_entry *ce; - if (get_tree_entry(ent->hash, path, oid.hash, &mode)) { + if (get_tree_entry(ent, path, &oid, &mode)) { if (which) error("%s: not in %s branch.", path, which); return NULL; @@ -1059,6 +1059,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix) break; switch (parseopt_state) { case PARSE_OPT_HELP: + case PARSE_OPT_ERROR: exit(129); case PARSE_OPT_NON_OPTION: case PARSE_OPT_DONE: diff --git a/builtin/verify-commit.c b/builtin/verify-commit.c index 05315ea7c9..dcdaada111 100644 --- a/builtin/verify-commit.c +++ b/builtin/verify-commit.c @@ -44,7 +44,7 @@ static int verify_commit(const char *name, unsigned flags) if (get_oid(name, &oid)) return error("commit '%s' not found.", name); - buf = read_sha1_file(oid.hash, &type, &size); + buf = read_object_file(&oid, &type, &size); if (!buf) return error("%s: unable to read file.", name); if (type != OBJ_COMMIT) diff --git a/builtin/verify-tag.c b/builtin/verify-tag.c index ad7b79fa5c..6fa04b751a 100644 --- a/builtin/verify-tag.c +++ b/builtin/verify-tag.c @@ -72,7 +72,7 @@ int cmd_verify_tag(int argc, const char **argv, const char *prefix) } if (format.format) - pretty_print_ref(name, oid.hash, &format); + pretty_print_ref(name, &oid, &format); } return had_error; } diff --git a/builtin/worktree.c b/builtin/worktree.c index 670555dedd..40a438ed6c 100644 --- a/builtin/worktree.c +++ b/builtin/worktree.c @@ -101,16 +101,9 @@ static int prune_worktree(const char *id, struct strbuf *reason) } path[len] = '\0'; if (!file_exists(path)) { - struct stat st_link; free(path); - /* - * the repo is moved manually and has not been - * accessed since? - */ - if (!stat(git_path("worktrees/%s/link", id), &st_link) && - st_link.st_nlink > 1) - return 0; - if (st.st_mtime <= expire) { + if (stat(git_path("worktrees/%s/index", id), &st) || + st.st_mtime <= expire) { strbuf_addf(reason, _("Removing worktrees/%s: gitdir file points to non-existent location"), id); return 1; } else { @@ -502,7 +495,7 @@ static void show_worktree(struct worktree *wt, int path_maxlen, int abbrev_len) strbuf_addstr(&sb, "(bare)"); else { strbuf_addf(&sb, "%-*s ", abbrev_len, - find_unique_abbrev(wt->head_oid.hash, DEFAULT_ABBREV)); + find_unique_abbrev(&wt->head_oid, DEFAULT_ABBREV)); if (wt->is_detached) strbuf_addstr(&sb, "(detached HEAD)"); else if (wt->head_ref) { @@ -527,7 +520,7 @@ static void measure_widths(struct worktree **wt, int *abbrev, int *maxlen) if (path_len > *maxlen) *maxlen = path_len; - sha1_len = strlen(find_unique_abbrev(wt[i]->head_oid.hash, *abbrev)); + sha1_len = strlen(find_unique_abbrev(&wt[i]->head_oid, *abbrev)); if (sha1_len > *abbrev) *abbrev = sha1_len; } diff --git a/builtin/write-tree.c b/builtin/write-tree.c index bd0a78aa3c..c9d3c544e7 100644 --- a/builtin/write-tree.c +++ b/builtin/write-tree.c @@ -19,7 +19,7 @@ int cmd_write_tree(int argc, const char **argv, const char *unused_prefix) { int flags = 0, ret; const char *prefix = NULL; - unsigned char sha1[20]; + struct object_id oid; const char *me = "git-write-tree"; struct option write_tree_options[] = { OPT_BIT(0, "missing-ok", &flags, N_("allow missing objects"), @@ -38,10 +38,10 @@ int cmd_write_tree(int argc, const char **argv, const char *unused_prefix) argc = parse_options(argc, argv, unused_prefix, write_tree_options, write_tree_usage, 0); - ret = write_cache_as_tree(sha1, flags, prefix); + ret = write_cache_as_tree(&oid, flags, prefix); switch (ret) { case 0: - printf("%s\n", sha1_to_hex(sha1)); + printf("%s\n", oid_to_hex(&oid)); break; case WRITE_TREE_UNREADABLE_INDEX: die("%s: error reading the index", me); diff --git a/bulk-checkin.c b/bulk-checkin.c index 9d87eac07b..de1f4040c7 100644 --- a/bulk-checkin.c +++ b/bulk-checkin.c @@ -3,6 +3,7 @@ */ #include "cache.h" #include "bulk-checkin.h" +#include "repository.h" #include "csum-file.h" #include "pack.h" #include "strbuf.h" @@ -57,20 +58,20 @@ static void finish_bulk_checkin(struct bulk_checkin_state *state) strbuf_release(&packname); /* Make objects we just wrote available to ourselves */ - reprepare_packed_git(); + reprepare_packed_git(the_repository); } -static int already_written(struct bulk_checkin_state *state, unsigned char sha1[]) +static int already_written(struct bulk_checkin_state *state, struct object_id *oid) { int i; /* The object may already exist in the repository */ - if (has_sha1_file(sha1)) + if (has_sha1_file(oid->hash)) return 1; /* Might want to keep the list sorted */ for (i = 0; i < state->nr_written; i++) - if (!hashcmp(state->written[i]->oid.hash, sha1)) + if (!oidcmp(&state->written[i]->oid, oid)) return 1; /* This is a new object we need to keep */ @@ -186,7 +187,7 @@ static void prepare_to_stream(struct bulk_checkin_state *state, } static int deflate_to_pack(struct bulk_checkin_state *state, - unsigned char result_sha1[], + struct object_id *result_oid, int fd, size_t size, enum object_type type, const char *path, unsigned flags) @@ -236,17 +237,17 @@ static int deflate_to_pack(struct bulk_checkin_state *state, if (lseek(fd, seekback, SEEK_SET) == (off_t) -1) return error("cannot seek back"); } - the_hash_algo->final_fn(result_sha1, &ctx); + the_hash_algo->final_fn(result_oid->hash, &ctx); if (!idx) return 0; idx->crc32 = crc32_end(state->f); - if (already_written(state, result_sha1)) { + if (already_written(state, result_oid)) { hashfile_truncate(state->f, &checkpoint); state->offset = checkpoint.offset; free(idx); } else { - hashcpy(idx->oid.hash, result_sha1); + oidcpy(&idx->oid, result_oid); ALLOC_GROW(state->written, state->nr_written + 1, state->alloc_written); @@ -255,11 +256,11 @@ static int deflate_to_pack(struct bulk_checkin_state *state, return 0; } -int index_bulk_checkin(unsigned char *sha1, +int index_bulk_checkin(struct object_id *oid, int fd, size_t size, enum object_type type, const char *path, unsigned flags) { - int status = deflate_to_pack(&state, sha1, fd, size, type, + int status = deflate_to_pack(&state, oid, fd, size, type, path, flags); if (!state.plugged) finish_bulk_checkin(&state); diff --git a/bulk-checkin.h b/bulk-checkin.h index fbd40fc98c..a85527318b 100644 --- a/bulk-checkin.h +++ b/bulk-checkin.h @@ -4,7 +4,7 @@ #ifndef BULK_CHECKIN_H #define BULK_CHECKIN_H -extern int index_bulk_checkin(unsigned char sha1[], +extern int index_bulk_checkin(struct object_id *oid, int fd, size_t size, enum object_type type, const char *path, unsigned flags); diff --git a/bundle.c b/bundle.c index efe547e25f..902c9b5448 100644 --- a/bundle.c +++ b/bundle.c @@ -222,7 +222,7 @@ static int is_tag_in_date_range(struct object *tag, struct rev_info *revs) if (revs->max_age == -1 && revs->min_age == -1) goto out; - buf = read_sha1_file(tag->oid.hash, &type, &size); + buf = read_object_file(&tag->oid, &type, &size); if (!buf) goto out; line = memmem(buf, size, "\ntagger ", 8); diff --git a/cache-tree.c b/cache-tree.c index c52e4303df..6a555f4d43 100644 --- a/cache-tree.c +++ b/cache-tree.c @@ -320,7 +320,7 @@ static int update_one(struct cache_tree *it, struct cache_tree_sub *sub = NULL; const char *path, *slash; int pathlen, entlen; - const unsigned char *sha1; + const struct object_id *oid; unsigned mode; int expected_missing = 0; int contains_ita = 0; @@ -338,7 +338,7 @@ static int update_one(struct cache_tree *it, die("cache-tree.c: '%.*s' in '%s' not found", entlen, path + baselen, path); i += sub->count; - sha1 = sub->cache_tree->oid.hash; + oid = &sub->cache_tree->oid; mode = S_IFDIR; contains_ita = sub->cache_tree->entry_count < 0; if (contains_ita) { @@ -347,19 +347,19 @@ static int update_one(struct cache_tree *it, } } else { - sha1 = ce->oid.hash; + oid = &ce->oid; mode = ce->ce_mode; entlen = pathlen - baselen; i++; } - if (is_null_sha1(sha1) || - (mode != S_IFGITLINK && !missing_ok && !has_sha1_file(sha1))) { + if (is_null_oid(oid) || + (mode != S_IFGITLINK && !missing_ok && !has_object_file(oid))) { strbuf_release(&buffer); if (expected_missing) return -1; return error("invalid object %06o %s for '%.*s'", - mode, sha1_to_hex(sha1), entlen+baselen, path); + mode, oid_to_hex(oid), entlen+baselen, path); } /* @@ -385,12 +385,12 @@ static int update_one(struct cache_tree *it, /* * "sub" can be an empty tree if all subentries are i-t-a. */ - if (contains_ita && !hashcmp(sha1, EMPTY_TREE_SHA1_BIN)) + if (contains_ita && !oidcmp(oid, &empty_tree_oid)) continue; strbuf_grow(&buffer, entlen + 100); strbuf_addf(&buffer, "%o %.*s%c", mode, entlen, path + baselen, '\0'); - strbuf_add(&buffer, sha1, 20); + strbuf_add(&buffer, oid->hash, the_hash_algo->rawsz); #if DEBUG fprintf(stderr, "cache-tree update-one %o %.*s\n", @@ -401,7 +401,7 @@ static int update_one(struct cache_tree *it, if (repair) { struct object_id oid; hash_object_file(buffer.buf, buffer.len, tree_type, &oid); - if (has_sha1_file(oid.hash)) + if (has_object_file(&oid)) oidcpy(&it->oid, &oid); else to_invalidate = 1; @@ -465,7 +465,7 @@ static void write_one(struct strbuf *buffer, struct cache_tree *it, #endif if (0 <= it->entry_count) { - strbuf_add(buffer, it->oid.hash, 20); + strbuf_add(buffer, it->oid.hash, the_hash_algo->rawsz); } for (i = 0; i < it->subtree_nr; i++) { struct cache_tree_sub *down = it->down[i]; @@ -492,6 +492,7 @@ static struct cache_tree *read_one(const char **buffer, unsigned long *size_p) char *ep; struct cache_tree *it; int i, subtree_nr; + const unsigned rawsz = the_hash_algo->rawsz; it = NULL; /* skip name, but make sure name exists */ @@ -520,11 +521,11 @@ static struct cache_tree *read_one(const char **buffer, unsigned long *size_p) goto free_return; buf++; size--; if (0 <= it->entry_count) { - if (size < 20) + if (size < rawsz) goto free_return; - hashcpy(it->oid.hash, (const unsigned char*)buf); - buf += 20; - size -= 20; + memcpy(it->oid.hash, (const unsigned char*)buf, rawsz); + buf += rawsz; + size -= rawsz; } #if DEBUG @@ -599,7 +600,7 @@ static struct cache_tree *cache_tree_find(struct cache_tree *it, const char *pat return it; } -int write_index_as_tree(unsigned char *sha1, struct index_state *index_state, const char *index_path, int flags, const char *prefix) +int write_index_as_tree(struct object_id *oid, struct index_state *index_state, const char *index_path, int flags, const char *prefix) { int entries, was_valid; struct lock_file lock_file = LOCK_INIT; @@ -640,19 +641,19 @@ int write_index_as_tree(unsigned char *sha1, struct index_state *index_state, co ret = WRITE_TREE_PREFIX_ERROR; goto out; } - hashcpy(sha1, subtree->oid.hash); + oidcpy(oid, &subtree->oid); } else - hashcpy(sha1, index_state->cache_tree->oid.hash); + oidcpy(oid, &index_state->cache_tree->oid); out: rollback_lock_file(&lock_file); return ret; } -int write_cache_as_tree(unsigned char *sha1, int flags, const char *prefix) +int write_cache_as_tree(struct object_id *oid, int flags, const char *prefix) { - return write_index_as_tree(sha1, &the_index, get_index_file(), flags, prefix); + return write_index_as_tree(oid, &the_index, get_index_file(), flags, prefix); } static void prime_cache_tree_rec(struct cache_tree *it, struct tree *tree) diff --git a/cache-tree.h b/cache-tree.h index f7b9cab7ee..cfd5328cc9 100644 --- a/cache-tree.h +++ b/cache-tree.h @@ -47,8 +47,8 @@ int update_main_cache_tree(int); #define WRITE_TREE_UNMERGED_INDEX (-2) #define WRITE_TREE_PREFIX_ERROR (-3) -int write_index_as_tree(unsigned char *sha1, struct index_state *index_state, const char *index_path, int flags, const char *prefix); -int write_cache_as_tree(unsigned char *sha1, int flags, const char *prefix); +int write_index_as_tree(struct object_id *oid, struct index_state *index_state, const char *index_path, int flags, const char *prefix); +int write_cache_as_tree(struct object_id *oid, int flags, const char *prefix); void prime_cache_tree(struct index_state *, struct tree *); extern int cache_tree_matches_traversal(struct cache_tree *, struct name_entry *ent, struct traverse_info *info); diff --git a/cache.h b/cache.h index a61b2d3f0d..77b7acebb6 100644 --- a/cache.h +++ b/cache.h @@ -459,7 +459,7 @@ static inline enum object_type object_type(unsigned int mode) */ extern const char * const local_repo_env[]; -extern void setup_git_env(void); +extern void setup_git_env(const char *git_dir); /* * Returns true iff we have a configured git repository (either via @@ -477,7 +477,7 @@ extern const char *get_git_common_dir(void); extern char *get_object_directory(void); extern char *get_index_file(void); extern char *get_graft_file(void); -extern int set_git_dir(const char *path); +extern void set_git_dir(const char *path); extern int get_common_dir_noenv(struct strbuf *sb, const char *gitdir); extern int get_common_dir(struct strbuf *sb, const char *gitdir); extern const char *get_git_namespace(void); @@ -940,12 +940,6 @@ extern void check_repository_format(void); #define DATA_CHANGED 0x0020 #define TYPE_CHANGED 0x0040 -/* - * Put in `buf` the name of the file in the local object database that - * would be used to store a loose object with the specified sha1. - */ -extern void sha1_file_name(struct strbuf *buf, const unsigned char *sha1); - /* * Return an abbreviated sha1 unique within this repository's object database. * The result will be at least `len` characters long, and will be NUL @@ -955,14 +949,14 @@ extern void sha1_file_name(struct strbuf *buf, const unsigned char *sha1); * more calls to find_unique_abbrev are made. * * The `_r` variant writes to a buffer supplied by the caller, which must be at - * least `GIT_SHA1_HEXSZ + 1` bytes. The return value is the number of bytes + * least `GIT_MAX_HEXSZ + 1` bytes. The return value is the number of bytes * written (excluding the NUL terminator). * * Note that while this version avoids the static buffer, it is not fully * reentrant, as it calls into other non-reentrant git code. */ -extern const char *find_unique_abbrev(const unsigned char *sha1, int len); -extern int find_unique_abbrev_r(char *hex, const unsigned char *sha1, int len); +extern const char *find_unique_abbrev(const struct object_id *oid, int len); +extern int find_unique_abbrev_r(char *hex, const struct object_id *oid, int len); extern const unsigned char null_sha1[GIT_MAX_RAWSZ]; extern const struct object_id null_oid; @@ -1189,19 +1183,19 @@ extern char *xdg_config_home(const char *filename); */ extern char *xdg_cache_home(const char *filename); -extern void *read_sha1_file_extended(const unsigned char *sha1, - enum object_type *type, - unsigned long *size, int lookup_replace); -static inline void *read_sha1_file(const unsigned char *sha1, enum object_type *type, unsigned long *size) +extern void *read_object_file_extended(const struct object_id *oid, + enum object_type *type, + unsigned long *size, int lookup_replace); +static inline void *read_object_file(const struct object_id *oid, enum object_type *type, unsigned long *size) { - return read_sha1_file_extended(sha1, type, size, 1); + return read_object_file_extended(oid, type, size, 1); } /* * This internal function is only declared here for the benefit of * lookup_replace_object(). Please do not call it directly. */ -extern const unsigned char *do_lookup_replace_object(const unsigned char *sha1); +extern const struct object_id *do_lookup_replace_object(const struct object_id *oid); /* * If object sha1 should be replaced, return the replacement object's @@ -1209,15 +1203,15 @@ extern const unsigned char *do_lookup_replace_object(const unsigned char *sha1); * either sha1 or a pointer to a permanently-allocated value. When * object replacement is suppressed, always return sha1. */ -static inline const unsigned char *lookup_replace_object(const unsigned char *sha1) +static inline const struct object_id *lookup_replace_object(const struct object_id *oid) { if (!check_replace_refs) - return sha1; - return do_lookup_replace_object(sha1); + return oid; + return do_lookup_replace_object(oid); } -/* Read and unpack a sha1 file into memory, write memory to a sha1 file */ -extern int sha1_object_info(const unsigned char *, unsigned long *); +/* Read and unpack an object file into memory, write memory to an object file */ +extern int oid_object_info(const struct object_id *, unsigned long *); extern int hash_object_file(const void *buf, unsigned long len, const char *type, struct object_id *oid); @@ -1236,23 +1230,22 @@ extern int force_object_loose(const struct object_id *oid, time_t mtime); extern int git_open_cloexec(const char *name, int flags); #define git_open(name) git_open_cloexec(name, O_RDONLY) -extern void *map_sha1_file(const unsigned char *sha1, unsigned long *size); extern int unpack_sha1_header(git_zstream *stream, unsigned char *map, unsigned long mapsize, void *buffer, unsigned long bufsiz); extern int parse_sha1_header(const char *hdr, unsigned long *sizep); -extern int check_sha1_signature(const unsigned char *sha1, void *buf, unsigned long size, const char *type); +extern int check_object_signature(const struct object_id *oid, void *buf, unsigned long size, const char *type); extern int finalize_object_file(const char *tmpfile, const char *filename); /* - * Open the loose object at path, check its sha1, and return the contents, + * Open the loose object at path, check its hash, and return the contents, * type, and size. If the object is a blob, then "contents" may return NULL, * to allow streaming of large blobs. * * Returns 0 on success, negative on error (details may be written to stderr). */ int read_loose_object(const char *path, - const unsigned char *expected_sha1, + const struct object_id *expected_oid, enum object_type *type, unsigned long *size, void **contents); @@ -1279,7 +1272,7 @@ extern int has_object_file_with_flags(const struct object_id *oid, int flags); */ extern int has_loose_object_nonlocal(const unsigned char *sha1); -extern void assert_sha1_type(const unsigned char *sha1, enum object_type expect); +extern void assert_oid_type(const struct object_id *oid, enum object_type expect); /* Helper to check and "touch" a file */ extern int check_and_freshen_file(const char *fn, int freshen); @@ -1435,10 +1428,10 @@ extern int df_name_compare(const char *name1, int len1, int mode1, const char *n extern int name_compare(const char *name1, size_t len1, const char *name2, size_t len2); extern int cache_name_stage_compare(const char *name1, int len1, int stage1, const char *name2, int len2, int stage2); -extern void *read_object_with_reference(const unsigned char *sha1, +extern void *read_object_with_reference(const struct object_id *oid, const char *required_type, unsigned long *size, - unsigned char *sha1_ret); + struct object_id *oid_ret); extern struct object *peel_to_type(const char *name, int namelen, struct object *o, enum object_type); @@ -1564,57 +1557,6 @@ extern int has_dirs_only_path(const char *name, int len, int prefix_len); extern void schedule_dir_for_removal(const char *name, int len); extern void remove_scheduled_dirs(void); -extern struct alternate_object_database { - struct alternate_object_database *next; - - /* see alt_scratch_buf() */ - struct strbuf scratch; - size_t base_len; - - /* - * Used to store the results of readdir(3) calls when searching - * for unique abbreviated hashes. This cache is never - * invalidated, thus it's racy and not necessarily accurate. - * That's fine for its purpose; don't use it for tasks requiring - * greater accuracy! - */ - char loose_objects_subdir_seen[256]; - struct oid_array loose_objects_cache; - - char path[FLEX_ARRAY]; -} *alt_odb_list; -extern void prepare_alt_odb(void); -extern char *compute_alternate_path(const char *path, struct strbuf *err); -typedef int alt_odb_fn(struct alternate_object_database *, void *); -extern int foreach_alt_odb(alt_odb_fn, void*); - -/* - * Allocate a "struct alternate_object_database" but do _not_ actually - * add it to the list of alternates. - */ -struct alternate_object_database *alloc_alt_odb(const char *dir); - -/* - * Add the directory to the on-disk alternates file; the new entry will also - * take effect in the current process. - */ -extern void add_to_alternates_file(const char *dir); - -/* - * Add the directory to the in-memory list of alternates (along with any - * recursive alternates it points to), but do not modify the on-disk alternates - * file. - */ -extern void add_to_alternates_memory(const char *dir); - -/* - * Returns a scratch strbuf pre-filled with the alternate object directory, - * including a trailing slash, which can be used to access paths in the - * alternate. Always use this over direct access to alt->scratch, as it - * cleans up any previous use of the scratch buffer. - */ -extern struct strbuf *alt_scratch_buf(struct alternate_object_database *alt); - struct pack_window { struct pack_window *next; unsigned char *base; @@ -1624,35 +1566,6 @@ struct pack_window { unsigned int inuse_cnt; }; -extern struct packed_git { - struct packed_git *next; - struct list_head mru; - struct pack_window *windows; - off_t pack_size; - const void *index_data; - size_t index_size; - uint32_t num_objects; - uint32_t num_bad_objects; - unsigned char *bad_object_sha1; - int index_version; - time_t mtime; - int pack_fd; - unsigned pack_local:1, - pack_keep:1, - freshened:1, - do_not_close:1, - pack_promisor:1; - unsigned char sha1[20]; - struct revindex_entry *revindex; - /* something like ".git/objects/pack/xxxxx.pack" */ - char pack_name[FLEX_ARRAY]; /* more */ -} *packed_git; - -/* - * A most-recently-used ordered version of the packed_git list. - */ -extern struct list_head packed_git_mru; - struct pack_entry { off_t offset; unsigned char sha1[20]; @@ -1777,7 +1690,9 @@ struct object_info { #define OBJECT_INFO_SKIP_CACHED 4 /* Do not retry packed storage after checking packed and loose storage */ #define OBJECT_INFO_QUICK 8 -extern int sha1_object_info_extended(const unsigned char *, struct object_info *, unsigned flags); +/* Do not check loose object */ +#define OBJECT_INFO_IGNORE_LOOSE 16 +extern int oid_object_info_extended(const struct object_id *, struct object_info *, unsigned flags); /* * Set this to 0 to prevent sha1_object_info_extended() from fetching missing diff --git a/chdir-notify.c b/chdir-notify.c new file mode 100644 index 0000000000..5f7f2c2ac2 --- /dev/null +++ b/chdir-notify.c @@ -0,0 +1,93 @@ +#include "cache.h" +#include "chdir-notify.h" +#include "list.h" +#include "strbuf.h" + +struct chdir_notify_entry { + const char *name; + chdir_notify_callback cb; + void *data; + struct list_head list; +}; +static LIST_HEAD(chdir_notify_entries); + +void chdir_notify_register(const char *name, + chdir_notify_callback cb, + void *data) +{ + struct chdir_notify_entry *e = xmalloc(sizeof(*e)); + e->name = name; + e->cb = cb; + e->data = data; + list_add_tail(&e->list, &chdir_notify_entries); +} + +static void reparent_cb(const char *name, + const char *old_cwd, + const char *new_cwd, + void *data) +{ + char **path = data; + char *tmp = *path; + + if (!tmp) + return; + + *path = reparent_relative_path(old_cwd, new_cwd, tmp); + free(tmp); + + if (name) { + trace_printf_key(&trace_setup_key, + "setup: reparent %s to '%s'", + name, *path); + } +} + +void chdir_notify_reparent(const char *name, char **path) +{ + chdir_notify_register(name, reparent_cb, path); +} + +int chdir_notify(const char *new_cwd) +{ + struct strbuf old_cwd = STRBUF_INIT; + struct list_head *pos; + + if (strbuf_getcwd(&old_cwd) < 0) + return -1; + if (chdir(new_cwd) < 0) { + int saved_errno = errno; + strbuf_release(&old_cwd); + errno = saved_errno; + return -1; + } + + trace_printf_key(&trace_setup_key, + "setup: chdir from '%s' to '%s'", + old_cwd.buf, new_cwd); + + list_for_each(pos, &chdir_notify_entries) { + struct chdir_notify_entry *e = + list_entry(pos, struct chdir_notify_entry, list); + e->cb(e->name, old_cwd.buf, new_cwd, e->data); + } + + strbuf_release(&old_cwd); + return 0; +} + +char *reparent_relative_path(const char *old_cwd, + const char *new_cwd, + const char *path) +{ + char *ret, *full; + + if (is_absolute_path(path)) + return xstrdup(path); + + full = xstrfmt("%s/%s", old_cwd, path); + ret = xstrdup(remove_leading_path(full, new_cwd)); + free(full); + + return ret; +} diff --git a/chdir-notify.h b/chdir-notify.h new file mode 100644 index 0000000000..366e4c1ee9 --- /dev/null +++ b/chdir-notify.h @@ -0,0 +1,73 @@ +#ifndef CHDIR_NOTIFY_H +#define CHDIR_NOTIFY_H + +/* + * An API to let code "subscribe" to changes to the current working directory. + * The general idea is that some code asks to be notified when the working + * directory changes, and other code that calls chdir uses a special wrapper + * that notifies everyone. + */ + +/* + * Callers who need to know about changes can do: + * + * void foo(const char *old_path, const char *new_path, void *data) + * { + * warning("switched from %s to %s!", old_path, new_path); + * } + * ... + * chdir_notify_register("description", foo, data); + * + * In practice most callers will want to move a relative path to the new root; + * they can use the reparent_relative_path() helper for that. If that's all + * you're doing, you can also use the convenience function: + * + * chdir_notify_reparent("description", &my_path); + * + * Whenever a chdir event occurs, that will update my_path (if it's relative) + * to adjust for the new cwd by freeing any existing string and allocating a + * new one. + * + * Registered functions are called in the order in which they were added. Note + * that there's currently no way to remove a function, so make sure that the + * data parameter remains valid for the rest of the program. + * + * The "name" argument is used only for printing trace output from + * $GIT_TRACE_SETUP. It may be NULL, but if non-NULL should point to + * storage which lasts as long as the registration is active. + */ +typedef void (*chdir_notify_callback)(const char *name, + const char *old_cwd, + const char *new_cwd, + void *data); +void chdir_notify_register(const char *name, chdir_notify_callback cb, void *data); +void chdir_notify_reparent(const char *name, char **path); + +/* + * + * Callers that want to chdir: + * + * chdir_notify(new_path); + * + * to switch to the new path and notify any callbacks. + * + * Note that you don't need to chdir_notify() if you're just temporarily moving + * to a directory and back, as long as you don't call any subscribed code in + * between (but it should be safe to do so if you're unsure). + */ +int chdir_notify(const char *new_cwd); + +/* + * Reparent a relative path from old_root to new_root. For example: + * + * reparent_relative_path("/a", "/a/b", "b/rel"); + * + * would return the (newly allocated) string "rel". Note that we may return an + * absolute path in some cases (e.g., if the resulting path is not inside + * new_cwd). + */ +char *reparent_relative_path(const char *old_cwd, + const char *new_cwd, + const char *path); + +#endif /* CHDIR_NOTIFY_H */ diff --git a/combine-diff.c b/combine-diff.c index 1ec9af1f81..2ef495963f 100644 --- a/combine-diff.c +++ b/combine-diff.c @@ -306,7 +306,7 @@ static char *grab_blob(const struct object_id *oid, unsigned int mode, *size = fill_textconv(textconv, df, &blob); free_filespec(df); } else { - blob = read_sha1_file(oid->hash, &type, size); + blob = read_object_file(oid, &type, size); if (type != OBJ_BLOB) die("object '%s' is not a blob!", oid_to_hex(oid)); } @@ -915,11 +915,11 @@ static void show_combined_header(struct combine_diff_path *elem, "", elem->path, line_prefix, c_meta, c_reset); printf("%s%sindex ", line_prefix, c_meta); for (i = 0; i < num_parent; i++) { - abb = find_unique_abbrev(elem->parent[i].oid.hash, + abb = find_unique_abbrev(&elem->parent[i].oid, abbrev); printf("%s%s", i ? "," : "", abb); } - abb = find_unique_abbrev(elem->oid.hash, abbrev); + abb = find_unique_abbrev(&elem->oid, abbrev); printf("..%s%s\n", abb, c_reset); if (mode_differs) { diff --git a/commit.c b/commit.c index 00c99c7272..ca474a7c11 100644 --- a/commit.c +++ b/commit.c @@ -266,7 +266,7 @@ const void *get_commit_buffer(const struct commit *commit, unsigned long *sizep) if (!ret) { enum object_type type; unsigned long size; - ret = read_sha1_file(commit->object.oid.hash, &type, &size); + ret = read_object_file(&commit->object.oid, &type, &size); if (!ret) die("cannot read commit object %s", oid_to_hex(&commit->object.oid)); @@ -383,7 +383,7 @@ int parse_commit_gently(struct commit *item, int quiet_on_missing) return -1; if (item->object.parsed) return 0; - buffer = read_sha1_file(item->object.oid.hash, &type, &size); + buffer = read_object_file(&item->object.oid, &type, &size); if (!buffer) return quiet_on_missing ? -1 : error("Could not read %s", @@ -1206,7 +1206,7 @@ static void handle_signed_tag(struct commit *parent, struct commit_extra_header desc = merge_remote_util(parent); if (!desc || !desc->obj) return; - buf = read_sha1_file(desc->obj->oid.hash, &type, &size); + buf = read_object_file(&desc->obj->oid, &type, &size); if (!buf || type != OBJ_TAG) goto free_return; len = parse_signature(buf, size); @@ -1517,7 +1517,7 @@ int commit_tree_extended(const char *msg, size_t msg_len, int encoding_is_utf8; struct strbuf buffer; - assert_sha1_type(tree->hash, OBJ_TREE); + assert_oid_type(tree, OBJ_TREE); if (memchr(msg, '\0', msg_len)) return error("a NUL byte in commit log message not allowed."); diff --git a/common-main.c b/common-main.c index 6a689007e7..b989e136b5 100644 --- a/common-main.c +++ b/common-main.c @@ -1,5 +1,5 @@ #include "cache.h" -#include "exec_cmd.h" +#include "exec-cmd.h" #include "attr.h" /* @@ -34,6 +34,8 @@ int main(int argc, const char **argv) git_setup_gettext(); + initialize_the_repository(); + attr_start(); git_extract_argv0_path(argv[0]); diff --git a/config.c b/config.c index b0c20e6cb8..62c56099bf 100644 --- a/config.c +++ b/config.c @@ -9,7 +9,7 @@ #include "config.h" #include "repository.h" #include "lockfile.h" -#include "exec_cmd.h" +#include "exec-cmd.h" #include "strbuf.h" #include "quote.h" #include "hashmap.h" @@ -1426,6 +1426,7 @@ static int do_config_from_file(config_fn_t fn, void *data) { struct config_source top; + int ret; top.u.file = f; top.origin_type = origin_type; @@ -1436,7 +1437,10 @@ static int do_config_from_file(config_fn_t fn, top.do_ungetc = config_file_ungetc; top.do_ftell = config_file_ftell; - return do_config_from(&top, fn, data); + flockfile(f); + ret = do_config_from(&top, fn, data); + funlockfile(f); + return ret; } static int git_config_from_stdin(config_fn_t fn, void *data) @@ -1451,9 +1455,7 @@ int git_config_from_file(config_fn_t fn, const char *filename, void *data) f = fopen_or_warn(filename, "r"); if (f) { - flockfile(f); ret = do_config_from_file(fn, CONFIG_ORIGIN_FILE, filename, filename, f, data); - funlockfile(f); fclose(f); } return ret; @@ -1488,7 +1490,7 @@ int git_config_from_blob_oid(config_fn_t fn, unsigned long size; int ret; - buf = read_sha1_file(oid->hash, &type, &size); + buf = read_object_file(oid, &type, &size); if (!buf) return error("unable to load config blob object '%s'", name); if (type != OBJ_BLOB) { diff --git a/configure.ac b/configure.ac index 7f8415140f..e11b7976ab 100644 --- a/configure.ac +++ b/configure.ac @@ -254,25 +254,25 @@ GIT_PARSE_WITH([openssl])) # Perl-compatible regular expressions instead of standard or extended # POSIX regular expressions. # -# Currently USE_LIBPCRE is a synonym for USE_LIBPCRE1, define -# USE_LIBPCRE2 instead if you'd like to use version 2 of the PCRE -# library. The USE_LIBPCRE flag will likely be changed to mean v2 by -# default in future releases. +# USE_LIBPCRE is a synonym for USE_LIBPCRE2, define USE_LIBPCRE1 +# instead if you'd like to use the legacy version 1 of the PCRE +# library. Support for version 1 will likely be removed in some future +# release of Git, as upstream has all but abandoned it. # # Define LIBPCREDIR=/foo/bar if your PCRE header and library files are in # /foo/bar/include and /foo/bar/lib directories. # AC_ARG_WITH(libpcre, -AS_HELP_STRING([--with-libpcre],[synonym for --with-libpcre1]), +AS_HELP_STRING([--with-libpcre],[synonym for --with-libpcre2]), if test "$withval" = "no"; then - USE_LIBPCRE1= + USE_LIBPCRE2= elif test "$withval" = "yes"; then - USE_LIBPCRE1=YesPlease + USE_LIBPCRE2=YesPlease else - USE_LIBPCRE1=YesPlease + USE_LIBPCRE2=YesPlease LIBPCREDIR=$withval AC_MSG_NOTICE([Setting LIBPCREDIR to $LIBPCREDIR]) - dnl USE_LIBPCRE1 can still be modified below, so don't substitute + dnl USE_LIBPCRE2 can still be modified below, so don't substitute dnl it yet. GIT_CONF_SUBST([LIBPCREDIR]) fi) @@ -296,6 +296,10 @@ AS_HELP_STRING([], [ARG can be also prefix for libpcre library and hea AC_ARG_WITH(libpcre2, AS_HELP_STRING([--with-libpcre2],[support Perl-compatible regexes via libpcre2 (default is NO)]) AS_HELP_STRING([], [ARG can be also prefix for libpcre library and headers]), + if test -n "$USE_LIBPCRE2"; then + AC_MSG_ERROR([Only supply one of --with-libpcre or its synonym --with-libpcre2!]) + fi + if test -n "$USE_LIBPCRE1"; then AC_MSG_ERROR([Only supply one of --with-libpcre1 or --with-libpcre2!]) fi @@ -549,8 +553,8 @@ if test -n "$USE_LIBPCRE1"; then GIT_STASH_FLAGS($LIBPCREDIR) AC_CHECK_LIB([pcre], [pcre_version], -[USE_LIBPCRE=YesPlease], -[USE_LIBPCRE=]) +[USE_LIBPCRE1=YesPlease], +[USE_LIBPCRE1=]) GIT_UNSTASH_FLAGS($LIBPCREDIR) @@ -923,7 +927,7 @@ AC_RUN_IFELSE( [AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT], [[ FILE *f = fopen(".", "r"); - return f)]])], + return f != NULL;]])], [ac_cv_fread_reads_directories=no], [ac_cv_fread_reads_directories=yes]) ]) diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index c7957f0a90..01dd9ff07a 100644 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -29,6 +29,8 @@ # tell the completion to use commit completion. This also works with aliases # of form "!sh -c '...'". For example, "!sh -c ': git commit ; ... '". # +# Compatible with bash 3.2.57. +# # You can set the following environment variables to influence the behavior of # the completion routines: # @@ -280,6 +282,10 @@ __gitcomp () esac } +# Clear the variables caching builtins' options when (re-)sourcing +# the completion script. +unset $(set |sed -ne 's/^\(__gitcomp_builtin_[a-zA-Z0-9_][a-zA-Z0-9_]*\)=.*/\1/p') 2>/dev/null + # This function is equivalent to # # __gitcomp "$(git xxx --git-completion-helper) ..." @@ -384,12 +390,7 @@ __git_index_files () local root="${2-.}" file __git_ls_files_helper "$root" "$1" | - while read -r file; do - case "$file" in - ?*/*) echo "${file%%/*}" ;; - *) echo "$file" ;; - esac - done | sort | uniq + cut -f1 -d/ | sort | uniq } # Lists branches from the local repository. @@ -1280,6 +1281,12 @@ _git_checkout () _git_cherry () { + case "$cur" in + --*) + __gitcomp_builtin cherry + return + esac + __git_complete_refs } @@ -1499,16 +1506,6 @@ _git_fsck () esac } -_git_gc () -{ - case "$cur" in - --*) - __gitcomp_builtin gc - return - ;; - esac -} - _git_gitk () { _gitk @@ -1633,6 +1630,13 @@ _git_ls_remote () _git_ls_tree () { + case "$cur" in + --*) + __gitcomp_builtin ls-tree + return + ;; + esac + __git_complete_file } @@ -1808,11 +1812,6 @@ _git_mv () fi } -_git_name_rev () -{ - __gitcomp_builtin name-rev -} - _git_notes () { local subcommands='add append copy edit get-ref list merge prune remove show' @@ -3032,6 +3031,45 @@ _git_worktree () fi } +__git_complete_common () { + local command="$1" + + case "$cur" in + --*) + __gitcomp_builtin "$command" + ;; + esac +} + +__git_cmds_with_parseopt_helper= +__git_support_parseopt_helper () { + test -n "$__git_cmds_with_parseopt_helper" || + __git_cmds_with_parseopt_helper="$(__git --list-parseopt-builtins)" + + case " $__git_cmds_with_parseopt_helper " in + *" $1 "*) + return 0 + ;; + *) + return 1 + ;; + esac +} + +__git_complete_command () { + local command="$1" + local completion_func="_git_${command//-/_}" + if declare -f $completion_func >/dev/null 2>/dev/null; then + $completion_func + return 0 + elif __git_support_parseopt_helper "$command"; then + __git_complete_common "$command" + return 0 + else + return 1 + fi +} + __git_main () { local i c=1 command __git_dir __git_repo_path @@ -3091,14 +3129,12 @@ __git_main () return fi - local completion_func="_git_${command//-/_}" - declare -f $completion_func >/dev/null 2>/dev/null && $completion_func && return + __git_complete_command "$command" && return local expansion=$(__git_aliased_command "$command") if [ -n "$expansion" ]; then words[1]=$expansion - completion_func="_git_${expansion//-/_}" - declare -f $completion_func >/dev/null 2>/dev/null && $completion_func + __git_complete_command "$expansion" fi } diff --git a/contrib/diff-highlight/DiffHighlight.pm b/contrib/diff-highlight/DiffHighlight.pm index 663992e530..536754583b 100644 --- a/contrib/diff-highlight/DiffHighlight.pm +++ b/contrib/diff-highlight/DiffHighlight.pm @@ -21,37 +21,82 @@ package DiffHighlight; my $COLOR = qr/\x1b\[[0-9;]*m/; my $BORING = qr/$COLOR|\s/; -# The patch portion of git log -p --graph should only ever have preceding | and -# not / or \ as merge history only shows up on the commit line. -my $GRAPH = qr/$COLOR?\|$COLOR?\s+/; - my @removed; my @added; my $in_hunk; +my $graph_indent = 0; our $line_cb = sub { print @_ }; our $flush_cb = sub { local $| = 1 }; -sub handle_line { +# Count the visible width of a string, excluding any terminal color sequences. +sub visible_width { local $_ = shift; + my $ret = 0; + while (length) { + if (s/^$COLOR//) { + # skip colors + } elsif (s/^.//) { + $ret++; + } + } + return $ret; +} + +# Return a substring of $str, omitting $len visible characters from the +# beginning, where terminal color sequences do not count as visible. +sub visible_substr { + my ($str, $len) = @_; + while ($len > 0) { + if ($str =~ s/^$COLOR//) { + next + } + $str =~ s/^.//; + $len--; + } + return $str; +} + +sub handle_line { + my $orig = shift; + local $_ = $orig; + + # match a graph line that begins a commit + if (/^(?:$COLOR?\|$COLOR?[ ])* # zero or more leading "|" with space + $COLOR?\*$COLOR?[ ] # a "*" with its trailing space + (?:$COLOR?\|$COLOR?[ ])* # zero or more trailing "|" + [ ]* # trailing whitespace for merges + /x) { + my $graph_prefix = $&; + + # We must flush before setting graph indent, since the + # new commit may be indented differently from what we + # queued. + flush(); + $graph_indent = visible_width($graph_prefix); + + } elsif ($graph_indent) { + if (length($_) < $graph_indent) { + $graph_indent = 0; + } else { + $_ = visible_substr($_, $graph_indent); + } + } if (!$in_hunk) { - $line_cb->($_); - $in_hunk = /^$GRAPH*$COLOR*\@\@ /; + $line_cb->($orig); + $in_hunk = /^$COLOR*\@\@ /; } - elsif (/^$GRAPH*$COLOR*-/) { - push @removed, $_; + elsif (/^$COLOR*-/) { + push @removed, $orig; } - elsif (/^$GRAPH*$COLOR*\+/) { - push @added, $_; + elsif (/^$COLOR*\+/) { + push @added, $orig; } else { - show_hunk(\@removed, \@added); - @removed = (); - @added = (); - - $line_cb->($_); - $in_hunk = /^$GRAPH*$COLOR*[\@ ]/; + flush(); + $line_cb->($orig); + $in_hunk = /^$COLOR*[\@ ]/; } # Most of the time there is enough output to keep things streaming, @@ -71,6 +116,8 @@ sub flush { # Flush any queued hunk (this can happen when there is no trailing # context in the final diff of the input). show_hunk(\@removed, \@added); + @removed = (); + @added = (); } sub highlight_stdin { @@ -226,8 +273,8 @@ sub is_pair_interesting { my $suffix_a = join('', @$a[($sa+1)..$#$a]); my $suffix_b = join('', @$b[($sb+1)..$#$b]); - return $prefix_a !~ /^$GRAPH*$COLOR*-$BORING*$/ || - $prefix_b !~ /^$GRAPH*$COLOR*\+$BORING*$/ || + return visible_substr($prefix_a, $graph_indent) !~ /^$COLOR*-$BORING*$/ || + visible_substr($prefix_b, $graph_indent) !~ /^$COLOR*\+$BORING*$/ || $suffix_a !~ /^$BORING*$/ || $suffix_b !~ /^$BORING*$/; } diff --git a/contrib/diff-highlight/t/t9400-diff-highlight.sh b/contrib/diff-highlight/t/t9400-diff-highlight.sh index 3b43dbed74..f6f5195d00 100755 --- a/contrib/diff-highlight/t/t9400-diff-highlight.sh +++ b/contrib/diff-highlight/t/t9400-diff-highlight.sh @@ -52,15 +52,17 @@ test_strip_patch_header () { # dh_test_setup_history generates a contrived graph such that we have at least # 1 nesting (E) and 2 nestings (F). # -# A branch -# / -# D---E---F master +# A---B master +# / +# D---E---F branch # # git log --all --graph # * commit -# | A +# | B # | * commit # | | F +# * | commit +# | | A # | * commit # |/ # | E @@ -68,24 +70,30 @@ test_strip_patch_header () { # D # dh_test_setup_history () { - echo "file1" >file1 && - echo "file2" >file2 && - echo "file3" >file3 && - - cat file1 >file && + echo file1 >file && git add file && + test_tick && git commit -m "D" && git checkout -b branch && - cat file2 >file && - git commit -a -m "A" && + echo file2 >file && + test_tick && + git commit -a -m "E" && git checkout master && - cat file2 >file && - git commit -a -m "E" && + echo file2 >file && + test_tick && + git commit -a -m "A" && - cat file3 >file && - git commit -a -m "F" + git checkout branch && + echo file3 >file && + test_tick && + git commit -a -m "F" && + + git checkout master && + echo file3 >file && + test_tick && + git commit -a -m "B" } left_trim () { @@ -246,16 +254,25 @@ test_expect_failure 'diff-highlight treats combining code points as a unit' ' test_expect_success 'diff-highlight works with the --graph option' ' dh_test_setup_history && - # topo-order so that the order of the commits is the same as with --graph + # date-order so that the commits are interleaved for both # trim graph elements so we can do a diff # trim leading space because our trim_graph is not perfect - git log --branches -p --topo-order | + git log --branches -p --date-order | "$DIFF_HIGHLIGHT" | left_trim >graph.exp && - git log --branches -p --graph | + git log --branches -p --date-order --graph | "$DIFF_HIGHLIGHT" | trim_graph | left_trim >graph.act && test_cmp graph.exp graph.act ' +# Just reuse the previous graph test, but with --color. Our trimming +# doesn't know about color, so just sanity check that something got +# highlighted. +test_expect_success 'diff-highlight works with color graph' ' + git log --branches -p --date-order --graph --color | + "$DIFF_HIGHLIGHT" | trim_graph | left_trim >graph && + grep "\[7m" graph +' + # Most combined diffs won't meet diff-highlight's line-number filter. So we # create one here where one side drops a line and the other modifies it. That # should result in a diff like: @@ -293,4 +310,32 @@ test_expect_success 'diff-highlight ignores combined diffs' ' test_cmp expect actual ' +test_expect_success 'diff-highlight handles --graph with leading dash' ' + cat >file <<-\EOF && + before + the old line + -leading dash + EOF + git add file && + git commit -m before && + + sed s/old/new/ file.tmp && + mv file.tmp file && + git add file && + git commit -m after && + + cat >expect <<-EOF && + --- a/file + +++ b/file + @@ -1,3 +1,3 @@ + before + -the ${CW}old${CR} line + +the ${CW}new${CR} line + -leading dash + EOF + git log --graph -p -1 | "$DIFF_HIGHLIGHT" >actual.raw && + trim_graph actual && + test_cmp expect actual +' + test_done diff --git a/contrib/examples/README b/contrib/examples/README index 6946f3dd2a..18bc60b021 100644 --- a/contrib/examples/README +++ b/contrib/examples/README @@ -1,3 +1,20 @@ -These are original scripted implementations, kept primarily for their -reference value to any aspiring plumbing users who want to learn how -pieces can be fit together. +This directory used to contain scripted implementations of builtins +that have since been rewritten in C. + +They have now been removed, but can be retrieved from an older commit +that removed them from this directory. + +They're interesting for their reference value to any aspiring plumbing +users who want to learn how pieces can be fit together, but in many +cases have drifted enough from the actual implementations Git uses to +be instructive. + +Other things that can be useful: + + * Some commands such as git-gc wrap other commands, and what they're + doing behind the scenes can be seen by running them under + GIT_TRACE=1 + + * Doing `git log` on paths matching '*--helper.c' will show + incremental effort in the direction of moving existing shell + scripts to C. diff --git a/contrib/examples/builtin-fetch--tool.c b/contrib/examples/builtin-fetch--tool.c deleted file mode 100644 index 22648c3afb..0000000000 --- a/contrib/examples/builtin-fetch--tool.c +++ /dev/null @@ -1,575 +0,0 @@ -#include "builtin.h" -#include "cache.h" -#include "refs.h" -#include "commit.h" -#include "sigchain.h" - -static char *get_stdin(void) -{ - struct strbuf buf = STRBUF_INIT; - if (strbuf_read(&buf, 0, 1024) < 0) { - die_errno("error reading standard input"); - } - return strbuf_detach(&buf, NULL); -} - -static void show_new(enum object_type type, unsigned char *sha1_new) -{ - fprintf(stderr, " %s: %s\n", type_name(type), - find_unique_abbrev(sha1_new, DEFAULT_ABBREV)); -} - -static int update_ref_env(const char *action, - const char *refname, - unsigned char *sha1, - unsigned char *oldval) -{ - char msg[1024]; - const char *rla = getenv("GIT_REFLOG_ACTION"); - - if (!rla) - rla = "(reflog update)"; - if (snprintf(msg, sizeof(msg), "%s: %s", rla, action) >= sizeof(msg)) - warning("reflog message too long: %.*s...", 50, msg); - return update_ref(msg, refname, sha1, oldval, 0, - UPDATE_REFS_QUIET_ON_ERR); -} - -static int update_local_ref(const char *name, - const char *new_head, - const char *note, - int verbose, int force) -{ - unsigned char sha1_old[20], sha1_new[20]; - char oldh[41], newh[41]; - struct commit *current, *updated; - enum object_type type; - - if (get_sha1_hex(new_head, sha1_new)) - die("malformed object name %s", new_head); - - type = sha1_object_info(sha1_new, NULL); - if (type < 0) - die("object %s not found", new_head); - - if (!*name) { - /* Not storing */ - if (verbose) { - fprintf(stderr, "* fetched %s\n", note); - show_new(type, sha1_new); - } - return 0; - } - - if (get_sha1(name, sha1_old)) { - const char *msg; - just_store: - /* new ref */ - if (!strncmp(name, "refs/tags/", 10)) - msg = "storing tag"; - else - msg = "storing head"; - fprintf(stderr, "* %s: storing %s\n", - name, note); - show_new(type, sha1_new); - return update_ref_env(msg, name, sha1_new, NULL); - } - - if (!hashcmp(sha1_old, sha1_new)) { - if (verbose) { - fprintf(stderr, "* %s: same as %s\n", name, note); - show_new(type, sha1_new); - } - return 0; - } - - if (!strncmp(name, "refs/tags/", 10)) { - fprintf(stderr, "* %s: updating with %s\n", name, note); - show_new(type, sha1_new); - return update_ref_env("updating tag", name, sha1_new, NULL); - } - - current = lookup_commit_reference(sha1_old); - updated = lookup_commit_reference(sha1_new); - if (!current || !updated) - goto just_store; - - strcpy(oldh, find_unique_abbrev(current->object.sha1, DEFAULT_ABBREV)); - strcpy(newh, find_unique_abbrev(sha1_new, DEFAULT_ABBREV)); - - if (in_merge_bases(current, updated)) { - fprintf(stderr, "* %s: fast-forward to %s\n", - name, note); - fprintf(stderr, " old..new: %s..%s\n", oldh, newh); - return update_ref_env("fast-forward", name, sha1_new, sha1_old); - } - if (!force) { - fprintf(stderr, - "* %s: not updating to non-fast-forward %s\n", - name, note); - fprintf(stderr, - " old...new: %s...%s\n", oldh, newh); - return 1; - } - fprintf(stderr, - "* %s: forcing update to non-fast-forward %s\n", - name, note); - fprintf(stderr, " old...new: %s...%s\n", oldh, newh); - return update_ref_env("forced-update", name, sha1_new, sha1_old); -} - -static int append_fetch_head(FILE *fp, - const char *head, const char *remote, - const char *remote_name, const char *remote_nick, - const char *local_name, int not_for_merge, - int verbose, int force) -{ - struct commit *commit; - int remote_len, i, note_len; - unsigned char sha1[20]; - char note[1024]; - const char *what, *kind; - - if (get_sha1(head, sha1)) - return error("Not a valid object name: %s", head); - commit = lookup_commit_reference_gently(sha1, 1); - if (!commit) - not_for_merge = 1; - - if (!strcmp(remote_name, "HEAD")) { - kind = ""; - what = ""; - } - else if (!strncmp(remote_name, "refs/heads/", 11)) { - kind = "branch"; - what = remote_name + 11; - } - else if (!strncmp(remote_name, "refs/tags/", 10)) { - kind = "tag"; - what = remote_name + 10; - } - else if (!strncmp(remote_name, "refs/remotes/", 13)) { - kind = "remote-tracking branch"; - what = remote_name + 13; - } - else { - kind = ""; - what = remote_name; - } - - remote_len = strlen(remote); - for (i = remote_len - 1; remote[i] == '/' && 0 <= i; i--) - ; - remote_len = i + 1; - if (4 < i && !strncmp(".git", remote + i - 3, 4)) - remote_len = i - 3; - - note_len = 0; - if (*what) { - if (*kind) - note_len += sprintf(note + note_len, "%s ", kind); - note_len += sprintf(note + note_len, "'%s' of ", what); - } - note_len += sprintf(note + note_len, "%.*s", remote_len, remote); - fprintf(fp, "%s\t%s\t%s\n", - sha1_to_hex(commit ? commit->object.sha1 : sha1), - not_for_merge ? "not-for-merge" : "", - note); - return update_local_ref(local_name, head, note, verbose, force); -} - -static char *keep; -static void remove_keep(void) -{ - if (keep && *keep) - unlink(keep); -} - -static void remove_keep_on_signal(int signo) -{ - remove_keep(); - sigchain_pop(signo); - raise(signo); -} - -static char *find_local_name(const char *remote_name, const char *refs, - int *force_p, int *not_for_merge_p) -{ - const char *ref = refs; - int len = strlen(remote_name); - - while (ref) { - const char *next; - int single_force, not_for_merge; - - while (*ref == '\n') - ref++; - if (!*ref) - break; - next = strchr(ref, '\n'); - - single_force = not_for_merge = 0; - if (*ref == '+') { - single_force = 1; - ref++; - } - if (*ref == '.') { - not_for_merge = 1; - ref++; - if (*ref == '+') { - single_force = 1; - ref++; - } - } - if (!strncmp(remote_name, ref, len) && ref[len] == ':') { - const char *local_part = ref + len + 1; - int retlen; - - if (!next) - retlen = strlen(local_part); - else - retlen = next - local_part; - *force_p = single_force; - *not_for_merge_p = not_for_merge; - return xmemdupz(local_part, retlen); - } - ref = next; - } - return NULL; -} - -static int fetch_native_store(FILE *fp, - const char *remote, - const char *remote_nick, - const char *refs, - int verbose, int force) -{ - char buffer[1024]; - int err = 0; - - sigchain_push_common(remove_keep_on_signal); - atexit(remove_keep); - - while (fgets(buffer, sizeof(buffer), stdin)) { - int len; - char *cp; - char *local_name; - int single_force, not_for_merge; - - for (cp = buffer; *cp && !isspace(*cp); cp++) - ; - if (*cp) - *cp++ = 0; - len = strlen(cp); - if (len && cp[len-1] == '\n') - cp[--len] = 0; - if (!strcmp(buffer, "failed")) - die("Fetch failure: %s", remote); - if (!strcmp(buffer, "pack")) - continue; - if (!strcmp(buffer, "keep")) { - char *od = get_object_directory(); - int len = strlen(od) + strlen(cp) + 50; - keep = xmalloc(len); - sprintf(keep, "%s/pack/pack-%s.keep", od, cp); - continue; - } - - local_name = find_local_name(cp, refs, - &single_force, ¬_for_merge); - if (!local_name) - continue; - err |= append_fetch_head(fp, - buffer, remote, cp, remote_nick, - local_name, not_for_merge, - verbose, force || single_force); - } - return err; -} - -static int parse_reflist(const char *reflist) -{ - const char *ref; - - printf("refs='"); - for (ref = reflist; ref; ) { - const char *next; - while (*ref && isspace(*ref)) - ref++; - if (!*ref) - break; - for (next = ref; *next && !isspace(*next); next++) - ; - printf("\n%.*s", (int)(next - ref), ref); - ref = next; - } - printf("'\n"); - - printf("rref='"); - for (ref = reflist; ref; ) { - const char *next, *colon; - while (*ref && isspace(*ref)) - ref++; - if (!*ref) - break; - for (next = ref; *next && !isspace(*next); next++) - ; - if (*ref == '.') - ref++; - if (*ref == '+') - ref++; - colon = strchr(ref, ':'); - putchar('\n'); - printf("%.*s", (int)((colon ? colon : next) - ref), ref); - ref = next; - } - printf("'\n"); - return 0; -} - -static int expand_refs_wildcard(const char *ls_remote_result, int numrefs, - const char **refs) -{ - int i, matchlen, replacelen; - int found_one = 0; - const char *remote = *refs++; - numrefs--; - - if (numrefs == 0) { - fprintf(stderr, "Nothing specified for fetching with remote.%s.fetch\n", - remote); - printf("empty\n"); - } - - for (i = 0; i < numrefs; i++) { - const char *ref = refs[i]; - const char *lref = ref; - const char *colon; - const char *tail; - const char *ls; - const char *next; - - if (*lref == '+') - lref++; - colon = strchr(lref, ':'); - tail = lref + strlen(lref); - if (!(colon && - 2 < colon - lref && - colon[-1] == '*' && - colon[-2] == '/' && - 2 < tail - (colon + 1) && - tail[-1] == '*' && - tail[-2] == '/')) { - /* not a glob */ - if (!found_one++) - printf("explicit\n"); - printf("%s\n", ref); - continue; - } - - /* glob */ - if (!found_one++) - printf("glob\n"); - - /* lref to colon-2 is remote hierarchy name; - * colon+1 to tail-2 is local. - */ - matchlen = (colon-1) - lref; - replacelen = (tail-1) - (colon+1); - for (ls = ls_remote_result; ls; ls = next) { - const char *eol; - unsigned char sha1[20]; - int namelen; - - while (*ls && isspace(*ls)) - ls++; - next = strchr(ls, '\n'); - eol = !next ? (ls + strlen(ls)) : next; - if (!memcmp("^{}", eol-3, 3)) - continue; - if (eol - ls < 40) - continue; - if (get_sha1_hex(ls, sha1)) - continue; - ls += 40; - while (ls < eol && isspace(*ls)) - ls++; - /* ls to next (or eol) is the name. - * is it identical to lref to colon-2? - */ - if ((eol - ls) <= matchlen || - strncmp(ls, lref, matchlen)) - continue; - - /* Yes, it is a match */ - namelen = eol - ls; - if (lref != ref) - putchar('+'); - printf("%.*s:%.*s%.*s\n", - namelen, ls, - replacelen, colon + 1, - namelen - matchlen, ls + matchlen); - } - } - return 0; -} - -static int pick_rref(int sha1_only, const char *rref, const char *ls_remote_result) -{ - int err = 0; - int lrr_count = lrr_count, i, pass; - const char *cp; - struct lrr { - const char *line; - const char *name; - int namelen; - int shown; - } *lrr_list = lrr_list; - - for (pass = 0; pass < 2; pass++) { - /* pass 0 counts and allocates, pass 1 fills... */ - cp = ls_remote_result; - i = 0; - while (1) { - const char *np; - while (*cp && isspace(*cp)) - cp++; - if (!*cp) - break; - np = strchrnul(cp, '\n'); - if (pass) { - lrr_list[i].line = cp; - lrr_list[i].name = cp + 41; - lrr_list[i].namelen = np - (cp + 41); - } - i++; - cp = np; - } - if (!pass) { - lrr_count = i; - lrr_list = xcalloc(lrr_count, sizeof(*lrr_list)); - } - } - - while (1) { - const char *next; - int rreflen; - int i; - - while (*rref && isspace(*rref)) - rref++; - if (!*rref) - break; - next = strchrnul(rref, '\n'); - rreflen = next - rref; - - for (i = 0; i < lrr_count; i++) { - struct lrr *lrr = &(lrr_list[i]); - - if (rreflen == lrr->namelen && - !memcmp(lrr->name, rref, rreflen)) { - if (!lrr->shown) - printf("%.*s\n", - sha1_only ? 40 : lrr->namelen + 41, - lrr->line); - lrr->shown = 1; - break; - } - } - if (lrr_count <= i) { - error("pick-rref: %.*s not found", rreflen, rref); - err = 1; - } - rref = next; - } - free(lrr_list); - return err; -} - -int cmd_fetch__tool(int argc, const char **argv, const char *prefix) -{ - int verbose = 0; - int force = 0; - int sopt = 0; - - while (1 < argc) { - const char *arg = argv[1]; - if (!strcmp("-v", arg)) - verbose = 1; - else if (!strcmp("-f", arg)) - force = 1; - else if (!strcmp("-s", arg)) - sopt = 1; - else - break; - argc--; - argv++; - } - - if (argc <= 1) - return error("Missing subcommand"); - - if (!strcmp("append-fetch-head", argv[1])) { - int result; - FILE *fp; - char *filename; - - if (argc != 8) - return error("append-fetch-head takes 6 args"); - filename = git_path_fetch_head(); - fp = fopen(filename, "a"); - if (!fp) - return error("cannot open %s: %s", filename, strerror(errno)); - result = append_fetch_head(fp, argv[2], argv[3], - argv[4], argv[5], - argv[6], !!argv[7][0], - verbose, force); - fclose(fp); - return result; - } - if (!strcmp("native-store", argv[1])) { - int result; - FILE *fp; - char *filename; - - if (argc != 5) - return error("fetch-native-store takes 3 args"); - filename = git_path_fetch_head(); - fp = fopen(filename, "a"); - if (!fp) - return error("cannot open %s: %s", filename, strerror(errno)); - result = fetch_native_store(fp, argv[2], argv[3], argv[4], - verbose, force); - fclose(fp); - return result; - } - if (!strcmp("parse-reflist", argv[1])) { - const char *reflist; - if (argc != 3) - return error("parse-reflist takes 1 arg"); - reflist = argv[2]; - if (!strcmp(reflist, "-")) - reflist = get_stdin(); - return parse_reflist(reflist); - } - if (!strcmp("pick-rref", argv[1])) { - const char *ls_remote_result; - if (argc != 4) - return error("pick-rref takes 2 args"); - ls_remote_result = argv[3]; - if (!strcmp(ls_remote_result, "-")) - ls_remote_result = get_stdin(); - return pick_rref(sopt, argv[2], ls_remote_result); - } - if (!strcmp("expand-refs-wildcard", argv[1])) { - const char *reflist; - if (argc < 4) - return error("expand-refs-wildcard takes at least 2 args"); - reflist = argv[2]; - if (!strcmp(reflist, "-")) - reflist = get_stdin(); - return expand_refs_wildcard(reflist, argc - 3, argv + 3); - } - - return error("Unknown subcommand: %s", argv[1]); -} diff --git a/contrib/examples/git-am.sh b/contrib/examples/git-am.sh deleted file mode 100755 index dd539f1a8a..0000000000 --- a/contrib/examples/git-am.sh +++ /dev/null @@ -1,975 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 2005, 2006 Junio C Hamano - -SUBDIRECTORY_OK=Yes -OPTIONS_KEEPDASHDASH= -OPTIONS_STUCKLONG=t -OPTIONS_SPEC="\ -git am [options] [(|)...] -git am [options] (--continue | --skip | --abort) --- -i,interactive run interactively -b,binary* (historical option -- no-op) -3,3way allow fall back on 3way merging if needed -q,quiet be quiet -s,signoff add a Signed-off-by line to the commit message -u,utf8 recode into utf8 (default) -k,keep pass -k flag to git-mailinfo -keep-non-patch pass -b flag to git-mailinfo -m,message-id pass -m flag to git-mailinfo -keep-cr pass --keep-cr flag to git-mailsplit for mbox format -no-keep-cr do not pass --keep-cr flag to git-mailsplit independent of am.keepcr -c,scissors strip everything before a scissors line -whitespace= pass it through git-apply -ignore-space-change pass it through git-apply -ignore-whitespace pass it through git-apply -directory= pass it through git-apply -exclude= pass it through git-apply -include= pass it through git-apply -C= pass it through git-apply -p= pass it through git-apply -patch-format= format the patch(es) are in -reject pass it through git-apply -resolvemsg= override error message when patch failure occurs -continue continue applying patches after resolving a conflict -r,resolved synonyms for --continue -skip skip the current patch -abort restore the original branch and abort the patching operation. -committer-date-is-author-date lie about committer date -ignore-date use current timestamp for author date -rerere-autoupdate update the index with reused conflict resolution if possible -S,gpg-sign? GPG-sign commits -rebasing* (internal use for git-rebase)" - -. git-sh-setup -. git-sh-i18n -prefix=$(git rev-parse --show-prefix) -set_reflog_action am -require_work_tree -cd_to_toplevel - -git var GIT_COMMITTER_IDENT >/dev/null || - die "$(gettext "You need to set your committer info first")" - -if git rev-parse --verify -q HEAD >/dev/null -then - HAS_HEAD=yes -else - HAS_HEAD= -fi - -cmdline="git am" -if test '' != "$interactive" -then - cmdline="$cmdline -i" -fi -if test '' != "$threeway" -then - cmdline="$cmdline -3" -fi - -empty_tree=4b825dc642cb6eb9a060e54bf8d69288fbee4904 - -sq () { - git rev-parse --sq-quote "$@" -} - -stop_here () { - echo "$1" >"$dotest/next" - git rev-parse --verify -q HEAD >"$dotest/abort-safety" - exit 1 -} - -safe_to_abort () { - if test -f "$dotest/dirtyindex" - then - return 1 - fi - - if ! test -f "$dotest/abort-safety" - then - return 0 - fi - - abort_safety=$(cat "$dotest/abort-safety") - if test "z$(git rev-parse --verify -q HEAD)" = "z$abort_safety" - then - return 0 - fi - gettextln "You seem to have moved HEAD since the last 'am' failure. -Not rewinding to ORIG_HEAD" >&2 - return 1 -} - -stop_here_user_resolve () { - if [ -n "$resolvemsg" ]; then - printf '%s\n' "$resolvemsg" - stop_here $1 - fi - eval_gettextln "When you have resolved this problem, run \"\$cmdline --continue\". -If you prefer to skip this patch, run \"\$cmdline --skip\" instead. -To restore the original branch and stop patching, run \"\$cmdline --abort\"." - - stop_here $1 -} - -go_next () { - rm -f "$dotest/$msgnum" "$dotest/msg" "$dotest/msg-clean" \ - "$dotest/patch" "$dotest/info" - echo "$next" >"$dotest/next" - this=$next -} - -cannot_fallback () { - echo "$1" - gettextln "Cannot fall back to three-way merge." - exit 1 -} - -fall_back_3way () { - O_OBJECT=$(cd "$GIT_OBJECT_DIRECTORY" && pwd) - - rm -fr "$dotest"/patch-merge-* - mkdir "$dotest/patch-merge-tmp-dir" - - # First see if the patch records the index info that we can use. - cmd="git apply $git_apply_opt --build-fake-ancestor" && - cmd="$cmd "'"$dotest/patch-merge-tmp-index" "$dotest/patch"' && - eval "$cmd" && - GIT_INDEX_FILE="$dotest/patch-merge-tmp-index" \ - git write-tree >"$dotest/patch-merge-base+" || - cannot_fallback "$(gettext "Repository lacks necessary blobs to fall back on 3-way merge.")" - - say "$(gettext "Using index info to reconstruct a base tree...")" - - cmd='GIT_INDEX_FILE="$dotest/patch-merge-tmp-index"' - - if test -z "$GIT_QUIET" - then - eval "$cmd git diff-index --cached --diff-filter=AM --name-status HEAD" - fi - - cmd="$cmd git apply --cached $git_apply_opt"' <"$dotest/patch"' - if eval "$cmd" - then - mv "$dotest/patch-merge-base+" "$dotest/patch-merge-base" - mv "$dotest/patch-merge-tmp-index" "$dotest/patch-merge-index" - else - cannot_fallback "$(gettext "Did you hand edit your patch? -It does not apply to blobs recorded in its index.")" - fi - - test -f "$dotest/patch-merge-index" && - his_tree=$(GIT_INDEX_FILE="$dotest/patch-merge-index" git write-tree) && - orig_tree=$(cat "$dotest/patch-merge-base") && - rm -fr "$dotest"/patch-merge-* || exit 1 - - say "$(gettext "Falling back to patching base and 3-way merge...")" - - # This is not so wrong. Depending on which base we picked, - # orig_tree may be wildly different from ours, but his_tree - # has the same set of wildly different changes in parts the - # patch did not touch, so recursive ends up canceling them, - # saying that we reverted all those changes. - - eval GITHEAD_$his_tree='"$FIRSTLINE"' - export GITHEAD_$his_tree - if test -n "$GIT_QUIET" - then - GIT_MERGE_VERBOSITY=0 && export GIT_MERGE_VERBOSITY - fi - our_tree=$(git rev-parse --verify -q HEAD || echo $empty_tree) - git-merge-recursive $orig_tree -- $our_tree $his_tree || { - git rerere $allow_rerere_autoupdate - die "$(gettext "Failed to merge in the changes.")" - } - unset GITHEAD_$his_tree -} - -clean_abort () { - test $# = 0 || echo >&2 "$@" - rm -fr "$dotest" - exit 1 -} - -patch_format= - -check_patch_format () { - # early return if patch_format was set from the command line - if test -n "$patch_format" - then - return 0 - fi - - # we default to mbox format if input is from stdin and for - # directories - if test $# = 0 || test "x$1" = "x-" || test -d "$1" - then - patch_format=mbox - return 0 - fi - - # otherwise, check the first few non-blank lines of the first - # patch to try to detect its format - { - # Start from first line containing non-whitespace - l1= - while test -z "$l1" - do - read l1 || break - done - read l2 - read l3 - case "$l1" in - "From "* | "From: "*) - patch_format=mbox - ;; - '# This series applies on GIT commit'*) - patch_format=stgit-series - ;; - "# HG changeset patch") - patch_format=hg - ;; - *) - # if the second line is empty and the third is - # a From, Author or Date entry, this is very - # likely an StGIT patch - case "$l2,$l3" in - ,"From: "* | ,"Author: "* | ,"Date: "*) - patch_format=stgit - ;; - *) - ;; - esac - ;; - esac - if test -z "$patch_format" && - test -n "$l1" && - test -n "$l2" && - test -n "$l3" - then - # This begins with three non-empty lines. Is this a - # piece of e-mail a-la RFC2822? Grab all the headers, - # discarding the indented remainder of folded lines, - # and see if it looks like that they all begin with the - # header field names... - tr -d '\015' <"$1" | - sed -n -e '/^$/q' -e '/^[ ]/d' -e p | - sane_egrep -v '^[!-9;-~]+:' >/dev/null || - patch_format=mbox - fi - } < "$1" || clean_abort -} - -split_patches () { - case "$patch_format" in - mbox) - if test t = "$keepcr" - then - keep_cr=--keep-cr - else - keep_cr= - fi - git mailsplit -d"$prec" -o"$dotest" -b $keep_cr -- "$@" > "$dotest/last" || - clean_abort - ;; - stgit-series) - if test $# -ne 1 - then - clean_abort "$(gettext "Only one StGIT patch series can be applied at once")" - fi - series_dir=$(dirname "$1") - series_file="$1" - shift - { - set x - while read filename - do - set "$@" "$series_dir/$filename" - done - # remove the safety x - shift - # remove the arg coming from the first-line comment - shift - } < "$series_file" || clean_abort - # set the patch format appropriately - patch_format=stgit - # now handle the actual StGIT patches - split_patches "$@" - ;; - stgit) - this=0 - test 0 -eq "$#" && set -- - - for stgit in "$@" - do - this=$(expr "$this" + 1) - msgnum=$(printf "%0${prec}d" $this) - # Perl version of StGIT parse_patch. The first nonemptyline - # not starting with Author, From or Date is the - # subject, and the body starts with the next nonempty - # line not starting with Author, From or Date - @@PERL@@ -ne 'BEGIN { $subject = 0 } - if ($subject > 1) { print ; } - elsif (/^\s+$/) { next ; } - elsif (/^Author:/) { s/Author/From/ ; print ;} - elsif (/^(From|Date)/) { print ; } - elsif ($subject) { - $subject = 2 ; - print "\n" ; - print ; - } else { - print "Subject: ", $_ ; - $subject = 1; - } - ' -- "$stgit" >"$dotest/$msgnum" || clean_abort - done - echo "$this" > "$dotest/last" - this= - msgnum= - ;; - hg) - this=0 - test 0 -eq "$#" && set -- - - for hg in "$@" - do - this=$(( $this + 1 )) - msgnum=$(printf "%0${prec}d" $this) - # hg stores changeset metadata in #-commented lines preceding - # the commit message and diff(s). The only metadata we care about - # are the User and Date (Node ID and Parent are hashes which are - # only relevant to the hg repository and thus not useful to us) - # Since we cannot guarantee that the commit message is in - # git-friendly format, we put no Subject: line and just consume - # all of the message as the body - LANG=C LC_ALL=C @@PERL@@ -M'POSIX qw(strftime)' -ne 'BEGIN { $subject = 0 } - if ($subject) { print ; } - elsif (/^\# User /) { s/\# User/From:/ ; print ; } - elsif (/^\# Date /) { - my ($hashsign, $str, $time, $tz) = split ; - $tz_str = sprintf "%+05d", (0-$tz)/36; - print "Date: " . - strftime("%a, %d %b %Y %H:%M:%S ", - gmtime($time-$tz)) - . "$tz_str\n"; - } elsif (/^\# /) { next ; } - else { - print "\n", $_ ; - $subject = 1; - } - ' -- "$hg" >"$dotest/$msgnum" || clean_abort - done - echo "$this" >"$dotest/last" - this= - msgnum= - ;; - *) - if test -n "$patch_format" - then - clean_abort "$(eval_gettext "Patch format \$patch_format is not supported.")" - else - clean_abort "$(gettext "Patch format detection failed.")" - fi - ;; - esac -} - -prec=4 -dotest="$GIT_DIR/rebase-apply" -sign= utf8=t keep= keepcr= skip= interactive= resolved= rebasing= abort= -messageid= resolvemsg= resume= scissors= no_inbody_headers= -git_apply_opt= -committer_date_is_author_date= -ignore_date= -allow_rerere_autoupdate= -gpg_sign_opt= -threeway= - -if test "$(git config --bool --get am.messageid)" = true -then - messageid=t -fi - -if test "$(git config --bool --get am.keepcr)" = true -then - keepcr=t -fi - -while test $# != 0 -do - case "$1" in - -i|--interactive) - interactive=t ;; - -b|--binary) - gettextln >&2 "The -b/--binary option has been a no-op for long time, and -it will be removed. Please do not use it anymore." - ;; - -3|--3way) - threeway=t ;; - -s|--signoff) - sign=t ;; - -u|--utf8) - utf8=t ;; # this is now default - --no-utf8) - utf8= ;; - -m|--message-id) - messageid=t ;; - --no-message-id) - messageid=f ;; - -k|--keep) - keep=t ;; - --keep-non-patch) - keep=b ;; - -c|--scissors) - scissors=t ;; - --no-scissors) - scissors=f ;; - -r|--resolved|--continue) - resolved=t ;; - --skip) - skip=t ;; - --abort) - abort=t ;; - --rebasing) - rebasing=t threeway=t ;; - --resolvemsg=*) - resolvemsg="${1#--resolvemsg=}" ;; - --whitespace=*|--directory=*|--exclude=*|--include=*) - git_apply_opt="$git_apply_opt $(sq "$1")" ;; - -C*|-p*) - git_apply_opt="$git_apply_opt $(sq "$1")" ;; - --patch-format=*) - patch_format="${1#--patch-format=}" ;; - --reject|--ignore-whitespace|--ignore-space-change) - git_apply_opt="$git_apply_opt $1" ;; - --committer-date-is-author-date) - committer_date_is_author_date=t ;; - --ignore-date) - ignore_date=t ;; - --rerere-autoupdate|--no-rerere-autoupdate) - allow_rerere_autoupdate="$1" ;; - -q|--quiet) - GIT_QUIET=t ;; - --keep-cr) - keepcr=t ;; - --no-keep-cr) - keepcr=f ;; - --gpg-sign) - gpg_sign_opt=-S ;; - --gpg-sign=*) - gpg_sign_opt="-S${1#--gpg-sign=}" ;; - --) - shift; break ;; - *) - usage ;; - esac - shift -done - -# If the dotest directory exists, but we have finished applying all the -# patches in them, clear it out. -if test -d "$dotest" && - test -f "$dotest/last" && - test -f "$dotest/next" && - last=$(cat "$dotest/last") && - next=$(cat "$dotest/next") && - test $# != 0 && - test "$next" -gt "$last" -then - rm -fr "$dotest" -fi - -if test -d "$dotest" && test -f "$dotest/last" && test -f "$dotest/next" -then - case "$#,$skip$resolved$abort" in - 0,*t*) - # Explicit resume command and we do not have file, so - # we are happy. - : ;; - 0,) - # No file input but without resume parameters; catch - # user error to feed us a patch from standard input - # when there is already $dotest. This is somewhat - # unreliable -- stdin could be /dev/null for example - # and the caller did not intend to feed us a patch but - # wanted to continue unattended. - test -t 0 - ;; - *) - false - ;; - esac || - die "$(eval_gettext "previous rebase directory \$dotest still exists but mbox given.")" - resume=yes - - case "$skip,$abort" in - t,t) - die "$(gettext "Please make up your mind. --skip or --abort?")" - ;; - t,) - git rerere clear - head_tree=$(git rev-parse --verify -q HEAD || echo $empty_tree) && - git read-tree --reset -u $head_tree $head_tree && - index_tree=$(git write-tree) && - git read-tree -m -u $index_tree $head_tree - git read-tree -m $head_tree - ;; - ,t) - if test -f "$dotest/rebasing" - then - exec git rebase --abort - fi - git rerere clear - if safe_to_abort - then - head_tree=$(git rev-parse --verify -q HEAD || echo $empty_tree) && - git read-tree --reset -u $head_tree $head_tree && - index_tree=$(git write-tree) && - orig_head=$(git rev-parse --verify -q ORIG_HEAD || echo $empty_tree) && - git read-tree -m -u $index_tree $orig_head - if git rev-parse --verify -q ORIG_HEAD >/dev/null 2>&1 - then - git reset ORIG_HEAD - else - git read-tree $empty_tree - curr_branch=$(git symbolic-ref HEAD 2>/dev/null) && - git update-ref -d $curr_branch - fi - fi - rm -fr "$dotest" - exit ;; - esac - rm -f "$dotest/dirtyindex" -else - # Possible stray $dotest directory in the independent-run - # case; in the --rebasing case, it is upto the caller - # (git-rebase--am) to take care of stray directories. - if test -d "$dotest" && test -z "$rebasing" - then - case "$skip,$resolved,$abort" in - ,,t) - rm -fr "$dotest" - exit 0 - ;; - *) - die "$(eval_gettext "Stray \$dotest directory found. -Use \"git am --abort\" to remove it.")" - ;; - esac - fi - - # Make sure we are not given --skip, --continue, or --abort - test "$skip$resolved$abort" = "" || - die "$(gettext "Resolve operation not in progress, we are not resuming.")" - - # Start afresh. - mkdir -p "$dotest" || exit - - if test -n "$prefix" && test $# != 0 - then - first=t - for arg - do - test -n "$first" && { - set x - first= - } - if is_absolute_path "$arg" - then - set "$@" "$arg" - else - set "$@" "$prefix$arg" - fi - done - shift - fi - - check_patch_format "$@" - - split_patches "$@" - - # -i can and must be given when resuming; everything - # else is kept - echo " $git_apply_opt" >"$dotest/apply-opt" - echo "$threeway" >"$dotest/threeway" - echo "$sign" >"$dotest/sign" - echo "$utf8" >"$dotest/utf8" - echo "$keep" >"$dotest/keep" - echo "$messageid" >"$dotest/messageid" - echo "$scissors" >"$dotest/scissors" - echo "$no_inbody_headers" >"$dotest/no_inbody_headers" - echo "$GIT_QUIET" >"$dotest/quiet" - echo 1 >"$dotest/next" - if test -n "$rebasing" - then - : >"$dotest/rebasing" - else - : >"$dotest/applying" - if test -n "$HAS_HEAD" - then - git update-ref ORIG_HEAD HEAD - else - git update-ref -d ORIG_HEAD >/dev/null 2>&1 - fi - fi -fi - -git update-index -q --refresh - -case "$resolved" in -'') - case "$HAS_HEAD" in - '') - files=$(git ls-files) ;; - ?*) - files=$(git diff-index --cached --name-only HEAD --) ;; - esac || exit - if test "$files" - then - test -n "$HAS_HEAD" && : >"$dotest/dirtyindex" - die "$(eval_gettext "Dirty index: cannot apply patches (dirty: \$files)")" - fi -esac - -# Now, decide what command line options we will give to the git -# commands we invoke, based on the result of parsing command line -# options and previous invocation state stored in $dotest/ files. - -if test "$(cat "$dotest/utf8")" = t -then - utf8=-u -else - utf8=-n -fi -keep=$(cat "$dotest/keep") -case "$keep" in -t) - keep=-k ;; -b) - keep=-b ;; -*) - keep= ;; -esac -case "$(cat "$dotest/messageid")" in -t) - messageid=-m ;; -f) - messageid= ;; -esac -case "$(cat "$dotest/scissors")" in -t) - scissors=--scissors ;; -f) - scissors=--no-scissors ;; -esac -if test "$(cat "$dotest/no_inbody_headers")" = t -then - no_inbody_headers=--no-inbody-headers -else - no_inbody_headers= -fi -if test "$(cat "$dotest/quiet")" = t -then - GIT_QUIET=t -fi -if test "$(cat "$dotest/threeway")" = t -then - threeway=t -fi -git_apply_opt=$(cat "$dotest/apply-opt") -if test "$(cat "$dotest/sign")" = t -then - SIGNOFF=$(git var GIT_COMMITTER_IDENT | sed -e ' - s/>.*/>/ - s/^/Signed-off-by: /' - ) -else - SIGNOFF= -fi - -last=$(cat "$dotest/last") -this=$(cat "$dotest/next") -if test "$skip" = t -then - this=$(expr "$this" + 1) - resume= -fi - -while test "$this" -le "$last" -do - msgnum=$(printf "%0${prec}d" $this) - next=$(expr "$this" + 1) - test -f "$dotest/$msgnum" || { - resume= - go_next - continue - } - - # If we are not resuming, parse and extract the patch information - # into separate files: - # - info records the authorship and title - # - msg is the rest of commit log message - # - patch is the patch body. - # - # When we are resuming, these files are either already prepared - # by the user, or the user can tell us to do so by --continue flag. - case "$resume" in - '') - if test -f "$dotest/rebasing" - then - commit=$(sed -e 's/^From \([0-9a-f]*\) .*/\1/' \ - -e q "$dotest/$msgnum") && - test "$(git cat-file -t "$commit")" = commit || - stop_here $this - git cat-file commit "$commit" | - sed -e '1,/^$/d' >"$dotest/msg-clean" - echo "$commit" >"$dotest/original-commit" - get_author_ident_from_commit "$commit" >"$dotest/author-script" - git diff-tree --root --binary --full-index "$commit" >"$dotest/patch" - else - git mailinfo $keep $no_inbody_headers $messageid $scissors $utf8 "$dotest/msg" "$dotest/patch" \ - <"$dotest/$msgnum" >"$dotest/info" || - stop_here $this - - # skip pine's internal folder data - sane_grep '^Author: Mail System Internal Data$' \ - <"$dotest"/info >/dev/null && - go_next && continue - - test -s "$dotest/patch" || { - eval_gettextln "Patch is empty. Was it split wrong? -If you would prefer to skip this patch, instead run \"\$cmdline --skip\". -To restore the original branch and stop patching run \"\$cmdline --abort\"." - stop_here $this - } - rm -f "$dotest/original-commit" "$dotest/author-script" - { - sed -n '/^Subject/ s/Subject: //p' "$dotest/info" - echo - cat "$dotest/msg" - } | - git stripspace > "$dotest/msg-clean" - fi - ;; - esac - - if test -f "$dotest/author-script" - then - eval $(cat "$dotest/author-script") - else - GIT_AUTHOR_NAME="$(sed -n '/^Author/ s/Author: //p' "$dotest/info")" - GIT_AUTHOR_EMAIL="$(sed -n '/^Email/ s/Email: //p' "$dotest/info")" - GIT_AUTHOR_DATE="$(sed -n '/^Date/ s/Date: //p' "$dotest/info")" - fi - - if test -z "$GIT_AUTHOR_EMAIL" - then - gettextln "Patch does not have a valid e-mail address." - stop_here $this - fi - - export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE - - case "$resume" in - '') - if test '' != "$SIGNOFF" - then - LAST_SIGNED_OFF_BY=$( - sed -ne '/^Signed-off-by: /p' \ - "$dotest/msg-clean" | - sed -ne '$p' - ) - ADD_SIGNOFF=$( - test "$LAST_SIGNED_OFF_BY" = "$SIGNOFF" || { - test '' = "$LAST_SIGNED_OFF_BY" && echo - echo "$SIGNOFF" - }) - else - ADD_SIGNOFF= - fi - { - if test -s "$dotest/msg-clean" - then - cat "$dotest/msg-clean" - fi - if test '' != "$ADD_SIGNOFF" - then - echo "$ADD_SIGNOFF" - fi - } >"$dotest/final-commit" - ;; - *) - case "$resolved$interactive" in - tt) - # This is used only for interactive view option. - git diff-index -p --cached HEAD -- >"$dotest/patch" - ;; - esac - esac - - resume= - if test "$interactive" = t - then - test -t 0 || - die "$(gettext "cannot be interactive without stdin connected to a terminal.")" - action=again - while test "$action" = again - do - gettextln "Commit Body is:" - echo "--------------------------" - cat "$dotest/final-commit" - echo "--------------------------" - # TRANSLATORS: Make sure to include [y], [n], [e], [v] and [a] - # in your translation. The program will only accept English - # input at this point. - gettext "Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all " - read reply - case "$reply" in - [yY]*) action=yes ;; - [aA]*) action=yes interactive= ;; - [nN]*) action=skip ;; - [eE]*) git_editor "$dotest/final-commit" - action=again ;; - [vV]*) action=again - git_pager "$dotest/patch" ;; - *) action=again ;; - esac - done - else - action=yes - fi - - if test $action = skip - then - go_next - continue - fi - - hook="$(git rev-parse --git-path hooks/applypatch-msg)" - if test -x "$hook" - then - "$hook" "$dotest/final-commit" || stop_here $this - fi - - if test -f "$dotest/final-commit" - then - FIRSTLINE=$(sed 1q "$dotest/final-commit") - else - FIRSTLINE="" - fi - - say "$(eval_gettext "Applying: \$FIRSTLINE")" - - case "$resolved" in - '') - # When we are allowed to fall back to 3-way later, don't give - # false errors during the initial attempt. - squelch= - if test "$threeway" = t - then - squelch='>/dev/null 2>&1 ' - fi - eval "git apply $squelch$git_apply_opt"' --index "$dotest/patch"' - apply_status=$? - ;; - t) - # Resolved means the user did all the hard work, and - # we do not have to do any patch application. Just - # trust what the user has in the index file and the - # working tree. - resolved= - git diff-index --quiet --cached HEAD -- && { - gettextln "No changes - did you forget to use 'git add'? -If there is nothing left to stage, chances are that something else -already introduced the same changes; you might want to skip this patch." - stop_here_user_resolve $this - } - unmerged=$(git ls-files -u) - if test -n "$unmerged" - then - gettextln "You still have unmerged paths in your index -did you forget to use 'git add'?" - stop_here_user_resolve $this - fi - apply_status=0 - git rerere - ;; - esac - - if test $apply_status != 0 && test "$threeway" = t - then - if (fall_back_3way) - then - # Applying the patch to an earlier tree and merging the - # result may have produced the same tree as ours. - git diff-index --quiet --cached HEAD -- && { - say "$(gettext "No changes -- Patch already applied.")" - go_next - continue - } - # clear apply_status -- we have successfully merged. - apply_status=0 - fi - fi - if test $apply_status != 0 - then - eval_gettextln 'Patch failed at $msgnum $FIRSTLINE' - if test "$(git config --bool advice.amworkdir)" != false - then - eval_gettextln 'The copy of the patch that failed is found in: - $dotest/patch' - fi - stop_here_user_resolve $this - fi - - hook="$(git rev-parse --git-path hooks/pre-applypatch)" - if test -x "$hook" - then - "$hook" || stop_here $this - fi - - tree=$(git write-tree) && - commit=$( - if test -n "$ignore_date" - then - GIT_AUTHOR_DATE= - fi - parent=$(git rev-parse --verify -q HEAD) || - say >&2 "$(gettext "applying to an empty history")" - - if test -n "$committer_date_is_author_date" - then - GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE" - export GIT_COMMITTER_DATE - fi && - git commit-tree ${parent:+-p} $parent ${gpg_sign_opt:+"$gpg_sign_opt"} $tree \ - <"$dotest/final-commit" - ) && - git update-ref -m "$GIT_REFLOG_ACTION: $FIRSTLINE" HEAD $commit $parent || - stop_here $this - - if test -f "$dotest/original-commit"; then - echo "$(cat "$dotest/original-commit") $commit" >> "$dotest/rewritten" - fi - - hook="$(git rev-parse --git-path hooks/post-applypatch)" - test -x "$hook" && "$hook" - - go_next -done - -if test -s "$dotest"/rewritten; then - git notes copy --for-rewrite=rebase < "$dotest"/rewritten - hook="$(git rev-parse --git-path hooks/post-rewrite)" - if test -x "$hook"; then - "$hook" rebase < "$dotest"/rewritten - fi -fi - -# If am was called with --rebasing (from git-rebase--am), it's up to -# the caller to take care of housekeeping. -if ! test -f "$dotest/rebasing" -then - rm -fr "$dotest" - git gc --auto -fi diff --git a/contrib/examples/git-checkout.sh b/contrib/examples/git-checkout.sh deleted file mode 100755 index 683cae7c3f..0000000000 --- a/contrib/examples/git-checkout.sh +++ /dev/null @@ -1,302 +0,0 @@ -#!/bin/sh - -OPTIONS_KEEPDASHDASH=t -OPTIONS_SPEC="\ -git-checkout [options] [] [...] --- -b= create a new branch started at -l create the new branch's reflog -track arrange that the new branch tracks the remote branch -f proceed even if the index or working tree is not HEAD -m merge local modifications into the new branch -q,quiet be quiet -" -SUBDIRECTORY_OK=Sometimes -. git-sh-setup -require_work_tree - -old_name=HEAD -old=$(git rev-parse --verify $old_name 2>/dev/null) -oldbranch=$(git symbolic-ref $old_name 2>/dev/null) -new= -new_name= -force= -branch= -track= -newbranch= -newbranch_log= -merge= -quiet= -v=-v -LF=' -' - -while test $# != 0; do - case "$1" in - -b) - shift - newbranch="$1" - [ -z "$newbranch" ] && - die "git checkout: -b needs a branch name" - git show-ref --verify --quiet -- "refs/heads/$newbranch" && - die "git checkout: branch $newbranch already exists" - git check-ref-format "heads/$newbranch" || - die "git checkout: we do not like '$newbranch' as a branch name." - ;; - -l) - newbranch_log=-l - ;; - --track|--no-track) - track="$1" - ;; - -f) - force=1 - ;; - -m) - merge=1 - ;; - -q|--quiet) - quiet=1 - v= - ;; - --) - shift - break - ;; - *) - usage - ;; - esac - shift -done - -arg="$1" -rev=$(git rev-parse --verify "$arg" 2>/dev/null) -if rev=$(git rev-parse --verify "$rev^0" 2>/dev/null) -then - [ -z "$rev" ] && die "unknown flag $arg" - new_name="$arg" - if git show-ref --verify --quiet -- "refs/heads/$arg" - then - rev=$(git rev-parse --verify "refs/heads/$arg^0") - branch="$arg" - fi - new="$rev" - shift -elif rev=$(git rev-parse --verify "$rev^{tree}" 2>/dev/null) -then - # checking out selected paths from a tree-ish. - new="$rev" - new_name="$rev^{tree}" - shift -fi -[ "$1" = "--" ] && shift - -case "$newbranch,$track" in -,--*) - die "git checkout: --track and --no-track require -b" -esac - -case "$force$merge" in -11) - die "git checkout: -f and -m are incompatible" -esac - -# The behaviour of the command with and without explicit path -# parameters is quite different. -# -# Without paths, we are checking out everything in the work tree, -# possibly switching branches. This is the traditional behaviour. -# -# With paths, we are _never_ switching branch, but checking out -# the named paths from either index (when no rev is given), -# or the named tree-ish (when rev is given). - -if test "$#" -ge 1 -then - hint= - if test "$#" -eq 1 - then - hint=" -Did you intend to checkout '$@' which can not be resolved as commit?" - fi - if test '' != "$newbranch$force$merge" - then - die "git checkout: updating paths is incompatible with switching branches/forcing$hint" - fi - if test '' != "$new" - then - # from a specific tree-ish; note that this is for - # rescuing paths and is never meant to remove what - # is not in the named tree-ish. - git ls-tree --full-name -r "$new" "$@" | - git update-index --index-info || exit $? - fi - - # Make sure the request is about existing paths. - git ls-files --full-name --error-unmatch -- "$@" >/dev/null || exit - git ls-files --full-name -- "$@" | - (cd_to_toplevel && git checkout-index -f -u --stdin) - - # Run a post-checkout hook -- the HEAD does not change so the - # current HEAD is passed in for both args - if test -x "$GIT_DIR"/hooks/post-checkout; then - "$GIT_DIR"/hooks/post-checkout $old $old 0 - fi - - exit $? -else - # Make sure we did not fall back on $arg^{tree} codepath - # since we are not checking out from an arbitrary tree-ish, - # but switching branches. - if test '' != "$new" - then - git rev-parse --verify "$new^{commit}" >/dev/null 2>&1 || - die "Cannot switch branch to a non-commit." - fi -fi - -# We are switching branches and checking out trees, so -# we *NEED* to be at the toplevel. -cd_to_toplevel - -[ -z "$new" ] && new=$old && new_name="$old_name" - -# If we don't have an existing branch that we're switching to, -# and we don't have a new branch name for the target we -# are switching to, then we are detaching our HEAD from any -# branch. However, if "git checkout HEAD" detaches the HEAD -# from the current branch, even though that may be logically -# correct, it feels somewhat funny. More importantly, we do not -# want "git checkout" or "git checkout -f" to detach HEAD. - -detached= -detach_warn= - -describe_detached_head () { - test -n "$quiet" || { - printf >&2 "$1 " - GIT_PAGER= git log >&2 -1 --pretty=oneline --abbrev-commit "$2" -- - } -} - -if test -z "$branch$newbranch" && test "$new_name" != "$old_name" -then - detached="$new" - if test -n "$oldbranch" && test -z "$quiet" - then - detach_warn="Note: moving to \"$new_name\" which isn't a local branch -If you want to create a new branch from this checkout, you may do so -(now or later) by using -b with the checkout command again. Example: - git checkout -b " - fi -elif test -z "$oldbranch" && test "$new" != "$old" -then - describe_detached_head 'Previous HEAD position was' "$old" -fi - -if [ "X$old" = X ] -then - if test -z "$quiet" - then - echo >&2 "warning: You appear to be on a branch yet to be born." - echo >&2 "warning: Forcing checkout of $new_name." - fi - force=1 -fi - -if [ "$force" ] -then - git read-tree $v --reset -u $new -else - git update-index --refresh >/dev/null - git read-tree $v -m -u --exclude-per-directory=.gitignore $old $new || ( - case "$merge,$v" in - ,*) - exit 1 ;; - 1,) - ;; # quiet - *) - echo >&2 "Falling back to 3-way merge..." ;; - esac - - # Match the index to the working tree, and do a three-way. - git diff-files --name-only | git update-index --remove --stdin && - work=$(git write-tree) && - git read-tree $v --reset -u $new || exit - - eval GITHEAD_$new='${new_name:-${branch:-$new}}' && - eval GITHEAD_$work=local && - export GITHEAD_$new GITHEAD_$work && - git merge-recursive $old -- $new $work - - # Do not register the cleanly merged paths in the index yet. - # this is not a real merge before committing, but just carrying - # the working tree changes along. - unmerged=$(git ls-files -u) - git read-tree $v --reset $new - case "$unmerged" in - '') ;; - *) - ( - z40=0000000000000000000000000000000000000000 - echo "$unmerged" | - sed -e 's/^[0-7]* [0-9a-f]* /'"0 $z40 /" - echo "$unmerged" - ) | git update-index --index-info - ;; - esac - exit 0 - ) - saved_err=$? - if test "$saved_err" = 0 && test -z "$quiet" - then - git diff-index --name-status "$new" - fi - (exit $saved_err) -fi - -# -# Switch the HEAD pointer to the new branch if we -# checked out a branch head, and remove any potential -# old MERGE_HEAD's (subsequent commits will clearly not -# be based on them, since we re-set the index) -# -if [ "$?" -eq 0 ]; then - if [ "$newbranch" ]; then - git branch $track $newbranch_log "$newbranch" "$new_name" || exit - branch="$newbranch" - fi - if test -n "$branch" - then - old_branch_name=$(expr "z$oldbranch" : 'zrefs/heads/\(.*\)') - GIT_DIR="$GIT_DIR" git symbolic-ref -m "checkout: moving from ${old_branch_name:-$old} to $branch" HEAD "refs/heads/$branch" - if test -n "$quiet" - then - true # nothing - elif test "refs/heads/$branch" = "$oldbranch" - then - echo >&2 "Already on branch \"$branch\"" - else - echo >&2 "Switched to${newbranch:+ a new} branch \"$branch\"" - fi - elif test -n "$detached" - then - old_branch_name=$(expr "z$oldbranch" : 'zrefs/heads/\(.*\)') - git update-ref --no-deref -m "checkout: moving from ${old_branch_name:-$old} to $arg" HEAD "$detached" || - die "Cannot detach HEAD" - if test -n "$detach_warn" - then - echo >&2 "$detach_warn" - fi - describe_detached_head 'HEAD is now at' HEAD - fi - rm -f "$GIT_DIR/MERGE_HEAD" -else - exit 1 -fi - -# Run a post-checkout hook -if test -x "$GIT_DIR"/hooks/post-checkout; then - "$GIT_DIR"/hooks/post-checkout $old $new 1 -fi diff --git a/contrib/examples/git-clean.sh b/contrib/examples/git-clean.sh deleted file mode 100755 index 01c95e9fe8..0000000000 --- a/contrib/examples/git-clean.sh +++ /dev/null @@ -1,118 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 2005-2006 Pavel Roskin -# - -OPTIONS_KEEPDASHDASH= -OPTIONS_SPEC="\ -git-clean [options] ... - -Clean untracked files from the working directory - -When optional ... arguments are given, the paths -affected are further limited to those that match them. --- -d remove directories as well -f override clean.requireForce and clean anyway -n don't remove anything, just show what would be done -q be quiet, only report errors -x remove ignored files as well -X remove only ignored files" - -SUBDIRECTORY_OK=Yes -. git-sh-setup -require_work_tree - -ignored= -ignoredonly= -cleandir= -rmf="rm -f --" -rmrf="rm -rf --" -rm_refuse="echo Not removing" -echo1="echo" - -disabled=$(git config --bool clean.requireForce) - -while test $# != 0 -do - case "$1" in - -d) - cleandir=1 - ;; - -f) - disabled=false - ;; - -n) - disabled=false - rmf="echo Would remove" - rmrf="echo Would remove" - rm_refuse="echo Would not remove" - echo1=":" - ;; - -q) - echo1=":" - ;; - -x) - ignored=1 - ;; - -X) - ignoredonly=1 - ;; - --) - shift - break - ;; - *) - usage # should not happen - ;; - esac - shift -done - -# requireForce used to default to false but now it defaults to true. -# IOW, lack of explicit "clean.requireForce = false" is taken as -# "clean.requireForce = true". -case "$disabled" in -"") - die "clean.requireForce not set and -n or -f not given; refusing to clean" - ;; -"true") - die "clean.requireForce set and -n or -f not given; refusing to clean" - ;; -esac - -if [ "$ignored,$ignoredonly" = "1,1" ]; then - die "-x and -X cannot be set together" -fi - -if [ -z "$ignored" ]; then - excl="--exclude-per-directory=.gitignore" - excl_info= excludes_file= - if [ -f "$GIT_DIR/info/exclude" ]; then - excl_info="--exclude-from=$GIT_DIR/info/exclude" - fi - if cfg_excl=$(git config core.excludesfile) && test -f "$cfg_excl" - then - excludes_file="--exclude-from=$cfg_excl" - fi - if [ "$ignoredonly" ]; then - excl="$excl --ignored" - fi -fi - -git ls-files --others --directory \ - $excl ${excl_info:+"$excl_info"} ${excludes_file:+"$excludes_file"} \ - -- "$@" | -while read -r file; do - if [ -d "$file" -a ! -L "$file" ]; then - if [ -z "$cleandir" ]; then - $rm_refuse "$file" - continue - fi - $echo1 "Removing $file" - $rmrf "$file" - else - $echo1 "Removing $file" - $rmf "$file" - fi -done diff --git a/contrib/examples/git-clone.sh b/contrib/examples/git-clone.sh deleted file mode 100755 index 08cf246bbb..0000000000 --- a/contrib/examples/git-clone.sh +++ /dev/null @@ -1,525 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 2005, Linus Torvalds -# Copyright (c) 2005, Junio C Hamano -# -# Clone a repository into a different directory that does not yet exist. - -# See git-sh-setup why. -unset CDPATH - -OPTIONS_SPEC="\ -git-clone [options] [--] [] --- -n,no-checkout don't create a checkout -bare create a bare repository -naked create a bare repository -l,local to clone from a local repository -no-hardlinks don't use local hardlinks, always copy -s,shared setup as a shared repository -template= path to the template directory -q,quiet be quiet -reference= reference repository -o,origin= use instead of 'origin' to track upstream -u,upload-pack= path to git-upload-pack on the remote -depth= create a shallow clone of that depth - -use-separate-remote compatibility, do not use -no-separate-remote compatibility, do not use" - -die() { - echo >&2 "$@" - exit 1 -} - -usage() { - exec "$0" -h -} - -eval "$(echo "$OPTIONS_SPEC" | git rev-parse --parseopt -- "$@" || echo exit $?)" - -get_repo_base() { - ( - cd "$(/bin/pwd)" && - cd "$1" || cd "$1.git" && - { - cd .git - pwd - } - ) 2>/dev/null -} - -if [ -n "$GIT_SSL_NO_VERIFY" -o \ - "$(git config --bool http.sslVerify)" = false ]; then - curl_extra_args="-k" -fi - -http_fetch () { - # $1 = Remote, $2 = Local - curl -nsfL $curl_extra_args "$1" >"$2" - curl_exit_status=$? - case $curl_exit_status in - 126|127) exit ;; - *) return $curl_exit_status ;; - esac -} - -clone_dumb_http () { - # $1 - remote, $2 - local - cd "$2" && - clone_tmp="$GIT_DIR/clone-tmp" && - mkdir -p "$clone_tmp" || exit 1 - if [ -n "$GIT_CURL_FTP_NO_EPSV" -o \ - "$(git config --bool http.noEPSV)" = true ]; then - curl_extra_args="${curl_extra_args} --disable-epsv" - fi - http_fetch "$1/info/refs" "$clone_tmp/refs" || - die "Cannot get remote repository information. -Perhaps git-update-server-info needs to be run there?" - test "z$quiet" = z && v=-v || v= - while read sha1 refname - do - name=$(expr "z$refname" : 'zrefs/\(.*\)') && - case "$name" in - *^*) continue;; - esac - case "$bare,$name" in - yes,* | ,heads/* | ,tags/*) ;; - *) continue ;; - esac - if test -n "$use_separate_remote" && - branch_name=$(expr "z$name" : 'zheads/\(.*\)') - then - tname="remotes/$origin/$branch_name" - else - tname=$name - fi - git-http-fetch $v -a -w "$tname" "$sha1" "$1" || exit 1 - done <"$clone_tmp/refs" - rm -fr "$clone_tmp" - http_fetch "$1/HEAD" "$GIT_DIR/REMOTE_HEAD" || - rm -f "$GIT_DIR/REMOTE_HEAD" - if test -f "$GIT_DIR/REMOTE_HEAD"; then - head_sha1=$(cat "$GIT_DIR/REMOTE_HEAD") - case "$head_sha1" in - 'ref: refs/'*) - ;; - *) - git-http-fetch $v -a "$head_sha1" "$1" || - rm -f "$GIT_DIR/REMOTE_HEAD" - ;; - esac - fi -} - -quiet= -local=no -use_local_hardlink=yes -local_shared=no -unset template -no_checkout= -upload_pack= -bare= -reference= -origin= -origin_override= -use_separate_remote=t -depth= -no_progress= -local_explicitly_asked_for= -test -t 1 || no_progress=--no-progress - -while test $# != 0 -do - case "$1" in - -n|--no-checkout) - no_checkout=yes ;; - --naked|--bare) - bare=yes ;; - -l|--local) - local_explicitly_asked_for=yes - use_local_hardlink=yes - ;; - --no-hardlinks) - use_local_hardlink=no ;; - -s|--shared) - local_shared=yes ;; - --template) - shift; template="--template=$1" ;; - -q|--quiet) - quiet=-q ;; - --use-separate-remote|--no-separate-remote) - die "clones are always made with separate-remote layout" ;; - --reference) - shift; reference="$1" ;; - -o|--origin) - shift; - case "$1" in - '') - usage ;; - */*) - die "'$1' is not suitable for an origin name" - esac - git check-ref-format "heads/$1" || - die "'$1' is not suitable for a branch name" - test -z "$origin_override" || - die "Do not give more than one --origin options." - origin_override=yes - origin="$1" - ;; - -u|--upload-pack) - shift - upload_pack="--upload-pack=$1" ;; - --depth) - shift - depth="--depth=$1" ;; - --) - shift - break ;; - *) - usage ;; - esac - shift -done - -repo="$1" -test -n "$repo" || - die 'you must specify a repository to clone.' - -# --bare implies --no-checkout and --no-separate-remote -if test yes = "$bare" -then - if test yes = "$origin_override" - then - die '--bare and --origin $origin options are incompatible.' - fi - no_checkout=yes - use_separate_remote= -fi - -if test -z "$origin" -then - origin=origin -fi - -# Turn the source into an absolute path if -# it is local -if base=$(get_repo_base "$repo"); then - repo="$base" - if test -z "$depth" - then - local=yes - fi -elif test -f "$repo" -then - case "$repo" in /*) ;; *) repo="$PWD/$repo" ;; esac -fi - -# Decide the directory name of the new repository -if test -n "$2" -then - dir="$2" - test $# = 2 || die "excess parameter to git-clone" -else - # Derive one from the repository name - # Try using "humanish" part of source repo if user didn't specify one - if test -f "$repo" - then - # Cloning from a bundle - dir=$(echo "$repo" | sed -e 's|/*\.bundle$||' -e 's|.*/||g') - else - dir=$(echo "$repo" | - sed -e 's|/$||' -e 's|:*/*\.git$||' -e 's|.*[/:]||g') - fi -fi - -[ -e "$dir" ] && die "destination directory '$dir' already exists." -[ yes = "$bare" ] && unset GIT_WORK_TREE -[ -n "$GIT_WORK_TREE" ] && [ -e "$GIT_WORK_TREE" ] && -die "working tree '$GIT_WORK_TREE' already exists." -D= -W= -cleanup() { - test -z "$D" && rm -rf "$dir" - test -z "$W" && test -n "$GIT_WORK_TREE" && rm -rf "$GIT_WORK_TREE" - cd .. - test -n "$D" && rm -rf "$D" - test -n "$W" && rm -rf "$W" - exit $err -} -trap 'err=$?; cleanup' 0 -mkdir -p "$dir" && D=$(cd "$dir" && pwd) || usage -test -n "$GIT_WORK_TREE" && mkdir -p "$GIT_WORK_TREE" && -W=$(cd "$GIT_WORK_TREE" && pwd) && GIT_WORK_TREE="$W" && export GIT_WORK_TREE -if test yes = "$bare" || test -n "$GIT_WORK_TREE"; then - GIT_DIR="$D" -else - GIT_DIR="$D/.git" -fi && -export GIT_DIR && -GIT_CONFIG="$GIT_DIR/config" git-init $quiet ${template+"$template"} || usage - -if test -n "$bare" -then - GIT_CONFIG="$GIT_DIR/config" git config core.bare true -fi - -if test -n "$reference" -then - ref_git= - if test -d "$reference" - then - if test -d "$reference/.git/objects" - then - ref_git="$reference/.git" - elif test -d "$reference/objects" - then - ref_git="$reference" - fi - fi - if test -n "$ref_git" - then - ref_git=$(cd "$ref_git" && pwd) - echo "$ref_git/objects" >"$GIT_DIR/objects/info/alternates" - ( - GIT_DIR="$ref_git" git for-each-ref \ - --format='%(objectname) %(*objectname)' - ) | - while read a b - do - test -z "$a" || - git update-ref "refs/reference-tmp/$a" "$a" - test -z "$b" || - git update-ref "refs/reference-tmp/$b" "$b" - done - else - die "reference repository '$reference' is not a local directory." - fi -fi - -rm -f "$GIT_DIR/CLONE_HEAD" - -# We do local magic only when the user tells us to. -case "$local" in -yes) - ( cd "$repo/objects" ) || - die "cannot chdir to local '$repo/objects'." - - if test "$local_shared" = yes - then - mkdir -p "$GIT_DIR/objects/info" - echo "$repo/objects" >>"$GIT_DIR/objects/info/alternates" - else - cpio_quiet_flag="" - cpio --help 2>&1 | grep -- --quiet >/dev/null && \ - cpio_quiet_flag=--quiet - l= && - if test "$use_local_hardlink" = yes - then - # See if we can hardlink and drop "l" if not. - sample_file=$(cd "$repo" && \ - find objects -type f -print | sed -e 1q) - # objects directory should not be empty because - # we are cloning! - test -f "$repo/$sample_file" || - die "fatal: cannot clone empty repository" - if ln "$repo/$sample_file" "$GIT_DIR/objects/sample" 2>/dev/null - then - rm -f "$GIT_DIR/objects/sample" - l=l - elif test -n "$local_explicitly_asked_for" - then - echo >&2 "Warning: -l asked but cannot hardlink to $repo" - fi - fi && - cd "$repo" && - # Create dirs using umask and permissions and destination - find objects -type d -print | (cd "$GIT_DIR" && xargs mkdir -p) && - # Copy existing 0444 permissions on content - find objects ! -type d -print | cpio $cpio_quiet_flag -pumd$l "$GIT_DIR/" || \ - exit 1 - fi - git-ls-remote "$repo" >"$GIT_DIR/CLONE_HEAD" || exit 1 - ;; -*) - case "$repo" in - rsync://*) - case "$depth" in - "") ;; - *) die "shallow over rsync not supported" ;; - esac - rsync $quiet -av --ignore-existing \ - --exclude info "$repo/objects/" "$GIT_DIR/objects/" || - exit - # Look at objects/info/alternates for rsync -- http will - # support it natively and git native ones will do it on the - # remote end. Not having that file is not a crime. - rsync -q "$repo/objects/info/alternates" \ - "$GIT_DIR/TMP_ALT" 2>/dev/null || - rm -f "$GIT_DIR/TMP_ALT" - if test -f "$GIT_DIR/TMP_ALT" - then - ( cd "$D" && - . git-parse-remote && - resolve_alternates "$repo" <"$GIT_DIR/TMP_ALT" ) | - while read alt - do - case "$alt" in 'bad alternate: '*) die "$alt";; esac - case "$quiet" in - '') echo >&2 "Getting alternate: $alt" ;; - esac - rsync $quiet -av --ignore-existing \ - --exclude info "$alt" "$GIT_DIR/objects" || exit - done - rm -f "$GIT_DIR/TMP_ALT" - fi - git-ls-remote "$repo" >"$GIT_DIR/CLONE_HEAD" || exit 1 - ;; - https://*|http://*|ftp://*) - case "$depth" in - "") ;; - *) die "shallow over http or ftp not supported" ;; - esac - if test -z "@@NO_CURL@@" - then - clone_dumb_http "$repo" "$D" - else - die "http transport not supported, rebuild Git with curl support" - fi - ;; - *) - if [ -f "$repo" ] ; then - git bundle unbundle "$repo" > "$GIT_DIR/CLONE_HEAD" || - die "unbundle from '$repo' failed." - else - case "$upload_pack" in - '') git-fetch-pack --all -k $quiet $depth $no_progress "$repo";; - *) git-fetch-pack --all -k \ - $quiet "$upload_pack" $depth $no_progress "$repo" ;; - esac >"$GIT_DIR/CLONE_HEAD" || - die "fetch-pack from '$repo' failed." - fi - ;; - esac - ;; -esac -test -d "$GIT_DIR/refs/reference-tmp" && rm -fr "$GIT_DIR/refs/reference-tmp" - -if test -f "$GIT_DIR/CLONE_HEAD" -then - # Read git-fetch-pack -k output and store the remote branches. - if [ -n "$use_separate_remote" ] - then - branch_top="remotes/$origin" - else - branch_top="heads" - fi - tag_top="tags" - while read sha1 name - do - case "$name" in - *'^{}') - continue ;; - HEAD) - destname="REMOTE_HEAD" ;; - refs/heads/*) - destname="refs/$branch_top/${name#refs/heads/}" ;; - refs/tags/*) - destname="refs/$tag_top/${name#refs/tags/}" ;; - *) - continue ;; - esac - git update-ref -m "clone: from $repo" "$destname" "$sha1" "" - done < "$GIT_DIR/CLONE_HEAD" -fi - -if test -n "$W"; then - cd "$W" || exit -else - cd "$D" || exit -fi - -if test -z "$bare" -then - # a non-bare repository is always in separate-remote layout - remote_top="refs/remotes/$origin" - head_sha1= - test ! -r "$GIT_DIR/REMOTE_HEAD" || head_sha1=$(cat "$GIT_DIR/REMOTE_HEAD") - case "$head_sha1" in - 'ref: refs/'*) - # Uh-oh, the remote told us (http transport done against - # new style repository with a symref HEAD). - # Ideally we should skip the guesswork but for now - # opt for minimum change. - head_sha1=$(expr "z$head_sha1" : 'zref: refs/heads/\(.*\)') - head_sha1=$(cat "$GIT_DIR/$remote_top/$head_sha1") - ;; - esac - - # The name under $remote_top the remote HEAD seems to point at. - head_points_at=$( - ( - test -f "$GIT_DIR/$remote_top/master" && echo "master" - cd "$GIT_DIR/$remote_top" && - find . -type f -print | sed -e 's/^\.\///' - ) | ( - done=f - while read name - do - test t = $done && continue - branch_tip=$(cat "$GIT_DIR/$remote_top/$name") - if test "$head_sha1" = "$branch_tip" - then - echo "$name" - done=t - fi - done - ) - ) - - # Upstream URL - git config remote."$origin".url "$repo" && - - # Set up the mappings to track the remote branches. - git config remote."$origin".fetch \ - "+refs/heads/*:$remote_top/*" '^$' && - - # Write out remote.$origin config, and update our "$head_points_at". - case "$head_points_at" in - ?*) - # Local default branch - git symbolic-ref HEAD "refs/heads/$head_points_at" && - - # Tracking branch for the primary branch at the remote. - git update-ref HEAD "$head_sha1" && - - rm -f "refs/remotes/$origin/HEAD" - git symbolic-ref "refs/remotes/$origin/HEAD" \ - "refs/remotes/$origin/$head_points_at" && - - git config branch."$head_points_at".remote "$origin" && - git config branch."$head_points_at".merge "refs/heads/$head_points_at" - ;; - '') - if test -z "$head_sha1" - then - # Source had nonexistent ref in HEAD - echo >&2 "Warning: Remote HEAD refers to nonexistent ref, unable to checkout." - no_checkout=t - else - # Source had detached HEAD pointing nowhere - git update-ref --no-deref HEAD "$head_sha1" && - rm -f "refs/remotes/$origin/HEAD" - fi - ;; - esac - - case "$no_checkout" in - '') - test "z$quiet" = z && test "z$no_progress" = z && v=-v || v= - git read-tree -m -u $v HEAD HEAD - esac -fi -rm -f "$GIT_DIR/CLONE_HEAD" "$GIT_DIR/REMOTE_HEAD" - -trap - 0 diff --git a/contrib/examples/git-commit.sh b/contrib/examples/git-commit.sh deleted file mode 100755 index 86c9cfa0c7..0000000000 --- a/contrib/examples/git-commit.sh +++ /dev/null @@ -1,639 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 2005 Linus Torvalds -# Copyright (c) 2006 Junio C Hamano - -USAGE='[-a | --interactive] [-s] [-v] [--no-verify] [-m | -F | (-C|-c) | --amend] [-u] [-e] [--author ] [--template ] [[-i | -o] ...]' -SUBDIRECTORY_OK=Yes -OPTIONS_SPEC= -. git-sh-setup -require_work_tree - -git rev-parse --verify HEAD >/dev/null 2>&1 || initial_commit=t - -case "$0" in -*status) - status_only=t - ;; -*commit) - status_only= - ;; -esac - -refuse_partial () { - echo >&2 "$1" - echo >&2 "You might have meant to say 'git commit -i paths...', perhaps?" - exit 1 -} - -TMP_INDEX= -THIS_INDEX="${GIT_INDEX_FILE:-$GIT_DIR/index}" -NEXT_INDEX="$GIT_DIR/next-index$$" -rm -f "$NEXT_INDEX" -save_index () { - cp -p "$THIS_INDEX" "$NEXT_INDEX" -} - -run_status () { - # If TMP_INDEX is defined, that means we are doing - # "--only" partial commit, and that index file is used - # to build the tree for the commit. Otherwise, if - # NEXT_INDEX exists, that is the index file used to - # make the commit. Otherwise we are using as-is commit - # so the regular index file is what we use to compare. - if test '' != "$TMP_INDEX" - then - GIT_INDEX_FILE="$TMP_INDEX" - export GIT_INDEX_FILE - elif test -f "$NEXT_INDEX" - then - GIT_INDEX_FILE="$NEXT_INDEX" - export GIT_INDEX_FILE - fi - - if test "$status_only" = "t" || test "$use_status_color" = "t"; then - color= - else - color=--nocolor - fi - git runstatus ${color} \ - ${verbose:+--verbose} \ - ${amend:+--amend} \ - ${untracked_files:+--untracked} -} - -trap ' - test -z "$TMP_INDEX" || { - test -f "$TMP_INDEX" && rm -f "$TMP_INDEX" - } - rm -f "$NEXT_INDEX" -' 0 - -################################################################ -# Command line argument parsing and sanity checking - -all= -also= -allow_empty=f -interactive= -only= -logfile= -use_commit= -amend= -edit_flag= -no_edit= -log_given= -log_message= -verify=t -quiet= -verbose= -signoff= -force_author= -only_include_assumed= -untracked_files= -templatefile="$(git config commit.template)" -while test $# != 0 -do - case "$1" in - -F|--F|-f|--f|--fi|--fil|--file) - case "$#" in 1) usage ;; esac - shift - no_edit=t - log_given=t$log_given - logfile="$1" - ;; - -F*|-f*) - no_edit=t - log_given=t$log_given - logfile="${1#-[Ff]}" - ;; - --F=*|--f=*|--fi=*|--fil=*|--file=*) - no_edit=t - log_given=t$log_given - logfile="${1#*=}" - ;; - -a|--a|--al|--all) - all=t - ;; - --allo|--allow|--allow-|--allow-e|--allow-em|--allow-emp|\ - --allow-empt|--allow-empty) - allow_empty=t - ;; - --au=*|--aut=*|--auth=*|--autho=*|--author=*) - force_author="${1#*=}" - ;; - --au|--aut|--auth|--autho|--author) - case "$#" in 1) usage ;; esac - shift - force_author="$1" - ;; - -e|--e|--ed|--edi|--edit) - edit_flag=t - ;; - -i|--i|--in|--inc|--incl|--inclu|--includ|--include) - also=t - ;; - --int|--inte|--inter|--intera|--interac|--interact|--interacti|\ - --interactiv|--interactive) - interactive=t - ;; - -o|--o|--on|--onl|--only) - only=t - ;; - -m|--m|--me|--mes|--mess|--messa|--messag|--message) - case "$#" in 1) usage ;; esac - shift - log_given=m$log_given - log_message="${log_message:+${log_message} - -}$1" - no_edit=t - ;; - -m*) - log_given=m$log_given - log_message="${log_message:+${log_message} - -}${1#-m}" - no_edit=t - ;; - --m=*|--me=*|--mes=*|--mess=*|--messa=*|--messag=*|--message=*) - log_given=m$log_given - log_message="${log_message:+${log_message} - -}${1#*=}" - no_edit=t - ;; - -n|--n|--no|--no-|--no-v|--no-ve|--no-ver|--no-veri|--no-verif|\ - --no-verify) - verify= - ;; - --a|--am|--ame|--amen|--amend) - amend=t - use_commit=HEAD - ;; - -c) - case "$#" in 1) usage ;; esac - shift - log_given=t$log_given - use_commit="$1" - no_edit= - ;; - --ree=*|--reed=*|--reedi=*|--reedit=*|--reedit-=*|--reedit-m=*|\ - --reedit-me=*|--reedit-mes=*|--reedit-mess=*|--reedit-messa=*|\ - --reedit-messag=*|--reedit-message=*) - log_given=t$log_given - use_commit="${1#*=}" - no_edit= - ;; - --ree|--reed|--reedi|--reedit|--reedit-|--reedit-m|--reedit-me|\ - --reedit-mes|--reedit-mess|--reedit-messa|--reedit-messag|\ - --reedit-message) - case "$#" in 1) usage ;; esac - shift - log_given=t$log_given - use_commit="$1" - no_edit= - ;; - -C) - case "$#" in 1) usage ;; esac - shift - log_given=t$log_given - use_commit="$1" - no_edit=t - ;; - --reu=*|--reus=*|--reuse=*|--reuse-=*|--reuse-m=*|--reuse-me=*|\ - --reuse-mes=*|--reuse-mess=*|--reuse-messa=*|--reuse-messag=*|\ - --reuse-message=*) - log_given=t$log_given - use_commit="${1#*=}" - no_edit=t - ;; - --reu|--reus|--reuse|--reuse-|--reuse-m|--reuse-me|--reuse-mes|\ - --reuse-mess|--reuse-messa|--reuse-messag|--reuse-message) - case "$#" in 1) usage ;; esac - shift - log_given=t$log_given - use_commit="$1" - no_edit=t - ;; - -s|--s|--si|--sig|--sign|--signo|--signof|--signoff) - signoff=t - ;; - -t|--t|--te|--tem|--temp|--templ|--templa|--templat|--template) - case "$#" in 1) usage ;; esac - shift - templatefile="$1" - no_edit= - ;; - -q|--q|--qu|--qui|--quie|--quiet) - quiet=t - ;; - -v|--v|--ve|--ver|--verb|--verbo|--verbos|--verbose) - verbose=t - ;; - -u|--u|--un|--unt|--untr|--untra|--untrac|--untrack|--untracke|\ - --untracked|--untracked-|--untracked-f|--untracked-fi|--untracked-fil|\ - --untracked-file|--untracked-files) - untracked_files=t - ;; - --) - shift - break - ;; - -*) - usage - ;; - *) - break - ;; - esac - shift -done -case "$edit_flag" in t) no_edit= ;; esac - -################################################################ -# Sanity check options - -case "$amend,$initial_commit" in -t,t) - die "You do not have anything to amend." ;; -t,) - if [ -f "$GIT_DIR/MERGE_HEAD" ]; then - die "You are in the middle of a merge -- cannot amend." - fi ;; -esac - -case "$log_given" in -tt*) - die "Only one of -c/-C/-F can be used." ;; -*tm*|*mt*) - die "Option -m cannot be combined with -c/-C/-F." ;; -esac - -case "$#,$also,$only,$amend" in -*,t,t,*) - die "Only one of --include/--only can be used." ;; -0,t,,* | 0,,t,) - die "No paths with --include/--only does not make sense." ;; -0,,t,t) - only_include_assumed="# Clever... amending the last one with dirty index." ;; -0,,,*) - ;; -*,,,*) - only_include_assumed="# Explicit paths specified without -i or -o; assuming --only paths..." - also= - ;; -esac -unset only -case "$all,$interactive,$also,$#" in -*t,*t,*) - die "Cannot use -a, --interactive or -i at the same time." ;; -t,,,[1-9]*) - die "Paths with -a does not make sense." ;; -,t,,[1-9]*) - die "Paths with --interactive does not make sense." ;; -,,t,0) - die "No paths with -i does not make sense." ;; -esac - -if test ! -z "$templatefile" && test -z "$log_given" -then - if test ! -f "$templatefile" - then - die "Commit template file does not exist." - fi -fi - -################################################################ -# Prepare index to have a tree to be committed - -case "$all,$also" in -t,) - if test ! -f "$THIS_INDEX" - then - die 'nothing to commit (use "git add file1 file2" to include for commit)' - fi - save_index && - ( - cd_to_toplevel && - GIT_INDEX_FILE="$NEXT_INDEX" && - export GIT_INDEX_FILE && - git diff-files --name-only -z | - git update-index --remove -z --stdin - ) || exit - ;; -,t) - save_index && - git ls-files --error-unmatch -- "$@" >/dev/null || exit - - git diff-files --name-only -z -- "$@" | - ( - cd_to_toplevel && - GIT_INDEX_FILE="$NEXT_INDEX" && - export GIT_INDEX_FILE && - git update-index --remove -z --stdin - ) || exit - ;; -,) - if test "$interactive" = t; then - git add --interactive || exit - fi - case "$#" in - 0) - ;; # commit as-is - *) - if test -f "$GIT_DIR/MERGE_HEAD" - then - refuse_partial "Cannot do a partial commit during a merge." - fi - - TMP_INDEX="$GIT_DIR/tmp-index$$" - W= - test -z "$initial_commit" && W=--with-tree=HEAD - commit_only=$(git ls-files --error-unmatch $W -- "$@") || exit - - # Build a temporary index and update the real index - # the same way. - if test -z "$initial_commit" - then - GIT_INDEX_FILE="$THIS_INDEX" \ - git read-tree --index-output="$TMP_INDEX" -i -m HEAD - else - rm -f "$TMP_INDEX" - fi || exit - - printf '%s\n' "$commit_only" | - GIT_INDEX_FILE="$TMP_INDEX" \ - git update-index --add --remove --stdin && - - save_index && - printf '%s\n' "$commit_only" | - ( - GIT_INDEX_FILE="$NEXT_INDEX" - export GIT_INDEX_FILE - git update-index --add --remove --stdin - ) || exit - ;; - esac - ;; -esac - -################################################################ -# If we do as-is commit, the index file will be THIS_INDEX, -# otherwise NEXT_INDEX after we make this commit. We leave -# the index as is if we abort. - -if test -f "$NEXT_INDEX" -then - USE_INDEX="$NEXT_INDEX" -else - USE_INDEX="$THIS_INDEX" -fi - -case "$status_only" in -t) - # This will silently fail in a read-only repository, which is - # what we want. - GIT_INDEX_FILE="$USE_INDEX" git update-index -q --unmerged --refresh - run_status - exit $? - ;; -'') - GIT_INDEX_FILE="$USE_INDEX" git update-index -q --refresh || exit - ;; -esac - -################################################################ -# Grab commit message, write out tree and make commit. - -if test t = "$verify" && test -x "$GIT_DIR"/hooks/pre-commit -then - GIT_INDEX_FILE="${TMP_INDEX:-${USE_INDEX}}" "$GIT_DIR"/hooks/pre-commit \ - || exit -fi - -if test "$log_message" != '' -then - printf '%s\n' "$log_message" -elif test "$logfile" != "" -then - if test "$logfile" = - - then - test -t 0 && - echo >&2 "(reading log message from standard input)" - cat - else - cat <"$logfile" - fi -elif test "$use_commit" != "" -then - encoding=$(git config i18n.commitencoding || echo UTF-8) - git show -s --pretty=raw --encoding="$encoding" "$use_commit" | - sed -e '1,/^$/d' -e 's/^ //' -elif test -f "$GIT_DIR/MERGE_MSG" -then - cat "$GIT_DIR/MERGE_MSG" -elif test -f "$GIT_DIR/SQUASH_MSG" -then - cat "$GIT_DIR/SQUASH_MSG" -elif test "$templatefile" != "" -then - cat "$templatefile" -fi | git stripspace >"$GIT_DIR"/COMMIT_EDITMSG - -case "$signoff" in -t) - sign=$(git var GIT_COMMITTER_IDENT | sed -e ' - s/>.*/>/ - s/^/Signed-off-by: / - ') - blank_before_signoff= - tail -n 1 "$GIT_DIR"/COMMIT_EDITMSG | - grep 'Signed-off-by:' >/dev/null || blank_before_signoff=' -' - tail -n 1 "$GIT_DIR"/COMMIT_EDITMSG | - grep "$sign"$ >/dev/null || - printf '%s%s\n' "$blank_before_signoff" "$sign" \ - >>"$GIT_DIR"/COMMIT_EDITMSG - ;; -esac - -if test -f "$GIT_DIR/MERGE_HEAD" && test -z "$no_edit"; then - echo "#" - echo "# It looks like you may be committing a MERGE." - echo "# If this is not correct, please remove the file" - printf '%s\n' "# $GIT_DIR/MERGE_HEAD" - echo "# and try again" - echo "#" -fi >>"$GIT_DIR"/COMMIT_EDITMSG - -# Author -if test '' != "$use_commit" -then - eval "$(get_author_ident_from_commit "$use_commit")" - export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE -fi -if test '' != "$force_author" -then - GIT_AUTHOR_NAME=$(expr "z$force_author" : 'z\(.*[^ ]\) *<.*') && - GIT_AUTHOR_EMAIL=$(expr "z$force_author" : '.*\(<.*\)') && - test '' != "$GIT_AUTHOR_NAME" && - test '' != "$GIT_AUTHOR_EMAIL" || - die "malformed --author parameter" - export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL -fi - -PARENTS="-p HEAD" -if test -z "$initial_commit" -then - rloga='commit' - if [ -f "$GIT_DIR/MERGE_HEAD" ]; then - rloga='commit (merge)' - PARENTS="-p HEAD "$(sed -e 's/^/-p /' "$GIT_DIR/MERGE_HEAD") - elif test -n "$amend"; then - rloga='commit (amend)' - PARENTS=$(git cat-file commit HEAD | - sed -n -e '/^$/q' -e 's/^parent /-p /p') - fi - current="$(git rev-parse --verify HEAD)" -else - if [ -z "$(git ls-files)" ]; then - echo >&2 'nothing to commit (use "git add file1 file2" to include for commit)' - exit 1 - fi - PARENTS="" - rloga='commit (initial)' - current='' -fi -set_reflog_action "$rloga" - -if test -z "$no_edit" -then - { - echo "" - echo "# Please enter the commit message for your changes." - echo "# (Comment lines starting with '#' will not be included)" - test -z "$only_include_assumed" || echo "$only_include_assumed" - run_status - } >>"$GIT_DIR"/COMMIT_EDITMSG -else - # we need to check if there is anything to commit - run_status >/dev/null -fi -case "$allow_empty,$?,$PARENTS" in -t,* | ?,0,* | ?,*,-p' '?*-p' '?*) - # an explicit --allow-empty, or a merge commit can record the - # same tree as its parent. Otherwise having commitable paths - # is required. - ;; -*) - rm -f "$GIT_DIR/COMMIT_EDITMSG" "$GIT_DIR/SQUASH_MSG" - use_status_color=t - run_status - exit 1 -esac - -case "$no_edit" in -'') - git var GIT_AUTHOR_IDENT > /dev/null || die - git var GIT_COMMITTER_IDENT > /dev/null || die - git_editor "$GIT_DIR/COMMIT_EDITMSG" - ;; -esac - -case "$verify" in -t) - if test -x "$GIT_DIR"/hooks/commit-msg - then - "$GIT_DIR"/hooks/commit-msg "$GIT_DIR"/COMMIT_EDITMSG || exit - fi -esac - -if test -z "$no_edit" -then - sed -e ' - /^diff --git a\/.*/{ - s/// - q - } - /^#/d - ' "$GIT_DIR"/COMMIT_EDITMSG -else - cat "$GIT_DIR"/COMMIT_EDITMSG -fi | -git stripspace >"$GIT_DIR"/COMMIT_MSG - -# Test whether the commit message has any content we didn't supply. -have_commitmsg= -grep -v -i '^Signed-off-by' "$GIT_DIR"/COMMIT_MSG | - git stripspace > "$GIT_DIR"/COMMIT_BAREMSG - -# Is the commit message totally empty? -if test -s "$GIT_DIR"/COMMIT_BAREMSG -then - if test "$templatefile" != "" - then - # Test whether this is just the unaltered template. - if cnt=$(sed -e '/^#/d' < "$templatefile" | - git stripspace | - diff "$GIT_DIR"/COMMIT_BAREMSG - | - wc -l) && - test 0 -lt $cnt - then - have_commitmsg=t - fi - else - # No template, so the content in the commit message must - # have come from the user. - have_commitmsg=t - fi -fi - -rm -f "$GIT_DIR"/COMMIT_BAREMSG - -if test "$have_commitmsg" = "t" -then - if test -z "$TMP_INDEX" - then - tree=$(GIT_INDEX_FILE="$USE_INDEX" git write-tree) - else - tree=$(GIT_INDEX_FILE="$TMP_INDEX" git write-tree) && - rm -f "$TMP_INDEX" - fi && - commit=$(git commit-tree $tree $PARENTS <"$GIT_DIR/COMMIT_MSG") && - rlogm=$(sed -e 1q "$GIT_DIR"/COMMIT_MSG) && - git update-ref -m "$GIT_REFLOG_ACTION: $rlogm" HEAD $commit "$current" && - rm -f -- "$GIT_DIR/MERGE_HEAD" "$GIT_DIR/MERGE_MSG" && - if test -f "$NEXT_INDEX" - then - mv "$NEXT_INDEX" "$THIS_INDEX" - else - : ;# happy - fi -else - echo >&2 "* no commit message? aborting commit." - false -fi -ret="$?" -rm -f "$GIT_DIR/COMMIT_MSG" "$GIT_DIR/COMMIT_EDITMSG" "$GIT_DIR/SQUASH_MSG" - -cd_to_toplevel - -git rerere - -if test "$ret" = 0 -then - git gc --auto - if test -x "$GIT_DIR"/hooks/post-commit - then - "$GIT_DIR"/hooks/post-commit - fi - if test -z "$quiet" - then - commit=$(git diff-tree --always --shortstat --pretty="format:%h: %s"\ - --abbrev --summary --root HEAD --) - echo "Created${initial_commit:+ initial} commit $commit" - fi -fi - -exit "$ret" diff --git a/contrib/examples/git-difftool.perl b/contrib/examples/git-difftool.perl deleted file mode 100755 index b2ea80f9ed..0000000000 --- a/contrib/examples/git-difftool.perl +++ /dev/null @@ -1,481 +0,0 @@ -#!/usr/bin/perl -# Copyright (c) 2009, 2010 David Aguilar -# Copyright (c) 2012 Tim Henigan -# -# This is a wrapper around the GIT_EXTERNAL_DIFF-compatible -# git-difftool--helper script. -# -# This script exports GIT_EXTERNAL_DIFF and GIT_PAGER for use by git. -# The GIT_DIFF* variables are exported for use by git-difftool--helper. -# -# Any arguments that are unknown to this script are forwarded to 'git diff'. - -use 5.008; -use strict; -use warnings; -use Git::LoadCPAN::Error qw(:try); -use File::Basename qw(dirname); -use File::Copy; -use File::Find; -use File::stat; -use File::Path qw(mkpath rmtree); -use File::Temp qw(tempdir); -use Getopt::Long qw(:config pass_through); -use Git; -use Git::I18N; - -sub usage -{ - my $exitcode = shift; - print << 'USAGE'; -usage: git difftool [-t|--tool=] [--tool-help] - [-x|--extcmd=] - [-g|--gui] [--no-gui] - [--prompt] [-y|--no-prompt] - [-d|--dir-diff] - ['git diff' options] -USAGE - exit($exitcode); -} - -sub print_tool_help -{ - # See the comment at the bottom of file_diff() for the reason behind - # using system() followed by exit() instead of exec(). - my $rc = system(qw(git mergetool --tool-help=diff)); - exit($rc | ($rc >> 8)); -} - -sub exit_cleanup -{ - my ($tmpdir, $status) = @_; - my $errno = $!; - rmtree($tmpdir); - if ($status and $errno) { - my ($package, $file, $line) = caller(); - warn "$file line $line: $errno\n"; - } - exit($status | ($status >> 8)); -} - -sub use_wt_file -{ - my ($file, $sha1) = @_; - my $null_sha1 = '0' x 40; - - if (-l $file || ! -e _) { - return (0, $null_sha1); - } - - my $wt_sha1 = Git::command_oneline('hash-object', $file); - my $use = ($sha1 eq $null_sha1) || ($sha1 eq $wt_sha1); - return ($use, $wt_sha1); -} - -sub changed_files -{ - my ($repo_path, $index, $worktree) = @_; - $ENV{GIT_INDEX_FILE} = $index; - - my @gitargs = ('--git-dir', $repo_path, '--work-tree', $worktree); - my @refreshargs = ( - @gitargs, 'update-index', - '--really-refresh', '-q', '--unmerged'); - try { - Git::command_oneline(@refreshargs); - } catch Git::Error::Command with {}; - - my @diffargs = (@gitargs, 'diff-files', '--name-only', '-z'); - my $line = Git::command_oneline(@diffargs); - my @files; - if (defined $line) { - @files = split('\0', $line); - } else { - @files = (); - } - - delete($ENV{GIT_INDEX_FILE}); - - return map { $_ => 1 } @files; -} - -sub setup_dir_diff -{ - my ($worktree, $symlinks) = @_; - my @gitargs = ('diff', '--raw', '--no-abbrev', '-z', @ARGV); - my $diffrtn = Git::command_oneline(@gitargs); - exit(0) unless defined($diffrtn); - - # Go to the root of the worktree now that we've captured the list of - # changed files. The paths returned by diff --raw are relative to the - # top-level of the repository, but we defer changing directories so - # that @ARGV can perform pathspec limiting in the current directory. - chdir($worktree); - - # Build index info for left and right sides of the diff - my $submodule_mode = '160000'; - my $symlink_mode = '120000'; - my $null_mode = '0' x 6; - my $null_sha1 = '0' x 40; - my $lindex = ''; - my $rindex = ''; - my $wtindex = ''; - my %submodule; - my %symlink; - my @files = (); - my %working_tree_dups = (); - my @rawdiff = split('\0', $diffrtn); - - my $i = 0; - while ($i < $#rawdiff) { - if ($rawdiff[$i] =~ /^::/) { - warn __ <<'EOF'; -Combined diff formats ('-c' and '--cc') are not supported in -directory diff mode ('-d' and '--dir-diff'). -EOF - exit(1); - } - - my ($lmode, $rmode, $lsha1, $rsha1, $status) = - split(' ', substr($rawdiff[$i], 1)); - my $src_path = $rawdiff[$i + 1]; - my $dst_path; - - if ($status =~ /^[CR]/) { - $dst_path = $rawdiff[$i + 2]; - $i += 3; - } else { - $dst_path = $src_path; - $i += 2; - } - - if ($lmode eq $submodule_mode or $rmode eq $submodule_mode) { - $submodule{$src_path}{left} = $lsha1; - if ($lsha1 ne $rsha1) { - $submodule{$dst_path}{right} = $rsha1; - } else { - $submodule{$dst_path}{right} = "$rsha1-dirty"; - } - next; - } - - if ($lmode eq $symlink_mode) { - $symlink{$src_path}{left} = - Git::command_oneline('show', $lsha1); - } - - if ($rmode eq $symlink_mode) { - $symlink{$dst_path}{right} = - Git::command_oneline('show', $rsha1); - } - - if ($lmode ne $null_mode and $status !~ /^C/) { - $lindex .= "$lmode $lsha1\t$src_path\0"; - } - - if ($rmode ne $null_mode) { - # Avoid duplicate entries - if ($working_tree_dups{$dst_path}++) { - next; - } - my ($use, $wt_sha1) = - use_wt_file($dst_path, $rsha1); - if ($use) { - push @files, $dst_path; - $wtindex .= "$rmode $wt_sha1\t$dst_path\0"; - } else { - $rindex .= "$rmode $rsha1\t$dst_path\0"; - } - } - } - - # Go to the root of the worktree so that the left index files - # are properly setup -- the index is toplevel-relative. - chdir($worktree); - - # Setup temp directories - my $tmpdir = tempdir('git-difftool.XXXXX', CLEANUP => 0, TMPDIR => 1); - my $ldir = "$tmpdir/left"; - my $rdir = "$tmpdir/right"; - mkpath($ldir) or exit_cleanup($tmpdir, 1); - mkpath($rdir) or exit_cleanup($tmpdir, 1); - - # Populate the left and right directories based on each index file - my ($inpipe, $ctx); - $ENV{GIT_INDEX_FILE} = "$tmpdir/lindex"; - ($inpipe, $ctx) = - Git::command_input_pipe('update-index', '-z', '--index-info'); - print($inpipe $lindex); - Git::command_close_pipe($inpipe, $ctx); - - my $rc = system('git', 'checkout-index', '--all', "--prefix=$ldir/"); - exit_cleanup($tmpdir, $rc) if $rc != 0; - - $ENV{GIT_INDEX_FILE} = "$tmpdir/rindex"; - ($inpipe, $ctx) = - Git::command_input_pipe('update-index', '-z', '--index-info'); - print($inpipe $rindex); - Git::command_close_pipe($inpipe, $ctx); - - $rc = system('git', 'checkout-index', '--all', "--prefix=$rdir/"); - exit_cleanup($tmpdir, $rc) if $rc != 0; - - $ENV{GIT_INDEX_FILE} = "$tmpdir/wtindex"; - ($inpipe, $ctx) = - Git::command_input_pipe('update-index', '--info-only', '-z', '--index-info'); - print($inpipe $wtindex); - Git::command_close_pipe($inpipe, $ctx); - - # If $GIT_DIR was explicitly set just for the update/checkout - # commands, then it should be unset before continuing. - delete($ENV{GIT_INDEX_FILE}); - - # Changes in the working tree need special treatment since they are - # not part of the index. - for my $file (@files) { - my $dir = dirname($file); - unless (-d "$rdir/$dir") { - mkpath("$rdir/$dir") or - exit_cleanup($tmpdir, 1); - } - if ($symlinks) { - symlink("$worktree/$file", "$rdir/$file") or - exit_cleanup($tmpdir, 1); - } else { - copy($file, "$rdir/$file") or - exit_cleanup($tmpdir, 1); - - my $mode = stat($file)->mode; - chmod($mode, "$rdir/$file") or - exit_cleanup($tmpdir, 1); - } - } - - # Changes to submodules require special treatment. This loop writes a - # temporary file to both the left and right directories to show the - # change in the recorded SHA1 for the submodule. - for my $path (keys %submodule) { - my $ok = 0; - if (defined($submodule{$path}{left})) { - $ok = write_to_file("$ldir/$path", - "Subproject commit $submodule{$path}{left}"); - } - if (defined($submodule{$path}{right})) { - $ok = write_to_file("$rdir/$path", - "Subproject commit $submodule{$path}{right}"); - } - exit_cleanup($tmpdir, 1) if not $ok; - } - - # Symbolic links require special treatment. The standard "git diff" - # shows only the link itself, not the contents of the link target. - # This loop replicates that behavior. - for my $path (keys %symlink) { - my $ok = 0; - if (defined($symlink{$path}{left})) { - $ok = write_to_file("$ldir/$path", - $symlink{$path}{left}); - } - if (defined($symlink{$path}{right})) { - $ok = write_to_file("$rdir/$path", - $symlink{$path}{right}); - } - exit_cleanup($tmpdir, 1) if not $ok; - } - - return ($ldir, $rdir, $tmpdir, @files); -} - -sub write_to_file -{ - my $path = shift; - my $value = shift; - - # Make sure the path to the file exists - my $dir = dirname($path); - unless (-d "$dir") { - mkpath("$dir") or return 0; - } - - # If the file already exists in that location, delete it. This - # is required in the case of symbolic links. - unlink($path); - - open(my $fh, '>', $path) or return 0; - print($fh $value); - close($fh); - - return 1; -} - -sub main -{ - # parse command-line options. all unrecognized options and arguments - # are passed through to the 'git diff' command. - my %opts = ( - difftool_cmd => undef, - dirdiff => undef, - extcmd => undef, - gui => undef, - help => undef, - prompt => undef, - symlinks => $^O ne 'cygwin' && - $^O ne 'MSWin32' && $^O ne 'msys', - tool_help => undef, - trust_exit_code => undef, - ); - GetOptions('g|gui!' => \$opts{gui}, - 'd|dir-diff' => \$opts{dirdiff}, - 'h' => \$opts{help}, - 'prompt!' => \$opts{prompt}, - 'y' => sub { $opts{prompt} = 0; }, - 'symlinks' => \$opts{symlinks}, - 'no-symlinks' => sub { $opts{symlinks} = 0; }, - 't|tool:s' => \$opts{difftool_cmd}, - 'tool-help' => \$opts{tool_help}, - 'trust-exit-code' => \$opts{trust_exit_code}, - 'no-trust-exit-code' => sub { $opts{trust_exit_code} = 0; }, - 'x|extcmd:s' => \$opts{extcmd}); - - if (defined($opts{help})) { - usage(0); - } - if (defined($opts{tool_help})) { - print_tool_help(); - } - if (defined($opts{difftool_cmd})) { - if (length($opts{difftool_cmd}) > 0) { - $ENV{GIT_DIFF_TOOL} = $opts{difftool_cmd}; - } else { - print __("No given for --tool=\n"); - usage(1); - } - } - if (defined($opts{extcmd})) { - if (length($opts{extcmd}) > 0) { - $ENV{GIT_DIFFTOOL_EXTCMD} = $opts{extcmd}; - } else { - print __("No given for --extcmd=\n"); - usage(1); - } - } - if ($opts{gui}) { - my $guitool = Git::config('diff.guitool'); - if (defined($guitool) && length($guitool) > 0) { - $ENV{GIT_DIFF_TOOL} = $guitool; - } - } - - if (!defined $opts{trust_exit_code}) { - $opts{trust_exit_code} = Git::config_bool('difftool.trustExitCode'); - } - if ($opts{trust_exit_code}) { - $ENV{GIT_DIFFTOOL_TRUST_EXIT_CODE} = 'true'; - } else { - $ENV{GIT_DIFFTOOL_TRUST_EXIT_CODE} = 'false'; - } - - # In directory diff mode, 'git-difftool--helper' is called once - # to compare the a/b directories. In file diff mode, 'git diff' - # will invoke a separate instance of 'git-difftool--helper' for - # each file that changed. - if (defined($opts{dirdiff})) { - dir_diff($opts{extcmd}, $opts{symlinks}); - } else { - file_diff($opts{prompt}); - } -} - -sub dir_diff -{ - my ($extcmd, $symlinks) = @_; - my $rc; - my $error = 0; - my $repo = Git->repository(); - my $repo_path = $repo->repo_path(); - my $worktree = $repo->wc_path(); - $worktree =~ s|/$||; # Avoid double slashes in symlink targets - my ($a, $b, $tmpdir, @files) = setup_dir_diff($worktree, $symlinks); - - if (defined($extcmd)) { - $rc = system($extcmd, $a, $b); - } else { - $ENV{GIT_DIFFTOOL_DIRDIFF} = 'true'; - $rc = system('git', 'difftool--helper', $a, $b); - } - # If the diff including working copy files and those - # files were modified during the diff, then the changes - # should be copied back to the working tree. - # Do not copy back files when symlinks are used and the - # external tool did not replace the original link with a file. - # - # These hashes are loaded lazily since they aren't needed - # in the common case of --symlinks and the difftool updating - # files through the symlink. - my %wt_modified; - my %tmp_modified; - my $indices_loaded = 0; - - for my $file (@files) { - next if $symlinks && -l "$b/$file"; - next if ! -f "$b/$file"; - - if (!$indices_loaded) { - %wt_modified = changed_files( - $repo_path, "$tmpdir/wtindex", $worktree); - %tmp_modified = changed_files( - $repo_path, "$tmpdir/wtindex", $b); - $indices_loaded = 1; - } - - if (exists $wt_modified{$file} and exists $tmp_modified{$file}) { - warn sprintf(__( - "warning: Both files modified:\n" . - "'%s/%s' and '%s/%s'.\n" . - "warning: Working tree file has been left.\n" . - "warning:\n"), $worktree, $file, $b, $file); - $error = 1; - } elsif (exists $tmp_modified{$file}) { - my $mode = stat("$b/$file")->mode; - copy("$b/$file", $file) or - exit_cleanup($tmpdir, 1); - - chmod($mode, $file) or - exit_cleanup($tmpdir, 1); - } - } - if ($error) { - warn sprintf(__( - "warning: Temporary files exist in '%s'.\n" . - "warning: You may want to cleanup or recover these.\n"), $tmpdir); - exit(1); - } else { - exit_cleanup($tmpdir, $rc); - } -} - -sub file_diff -{ - my ($prompt) = @_; - - if (defined($prompt)) { - if ($prompt) { - $ENV{GIT_DIFFTOOL_PROMPT} = 'true'; - } else { - $ENV{GIT_DIFFTOOL_NO_PROMPT} = 'true'; - } - } - - $ENV{GIT_PAGER} = ''; - $ENV{GIT_EXTERNAL_DIFF} = 'git-difftool--helper'; - - # ActiveState Perl for Win32 does not implement POSIX semantics of - # exec* system call. It just spawns the given executable and finishes - # the starting program, exiting with code 0. - # system will at least catch the errors returned by git diff, - # allowing the caller of git difftool better handling of failures. - my $rc = system('git', 'diff', @ARGV); - exit($rc | ($rc >> 8)); -} - -main(); diff --git a/contrib/examples/git-fetch.sh b/contrib/examples/git-fetch.sh deleted file mode 100755 index 57d2e5616f..0000000000 --- a/contrib/examples/git-fetch.sh +++ /dev/null @@ -1,379 +0,0 @@ -#!/bin/sh -# - -USAGE=' ...' -SUBDIRECTORY_OK=Yes -. git-sh-setup -set_reflog_action "fetch $*" -cd_to_toplevel ;# probably unnecessary... - -. git-parse-remote -_x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]' -_x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40" - -LF=' -' -IFS="$LF" - -no_tags= -tags= -append= -force= -verbose= -update_head_ok= -exec= -keep= -shallow_depth= -no_progress= -test -t 1 || no_progress=--no-progress -quiet= -while test $# != 0 -do - case "$1" in - -a|--a|--ap|--app|--appe|--appen|--append) - append=t - ;; - --upl|--uplo|--uploa|--upload|--upload-|--upload-p|\ - --upload-pa|--upload-pac|--upload-pack) - shift - exec="--upload-pack=$1" - ;; - --upl=*|--uplo=*|--uploa=*|--upload=*|\ - --upload-=*|--upload-p=*|--upload-pa=*|--upload-pac=*|--upload-pack=*) - exec=--upload-pack=$(expr "z$1" : 'z-[^=]*=\(.*\)') - shift - ;; - -f|--f|--fo|--for|--forc|--force) - force=t - ;; - -t|--t|--ta|--tag|--tags) - tags=t - ;; - -n|--n|--no|--no-|--no-t|--no-ta|--no-tag|--no-tags) - no_tags=t - ;; - -u|--u|--up|--upd|--upda|--updat|--update|--update-|--update-h|\ - --update-he|--update-hea|--update-head|--update-head-|\ - --update-head-o|--update-head-ok) - update_head_ok=t - ;; - -q|--q|--qu|--qui|--quie|--quiet) - quiet=--quiet - ;; - -v|--verbose) - verbose="$verbose"Yes - ;; - -k|--k|--ke|--kee|--keep) - keep='-k -k' - ;; - --depth=*) - shallow_depth="--depth=$(expr "z$1" : 'z-[^=]*=\(.*\)')" - ;; - --depth) - shift - shallow_depth="--depth=$1" - ;; - -*) - usage - ;; - *) - break - ;; - esac - shift -done - -case "$#" in -0) - origin=$(get_default_remote) - test -n "$(get_remote_url ${origin})" || - die "Where do you want to fetch from today?" - set x $origin ; shift ;; -esac - -if test -z "$exec" -then - # No command line override and we have configuration for the remote. - exec="--upload-pack=$(get_uploadpack $1)" -fi - -remote_nick="$1" -remote=$(get_remote_url "$@") -refs= -rref= -rsync_slurped_objects= - -if test "" = "$append" -then - : >"$GIT_DIR/FETCH_HEAD" -fi - -# Global that is reused later -ls_remote_result=$(git ls-remote $exec "$remote") || - die "Cannot get the repository state from $remote" - -append_fetch_head () { - flags= - test -n "$verbose" && flags="$flags$LF-v" - test -n "$force$single_force" && flags="$flags$LF-f" - GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION" \ - git fetch--tool $flags append-fetch-head "$@" -} - -# updating the current HEAD with git-fetch in a bare -# repository is always fine. -if test -z "$update_head_ok" && test $(is_bare_repository) = false -then - orig_head=$(git rev-parse --verify HEAD 2>/dev/null) -fi - -# Allow --tags/--notags from remote.$1.tagopt -case "$tags$no_tags" in -'') - case "$(git config --get "remote.$1.tagopt")" in - --tags) - tags=t ;; - --no-tags) - no_tags=t ;; - esac -esac - -# If --tags (and later --heads or --all) is specified, then we are -# not talking about defaults stored in Pull: line of remotes or -# branches file, and just fetch those and refspecs explicitly given. -# Otherwise we do what we always did. - -reflist=$(get_remote_refs_for_fetch "$@") -if test "$tags" -then - taglist=$(IFS=' ' && - echo "$ls_remote_result" | - git show-ref --exclude-existing=refs/tags/ | - while read sha1 name - do - echo ".${name}:${name}" - done) || exit - if test "$#" -gt 1 - then - # remote URL plus explicit refspecs; we need to merge them. - reflist="$reflist$LF$taglist" - else - # No explicit refspecs; fetch tags only. - reflist=$taglist - fi -fi - -fetch_all_at_once () { - - eval=$(echo "$1" | git fetch--tool parse-reflist "-") - eval "$eval" - - ( : subshell because we muck with IFS - IFS=" $LF" - ( - if test "$remote" = . ; then - git show-ref $rref || echo failed "$remote" - elif test -f "$remote" ; then - test -n "$shallow_depth" && - die "shallow clone with bundle is not supported" - git bundle unbundle "$remote" $rref || - echo failed "$remote" - else - if test -d "$remote" && - - # The remote might be our alternate. With - # this optimization we will bypass fetch-pack - # altogether, which means we cannot be doing - # the shallow stuff at all. - test ! -f "$GIT_DIR/shallow" && - test -z "$shallow_depth" && - - # See if all of what we are going to fetch are - # connected to our repository's tips, in which - # case we do not have to do any fetch. - theirs=$(echo "$ls_remote_result" | \ - git fetch--tool -s pick-rref "$rref" "-") && - - # This will barf when $theirs reach an object that - # we do not have in our repository. Otherwise, - # we already have everything the fetch would bring in. - git rev-list --objects $theirs --not --all \ - >/dev/null 2>/dev/null - then - echo "$ls_remote_result" | \ - git fetch--tool pick-rref "$rref" "-" - else - flags= - case $verbose in - YesYes*) - flags="-v" - ;; - esac - git-fetch-pack --thin $exec $keep $shallow_depth \ - $quiet $no_progress $flags "$remote" $rref || - echo failed "$remote" - fi - fi - ) | - ( - flags= - test -n "$verbose" && flags="$flags -v" - test -n "$force" && flags="$flags -f" - GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION" \ - git fetch--tool $flags native-store \ - "$remote" "$remote_nick" "$refs" - ) - ) || exit - -} - -fetch_per_ref () { - reflist="$1" - refs= - rref= - - for ref in $reflist - do - refs="$refs$LF$ref" - - # These are relative path from $GIT_DIR, typically starting at refs/ - # but may be HEAD - if expr "z$ref" : 'z\.' >/dev/null - then - not_for_merge=t - ref=$(expr "z$ref" : 'z\.\(.*\)') - else - not_for_merge= - fi - if expr "z$ref" : 'z+' >/dev/null - then - single_force=t - ref=$(expr "z$ref" : 'z+\(.*\)') - else - single_force= - fi - remote_name=$(expr "z$ref" : 'z\([^:]*\):') - local_name=$(expr "z$ref" : 'z[^:]*:\(.*\)') - - rref="$rref$LF$remote_name" - - # There are transports that can fetch only one head at a time... - case "$remote" in - http://* | https://* | ftp://*) - test -n "$shallow_depth" && - die "shallow clone with http not supported" - proto=$(expr "$remote" : '\([^:]*\):') - if [ -n "$GIT_SSL_NO_VERIFY" ]; then - curl_extra_args="-k" - fi - if [ -n "$GIT_CURL_FTP_NO_EPSV" -o \ - "$(git config --bool http.noEPSV)" = true ]; then - noepsv_opt="--disable-epsv" - fi - - # Find $remote_name from ls-remote output. - head=$(echo "$ls_remote_result" | \ - git fetch--tool -s pick-rref "$remote_name" "-") - expr "z$head" : "z$_x40\$" >/dev/null || - die "No such ref $remote_name at $remote" - echo >&2 "Fetching $remote_name from $remote using $proto" - case "$quiet" in '') v=-v ;; *) v= ;; esac - git-http-fetch $v -a "$head" "$remote" || exit - ;; - rsync://*) - test -n "$shallow_depth" && - die "shallow clone with rsync not supported" - TMP_HEAD="$GIT_DIR/TMP_HEAD" - rsync -L -q "$remote/$remote_name" "$TMP_HEAD" || exit 1 - head=$(git rev-parse --verify TMP_HEAD) - rm -f "$TMP_HEAD" - case "$quiet" in '') v=-v ;; *) v= ;; esac - test "$rsync_slurped_objects" || { - rsync -a $v --ignore-existing --exclude info \ - "$remote/objects/" "$GIT_OBJECT_DIRECTORY/" || exit - - # Look at objects/info/alternates for rsync -- http will - # support it natively and git native ones will do it on - # the remote end. Not having that file is not a crime. - rsync -q "$remote/objects/info/alternates" \ - "$GIT_DIR/TMP_ALT" 2>/dev/null || - rm -f "$GIT_DIR/TMP_ALT" - if test -f "$GIT_DIR/TMP_ALT" - then - resolve_alternates "$remote" <"$GIT_DIR/TMP_ALT" | - while read alt - do - case "$alt" in 'bad alternate: '*) die "$alt";; esac - echo >&2 "Getting alternate: $alt" - rsync -av --ignore-existing --exclude info \ - "$alt" "$GIT_OBJECT_DIRECTORY/" || exit - done - rm -f "$GIT_DIR/TMP_ALT" - fi - rsync_slurped_objects=t - } - ;; - esac - - append_fetch_head "$head" "$remote" \ - "$remote_name" "$remote_nick" "$local_name" "$not_for_merge" || exit - - done - -} - -fetch_main () { - case "$remote" in - http://* | https://* | ftp://* | rsync://* ) - fetch_per_ref "$@" - ;; - *) - fetch_all_at_once "$@" - ;; - esac -} - -fetch_main "$reflist" || exit - -# automated tag following -case "$no_tags$tags" in -'') - case "$reflist" in - *:refs/*) - # effective only when we are following remote branch - # using local tracking branch. - taglist=$(IFS=' ' && - echo "$ls_remote_result" | - git show-ref --exclude-existing=refs/tags/ | - while read sha1 name - do - git cat-file -t "$sha1" >/dev/null 2>&1 || continue - echo >&2 "Auto-following $name" - echo ".${name}:${name}" - done) - esac - case "$taglist" in - '') ;; - ?*) - # do not deepen a shallow tree when following tags - shallow_depth= - fetch_main "$taglist" || exit ;; - esac -esac - -# If the original head was empty (i.e. no "master" yet), or -# if we were told not to worry, we do not have to check. -case "$orig_head" in -'') - ;; -?*) - curr_head=$(git rev-parse --verify HEAD 2>/dev/null) - if test "$curr_head" != "$orig_head" - then - git update-ref \ - -m "$GIT_REFLOG_ACTION: Undoing incorrectly fetched HEAD." \ - HEAD "$orig_head" - die "Cannot fetch into the current branch." - fi - ;; -esac diff --git a/contrib/examples/git-gc.sh b/contrib/examples/git-gc.sh deleted file mode 100755 index 1597e9f33f..0000000000 --- a/contrib/examples/git-gc.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 2006, Shawn O. Pearce -# -# Cleanup unreachable files and optimize the repository. - -USAGE='[--prune]' -SUBDIRECTORY_OK=Yes -. git-sh-setup - -no_prune=: -while test $# != 0 -do - case "$1" in - --prune) - no_prune= - ;; - --) - usage - ;; - esac - shift -done - -case "$(git config --get gc.packrefs)" in -notbare|"") - test $(is_bare_repository) = true || pack_refs=true;; -*) - pack_refs=$(git config --bool --get gc.packrefs) -esac - -test "true" != "$pack_refs" || -git pack-refs --prune && -git reflog expire --all && -git-repack -a -d -l && -$no_prune git prune && -git rerere gc || exit diff --git a/contrib/examples/git-log.sh b/contrib/examples/git-log.sh deleted file mode 100755 index c2ea71cf14..0000000000 --- a/contrib/examples/git-log.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 2005 Linus Torvalds -# - -USAGE='[--max-count=] [..] [--pretty=] [git-rev-list options]' -SUBDIRECTORY_OK='Yes' -. git-sh-setup - -revs=$(git-rev-parse --revs-only --no-flags --default HEAD "$@") || exit -[ "$revs" ] || { - die "No HEAD ref" -} -git-rev-list --pretty $(git-rev-parse --default HEAD "$@") | -LESS=-S ${PAGER:-less} diff --git a/contrib/examples/git-ls-remote.sh b/contrib/examples/git-ls-remote.sh deleted file mode 100755 index 2aa89a7df8..0000000000 --- a/contrib/examples/git-ls-remote.sh +++ /dev/null @@ -1,142 +0,0 @@ -#!/bin/sh -# - -usage () { - echo >&2 "usage: $0 [--heads] [--tags] [-u|--upload-pack ]" - echo >&2 " ..." - exit 1; -} - -die () { - echo >&2 "$*" - exit 1 -} - -exec= -while test $# != 0 -do - case "$1" in - -h|--h|--he|--hea|--head|--heads) - heads=heads; shift ;; - -t|--t|--ta|--tag|--tags) - tags=tags; shift ;; - -u|--u|--up|--upl|--uploa|--upload|--upload-|--upload-p|--upload-pa|\ - --upload-pac|--upload-pack) - shift - exec="--upload-pack=$1" - shift;; - -u=*|--u=*|--up=*|--upl=*|--uplo=*|--uploa=*|--upload=*|\ - --upload-=*|--upload-p=*|--upload-pa=*|--upload-pac=*|--upload-pack=*) - exec=--upload-pack=$(expr "z$1" : 'z-[^=]*=\(.*\)') - shift;; - --) - shift; break ;; - -*) - usage ;; - *) - break ;; - esac -done - -case "$#" in 0) usage ;; esac - -case ",$heads,$tags," in -,,,) heads=heads tags=tags other=other ;; -esac - -. git-parse-remote -peek_repo="$(get_remote_url "$@")" -shift - -tmp=.ls-remote-$$ -trap "rm -fr $tmp-*" 0 1 2 3 15 -tmpdir=$tmp-d - -case "$peek_repo" in -http://* | https://* | ftp://* ) - if [ -n "$GIT_SSL_NO_VERIFY" -o \ - "$(git config --bool http.sslVerify)" = false ]; then - curl_extra_args="-k" - fi - if [ -n "$GIT_CURL_FTP_NO_EPSV" -o \ - "$(git config --bool http.noEPSV)" = true ]; then - curl_extra_args="${curl_extra_args} --disable-epsv" - fi - curl -nsf $curl_extra_args --header "Pragma: no-cache" "$peek_repo/info/refs" || - echo "failed slurping" - ;; - -rsync://* ) - mkdir $tmpdir && - rsync -rlq "$peek_repo/HEAD" $tmpdir && - rsync -rq "$peek_repo/refs" $tmpdir || { - echo "failed slurping" - exit - } - head=$(cat "$tmpdir/HEAD") && - case "$head" in - ref:' '*) - head=$(expr "z$head" : 'zref: \(.*\)') && - head=$(cat "$tmpdir/$head") || exit - esac && - echo "$head HEAD" - (cd $tmpdir && find refs -type f) | - while read path - do - tr -d '\012' <"$tmpdir/$path" - echo " $path" - done && - rm -fr $tmpdir - ;; - -* ) - if test -f "$peek_repo" ; then - git bundle list-heads "$peek_repo" || - echo "failed slurping" - else - git-peek-remote $exec "$peek_repo" || - echo "failed slurping" - fi - ;; -esac | -sort -t ' ' -k 2 | -while read sha1 path -do - case "$sha1" in - failed) - exit 1 ;; - esac - case "$path" in - refs/heads/*) - group=heads ;; - refs/tags/*) - group=tags ;; - *) - group=other ;; - esac - case ",$heads,$tags,$other," in - *,$group,*) - ;; - *) - continue;; - esac - case "$#" in - 0) - match=yes ;; - *) - match=no - for pat - do - case "/$path" in - */$pat ) - match=yes - break ;; - esac - done - esac - case "$match" in - no) - continue ;; - esac - echo "$sha1 $path" -done diff --git a/contrib/examples/git-merge-ours.sh b/contrib/examples/git-merge-ours.sh deleted file mode 100755 index 29dba4ba3a..0000000000 --- a/contrib/examples/git-merge-ours.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 2005 Junio C Hamano -# -# Pretend we resolved the heads, but declare our tree trumps everybody else. -# - -# We need to exit with 2 if the index does not match our HEAD tree, -# because the current index is what we will be committing as the -# merge result. - -git diff-index --quiet --cached HEAD -- || exit 2 - -exit 0 diff --git a/contrib/examples/git-merge.sh b/contrib/examples/git-merge.sh deleted file mode 100755 index 932e78dbfe..0000000000 --- a/contrib/examples/git-merge.sh +++ /dev/null @@ -1,620 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 2005 Junio C Hamano -# - -OPTIONS_KEEPDASHDASH= -OPTIONS_SPEC="\ -git merge [options] ... -git merge [options] HEAD --- -stat show a diffstat at the end of the merge -n don't show a diffstat at the end of the merge -summary (synonym to --stat) -log add list of one-line log to merge commit message -squash create a single commit instead of doing a merge -commit perform a commit if the merge succeeds (default) -ff allow fast-forward (default) -ff-only abort if fast-forward is not possible -rerere-autoupdate update index with any reused conflict resolution -s,strategy= merge strategy to use -X= option for selected merge strategy -m,message= message to be used for the merge commit (if any) -" - -SUBDIRECTORY_OK=Yes -. git-sh-setup -require_work_tree -cd_to_toplevel - -test -z "$(git ls-files -u)" || - die "Merge is not possible because you have unmerged files." - -! test -e "$GIT_DIR/MERGE_HEAD" || - die 'You have not concluded your merge (MERGE_HEAD exists).' - -LF=' -' - -all_strategies='recur recursive octopus resolve stupid ours subtree' -all_strategies="$all_strategies recursive-ours recursive-theirs" -not_strategies='base file index tree' -default_twohead_strategies='recursive' -default_octopus_strategies='octopus' -no_fast_forward_strategies='subtree ours' -no_trivial_strategies='recursive recur subtree ours recursive-ours recursive-theirs' -use_strategies= -xopt= - -allow_fast_forward=t -fast_forward_only= -allow_trivial_merge=t -squash= no_commit= log_arg= rr_arg= - -dropsave() { - rm -f -- "$GIT_DIR/MERGE_HEAD" "$GIT_DIR/MERGE_MSG" \ - "$GIT_DIR/MERGE_STASH" "$GIT_DIR/MERGE_MODE" || exit 1 -} - -savestate() { - # Stash away any local modifications. - git stash create >"$GIT_DIR/MERGE_STASH" -} - -restorestate() { - if test -f "$GIT_DIR/MERGE_STASH" - then - git reset --hard $head >/dev/null - git stash apply $(cat "$GIT_DIR/MERGE_STASH") - git update-index --refresh >/dev/null - fi -} - -finish_up_to_date () { - case "$squash" in - t) - echo "$1 (nothing to squash)" ;; - '') - echo "$1" ;; - esac - dropsave -} - -squash_message () { - echo Squashed commit of the following: - echo - git log --no-merges --pretty=medium ^"$head" $remoteheads -} - -finish () { - if test '' = "$2" - then - rlogm="$GIT_REFLOG_ACTION" - else - echo "$2" - rlogm="$GIT_REFLOG_ACTION: $2" - fi - case "$squash" in - t) - echo "Squash commit -- not updating HEAD" - squash_message >"$GIT_DIR/SQUASH_MSG" - ;; - '') - case "$merge_msg" in - '') - echo "No merge message -- not updating HEAD" - ;; - *) - git update-ref -m "$rlogm" HEAD "$1" "$head" || exit 1 - git gc --auto - ;; - esac - ;; - esac - case "$1" in - '') - ;; - ?*) - if test "$show_diffstat" = t - then - # We want color (if set), but no pager - GIT_PAGER='' git diff --stat --summary -M "$head" "$1" - fi - ;; - esac - - # Run a post-merge hook - if test -x "$GIT_DIR"/hooks/post-merge - then - case "$squash" in - t) - "$GIT_DIR"/hooks/post-merge 1 - ;; - '') - "$GIT_DIR"/hooks/post-merge 0 - ;; - esac - fi -} - -merge_name () { - remote="$1" - rh=$(git rev-parse --verify "$remote^0" 2>/dev/null) || return - if truname=$(expr "$remote" : '\(.*\)~[0-9]*$') && - git show-ref -q --verify "refs/heads/$truname" 2>/dev/null - then - echo "$rh branch '$truname' (early part) of ." - return - fi - if found_ref=$(git rev-parse --symbolic-full-name --verify \ - "$remote" 2>/dev/null) - then - expanded=$(git check-ref-format --branch "$remote") || - exit - if test "${found_ref#refs/heads/}" != "$found_ref" - then - echo "$rh branch '$expanded' of ." - return - elif test "${found_ref#refs/remotes/}" != "$found_ref" - then - echo "$rh remote branch '$expanded' of ." - return - fi - fi - if test "$remote" = "FETCH_HEAD" && test -r "$GIT_DIR/FETCH_HEAD" - then - sed -e 's/ not-for-merge / /' -e 1q \ - "$GIT_DIR/FETCH_HEAD" - return - fi - echo "$rh commit '$remote'" -} - -parse_config () { - while test $# != 0; do - case "$1" in - -n|--no-stat|--no-summary) - show_diffstat=false ;; - --stat|--summary) - show_diffstat=t ;; - --log|--no-log) - log_arg=$1 ;; - --squash) - test "$allow_fast_forward" = t || - die "You cannot combine --squash with --no-ff." - squash=t no_commit=t ;; - --no-squash) - squash= no_commit= ;; - --commit) - no_commit= ;; - --no-commit) - no_commit=t ;; - --ff) - allow_fast_forward=t ;; - --no-ff) - test "$squash" != t || - die "You cannot combine --squash with --no-ff." - test "$fast_forward_only" != t || - die "You cannot combine --ff-only with --no-ff." - allow_fast_forward=f ;; - --ff-only) - test "$allow_fast_forward" != f || - die "You cannot combine --ff-only with --no-ff." - fast_forward_only=t ;; - --rerere-autoupdate|--no-rerere-autoupdate) - rr_arg=$1 ;; - -s|--strategy) - shift - case " $all_strategies " in - *" $1 "*) - use_strategies="$use_strategies$1 " - ;; - *) - case " $not_strategies " in - *" $1 "*) - false - esac && - type "git-merge-$1" >/dev/null 2>&1 || - die "available strategies are: $all_strategies" - use_strategies="$use_strategies$1 " - ;; - esac - ;; - -X) - shift - xopt="${xopt:+$xopt }$(git rev-parse --sq-quote "--$1")" - ;; - -m|--message) - shift - merge_msg="$1" - have_message=t - ;; - --) - shift - break ;; - *) usage ;; - esac - shift - done - args_left=$# -} - -test $# != 0 || usage - -have_message= - -if branch=$(git-symbolic-ref -q HEAD) -then - mergeopts=$(git config "branch.${branch#refs/heads/}.mergeoptions") - if test -n "$mergeopts" - then - parse_config $mergeopts -- - fi -fi - -parse_config "$@" -while test $args_left -lt $#; do shift; done - -if test -z "$show_diffstat"; then - test "$(git config --bool merge.diffstat)" = false && show_diffstat=false - test "$(git config --bool merge.stat)" = false && show_diffstat=false - test -z "$show_diffstat" && show_diffstat=t -fi - -# This could be traditional "merge HEAD ..." and the -# way we can tell it is to see if the second token is HEAD, but some -# people might have misused the interface and used a commit-ish that -# is the same as HEAD there instead. Traditional format never would -# have "-m" so it is an additional safety measure to check for it. - -if test -z "$have_message" && - second_token=$(git rev-parse --verify "$2^0" 2>/dev/null) && - head_commit=$(git rev-parse --verify "HEAD" 2>/dev/null) && - test "$second_token" = "$head_commit" -then - merge_msg="$1" - shift - head_arg="$1" - shift -elif ! git rev-parse --verify HEAD >/dev/null 2>&1 -then - # If the merged head is a valid one there is no reason to - # forbid "git merge" into a branch yet to be born. We do - # the same for "git pull". - if test 1 -ne $# - then - echo >&2 "Can merge only exactly one commit into empty head" - exit 1 - fi - - test "$squash" != t || - die "Squash commit into empty head not supported yet" - test "$allow_fast_forward" = t || - die "Non-fast-forward into an empty head does not make sense" - rh=$(git rev-parse --verify "$1^0") || - die "$1 - not something we can merge" - - git update-ref -m "initial pull" HEAD "$rh" "" && - git read-tree --reset -u HEAD - exit - -else - # We are invoked directly as the first-class UI. - head_arg=HEAD - - # All the rest are the commits being merged; prepare - # the standard merge summary message to be appended to - # the given message. If remote is invalid we will die - # later in the common codepath so we discard the error - # in this loop. - merge_msg="$( - for remote - do - merge_name "$remote" - done | - if test "$have_message" = t - then - git fmt-merge-msg -m "$merge_msg" $log_arg - else - git fmt-merge-msg $log_arg - fi - )" -fi -head=$(git rev-parse --verify "$head_arg"^0) || usage - -# All the rest are remote heads -test "$#" = 0 && usage ;# we need at least one remote head. -set_reflog_action "merge $*" - -remoteheads= -for remote -do - remotehead=$(git rev-parse --verify "$remote"^0 2>/dev/null) || - die "$remote - not something we can merge" - remoteheads="${remoteheads}$remotehead " - eval GITHEAD_$remotehead='"$remote"' - export GITHEAD_$remotehead -done -set x $remoteheads ; shift - -case "$use_strategies" in -'') - case "$#" in - 1) - var="$(git config --get pull.twohead)" - if test -n "$var" - then - use_strategies="$var" - else - use_strategies="$default_twohead_strategies" - fi ;; - *) - var="$(git config --get pull.octopus)" - if test -n "$var" - then - use_strategies="$var" - else - use_strategies="$default_octopus_strategies" - fi ;; - esac - ;; -esac - -for s in $use_strategies -do - for ss in $no_fast_forward_strategies - do - case " $s " in - *" $ss "*) - allow_fast_forward=f - break - ;; - esac - done - for ss in $no_trivial_strategies - do - case " $s " in - *" $ss "*) - allow_trivial_merge=f - break - ;; - esac - done -done - -case "$#" in -1) - common=$(git merge-base --all $head "$@") - ;; -*) - common=$(git merge-base --all --octopus $head "$@") - ;; -esac -echo "$head" >"$GIT_DIR/ORIG_HEAD" - -case "$allow_fast_forward,$#,$common,$no_commit" in -?,*,'',*) - # No common ancestors found. We need a real merge. - ;; -?,1,"$1",*) - # If head can reach all the merge then we are up to date. - # but first the most common case of merging one remote. - finish_up_to_date "Already up to date." - exit 0 - ;; -t,1,"$head",*) - # Again the most common case of merging one remote. - echo "Updating $(git rev-parse --short $head)..$(git rev-parse --short $1)" - git update-index --refresh 2>/dev/null - msg="Fast-forward" - if test -n "$have_message" - then - msg="$msg (no commit created; -m option ignored)" - fi - new_head=$(git rev-parse --verify "$1^0") && - git read-tree -v -m -u --exclude-per-directory=.gitignore $head "$new_head" && - finish "$new_head" "$msg" || exit - dropsave - exit 0 - ;; -?,1,?*"$LF"?*,*) - # We are not doing octopus and not fast-forward. Need a - # real merge. - ;; -?,1,*,) - # We are not doing octopus, not fast-forward, and have only - # one common. - git update-index --refresh 2>/dev/null - case "$allow_trivial_merge,$fast_forward_only" in - t,) - # See if it is really trivial. - git var GIT_COMMITTER_IDENT >/dev/null || exit - echo "Trying really trivial in-index merge..." - if git read-tree --trivial -m -u -v $common $head "$1" && - result_tree=$(git write-tree) - then - echo "Wonderful." - result_commit=$( - printf '%s\n' "$merge_msg" | - git commit-tree $result_tree -p HEAD -p "$1" - ) || exit - finish "$result_commit" "In-index merge" - dropsave - exit 0 - fi - echo "Nope." - esac - ;; -*) - # An octopus. If we can reach all the remote we are up to date. - up_to_date=t - for remote - do - common_one=$(git merge-base --all $head $remote) - if test "$common_one" != "$remote" - then - up_to_date=f - break - fi - done - if test "$up_to_date" = t - then - finish_up_to_date "Already up to date. Yeeah!" - exit 0 - fi - ;; -esac - -if test "$fast_forward_only" = t -then - die "Not possible to fast-forward, aborting." -fi - -# We are going to make a new commit. -git var GIT_COMMITTER_IDENT >/dev/null || exit - -# At this point, we need a real merge. No matter what strategy -# we use, it would operate on the index, possibly affecting the -# working tree, and when resolved cleanly, have the desired tree -# in the index -- this means that the index must be in sync with -# the $head commit. The strategies are responsible to ensure this. - -case "$use_strategies" in -?*' '?*) - # Stash away the local changes so that we can try more than one. - savestate - single_strategy=no - ;; -*) - rm -f "$GIT_DIR/MERGE_STASH" - single_strategy=yes - ;; -esac - -result_tree= best_cnt=-1 best_strategy= wt_strategy= -merge_was_ok= -for strategy in $use_strategies -do - test "$wt_strategy" = '' || { - echo "Rewinding the tree to pristine..." - restorestate - } - case "$single_strategy" in - no) - echo "Trying merge strategy $strategy..." - ;; - esac - - # Remember which strategy left the state in the working tree - wt_strategy=$strategy - - eval 'git-merge-$strategy '"$xopt"' $common -- "$head_arg" "$@"' - exit=$? - if test "$no_commit" = t && test "$exit" = 0 - then - merge_was_ok=t - exit=1 ;# pretend it left conflicts. - fi - - test "$exit" = 0 || { - - # The backend exits with 1 when conflicts are left to be resolved, - # with 2 when it does not handle the given merge at all. - - if test "$exit" -eq 1 - then - cnt=$({ - git diff-files --name-only - git ls-files --unmerged - } | wc -l) - if test $best_cnt -le 0 || test $cnt -le $best_cnt - then - best_strategy=$strategy - best_cnt=$cnt - fi - fi - continue - } - - # Automerge succeeded. - result_tree=$(git write-tree) && break -done - -# If we have a resulting tree, that means the strategy module -# auto resolved the merge cleanly. -if test '' != "$result_tree" -then - if test "$allow_fast_forward" = "t" - then - parents=$(git merge-base --independent "$head" "$@") - else - parents=$(git rev-parse "$head" "$@") - fi - parents=$(echo "$parents" | sed -e 's/^/-p /') - result_commit=$(printf '%s\n' "$merge_msg" | git commit-tree $result_tree $parents) || exit - finish "$result_commit" "Merge made by $wt_strategy." - dropsave - exit 0 -fi - -# Pick the result from the best strategy and have the user fix it up. -case "$best_strategy" in -'') - restorestate - case "$use_strategies" in - ?*' '?*) - echo >&2 "No merge strategy handled the merge." - ;; - *) - echo >&2 "Merge with strategy $use_strategies failed." - ;; - esac - exit 2 - ;; -"$wt_strategy") - # We already have its result in the working tree. - ;; -*) - echo "Rewinding the tree to pristine..." - restorestate - echo "Using the $best_strategy to prepare resolving by hand." - git-merge-$best_strategy $common -- "$head_arg" "$@" - ;; -esac - -if test "$squash" = t -then - finish -else - for remote - do - echo $remote - done >"$GIT_DIR/MERGE_HEAD" - printf '%s\n' "$merge_msg" >"$GIT_DIR/MERGE_MSG" || - die "Could not write to $GIT_DIR/MERGE_MSG" - if test "$allow_fast_forward" != t - then - printf "%s" no-ff - else - : - fi >"$GIT_DIR/MERGE_MODE" || - die "Could not write to $GIT_DIR/MERGE_MODE" -fi - -if test "$merge_was_ok" = t -then - echo >&2 \ - "Automatic merge went well; stopped before committing as requested" - exit 0 -else - { - echo ' -Conflicts: -' - git ls-files --unmerged | - sed -e 's/^[^ ]* / /' | - uniq - } >>"$GIT_DIR/MERGE_MSG" - git rerere $rr_arg - die "Automatic merge failed; fix conflicts and then commit the result." -fi diff --git a/contrib/examples/git-notes.sh b/contrib/examples/git-notes.sh deleted file mode 100755 index e642e47d9f..0000000000 --- a/contrib/examples/git-notes.sh +++ /dev/null @@ -1,121 +0,0 @@ -#!/bin/sh - -USAGE="(edit [-F | -m ] | show) [commit]" -. git-sh-setup - -test -z "$1" && usage -ACTION="$1"; shift - -test -z "$GIT_NOTES_REF" && GIT_NOTES_REF="$(git config core.notesref)" -test -z "$GIT_NOTES_REF" && GIT_NOTES_REF="refs/notes/commits" - -MESSAGE= -while test $# != 0 -do - case "$1" in - -m) - test "$ACTION" = "edit" || usage - shift - if test "$#" = "0"; then - die "error: option -m needs an argument" - else - if [ -z "$MESSAGE" ]; then - MESSAGE="$1" - else - MESSAGE="$MESSAGE - -$1" - fi - shift - fi - ;; - -F) - test "$ACTION" = "edit" || usage - shift - if test "$#" = "0"; then - die "error: option -F needs an argument" - else - if [ -z "$MESSAGE" ]; then - MESSAGE="$(cat "$1")" - else - MESSAGE="$MESSAGE - -$(cat "$1")" - fi - shift - fi - ;; - -*) - usage - ;; - *) - break - ;; - esac -done - -COMMIT=$(git rev-parse --verify --default HEAD "$@") || -die "Invalid commit: $@" - -case "$ACTION" in -edit) - if [ "${GIT_NOTES_REF#refs/notes/}" = "$GIT_NOTES_REF" ]; then - die "Refusing to edit notes in $GIT_NOTES_REF (outside of refs/notes/)" - fi - - MSG_FILE="$GIT_DIR/new-notes-$COMMIT" - GIT_INDEX_FILE="$MSG_FILE.idx" - export GIT_INDEX_FILE - - trap ' - test -f "$MSG_FILE" && rm "$MSG_FILE" - test -f "$GIT_INDEX_FILE" && rm "$GIT_INDEX_FILE" - ' 0 - - CURRENT_HEAD=$(git show-ref "$GIT_NOTES_REF" | cut -f 1 -d ' ') - if [ -z "$CURRENT_HEAD" ]; then - PARENT= - else - PARENT="-p $CURRENT_HEAD" - git read-tree "$GIT_NOTES_REF" || die "Could not read index" - fi - - if [ -z "$MESSAGE" ]; then - GIT_NOTES_REF= git log -1 $COMMIT | sed "s/^/#/" > "$MSG_FILE" - if [ ! -z "$CURRENT_HEAD" ]; then - git cat-file blob :$COMMIT >> "$MSG_FILE" 2> /dev/null - fi - core_editor="$(git config core.editor)" - ${GIT_EDITOR:-${core_editor:-${VISUAL:-${EDITOR:-vi}}}} "$MSG_FILE" - else - echo "$MESSAGE" > "$MSG_FILE" - fi - - grep -v ^# < "$MSG_FILE" | git stripspace > "$MSG_FILE".processed - mv "$MSG_FILE".processed "$MSG_FILE" - if [ -s "$MSG_FILE" ]; then - BLOB=$(git hash-object -w "$MSG_FILE") || - die "Could not write into object database" - git update-index --add --cacheinfo 0644 $BLOB $COMMIT || - die "Could not write index" - else - test -z "$CURRENT_HEAD" && - die "Will not initialise with empty tree" - git update-index --force-remove $COMMIT || - die "Could not update index" - fi - - TREE=$(git write-tree) || die "Could not write tree" - NEW_HEAD=$(echo Annotate $COMMIT | git commit-tree $TREE $PARENT) || - die "Could not annotate" - git update-ref -m "Annotate $COMMIT" \ - "$GIT_NOTES_REF" $NEW_HEAD $CURRENT_HEAD -;; -show) - git rev-parse -q --verify "$GIT_NOTES_REF":$COMMIT > /dev/null || - die "No note for commit $COMMIT." - git show "$GIT_NOTES_REF":$COMMIT -;; -*) - usage -esac diff --git a/contrib/examples/git-pull.sh b/contrib/examples/git-pull.sh deleted file mode 100755 index 6b3a03f9b0..0000000000 --- a/contrib/examples/git-pull.sh +++ /dev/null @@ -1,381 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 2005 Junio C Hamano -# -# Fetch one or more remote refs and merge it/them into the current HEAD. - -SUBDIRECTORY_OK=Yes -OPTIONS_KEEPDASHDASH= -OPTIONS_STUCKLONG=Yes -OPTIONS_SPEC="\ -git pull [options] [ [...]] - -Fetch one or more remote refs and integrate it/them with the current HEAD. --- -v,verbose be more verbose -q,quiet be more quiet -progress force progress reporting - - Options related to merging -r,rebase?false|true|preserve incorporate changes by rebasing rather than merging -n! do not show a diffstat at the end of the merge -stat show a diffstat at the end of the merge -summary (synonym to --stat) -log?n add (at most ) entries from shortlog to merge commit message -squash create a single commit instead of doing a merge -commit perform a commit if the merge succeeds (default) -e,edit edit message before committing -ff allow fast-forward -ff-only! abort if fast-forward is not possible -verify-signatures verify that the named commit has a valid GPG signature -s,strategy=strategy merge strategy to use -X,strategy-option=option option for selected merge strategy -S,gpg-sign?key-id GPG sign commit - - Options related to fetching -all fetch from all remotes -a,append append to .git/FETCH_HEAD instead of overwriting -upload-pack=path path to upload pack on remote end -f,force force overwrite of local branch -t,tags fetch all tags and associated objects -p,prune prune remote-tracking branches no longer on remote -recurse-submodules?on-demand control recursive fetching of submodules -dry-run dry run -k,keep keep downloaded pack -depth=depth deepen history of shallow clone -unshallow convert to a complete repository -update-shallow accept refs that update .git/shallow -refmap=refmap specify fetch refmap -" -test $# -gt 0 && args="$*" -. git-sh-setup -. git-sh-i18n -set_reflog_action "pull${args+ $args}" -require_work_tree_exists -cd_to_toplevel - - -die_conflict () { - git diff-index --cached --name-status -r --ignore-submodules HEAD -- - if [ $(git config --bool --get advice.resolveConflict || echo true) = "true" ]; then - die "$(gettext "Pull is not possible because you have unmerged files. -Please, fix them up in the work tree, and then use 'git add/rm ' -as appropriate to mark resolution and make a commit.")" - else - die "$(gettext "Pull is not possible because you have unmerged files.")" - fi -} - -die_merge () { - if [ $(git config --bool --get advice.resolveConflict || echo true) = "true" ]; then - die "$(gettext "You have not concluded your merge (MERGE_HEAD exists). -Please, commit your changes before merging.")" - else - die "$(gettext "You have not concluded your merge (MERGE_HEAD exists).")" - fi -} - -test -z "$(git ls-files -u)" || die_conflict -test -f "$GIT_DIR/MERGE_HEAD" && die_merge - -bool_or_string_config () { - git config --bool "$1" 2>/dev/null || git config "$1" -} - -strategy_args= diffstat= no_commit= squash= no_ff= ff_only= -log_arg= verbosity= progress= recurse_submodules= verify_signatures= -merge_args= edit= rebase_args= all= append= upload_pack= force= tags= prune= -keep= depth= unshallow= update_shallow= refmap= -curr_branch=$(git symbolic-ref -q HEAD) -curr_branch_short="${curr_branch#refs/heads/}" -rebase=$(bool_or_string_config branch.$curr_branch_short.rebase) -if test -z "$rebase" -then - rebase=$(bool_or_string_config pull.rebase) -fi - -# Setup default fast-forward options via `pull.ff` -pull_ff=$(bool_or_string_config pull.ff) -case "$pull_ff" in -true) - no_ff=--ff - ;; -false) - no_ff=--no-ff - ;; -only) - ff_only=--ff-only - ;; -esac - - -dry_run= -while : -do - case "$1" in - -q|--quiet) - verbosity="$verbosity -q" ;; - -v|--verbose) - verbosity="$verbosity -v" ;; - --progress) - progress=--progress ;; - --no-progress) - progress=--no-progress ;; - -n|--no-stat|--no-summary) - diffstat=--no-stat ;; - --stat|--summary) - diffstat=--stat ;; - --log|--log=*|--no-log) - log_arg="$1" ;; - --no-commit) - no_commit=--no-commit ;; - --commit) - no_commit=--commit ;; - -e|--edit) - edit=--edit ;; - --no-edit) - edit=--no-edit ;; - --squash) - squash=--squash ;; - --no-squash) - squash=--no-squash ;; - --ff) - no_ff=--ff ;; - --no-ff) - no_ff=--no-ff ;; - --ff-only) - ff_only=--ff-only ;; - -s*|--strategy=*) - strategy_args="$strategy_args $1" - ;; - -X*|--strategy-option=*) - merge_args="$merge_args $(git rev-parse --sq-quote "$1")" - ;; - -r*|--rebase=*) - rebase="${1#*=}" - ;; - --rebase) - rebase=true - ;; - --no-rebase) - rebase=false - ;; - --recurse-submodules) - recurse_submodules=--recurse-submodules - ;; - --recurse-submodules=*) - recurse_submodules="$1" - ;; - --no-recurse-submodules) - recurse_submodules=--no-recurse-submodules - ;; - --verify-signatures) - verify_signatures=--verify-signatures - ;; - --no-verify-signatures) - verify_signatures=--no-verify-signatures - ;; - --gpg-sign|-S) - gpg_sign_args=-S - ;; - --gpg-sign=*) - gpg_sign_args=$(git rev-parse --sq-quote "-S${1#--gpg-sign=}") - ;; - -S*) - gpg_sign_args=$(git rev-parse --sq-quote "$1") - ;; - --dry-run) - dry_run=--dry-run - ;; - --all|--no-all) - all=$1 ;; - -a|--append|--no-append) - append=$1 ;; - --upload-pack=*|--no-upload-pack) - upload_pack=$1 ;; - -f|--force|--no-force) - force="$force $1" ;; - -t|--tags|--no-tags) - tags=$1 ;; - -p|--prune|--no-prune) - prune=$1 ;; - -k|--keep|--no-keep) - keep=$1 ;; - --depth=*|--no-depth) - depth=$1 ;; - --unshallow|--no-unshallow) - unshallow=$1 ;; - --update-shallow|--no-update-shallow) - update_shallow=$1 ;; - --refmap=*|--no-refmap) - refmap=$1 ;; - -h|--help-all) - usage - ;; - --) - shift - break - ;; - *) - usage - ;; - esac - shift -done - -case "$rebase" in -preserve) - rebase=true - rebase_args=--preserve-merges - ;; -true|false|'') - ;; -*) - echo "Invalid value for --rebase, should be true, false, or preserve" - usage - exit 1 - ;; -esac - -error_on_no_merge_candidates () { - exec >&2 - - if test true = "$rebase" - then - op_type=rebase - op_prep=against - else - op_type=merge - op_prep=with - fi - - upstream=$(git config "branch.$curr_branch_short.merge") - remote=$(git config "branch.$curr_branch_short.remote") - - if [ $# -gt 1 ]; then - if [ "$rebase" = true ]; then - printf "There is no candidate for rebasing against " - else - printf "There are no candidates for merging " - fi - echo "among the refs that you just fetched." - echo "Generally this means that you provided a wildcard refspec which had no" - echo "matches on the remote end." - elif [ $# -gt 0 ] && [ "$1" != "$remote" ]; then - echo "You asked to pull from the remote '$1', but did not specify" - echo "a branch. Because this is not the default configured remote" - echo "for your current branch, you must specify a branch on the command line." - elif [ -z "$curr_branch" -o -z "$upstream" ]; then - . git-parse-remote - error_on_missing_default_upstream "pull" $op_type $op_prep \ - "git pull " - else - echo "Your configuration specifies to $op_type $op_prep the ref '${upstream#refs/heads/}'" - echo "from the remote, but no such ref was fetched." - fi - exit 1 -} - -test true = "$rebase" && { - if ! git rev-parse -q --verify HEAD >/dev/null - then - # On an unborn branch - if test -f "$(git rev-parse --git-path index)" - then - die "$(gettext "updating an unborn branch with changes added to the index")" - fi - else - require_clean_work_tree "pull with rebase" "Please commit or stash them." - fi - oldremoteref= && - test -n "$curr_branch" && - . git-parse-remote && - remoteref="$(get_remote_merge_branch "$@" 2>/dev/null)" && - oldremoteref=$(git merge-base --fork-point "$remoteref" $curr_branch 2>/dev/null) -} -orig_head=$(git rev-parse -q --verify HEAD) -git fetch $verbosity $progress $dry_run $recurse_submodules $all $append \ -${upload_pack:+"$upload_pack"} $force $tags $prune $keep $depth $unshallow $update_shallow \ -$refmap --update-head-ok "$@" || exit 1 -test -z "$dry_run" || exit 0 - -curr_head=$(git rev-parse -q --verify HEAD) -if test -n "$orig_head" && test "$curr_head" != "$orig_head" -then - # The fetch involved updating the current branch. - - # The working tree and the index file is still based on the - # $orig_head commit, but we are merging into $curr_head. - # First update the working tree to match $curr_head. - - eval_gettextln "Warning: fetch updated the current branch head. -Warning: fast-forwarding your working tree from -Warning: commit \$orig_head." >&2 - git update-index -q --refresh - git read-tree -u -m "$orig_head" "$curr_head" || - die "$(eval_gettext "Cannot fast-forward your working tree. -After making sure that you saved anything precious from -$ git diff \$orig_head -output, run -$ git reset --hard -to recover.")" - -fi - -merge_head=$(sed -e '/ not-for-merge /d' \ - -e 's/ .*//' "$GIT_DIR"/FETCH_HEAD | \ - tr '\012' ' ') - -case "$merge_head" in -'') - error_on_no_merge_candidates "$@" - ;; -?*' '?*) - if test -z "$orig_head" - then - die "$(gettext "Cannot merge multiple branches into empty head")" - fi - if test true = "$rebase" - then - die "$(gettext "Cannot rebase onto multiple branches")" - fi - ;; -esac - -# Pulling into unborn branch: a shorthand for branching off -# FETCH_HEAD, for lazy typers. -if test -z "$orig_head" -then - # Two-way merge: we claim the index is based on an empty tree, - # and try to fast-forward to HEAD. This ensures we will not - # lose index/worktree changes that the user already made on - # the unborn branch. - empty_tree=4b825dc642cb6eb9a060e54bf8d69288fbee4904 - git read-tree -m -u $empty_tree $merge_head && - git update-ref -m "initial pull" HEAD $merge_head "$curr_head" - exit -fi - -if test true = "$rebase" -then - o=$(git show-branch --merge-base $curr_branch $merge_head $oldremoteref) - if test "$oldremoteref" = "$o" - then - unset oldremoteref - fi -fi - -case "$rebase" in -true) - eval="git-rebase $diffstat $strategy_args $merge_args $rebase_args $verbosity" - eval="$eval $gpg_sign_args" - eval="$eval --onto $merge_head ${oldremoteref:-$merge_head}" - ;; -*) - eval="git-merge $diffstat $no_commit $verify_signatures $edit $squash $no_ff $ff_only" - eval="$eval $log_arg $strategy_args $merge_args $verbosity $progress" - eval="$eval $gpg_sign_args" - eval="$eval FETCH_HEAD" - ;; -esac -eval "exec $eval" diff --git a/contrib/examples/git-remote.perl b/contrib/examples/git-remote.perl deleted file mode 100755 index d42df7b418..0000000000 --- a/contrib/examples/git-remote.perl +++ /dev/null @@ -1,474 +0,0 @@ -#!/usr/bin/perl -w - -use strict; -use Git; -my $git = Git->repository(); - -sub add_remote_config { - my ($hash, $name, $what, $value) = @_; - if ($what eq 'url') { - # Having more than one is Ok -- it is used for push. - if (! exists $hash->{'URL'}) { - $hash->{$name}{'URL'} = $value; - } - } - elsif ($what eq 'fetch') { - $hash->{$name}{'FETCH'} ||= []; - push @{$hash->{$name}{'FETCH'}}, $value; - } - elsif ($what eq 'push') { - $hash->{$name}{'PUSH'} ||= []; - push @{$hash->{$name}{'PUSH'}}, $value; - } - if (!exists $hash->{$name}{'SOURCE'}) { - $hash->{$name}{'SOURCE'} = 'config'; - } -} - -sub add_remote_remotes { - my ($hash, $file, $name) = @_; - - if (exists $hash->{$name}) { - $hash->{$name}{'WARNING'} = 'ignored due to config'; - return; - } - - my $fh; - if (!open($fh, '<', $file)) { - print STDERR "Warning: cannot open $file\n"; - return; - } - my $it = { 'SOURCE' => 'remotes' }; - $hash->{$name} = $it; - while (<$fh>) { - chomp; - if (/^URL:\s*(.*)$/) { - # Having more than one is Ok -- it is used for push. - if (! exists $it->{'URL'}) { - $it->{'URL'} = $1; - } - } - elsif (/^Push:\s*(.*)$/) { - $it->{'PUSH'} ||= []; - push @{$it->{'PUSH'}}, $1; - } - elsif (/^Pull:\s*(.*)$/) { - $it->{'FETCH'} ||= []; - push @{$it->{'FETCH'}}, $1; - } - elsif (/^\#/) { - ; # ignore - } - else { - print STDERR "Warning: funny line in $file: $_\n"; - } - } - close($fh); -} - -sub list_remote { - my ($git) = @_; - my %seen = (); - my @remotes = eval { - $git->command(qw(config --get-regexp), '^remote\.'); - }; - for (@remotes) { - if (/^remote\.(\S+?)\.([^.\s]+)\s+(.*)$/) { - add_remote_config(\%seen, $1, $2, $3); - } - } - - my $dir = $git->repo_path() . "/remotes"; - if (opendir(my $dh, $dir)) { - local $_; - while ($_ = readdir($dh)) { - chomp; - next if (! -f "$dir/$_" || ! -r _); - add_remote_remotes(\%seen, "$dir/$_", $_); - } - } - - return \%seen; -} - -sub add_branch_config { - my ($hash, $name, $what, $value) = @_; - if ($what eq 'remote') { - if (exists $hash->{$name}{'REMOTE'}) { - print STDERR "Warning: more than one branch.$name.remote\n"; - } - $hash->{$name}{'REMOTE'} = $value; - } - elsif ($what eq 'merge') { - $hash->{$name}{'MERGE'} ||= []; - push @{$hash->{$name}{'MERGE'}}, $value; - } -} - -sub list_branch { - my ($git) = @_; - my %seen = (); - my @branches = eval { - $git->command(qw(config --get-regexp), '^branch\.'); - }; - for (@branches) { - if (/^branch\.([^.]*)\.(\S*)\s+(.*)$/) { - add_branch_config(\%seen, $1, $2, $3); - } - } - - return \%seen; -} - -my $remote = list_remote($git); -my $branch = list_branch($git); - -sub update_ls_remote { - my ($harder, $info) = @_; - - return if (($harder == 0) || - (($harder == 1) && exists $info->{'LS_REMOTE'})); - - my @ref = map { s|refs/heads/||; $_; } keys %{$git->remote_refs($info->{'URL'}, [ 'heads' ])}; - $info->{'LS_REMOTE'} = \@ref; -} - -sub list_wildcard_mapping { - my ($forced, $ours, $ls) = @_; - my %refs; - for (@$ls) { - $refs{$_} = 01; # bit #0 to say "they have" - } - for ($git->command('for-each-ref', "refs/remotes/$ours")) { - chomp; - next unless (s|^[0-9a-f]{40}\s[a-z]+\srefs/remotes/$ours/||); - next if ($_ eq 'HEAD'); - $refs{$_} ||= 0; - $refs{$_} |= 02; # bit #1 to say "we have" - } - my (@new, @stale, @tracked); - for (sort keys %refs) { - my $have = $refs{$_}; - if ($have == 1) { - push @new, $_; - } - elsif ($have == 2) { - push @stale, $_; - } - elsif ($have == 3) { - push @tracked, $_; - } - } - return \@new, \@stale, \@tracked; -} - -sub list_mapping { - my ($name, $info) = @_; - my $fetch = $info->{'FETCH'}; - my $ls = $info->{'LS_REMOTE'}; - my (@new, @stale, @tracked); - - for (@$fetch) { - next unless (/(\+)?([^:]+):(.*)/); - my ($forced, $theirs, $ours) = ($1, $2, $3); - if ($theirs eq 'refs/heads/*' && - $ours =~ /^refs\/remotes\/(.*)\/\*$/) { - # wildcard mapping - my ($w_new, $w_stale, $w_tracked) - = list_wildcard_mapping($forced, $1, $ls); - push @new, @$w_new; - push @stale, @$w_stale; - push @tracked, @$w_tracked; - } - elsif ($theirs =~ /\*/ || $ours =~ /\*/) { - print STDERR "Warning: unrecognized mapping in remotes.$name.fetch: $_\n"; - } - elsif ($theirs =~ s|^refs/heads/||) { - if (!grep { $_ eq $theirs } @$ls) { - push @stale, $theirs; - } - elsif ($ours ne '') { - push @tracked, $theirs; - } - } - } - return \@new, \@stale, \@tracked; -} - -sub show_mapping { - my ($name, $info) = @_; - my ($new, $stale, $tracked) = list_mapping($name, $info); - if (@$new) { - print " New remote branches (next fetch will store in remotes/$name)\n"; - print " @$new\n"; - } - if (@$stale) { - print " Stale tracking branches in remotes/$name (use 'git remote prune')\n"; - print " @$stale\n"; - } - if (@$tracked) { - print " Tracked remote branches\n"; - print " @$tracked\n"; - } -} - -sub prune_remote { - my ($name, $ls_remote) = @_; - if (!exists $remote->{$name}) { - print STDERR "No such remote $name\n"; - return 1; - } - my $info = $remote->{$name}; - update_ls_remote($ls_remote, $info); - - my ($new, $stale, $tracked) = list_mapping($name, $info); - my $prefix = "refs/remotes/$name"; - foreach my $to_prune (@$stale) { - my @v = $git->command(qw(rev-parse --verify), "$prefix/$to_prune"); - $git->command(qw(update-ref -d), "$prefix/$to_prune", $v[0]); - } - return 0; -} - -sub show_remote { - my ($name, $ls_remote) = @_; - if (!exists $remote->{$name}) { - print STDERR "No such remote $name\n"; - return 1; - } - my $info = $remote->{$name}; - update_ls_remote($ls_remote, $info); - - print "* remote $name\n"; - print " URL: $info->{'URL'}\n"; - for my $branchname (sort keys %$branch) { - next unless (defined $branch->{$branchname}{'REMOTE'} && - $branch->{$branchname}{'REMOTE'} eq $name); - my @merged = map { - s|^refs/heads/||; - $_; - } split(' ',"@{$branch->{$branchname}{'MERGE'}}"); - next unless (@merged); - print " Remote branch(es) merged with 'git pull' while on branch $branchname\n"; - print " @merged\n"; - } - if ($info->{'LS_REMOTE'}) { - show_mapping($name, $info); - } - if ($info->{'PUSH'}) { - my @pushed = map { - s|^refs/heads/||; - s|^\+refs/heads/|+|; - s|:refs/heads/|:|; - $_; - } @{$info->{'PUSH'}}; - print " Local branch(es) pushed with 'git push'\n"; - print " @pushed\n"; - } - return 0; -} - -sub add_remote { - my ($name, $url, $opts) = @_; - if (exists $remote->{$name}) { - print STDERR "remote $name already exists.\n"; - exit(1); - } - $git->command('config', "remote.$name.url", $url); - my $track = $opts->{'track'} || ["*"]; - - for (@$track) { - $git->command('config', '--add', "remote.$name.fetch", - $opts->{'mirror'} ? - "+refs/$_:refs/$_" : - "+refs/heads/$_:refs/remotes/$name/$_"); - } - if ($opts->{'fetch'}) { - $git->command('fetch', $name); - } - if (exists $opts->{'master'}) { - $git->command('symbolic-ref', "refs/remotes/$name/HEAD", - "refs/remotes/$name/$opts->{'master'}"); - } -} - -sub update_remote { - my ($name) = @_; - my @remotes; - - my $conf = $git->config("remotes." . $name); - if (defined($conf)) { - @remotes = split(' ', $conf); - } elsif ($name eq 'default') { - @remotes = (); - for (sort keys %$remote) { - my $do_fetch = $git->config_bool("remote." . $_ . - ".skipDefaultUpdate"); - unless ($do_fetch) { - push @remotes, $_; - } - } - } else { - print STDERR "Remote group $name does not exist.\n"; - exit(1); - } - for (@remotes) { - print "Updating $_\n"; - $git->command('fetch', "$_"); - } -} - -sub rm_remote { - my ($name) = @_; - if (!exists $remote->{$name}) { - print STDERR "No such remote $name\n"; - return 1; - } - - $git->command('config', '--remove-section', "remote.$name"); - - eval { - my @trackers = $git->command('config', '--get-regexp', - 'branch.*.remote', $name); - for (@trackers) { - /^branch\.(.*)?\.remote/; - $git->config('--unset', "branch.$1.remote"); - $git->config('--unset', "branch.$1.merge"); - } - }; - - my @refs = $git->command('for-each-ref', - '--format=%(refname) %(objectname)', "refs/remotes/$name"); - for (@refs) { - my ($ref, $object) = split; - $git->command(qw(update-ref -d), $ref, $object); - } - return 0; -} - -sub add_usage { - print STDERR "usage: git remote add [-f] [-t track]* [-m master] \n"; - exit(1); -} - -my $VERBOSE = 0; -@ARGV = grep { - if ($_ eq '-v' or $_ eq '--verbose') { - $VERBOSE=1; - 0 - } else { - 1 - } -} @ARGV; - -if (!@ARGV) { - for (sort keys %$remote) { - print "$_"; - print "\t$remote->{$_}->{URL}" if $VERBOSE; - print "\n"; - } -} -elsif ($ARGV[0] eq 'show') { - my $ls_remote = 1; - my $i; - for ($i = 1; $i < @ARGV; $i++) { - if ($ARGV[$i] eq '-n') { - $ls_remote = 0; - } - else { - last; - } - } - if ($i >= @ARGV) { - print STDERR "usage: git remote show \n"; - exit(1); - } - my $status = 0; - for (; $i < @ARGV; $i++) { - $status |= show_remote($ARGV[$i], $ls_remote); - } - exit($status); -} -elsif ($ARGV[0] eq 'update') { - if (@ARGV <= 1) { - update_remote("default"); - exit(1); - } - for (my $i = 1; $i < @ARGV; $i++) { - update_remote($ARGV[$i]); - } -} -elsif ($ARGV[0] eq 'prune') { - my $ls_remote = 1; - my $i; - for ($i = 1; $i < @ARGV; $i++) { - if ($ARGV[$i] eq '-n') { - $ls_remote = 0; - } - else { - last; - } - } - if ($i >= @ARGV) { - print STDERR "usage: git remote prune \n"; - exit(1); - } - my $status = 0; - for (; $i < @ARGV; $i++) { - $status |= prune_remote($ARGV[$i], $ls_remote); - } - exit($status); -} -elsif ($ARGV[0] eq 'add') { - my %opts = (); - while (1 < @ARGV && $ARGV[1] =~ /^-/) { - my $opt = $ARGV[1]; - shift @ARGV; - if ($opt eq '-f' || $opt eq '--fetch') { - $opts{'fetch'} = 1; - next; - } - if ($opt eq '-t' || $opt eq '--track') { - if (@ARGV < 1) { - add_usage(); - } - $opts{'track'} ||= []; - push @{$opts{'track'}}, $ARGV[1]; - shift @ARGV; - next; - } - if ($opt eq '-m' || $opt eq '--master') { - if ((@ARGV < 1) || exists $opts{'master'}) { - add_usage(); - } - $opts{'master'} = $ARGV[1]; - shift @ARGV; - next; - } - if ($opt eq '--mirror') { - $opts{'mirror'} = 1; - next; - } - add_usage(); - } - if (@ARGV != 3) { - add_usage(); - } - add_remote($ARGV[1], $ARGV[2], \%opts); -} -elsif ($ARGV[0] eq 'rm') { - if (@ARGV <= 1) { - print STDERR "usage: git remote rm \n"; - exit(1); - } - exit(rm_remote($ARGV[1])); -} -else { - print STDERR "usage: git remote\n"; - print STDERR " git remote add \n"; - print STDERR " git remote rm \n"; - print STDERR " git remote show \n"; - print STDERR " git remote prune \n"; - print STDERR " git remote update [group]\n"; - exit(1); -} diff --git a/contrib/examples/git-repack.sh b/contrib/examples/git-repack.sh deleted file mode 100755 index 672af93443..0000000000 --- a/contrib/examples/git-repack.sh +++ /dev/null @@ -1,194 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 2005 Linus Torvalds -# - -OPTIONS_KEEPDASHDASH= -OPTIONS_SPEC="\ -git repack [options] --- -a pack everything in a single pack -A same as -a, and turn unreachable objects loose -d remove redundant packs, and run git-prune-packed -f pass --no-reuse-delta to git-pack-objects -F pass --no-reuse-object to git-pack-objects -n do not run git-update-server-info -q,quiet be quiet -l pass --local to git-pack-objects -unpack-unreachable= with -A, do not loosen objects older than this - Packing constraints -window= size of the window used for delta compression -window-memory= same as the above, but limit memory size instead of entries count -depth= limits the maximum delta depth -max-pack-size= maximum size of each packfile -" -SUBDIRECTORY_OK='Yes' -. git-sh-setup - -no_update_info= all_into_one= remove_redundant= unpack_unreachable= -local= no_reuse= extra= -while test $# != 0 -do - case "$1" in - -n) no_update_info=t ;; - -a) all_into_one=t ;; - -A) all_into_one=t - unpack_unreachable=--unpack-unreachable ;; - --unpack-unreachable) - unpack_unreachable="--unpack-unreachable=$2"; shift ;; - -d) remove_redundant=t ;; - -q) GIT_QUIET=t ;; - -f) no_reuse=--no-reuse-delta ;; - -F) no_reuse=--no-reuse-object ;; - -l) local=--local ;; - --max-pack-size|--window|--window-memory|--depth) - extra="$extra $1=$2"; shift ;; - --) shift; break;; - *) usage ;; - esac - shift -done - -case "$(git config --bool repack.usedeltabaseoffset || echo true)" in -true) - extra="$extra --delta-base-offset" ;; -esac - -PACKDIR="$GIT_OBJECT_DIRECTORY/pack" -PACKTMP="$PACKDIR/.tmp-$$-pack" -rm -f "$PACKTMP"-* -trap 'rm -f "$PACKTMP"-*' 0 1 2 3 15 - -# There will be more repacking strategies to come... -case ",$all_into_one," in -,,) - args='--unpacked --incremental' - ;; -,t,) - args= existing= - if [ -d "$PACKDIR" ]; then - for e in $(cd "$PACKDIR" && find . -type f -name '*.pack' \ - | sed -e 's/^\.\///' -e 's/\.pack$//') - do - if [ -e "$PACKDIR/$e.keep" ]; then - : keep - else - existing="$existing $e" - fi - done - if test -n "$existing" && test -n "$unpack_unreachable" && \ - test -n "$remove_redundant" - then - # This may have arbitrary user arguments, so we - # have to protect it against whitespace splitting - # when it gets run as "pack-objects $args" later. - # Fortunately, we know it's an approxidate, so we - # can just use dots instead. - args="$args $(echo "$unpack_unreachable" | tr ' ' .)" - fi - fi - ;; -esac - -mkdir -p "$PACKDIR" || exit - -args="$args $local ${GIT_QUIET:+-q} $no_reuse$extra" -names=$(git pack-objects --keep-true-parents --honor-pack-keep --non-empty --all --reflog $args &2 "WARNING: Some packs in use have been renamed by" - echo >&2 "WARNING: prefixing old- to their name, in order to" - echo >&2 "WARNING: replace them with the new version of the" - echo >&2 "WARNING: file. But the operation failed, and" - echo >&2 "WARNING: attempt to rename them back to their" - echo >&2 "WARNING: original names also failed." - echo >&2 "WARNING: Please rename them in $PACKDIR manually:" - for file in $rollback_failure - do - echo >&2 "WARNING: old-$file -> $file" - done - fi - exit 1 -fi - -# Now the ones with the same name are out of the way... -fullbases= -for name in $names -do - fullbases="$fullbases pack-$name" - chmod a-w "$PACKTMP-$name.pack" - chmod a-w "$PACKTMP-$name.idx" - mv -f "$PACKTMP-$name.pack" "$PACKDIR/pack-$name.pack" && - mv -f "$PACKTMP-$name.idx" "$PACKDIR/pack-$name.idx" || - exit -done - -# Remove the "old-" files -for name in $names -do - rm -f "$PACKDIR/old-pack-$name.idx" - rm -f "$PACKDIR/old-pack-$name.pack" -done - -# End of pack replacement. - -if test "$remove_redundant" = t -then - # We know $existing are all redundant. - if [ -n "$existing" ] - then - ( cd "$PACKDIR" && - for e in $existing - do - case " $fullbases " in - *" $e "*) ;; - *) rm -f "$e.pack" "$e.idx" "$e.keep" ;; - esac - done - ) - fi - git prune-packed ${GIT_QUIET:+-q} -fi - -case "$no_update_info" in -t) : ;; -*) git update-server-info ;; -esac diff --git a/contrib/examples/git-rerere.perl b/contrib/examples/git-rerere.perl deleted file mode 100755 index 4f692091e7..0000000000 --- a/contrib/examples/git-rerere.perl +++ /dev/null @@ -1,284 +0,0 @@ -#!/usr/bin/perl -# -# REuse REcorded REsolve. This tool records a conflicted automerge -# result and its hand resolution, and helps to resolve future -# automerge that results in the same conflict. -# -# To enable this feature, create a directory 'rr-cache' under your -# .git/ directory. - -use Digest; -use File::Path; -use File::Copy; - -my $git_dir = $::ENV{GIT_DIR} || ".git"; -my $rr_dir = "$git_dir/rr-cache"; -my $merge_rr = "$git_dir/rr-cache/MERGE_RR"; - -my %merge_rr = (); - -sub read_rr { - if (!-f $merge_rr) { - %merge_rr = (); - return; - } - my $in; - local $/ = "\0"; - open $in, "<$merge_rr" or die "$!: $merge_rr"; - while (<$in>) { - chomp; - my ($name, $path) = /^([0-9a-f]{40})\t(.*)$/s; - $merge_rr{$path} = $name; - } - close $in; -} - -sub write_rr { - my $out; - open $out, ">$merge_rr" or die "$!: $merge_rr"; - for my $path (sort keys %merge_rr) { - my $name = $merge_rr{$path}; - print $out "$name\t$path\0"; - } - close $out; -} - -sub compute_conflict_name { - my ($path) = @_; - my @side = (); - my $in; - open $in, "<$path" or die "$!: $path"; - - my $sha1 = Digest->new("SHA-1"); - my $hunk = 0; - while (<$in>) { - if (/^<<<<<<< .*/) { - $hunk++; - @side = ([], undef); - } - elsif (/^=======$/) { - $side[1] = []; - } - elsif (/^>>>>>>> .*/) { - my ($one, $two); - $one = join('', @{$side[0]}); - $two = join('', @{$side[1]}); - if ($two le $one) { - ($one, $two) = ($two, $one); - } - $sha1->add($one); - $sha1->add("\0"); - $sha1->add($two); - $sha1->add("\0"); - @side = (); - } - elsif (@side == 0) { - next; - } - elsif (defined $side[1]) { - push @{$side[1]}, $_; - } - else { - push @{$side[0]}, $_; - } - } - close $in; - return ($sha1->hexdigest, $hunk); -} - -sub record_preimage { - my ($path, $name) = @_; - my @side = (); - my ($in, $out); - open $in, "<$path" or die "$!: $path"; - open $out, ">$name" or die "$!: $name"; - - while (<$in>) { - if (/^<<<<<<< .*/) { - @side = ([], undef); - } - elsif (/^=======$/) { - $side[1] = []; - } - elsif (/^>>>>>>> .*/) { - my ($one, $two); - $one = join('', @{$side[0]}); - $two = join('', @{$side[1]}); - if ($two le $one) { - ($one, $two) = ($two, $one); - } - print $out "<<<<<<<\n"; - print $out $one; - print $out "=======\n"; - print $out $two; - print $out ">>>>>>>\n"; - @side = (); - } - elsif (@side == 0) { - print $out $_; - } - elsif (defined $side[1]) { - push @{$side[1]}, $_; - } - else { - push @{$side[0]}, $_; - } - } - close $out; - close $in; -} - -sub find_conflict { - my $in; - local $/ = "\0"; - my $pid = open($in, '-|'); - die "$!" unless defined $pid; - if (!$pid) { - exec(qw(git ls-files -z -u)) or die "$!: ls-files"; - } - my %path = (); - my @path = (); - while (<$in>) { - chomp; - my ($mode, $sha1, $stage, $path) = - /^([0-7]+) ([0-9a-f]{40}) ([123])\t(.*)$/s; - $path{$path} |= (1 << $stage); - } - close $in; - while (my ($path, $status) = each %path) { - if ($status == 14) { push @path, $path; } - } - return @path; -} - -sub merge { - my ($name, $path) = @_; - record_preimage($path, "$rr_dir/$name/thisimage"); - unless (system('git', 'merge-file', map { "$rr_dir/$name/${_}image" } - qw(this pre post))) { - my $in; - open $in, "<$rr_dir/$name/thisimage" or - die "$!: $name/thisimage"; - my $out; - open $out, ">$path" or die "$!: $path"; - while (<$in>) { print $out $_; } - close $in; - close $out; - return 1; - } - return 0; -} - -sub garbage_collect_rerere { - # We should allow specifying these from the command line and - # that is why the caller gives @ARGV to us, but I am lazy. - - my $cutoff_noresolve = 15; # two weeks - my $cutoff_resolve = 60; # two months - my @to_remove; - while (<$rr_dir/*/preimage>) { - my ($dir) = /^(.*)\/preimage$/; - my $cutoff = ((-f "$dir/postimage") - ? $cutoff_resolve - : $cutoff_noresolve); - my $age = -M "$_"; - if ($cutoff <= $age) { - push @to_remove, $dir; - } - } - if (@to_remove) { - rmtree(\@to_remove); - } -} - --d "$rr_dir" || exit(0); - -read_rr(); - -if (@ARGV) { - my $arg = shift @ARGV; - if ($arg eq 'clear') { - for my $path (keys %merge_rr) { - my $name = $merge_rr{$path}; - if (-d "$rr_dir/$name" && - ! -f "$rr_dir/$name/postimage") { - rmtree(["$rr_dir/$name"]); - } - } - unlink $merge_rr; - } - elsif ($arg eq 'status') { - for my $path (keys %merge_rr) { - print $path, "\n"; - } - } - elsif ($arg eq 'diff') { - for my $path (keys %merge_rr) { - my $name = $merge_rr{$path}; - system('diff', ((@ARGV == 0) ? ('-u') : @ARGV), - '-L', "a/$path", '-L', "b/$path", - "$rr_dir/$name/preimage", $path); - } - } - elsif ($arg eq 'gc') { - garbage_collect_rerere(@ARGV); - } - else { - die "$0 unknown command: $arg\n"; - } - exit 0; -} - -my %conflict = map { $_ => 1 } find_conflict(); - -# MERGE_RR records paths with conflicts immediately after merge -# failed. Some of the conflicted paths might have been hand resolved -# in the working tree since then, but the initial run would catch all -# and register their preimages. - -for my $path (keys %conflict) { - # This path has conflict. If it is not recorded yet, - # record the pre-image. - if (!exists $merge_rr{$path}) { - my ($name, $hunk) = compute_conflict_name($path); - next unless ($hunk); - $merge_rr{$path} = $name; - if (! -d "$rr_dir/$name") { - mkpath("$rr_dir/$name", 0, 0777); - print STDERR "Recorded preimage for '$path'\n"; - record_preimage($path, "$rr_dir/$name/preimage"); - } - } -} - -# Now some of the paths that had conflicts earlier might have been -# hand resolved. Others may be similar to a conflict already that -# was resolved before. - -for my $path (keys %merge_rr) { - my $name = $merge_rr{$path}; - - # We could resolve this automatically if we have images. - if (-f "$rr_dir/$name/preimage" && - -f "$rr_dir/$name/postimage") { - if (merge($name, $path)) { - print STDERR "Resolved '$path' using previous resolution.\n"; - # Then we do not have to worry about this path - # anymore. - delete $merge_rr{$path}; - next; - } - } - - # Let's see if we have resolved it. - (undef, my $hunk) = compute_conflict_name($path); - next if ($hunk); - - print STDERR "Recorded resolution for '$path'.\n"; - copy($path, "$rr_dir/$name/postimage"); - # And we do not have to worry about this path anymore. - delete $merge_rr{$path}; -} - -# Write out the rest. -write_rr(); diff --git a/contrib/examples/git-reset.sh b/contrib/examples/git-reset.sh deleted file mode 100755 index cb1bbf3b90..0000000000 --- a/contrib/examples/git-reset.sh +++ /dev/null @@ -1,106 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 2005, 2006 Linus Torvalds and Junio C Hamano -# -USAGE='[--mixed | --soft | --hard] [] [ [--] ...]' -SUBDIRECTORY_OK=Yes -. git-sh-setup -set_reflog_action "reset $*" -require_work_tree - -update= reset_type=--mixed -unset rev - -while test $# != 0 -do - case "$1" in - --mixed | --soft | --hard) - reset_type="$1" - ;; - --) - break - ;; - -*) - usage - ;; - *) - rev=$(git rev-parse --verify "$1") || exit - shift - break - ;; - esac - shift -done - -: ${rev=HEAD} -rev=$(git rev-parse --verify $rev^0) || exit - -# Skip -- in "git reset HEAD -- foo" and "git reset -- foo". -case "$1" in --) shift ;; esac - -# git reset --mixed tree [--] paths... can be used to -# load chosen paths from the tree into the index without -# affecting the working tree or HEAD. -if test $# != 0 -then - test "$reset_type" = "--mixed" || - die "Cannot do partial $reset_type reset." - - git diff-index --cached $rev -- "$@" | - sed -e 's/^:\([0-7][0-7]*\) [0-7][0-7]* \([0-9a-f][0-9a-f]*\) [0-9a-f][0-9a-f]* [A-Z] \(.*\)$/\1 \2 \3/' | - git update-index --add --remove --index-info || exit - git update-index --refresh - exit -fi - -cd_to_toplevel - -if test "$reset_type" = "--hard" -then - update=-u -fi - -# Soft reset does not touch the index file or the working tree -# at all, but requires them in a good order. Other resets reset -# the index file to the tree object we are switching to. -if test "$reset_type" = "--soft" -then - if test -f "$GIT_DIR/MERGE_HEAD" || - test "" != "$(git ls-files --unmerged)" - then - die "Cannot do a soft reset in the middle of a merge." - fi -else - git read-tree -v --reset $update "$rev" || exit -fi - -# Any resets update HEAD to the head being switched to. -if orig=$(git rev-parse --verify HEAD 2>/dev/null) -then - echo "$orig" >"$GIT_DIR/ORIG_HEAD" -else - rm -f "$GIT_DIR/ORIG_HEAD" -fi -git update-ref -m "$GIT_REFLOG_ACTION" HEAD "$rev" -update_ref_status=$? - -case "$reset_type" in ---hard ) - test $update_ref_status = 0 && { - printf "HEAD is now at " - GIT_PAGER= git log --max-count=1 --pretty=oneline \ - --abbrev-commit HEAD - } - ;; ---soft ) - ;; # Nothing else to do ---mixed ) - # Report what has not been updated. - git update-index --refresh - ;; -esac - -rm -f "$GIT_DIR/MERGE_HEAD" "$GIT_DIR/rr-cache/MERGE_RR" \ - "$GIT_DIR/SQUASH_MSG" "$GIT_DIR/MERGE_MSG" - -exit $update_ref_status diff --git a/contrib/examples/git-resolve.sh b/contrib/examples/git-resolve.sh deleted file mode 100755 index 3099dc851a..0000000000 --- a/contrib/examples/git-resolve.sh +++ /dev/null @@ -1,112 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 2005 Linus Torvalds -# -# Resolve two trees. -# - -echo 'WARNING: This command is DEPRECATED and will be removed very soon.' >&2 -echo 'WARNING: Please use git-merge or git-pull instead.' >&2 -sleep 2 - -USAGE=' ' -. git-sh-setup - -dropheads() { - rm -f -- "$GIT_DIR/MERGE_HEAD" \ - "$GIT_DIR/LAST_MERGE" || exit 1 -} - -head=$(git rev-parse --verify "$1"^0) && -merge=$(git rev-parse --verify "$2"^0) && -merge_name="$2" && -merge_msg="$3" || usage - -# -# The remote name is just used for the message, -# but we do want it. -# -if [ -z "$head" -o -z "$merge" -o -z "$merge_msg" ]; then - usage -fi - -dropheads -echo $head > "$GIT_DIR"/ORIG_HEAD -echo $merge > "$GIT_DIR"/LAST_MERGE - -common=$(git merge-base $head $merge) -if [ -z "$common" ]; then - die "Unable to find common commit between" $merge $head -fi - -case "$common" in -"$merge") - echo "Already up to date. Yeeah!" - dropheads - exit 0 - ;; -"$head") - echo "Updating $(git rev-parse --short $head)..$(git rev-parse --short $merge)" - git read-tree -u -m $head $merge || exit 1 - git update-ref -m "resolve $merge_name: Fast-forward" \ - HEAD "$merge" "$head" - git diff-tree -p $head $merge | git apply --stat - dropheads - exit 0 - ;; -esac - -# We are going to make a new commit. -git var GIT_COMMITTER_IDENT >/dev/null || exit - -# Find an optimum merge base if there are more than one candidates. -LF=' -' -common=$(git merge-base -a $head $merge) -case "$common" in -?*"$LF"?*) - echo "Trying to find the optimum merge base." - G=.tmp-index$$ - best= - best_cnt=-1 - for c in $common - do - rm -f $G - GIT_INDEX_FILE=$G git read-tree -m $c $head $merge \ - 2>/dev/null || continue - # Count the paths that are unmerged. - cnt=$(GIT_INDEX_FILE=$G git ls-files --unmerged | wc -l) - if test $best_cnt -le 0 || test $cnt -le $best_cnt - then - best=$c - best_cnt=$cnt - if test "$best_cnt" -eq 0 - then - # Cannot do any better than all trivial merge. - break - fi - fi - done - rm -f $G - common="$best" -esac - -echo "Trying to merge $merge into $head using $common." -git update-index --refresh 2>/dev/null -git read-tree -u -m $common $head $merge || exit 1 -result_tree=$(git write-tree 2> /dev/null) -if [ $? -ne 0 ]; then - echo "Simple merge failed, trying Automatic merge" - git-merge-index -o git-merge-one-file -a - if [ $? -ne 0 ]; then - echo $merge > "$GIT_DIR"/MERGE_HEAD - die "Automatic merge failed, fix up by hand" - fi - result_tree=$(git write-tree) || exit 1 -fi -result_commit=$(echo "$merge_msg" | git commit-tree $result_tree -p $head -p $merge) -echo "Committed merge $result_commit" -git update-ref -m "resolve $merge_name: In-index merge" \ - HEAD "$result_commit" "$head" -git diff-tree -p $head $result_commit | git apply --stat -dropheads diff --git a/contrib/examples/git-revert.sh b/contrib/examples/git-revert.sh deleted file mode 100755 index 197838d10b..0000000000 --- a/contrib/examples/git-revert.sh +++ /dev/null @@ -1,207 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 2005 Linus Torvalds -# Copyright (c) 2005 Junio C Hamano -# - -case "$0" in -*-revert* ) - test -t 0 && edit=-e - replay= - me=revert - USAGE='[--edit | --no-edit] [-n] ' ;; -*-cherry-pick* ) - replay=t - edit= - me=cherry-pick - USAGE='[--edit] [-n] [-r] [-x] ' ;; -* ) - echo >&2 "What are you talking about?" - exit 1 ;; -esac - -SUBDIRECTORY_OK=Yes ;# we will cd up -. git-sh-setup -require_work_tree -cd_to_toplevel - -no_commit= -xopt= -while case "$#" in 0) break ;; esac -do - case "$1" in - -n|--n|--no|--no-|--no-c|--no-co|--no-com|--no-comm|\ - --no-commi|--no-commit) - no_commit=t - ;; - -e|--e|--ed|--edi|--edit) - edit=-e - ;; - --n|--no|--no-|--no-e|--no-ed|--no-edi|--no-edit) - edit= - ;; - -r) - : no-op ;; - -x|--i-really-want-to-expose-my-private-commit-object-name) - replay= - ;; - -X?*) - xopt="$xopt$(git rev-parse --sq-quote "--${1#-X}")" - ;; - --strategy-option=*) - xopt="$xopt$(git rev-parse --sq-quote "--${1#--strategy-option=}")" - ;; - -X|--strategy-option) - shift - xopt="$xopt$(git rev-parse --sq-quote "--$1")" - ;; - -*) - usage - ;; - *) - break - ;; - esac - shift -done - -set_reflog_action "$me" - -test "$me,$replay" = "revert,t" && usage - -case "$no_commit" in -t) - # We do not intend to commit immediately. We just want to - # merge the differences in. - head=$(git-write-tree) || - die "Your index file is unmerged." - ;; -*) - head=$(git-rev-parse --verify HEAD) || - die "You do not have a valid HEAD" - files=$(git-diff-index --cached --name-only $head) || exit - if [ "$files" ]; then - die "Dirty index: cannot $me (dirty: $files)" - fi - ;; -esac - -rev=$(git-rev-parse --verify "$@") && -commit=$(git-rev-parse --verify "$rev^0") || - die "Not a single commit $@" -prev=$(git-rev-parse --verify "$commit^1" 2>/dev/null) || - die "Cannot run $me a root commit" -git-rev-parse --verify "$commit^2" >/dev/null 2>&1 && - die "Cannot run $me a multi-parent commit." - -encoding=$(git config i18n.commitencoding || echo UTF-8) - -# "commit" is an existing commit. We would want to apply -# the difference it introduces since its first parent "prev" -# on top of the current HEAD if we are cherry-pick. Or the -# reverse of it if we are revert. - -case "$me" in -revert) - git show -s --pretty=oneline --encoding="$encoding" $commit | - sed -e ' - s/^[^ ]* /Revert "/ - s/$/"/ - ' - echo - echo "This reverts commit $commit." - test "$rev" = "$commit" || - echo "(original 'git revert' arguments: $@)" - base=$commit next=$prev - ;; - -cherry-pick) - pick_author_script=' - /^author /{ - s/'\''/'\''\\'\'\''/g - h - s/^author \([^<]*\) <[^>]*> .*$/\1/ - s/'\''/'\''\'\'\''/g - s/.*/GIT_AUTHOR_NAME='\''&'\''/p - - g - s/^author [^<]* <\([^>]*\)> .*$/\1/ - s/'\''/'\''\'\'\''/g - s/.*/GIT_AUTHOR_EMAIL='\''&'\''/p - - g - s/^author [^<]* <[^>]*> \(.*\)$/\1/ - s/'\''/'\''\'\'\''/g - s/.*/GIT_AUTHOR_DATE='\''&'\''/p - - q - }' - - logmsg=$(git show -s --pretty=raw --encoding="$encoding" "$commit") - set_author_env=$(echo "$logmsg" | - LANG=C LC_ALL=C sed -ne "$pick_author_script") - eval "$set_author_env" - export GIT_AUTHOR_NAME - export GIT_AUTHOR_EMAIL - export GIT_AUTHOR_DATE - - echo "$logmsg" | - sed -e '1,/^$/d' -e 's/^ //' - case "$replay" in - '') - echo "(cherry picked from commit $commit)" - test "$rev" = "$commit" || - echo "(original 'git cherry-pick' arguments: $@)" - ;; - esac - base=$prev next=$commit - ;; - -esac >.msg - -eval GITHEAD_$head=HEAD -eval GITHEAD_$next='$(git show -s \ - --pretty=oneline --encoding="$encoding" "$commit" | - sed -e "s/^[^ ]* //")' -export GITHEAD_$head GITHEAD_$next - -# This three way merge is an interesting one. We are at -# $head, and would want to apply the change between $commit -# and $prev on top of us (when reverting), or the change between -# $prev and $commit on top of us (when cherry-picking or replaying). - -eval "git merge-recursive $xopt $base -- $head $next" && -result=$(git-write-tree 2>/dev/null) || { - mv -f .msg "$GIT_DIR/MERGE_MSG" - { - echo ' -Conflicts: -' - git ls-files --unmerged | - sed -e 's/^[^ ]* / /' | - uniq - } >>"$GIT_DIR/MERGE_MSG" - echo >&2 "Automatic $me failed. After resolving the conflicts," - echo >&2 "mark the corrected paths with 'git-add '" - echo >&2 "and commit the result." - case "$me" in - cherry-pick) - echo >&2 "You may choose to use the following when making" - echo >&2 "the commit:" - echo >&2 "$set_author_env" - esac - exit 1 -} - -# If we are cherry-pick, and if the merge did not result in -# hand-editing, we will hit this commit and inherit the original -# author date and name. -# If we are revert, or if our cherry-pick results in a hand merge, -# we had better say that the current user is responsible for that. - -case "$no_commit" in -'') - git-commit -n -F .msg $edit - rm -f .msg - ;; -esac diff --git a/contrib/examples/git-svnimport.perl b/contrib/examples/git-svnimport.perl deleted file mode 100755 index 75a43e23b6..0000000000 --- a/contrib/examples/git-svnimport.perl +++ /dev/null @@ -1,976 +0,0 @@ -#!/usr/bin/perl - -# This tool is copyright (c) 2005, Matthias Urlichs. -# It is released under the Gnu Public License, version 2. -# -# The basic idea is to pull and analyze SVN changes. -# -# Checking out the files is done by a single long-running SVN connection. -# -# The head revision is on branch "origin" by default. -# You can change that with the '-o' option. - -use strict; -use warnings; -use Getopt::Std; -use File::Copy; -use File::Spec; -use File::Temp qw(tempfile); -use File::Path qw(mkpath); -use File::Basename qw(basename dirname); -use Time::Local; -use IO::Pipe; -use POSIX qw(strftime dup2); -use IPC::Open2; -use SVN::Core; -use SVN::Ra; - -die "Need SVN:Core 1.2.1 or better" if $SVN::Core::VERSION lt "1.2.1"; - -$SIG{'PIPE'}="IGNORE"; -$ENV{'TZ'}="UTC"; - -our($opt_h,$opt_o,$opt_v,$opt_u,$opt_C,$opt_i,$opt_m,$opt_M,$opt_t,$opt_T, - $opt_b,$opt_r,$opt_I,$opt_A,$opt_s,$opt_l,$opt_d,$opt_D,$opt_S,$opt_F, - $opt_P,$opt_R); - -sub usage() { - print STDERR <new_default; - -@ARGV == 1 or @ARGV == 2 or usage(); - -$opt_o ||= "origin"; -$opt_s ||= 1; -my $git_tree = $opt_C; -$git_tree ||= "."; - -my $svn_url = $ARGV[0]; -my $svn_dir = $ARGV[1]; - -our @mergerx = (); -if ($opt_m) { - my $branch_esc = quotemeta ($branch_name); - my $trunk_esc = quotemeta ($trunk_name); - @mergerx = - ( - qr!\b(?:merg(?:ed?|ing))\b.*?\b((?:(?<=$branch_esc/)[\w\.\-]+)|(?:$trunk_esc))\b!i, - qr!\b(?:from|of)\W+((?:(?<=$branch_esc/)[\w\.\-]+)|(?:$trunk_esc))\b!i, - qr!\b(?:from|of)\W+(?:the )?([\w\.\-]+)[-\s]branch\b!i - ); -} -if ($opt_M) { - unshift (@mergerx, qr/$opt_M/); -} - -# Absolutize filename now, since we will have chdir'ed by the time we -# get around to opening it. -$opt_A = File::Spec->rel2abs($opt_A) if $opt_A; - -our %users = (); -our $users_file = undef; -sub read_users($) { - $users_file = File::Spec->rel2abs(@_); - die "Cannot open $users_file\n" unless -f $users_file; - open(my $authors,$users_file); - while(<$authors>) { - chomp; - next unless /^(\S+?)\s*=\s*(.+?)\s*<(.+)>\s*$/; - (my $user,my $name,my $email) = ($1,$2,$3); - $users{$user} = [$name,$email]; - } - close($authors); -} - -select(STDERR); $|=1; select(STDOUT); - - -package SVNconn; -# Basic SVN connection. -# We're only interested in connecting and downloading, so ... - -use File::Spec; -use File::Temp qw(tempfile); -use POSIX qw(strftime dup2); -use Fcntl qw(SEEK_SET); - -sub new { - my($what,$repo) = @_; - $what=ref($what) if ref($what); - - my $self = {}; - $self->{'buffer'} = ""; - bless($self,$what); - - $repo =~ s#/+$##; - $self->{'fullrep'} = $repo; - $self->conn(); - - return $self; -} - -sub conn { - my $self = shift; - my $repo = $self->{'fullrep'}; - my $auth = SVN::Core::auth_open ([SVN::Client::get_simple_provider, - SVN::Client::get_ssl_server_trust_file_provider, - SVN::Client::get_username_provider]); - my $s = SVN::Ra->new(url => $repo, auth => $auth, pool => $root_pool); - die "SVN connection to $repo: $!\n" unless defined $s; - $self->{'svn'} = $s; - $self->{'repo'} = $repo; - $self->{'maxrev'} = $s->get_latest_revnum(); -} - -sub file { - my($self,$path,$rev) = @_; - - my ($fh, $name) = tempfile('gitsvn.XXXXXX', - DIR => File::Spec->tmpdir(), UNLINK => 1); - - print "... $rev $path ...\n" if $opt_v; - my (undef, $properties); - $path =~ s#^/*##; - my $subpool = SVN::Pool::new_default_sub; - eval { (undef, $properties) - = $self->{'svn'}->get_file($path,$rev,$fh); }; - if($@) { - return undef if $@ =~ /Attempted to get checksum/; - die $@; - } - my $mode; - if (exists $properties->{'svn:executable'}) { - $mode = '100755'; - } elsif (exists $properties->{'svn:special'}) { - my ($special_content, $filesize); - $filesize = tell $fh; - seek $fh, 0, SEEK_SET; - read $fh, $special_content, $filesize; - if ($special_content =~ s/^link //) { - $mode = '120000'; - seek $fh, 0, SEEK_SET; - truncate $fh, 0; - print $fh $special_content; - } else { - die "unexpected svn:special file encountered"; - } - } else { - $mode = '100644'; - } - close ($fh); - - return ($name, $mode); -} - -sub ignore { - my($self,$path,$rev) = @_; - - print "... $rev $path ...\n" if $opt_v; - $path =~ s#^/*##; - my $subpool = SVN::Pool::new_default_sub; - my (undef,undef,$properties) - = $self->{'svn'}->get_dir($path,$rev,undef); - if (exists $properties->{'svn:ignore'}) { - my ($fh, $name) = tempfile('gitsvn.XXXXXX', - DIR => File::Spec->tmpdir(), - UNLINK => 1); - print $fh $properties->{'svn:ignore'}; - close($fh); - return $name; - } else { - return undef; - } -} - -sub dir_list { - my($self,$path,$rev) = @_; - $path =~ s#^/*##; - my $subpool = SVN::Pool::new_default_sub; - my ($dirents,undef,$properties) - = $self->{'svn'}->get_dir($path,$rev,undef); - return $dirents; -} - -package main; -use URI; - -our $svn = $svn_url; -$svn .= "/$svn_dir" if defined $svn_dir; -my $svn2 = SVNconn->new($svn); -$svn = SVNconn->new($svn); - -my $lwp_ua; -if($opt_d or $opt_D) { - $svn_url = URI->new($svn_url)->canonical; - if($opt_D) { - $svn_dir =~ s#/*$#/#; - } else { - $svn_dir = ""; - } - if ($svn_url->scheme eq "http") { - use LWP::UserAgent; - $lwp_ua = LWP::UserAgent->new(keep_alive => 1, requests_redirectable => []); - } else { - print STDERR "Warning: not HTTP; turning off direct file access\n"; - $opt_d=0; - } -} - -sub pdate($) { - my($d) = @_; - $d =~ m#(\d\d\d\d)-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)# - or die "Unparseable date: $d\n"; - my $y=$1; $y+=1900 if $y<1000; - return timegm($6||0,$5,$4,$3,$2-1,$y); -} - -sub getwd() { - my $pwd = `pwd`; - chomp $pwd; - return $pwd; -} - - -sub get_headref($$) { - my $name = shift; - my $git_dir = shift; - my $sha; - - if (open(C,"$git_dir/refs/heads/$name")) { - chomp($sha = ); - close(C); - length($sha) == 40 - or die "Cannot get head id for $name ($sha): $!\n"; - } - return $sha; -} - - --d $git_tree - or mkdir($git_tree,0777) - or die "Could not create $git_tree: $!"; -chdir($git_tree); - -my $orig_branch = ""; -my $forward_master = 0; -my %branches; - -my $git_dir = $ENV{"GIT_DIR"} || ".git"; -$git_dir = getwd()."/".$git_dir unless $git_dir =~ m#^/#; -$ENV{"GIT_DIR"} = $git_dir; -my $orig_git_index; -$orig_git_index = $ENV{GIT_INDEX_FILE} if exists $ENV{GIT_INDEX_FILE}; -my ($git_ih, $git_index) = tempfile('gitXXXXXX', SUFFIX => '.idx', - DIR => File::Spec->tmpdir()); -close ($git_ih); -$ENV{GIT_INDEX_FILE} = $git_index; -my $maxnum = 0; -my $last_rev = ""; -my $last_branch; -my $current_rev = $opt_s || 1; -unless(-d $git_dir) { - system("git init"); - die "Cannot init the GIT db at $git_tree: $?\n" if $?; - system("git read-tree --empty"); - die "Cannot init an empty tree: $?\n" if $?; - - $last_branch = $opt_o; - $orig_branch = ""; -} else { - -f "$git_dir/refs/heads/$opt_o" - or die "Branch '$opt_o' does not exist.\n". - "Either use the correct '-o branch' option,\n". - "or import to a new repository.\n"; - - -f "$git_dir/svn2git" - or die "'$git_dir/svn2git' does not exist.\n". - "You need that file for incremental imports.\n"; - open(F, "git symbolic-ref HEAD |") or - die "Cannot run git-symbolic-ref: $!\n"; - chomp ($last_branch = ); - $last_branch = basename($last_branch); - close(F); - unless($last_branch) { - warn "Cannot read the last branch name: $! -- assuming 'master'\n"; - $last_branch = "master"; - } - $orig_branch = $last_branch; - $last_rev = get_headref($orig_branch, $git_dir); - if (-f "$git_dir/SVN2GIT_HEAD") { - die <) { - chomp; - my($num,$branch,$ref) = split; - $branches{$branch}{$num} = $ref; - $branches{$branch}{"LAST"} = $ref; - $current_rev = $num+1 if $current_rev <= $num; - } - close($B); -} --d $git_dir - or die "Could not create git subdir ($git_dir).\n"; - -my $default_authors = "$git_dir/svn-authors"; -if ($opt_A) { - read_users($opt_A); - copy($opt_A,$default_authors) or die "Copy failed: $!"; -} else { - read_users($default_authors) if -f $default_authors; -} - -open BRANCHES,">>", "$git_dir/svn2git"; - -sub node_kind($$) { - my ($svnpath, $revision) = @_; - $svnpath =~ s#^/*##; - my $subpool = SVN::Pool::new_default_sub; - my $kind = $svn->{'svn'}->check_path($svnpath,$revision); - return $kind; -} - -sub get_file($$$) { - my($svnpath,$rev,$path) = @_; - - # now get it - my ($name,$mode); - if($opt_d) { - my($req,$res); - - # /svn/!svn/bc/2/django/trunk/django-docs/build.py - my $url=$svn_url->clone(); - $url->path($url->path."/!svn/bc/$rev/$svn_dir$svnpath"); - print "... $path...\n" if $opt_v; - $req = HTTP::Request->new(GET => $url); - $res = $lwp_ua->request($req); - if ($res->is_success) { - my $fh; - ($fh, $name) = tempfile('gitsvn.XXXXXX', - DIR => File::Spec->tmpdir(), UNLINK => 1); - print $fh $res->content; - close($fh) or die "Could not write $name: $!\n"; - } else { - return undef if $res->code == 301; # directory? - die $res->status_line." at $url\n"; - } - $mode = '0644'; # can't obtain mode via direct http request? - } else { - ($name,$mode) = $svn->file("$svnpath",$rev); - return undef unless defined $name; - } - - my $pid = open(my $F, '-|'); - die $! unless defined $pid; - if (!$pid) { - exec("git", "hash-object", "-w", $name) - or die "Cannot create object: $!\n"; - } - my $sha = <$F>; - chomp $sha; - close $F; - unlink $name; - return [$mode, $sha, $path]; -} - -sub get_ignore($$$$$) { - my($new,$old,$rev,$path,$svnpath) = @_; - - return unless $opt_I; - my $name = $svn->ignore("$svnpath",$rev); - if ($path eq '/') { - $path = $opt_I; - } else { - $path = File::Spec->catfile($path,$opt_I); - } - if (defined $name) { - my $pid = open(my $F, '-|'); - die $! unless defined $pid; - if (!$pid) { - exec("git", "hash-object", "-w", $name) - or die "Cannot create object: $!\n"; - } - my $sha = <$F>; - chomp $sha; - close $F; - unlink $name; - push(@$new,['0644',$sha,$path]); - } elsif (defined $old) { - push(@$old,$path); - } -} - -sub project_path($$) -{ - my ($path, $project) = @_; - - $path = "/".$path unless ($path =~ m#^\/#) ; - return $1 if ($path =~ m#^$project\/(.*)$#); - - $path =~ s#\.#\\\.#g; - $path =~ s#\+#\\\+#g; - return "/" if ($project =~ m#^$path.*$#); - - return undef; -} - -sub split_path($$) { - my($rev,$path) = @_; - my $branch; - - if($path =~ s#^/\Q$tag_name\E/([^/]+)/?##) { - $branch = "/$1"; - } elsif($path =~ s#^/\Q$trunk_name\E/?##) { - $branch = "/"; - } elsif($path =~ s#^/\Q$branch_name\E/([^/]+)/?##) { - $branch = $1; - } else { - my %no_error = ( - "/" => 1, - "/$tag_name" => 1, - "/$branch_name" => 1 - ); - print STDERR "$rev: Unrecognized path: $path\n" unless (defined $no_error{$path}); - return () - } - if ($path eq "") { - $path = "/"; - } elsif ($project_name) { - $path = project_path($path, $project_name); - } - return ($branch,$path); -} - -sub branch_rev($$) { - - my ($srcbranch,$uptorev) = @_; - - my $bbranches = $branches{$srcbranch}; - my @revs = reverse sort { ($a eq 'LAST' ? 0 : $a) <=> ($b eq 'LAST' ? 0 : $b) } keys %$bbranches; - my $therev; - foreach my $arev(@revs) { - next if ($arev eq 'LAST'); - if ($arev <= $uptorev) { - $therev = $arev; - last; - } - } - return $therev; -} - -sub expand_svndir($$$); - -sub expand_svndir($$$) -{ - my ($svnpath, $rev, $path) = @_; - my @list; - get_ignore(\@list, undef, $rev, $path, $svnpath); - my $dirents = $svn->dir_list($svnpath, $rev); - foreach my $p(keys %$dirents) { - my $kind = node_kind($svnpath.'/'.$p, $rev); - if ($kind eq $SVN::Node::file) { - my $f = get_file($svnpath.'/'.$p, $rev, $path.'/'.$p); - push(@list, $f) if $f; - } elsif ($kind eq $SVN::Node::dir) { - push(@list, - expand_svndir($svnpath.'/'.$p, $rev, $path.'/'.$p)); - } - } - return @list; -} - -sub copy_path($$$$$$$$) { - # Somebody copied a whole subdirectory. - # We need to find the index entries from the old version which the - # SVN log entry points to, and add them to the new place. - - my($newrev,$newbranch,$path,$oldpath,$rev,$node_kind,$new,$parents) = @_; - - my($srcbranch,$srcpath) = split_path($rev,$oldpath); - unless(defined $srcbranch && defined $srcpath) { - print "Path not found when copying from $oldpath @ $rev.\n". - "Will try to copy from original SVN location...\n" - if $opt_v; - push (@$new, expand_svndir($oldpath, $rev, $path)); - return; - } - my $therev = branch_rev($srcbranch, $rev); - my $gitrev = $branches{$srcbranch}{$therev}; - unless($gitrev) { - print STDERR "$newrev:$newbranch: could not find $oldpath \@ $rev\n"; - return; - } - if ($srcbranch ne $newbranch) { - push(@$parents, $branches{$srcbranch}{'LAST'}); - } - print "$newrev:$newbranch:$path: copying from $srcbranch:$srcpath @ $rev\n" if $opt_v; - if ($node_kind eq $SVN::Node::dir) { - $srcpath =~ s#/*$#/#; - } - - my $pid = open my $f,'-|'; - die $! unless defined $pid; - if (!$pid) { - exec("git","ls-tree","-r","-z",$gitrev,$srcpath) - or die $!; - } - local $/ = "\0"; - while(<$f>) { - chomp; - my($m,$p) = split(/\t/,$_,2); - my($mode,$type,$sha1) = split(/ /,$m); - next if $type ne "blob"; - if ($node_kind eq $SVN::Node::dir) { - $p = $path . substr($p,length($srcpath)-1); - } else { - $p = $path; - } - push(@$new,[$mode,$sha1,$p]); - } - close($f) or - print STDERR "$newrev:$newbranch: could not list files in $oldpath \@ $rev\n"; -} - -sub commit { - my($branch, $changed_paths, $revision, $author, $date, $message) = @_; - my($committer_name,$committer_email,$dest); - my($author_name,$author_email); - my(@old,@new,@parents); - - if (not defined $author or $author eq "") { - $committer_name = $committer_email = "unknown"; - } elsif (defined $users_file) { - die "User $author is not listed in $users_file\n" - unless exists $users{$author}; - ($committer_name,$committer_email) = @{$users{$author}}; - } elsif ($author =~ /^(.*?)\s+<(.*)>$/) { - ($committer_name, $committer_email) = ($1, $2); - } else { - $author =~ s/^<(.*)>$/$1/; - $committer_name = $committer_email = $author; - } - - if ($opt_F && $message =~ /From:\s+(.*?)\s+<(.*)>\s*\n/) { - ($author_name, $author_email) = ($1, $2); - print "Author from From: $1 <$2>\n" if ($opt_v);; - } elsif ($opt_S && $message =~ /Signed-off-by:\s+(.*?)\s+<(.*)>\s*\n/) { - ($author_name, $author_email) = ($1, $2); - print "Author from Signed-off-by: $1 <$2>\n" if ($opt_v);; - } else { - $author_name = $committer_name; - $author_email = $committer_email; - } - - $date = pdate($date); - - my $tag; - my $parent; - if($branch eq "/") { # trunk - $parent = $opt_o; - } elsif($branch =~ m#^/(.+)#) { # tag - $tag = 1; - $parent = $1; - } else { # "normal" branch - # nothing to do - $parent = $branch; - } - $dest = $parent; - - my $prev = $changed_paths->{"/"}; - if($prev and $prev->[0] eq "A") { - delete $changed_paths->{"/"}; - my $oldpath = $prev->[1]; - my $rev; - if(defined $oldpath) { - my $p; - ($parent,$p) = split_path($revision,$oldpath); - if(defined $parent) { - if($parent eq "/") { - $parent = $opt_o; - } else { - $parent =~ s#^/##; # if it's a tag - } - } - } else { - $parent = undef; - } - } - - my $rev; - if($revision > $opt_s and defined $parent) { - open(H,'-|',"git","rev-parse","--verify",$parent); - $rev = ; - close(H) or do { - print STDERR "$revision: cannot find commit '$parent'!\n"; - return; - }; - chop $rev; - if(length($rev) != 40) { - print STDERR "$revision: cannot find commit '$parent'!\n"; - return; - } - $rev = $branches{($parent eq $opt_o) ? "/" : $parent}{"LAST"}; - if($revision != $opt_s and not $rev) { - print STDERR "$revision: do not know ancestor for '$parent'!\n"; - return; - } - } else { - $rev = undef; - } - -# if($prev and $prev->[0] eq "A") { -# if(not $tag) { -# unless(open(H,"> $git_dir/refs/heads/$branch")) { -# print STDERR "$revision: Could not create branch $branch: $!\n"; -# $state=11; -# next; -# } -# print H "$rev\n" -# or die "Could not write branch $branch: $!"; -# close(H) -# or die "Could not write branch $branch: $!"; -# } -# } - if(not defined $rev) { - unlink($git_index); - } elsif ($rev ne $last_rev) { - print "Switching from $last_rev to $rev ($branch)\n" if $opt_v; - system("git", "read-tree", $rev); - die "read-tree failed for $rev: $?\n" if $?; - $last_rev = $rev; - } - - push (@parents, $rev) if defined $rev; - - my $cid; - if($tag and not %$changed_paths) { - $cid = $rev; - } else { - my @paths = sort keys %$changed_paths; - foreach my $path(@paths) { - my $action = $changed_paths->{$path}; - - if ($action->[0] eq "R") { - # refer to a file/tree in an earlier commit - push(@old,$path); # remove any old stuff - } - if(($action->[0] eq "A") || ($action->[0] eq "R")) { - my $node_kind = node_kind($action->[3], $revision); - if ($node_kind eq $SVN::Node::file) { - my $f = get_file($action->[3], - $revision, $path); - if ($f) { - push(@new,$f) if $f; - } else { - my $opath = $action->[3]; - print STDERR "$revision: $branch: could not fetch '$opath'\n"; - } - } elsif ($node_kind eq $SVN::Node::dir) { - if($action->[1]) { - copy_path($revision, $branch, - $path, $action->[1], - $action->[2], $node_kind, - \@new, \@parents); - } else { - get_ignore(\@new, \@old, $revision, - $path, $action->[3]); - } - } - } elsif ($action->[0] eq "D") { - push(@old,$path); - } elsif ($action->[0] eq "M") { - my $node_kind = node_kind($action->[3], $revision); - if ($node_kind eq $SVN::Node::file) { - my $f = get_file($action->[3], - $revision, $path); - push(@new,$f) if $f; - } elsif ($node_kind eq $SVN::Node::dir) { - get_ignore(\@new, \@old, $revision, - $path, $action->[3]); - } - } else { - die "$revision: unknown action '".$action->[0]."' for $path\n"; - } - } - - while(@old) { - my @o1; - if(@old > 55) { - @o1 = splice(@old,0,50); - } else { - @o1 = @old; - @old = (); - } - my $pid = open my $F, "-|"; - die "$!" unless defined $pid; - if (!$pid) { - exec("git", "ls-files", "-z", @o1) or die $!; - } - @o1 = (); - local $/ = "\0"; - while(<$F>) { - chomp; - push(@o1,$_); - } - close($F); - - while(@o1) { - my @o2; - if(@o1 > 55) { - @o2 = splice(@o1,0,50); - } else { - @o2 = @o1; - @o1 = (); - } - system("git","update-index","--force-remove","--",@o2); - die "Cannot remove files: $?\n" if $?; - } - } - while(@new) { - my @n2; - if(@new > 12) { - @n2 = splice(@new,0,10); - } else { - @n2 = @new; - @new = (); - } - system("git","update-index","--add", - (map { ('--cacheinfo', @$_) } @n2)); - die "Cannot add files: $?\n" if $?; - } - - my $pid = open(C,"-|"); - die "Cannot fork: $!" unless defined $pid; - unless($pid) { - exec("git","write-tree"); - die "Cannot exec git-write-tree: $!\n"; - } - chomp(my $tree = ); - length($tree) == 40 - or die "Cannot get tree id ($tree): $!\n"; - close(C) - or die "Error running git-write-tree: $?\n"; - print "Tree ID $tree\n" if $opt_v; - - my $pr = IO::Pipe->new() or die "Cannot open pipe: $!\n"; - my $pw = IO::Pipe->new() or die "Cannot open pipe: $!\n"; - $pid = fork(); - die "Fork: $!\n" unless defined $pid; - unless($pid) { - $pr->writer(); - $pw->reader(); - open(OUT,">&STDOUT"); - dup2($pw->fileno(),0); - dup2($pr->fileno(),1); - $pr->close(); - $pw->close(); - - my @par = (); - - # loose detection of merges - # based on the commit msg - foreach my $rx (@mergerx) { - if ($message =~ $rx) { - my $mparent = $1; - if ($mparent eq 'HEAD') { $mparent = $opt_o }; - if ( -e "$git_dir/refs/heads/$mparent") { - $mparent = get_headref($mparent, $git_dir); - push (@parents, $mparent); - print OUT "Merge parent branch: $mparent\n" if $opt_v; - } - } - } - my %seen_parents = (); - my @unique_parents = grep { ! $seen_parents{$_} ++ } @parents; - foreach my $bparent (@unique_parents) { - push @par, '-p', $bparent; - print OUT "Merge parent branch: $bparent\n" if $opt_v; - } - - exec("env", - "GIT_AUTHOR_NAME=$author_name", - "GIT_AUTHOR_EMAIL=$author_email", - "GIT_AUTHOR_DATE=".strftime("+0000 %Y-%m-%d %H:%M:%S",gmtime($date)), - "GIT_COMMITTER_NAME=$committer_name", - "GIT_COMMITTER_EMAIL=$committer_email", - "GIT_COMMITTER_DATE=".strftime("+0000 %Y-%m-%d %H:%M:%S",gmtime($date)), - "git", "commit-tree", $tree,@par); - die "Cannot exec git-commit-tree: $!\n"; - } - $pw->writer(); - $pr->reader(); - - $message =~ s/[\s\n]+\z//; - $message = "r$revision: $message" if $opt_r; - - print $pw "$message\n" - or die "Error writing to git-commit-tree: $!\n"; - $pw->close(); - - print "Committed change $revision:$branch ".strftime("%Y-%m-%d %H:%M:%S",gmtime($date)).")\n" if $opt_v; - chomp($cid = <$pr>); - length($cid) == 40 - or die "Cannot get commit id ($cid): $!\n"; - print "Commit ID $cid\n" if $opt_v; - $pr->close(); - - waitpid($pid,0); - die "Error running git-commit-tree: $?\n" if $?; - } - - if (not defined $cid) { - $cid = $branches{"/"}{"LAST"}; - } - - if(not defined $dest) { - print "... no known parent\n" if $opt_v; - } elsif(not $tag) { - print "Writing to refs/heads/$dest\n" if $opt_v; - open(C,">$git_dir/refs/heads/$dest") and - print C ("$cid\n") and - close(C) - or die "Cannot write branch $dest for update: $!\n"; - } - - if ($tag) { - $last_rev = "-" if %$changed_paths; - # the tag was 'complex', i.e. did not refer to a "real" revision - - $dest =~ tr/_/\./ if $opt_u; - - system('git', 'tag', '-f', $dest, $cid) == 0 - or die "Cannot create tag $dest: $!\n"; - - print "Created tag '$dest' on '$branch'\n" if $opt_v; - } - $branches{$branch}{"LAST"} = $cid; - $branches{$branch}{$revision} = $cid; - $last_rev = $cid; - print BRANCHES "$revision $branch $cid\n"; - print "DONE: $revision $dest $cid\n" if $opt_v; -} - -sub commit_all { - # Recursive use of the SVN connection does not work - local $svn = $svn2; - - my ($changed_paths, $revision, $author, $date, $message) = @_; - my %p; - while(my($path,$action) = each %$changed_paths) { - $p{$path} = [ $action->action,$action->copyfrom_path, $action->copyfrom_rev, $path ]; - } - $changed_paths = \%p; - - my %done; - my @col; - my $pref; - my $branch; - - while(my($path,$action) = each %$changed_paths) { - ($branch,$path) = split_path($revision,$path); - next if not defined $branch; - next if not defined $path; - $done{$branch}{$path} = $action; - } - while(($branch,$changed_paths) = each %done) { - commit($branch, $changed_paths, $revision, $author, $date, $message); - } -} - -$opt_l = $svn->{'maxrev'} if not defined $opt_l or $opt_l > $svn->{'maxrev'}; - -if ($opt_l < $current_rev) { - print "Up to date: no new revisions to fetch!\n" if $opt_v; - unlink("$git_dir/SVN2GIT_HEAD"); - exit; -} - -print "Processing from $current_rev to $opt_l ...\n" if $opt_v; - -my $from_rev; -my $to_rev = $current_rev - 1; - -my $subpool = SVN::Pool::new_default_sub; -while ($to_rev < $opt_l) { - $subpool->clear; - $from_rev = $to_rev + 1; - $to_rev = $from_rev + $repack_after; - $to_rev = $opt_l if $opt_l < $to_rev; - print "Fetching from $from_rev to $to_rev ...\n" if $opt_v; - $svn->{'svn'}->get_log("",$from_rev,$to_rev,0,1,1,\&commit_all); - my $pid = fork(); - die "Fork: $!\n" unless defined $pid; - unless($pid) { - exec("git", "repack", "-d") - or die "Cannot repack: $!\n"; - } - waitpid($pid, 0); -} - - -unlink($git_index); - -if (defined $orig_git_index) { - $ENV{GIT_INDEX_FILE} = $orig_git_index; -} else { - delete $ENV{GIT_INDEX_FILE}; -} - -# Now switch back to the branch we were in before all of this happened -if($orig_branch) { - print "DONE\n" if $opt_v and (not defined $opt_l or $opt_l > 0); - system("cp","$git_dir/refs/heads/$opt_o","$git_dir/refs/heads/master") - if $forward_master; - unless ($opt_i) { - system('git', 'read-tree', '-m', '-u', 'SVN2GIT_HEAD', 'HEAD'); - die "read-tree failed: $?\n" if $?; - } -} else { - $orig_branch = "master"; - print "DONE; creating $orig_branch branch\n" if $opt_v and (not defined $opt_l or $opt_l > 0); - system("cp","$git_dir/refs/heads/$opt_o","$git_dir/refs/heads/master") - unless -f "$git_dir/refs/heads/master"; - system('git', 'update-ref', 'HEAD', "$orig_branch"); - unless ($opt_i) { - system('git checkout'); - die "checkout failed: $?\n" if $?; - } -} -unlink("$git_dir/SVN2GIT_HEAD"); -close(BRANCHES); diff --git a/contrib/examples/git-svnimport.txt b/contrib/examples/git-svnimport.txt deleted file mode 100644 index 3f0a9c33b5..0000000000 --- a/contrib/examples/git-svnimport.txt +++ /dev/null @@ -1,179 +0,0 @@ -git-svnimport(1) -================ -v0.1, July 2005 - -NAME ----- -git-svnimport - Import a SVN repository into git - - -SYNOPSIS --------- -[verse] -'git-svnimport' [ -o ] [ -h ] [ -v ] [ -d | -D ] - [ -C ] [ -i ] [ -u ] [-l limit_rev] - [ -b branch_subdir ] [ -T trunk_subdir ] [ -t tag_subdir ] - [ -s start_chg ] [ -m ] [ -r ] [ -M regex ] - [ -I ] [ -A ] - [ -R ] [ -P ] - [ ] - - -DESCRIPTION ------------ -Imports a SVN repository into git. It will either create a new -repository, or incrementally import into an existing one. - -SVN access is done by the SVN::Perl module. - -git-svnimport assumes that SVN repositories are organized into one -"trunk" directory where the main development happens, "branches/FOO" -directories for branches, and "/tags/FOO" directories for tags. -Other subdirectories are ignored. - -git-svnimport creates a file ".git/svn2git", which is required for -incremental SVN imports. - -OPTIONS -------- --C :: - The GIT repository to import to. If the directory doesn't - exist, it will be created. Default is the current directory. - --s :: - Start importing at this SVN change number. The default is 1. -+ -When importing incrementally, you might need to edit the .git/svn2git file. - --i:: - Import-only: don't perform a checkout after importing. This option - ensures the working directory and index remain untouched and will - not create them if they do not exist. - --T :: - Name the SVN trunk. Default "trunk". - --t :: - Name the SVN subdirectory for tags. Default "tags". - --b :: - Name the SVN subdirectory for branches. Default "branches". - --o :: - The 'trunk' branch from SVN is imported to the 'origin' branch within - the git repository. Use this option if you want to import into a - different branch. - --r:: - Prepend 'rX: ' to commit messages, where X is the imported - subversion revision. - --u:: - Replace underscores in tag names with periods. - --I :: - Import the svn:ignore directory property to files with this - name in each directory. (The Subversion and GIT ignore - syntaxes are similar enough that using the Subversion patterns - directly with "-I .gitignore" will almost always just work.) - --A :: - Read a file with lines on the form -+ ------- - username = User's Full Name - ------- -+ -and use "User's Full Name " as the GIT -author and committer for Subversion commits made by -"username". If encountering a commit made by a user not in the -list, abort. -+ -For convenience, this data is saved to $GIT_DIR/svn-authors -each time the -A option is provided, and read from that same -file each time git-svnimport is run with an existing GIT -repository without -A. - --m:: - Attempt to detect merges based on the commit message. This option - will enable default regexes that try to capture the name source - branch name from the commit message. - --M :: - Attempt to detect merges based on the commit message with a custom - regex. It can be used with -m to also see the default regexes. - You must escape forward slashes. - --l :: - Specify a maximum revision number to pull. -+ -Formerly, this option controlled how many revisions to pull, -due to SVN memory leaks. (These have been worked around.) - --R :: - Specify how often git repository should be repacked. -+ -The default value is 1000. git-svnimport will do imports in chunks of 1000 -revisions, after each chunk the git repository will be repacked. To disable -this behavior specify some large value here which is greater than the number of -revisions to import. - --P :: - Partial import of the SVN tree. -+ -By default, the whole tree on the SVN trunk (/trunk) is imported. -'-P my/proj' will import starting only from '/trunk/my/proj'. -This option is useful when you want to import one project from a -svn repo which hosts multiple projects under the same trunk. - --v:: - Verbosity: let 'svnimport' report what it is doing. - --d:: - Use direct HTTP requests if possible. The "" argument is used - only for retrieving the SVN logs; the path to the contents is - included in the SVN log. - --D:: - Use direct HTTP requests if possible. The "" argument is used - for retrieving the logs, as well as for the contents. -+ -There's no safe way to automatically find out which of these options to -use, so you need to try both. Usually, the one that's wrong will die -with a 40x error pretty quickly. - -:: - The URL of the SVN module you want to import. For local - repositories, use "file:///absolute/path". -+ -If you're using the "-d" or "-D" option, this is the URL of the SVN -repository itself; it usually ends in "/svn". - -:: - The path to the module you want to check out. - --h:: - Print a short usage message and exit. - -OUTPUT ------- -If '-v' is specified, the script reports what it is doing. - -Otherwise, success is indicated the Unix way, i.e. by simply exiting with -a zero exit status. - -Author ------- -Written by Matthias Urlichs , with help from -various participants of the git-list . - -Based on a cvs2git script by the same author. - -Documentation --------------- -Documentation by Matthias Urlichs . - -GIT ---- -Part of the linkgit:git[7] suite diff --git a/contrib/examples/git-tag.sh b/contrib/examples/git-tag.sh deleted file mode 100755 index 1bd8f3c58d..0000000000 --- a/contrib/examples/git-tag.sh +++ /dev/null @@ -1,205 +0,0 @@ -#!/bin/sh -# Copyright (c) 2005 Linus Torvalds - -USAGE='[-n []] -l [] | [-a | -s | -u ] [-f | -d | -v] [-m ] []' -SUBDIRECTORY_OK='Yes' -. git-sh-setup - -message_given= -annotate= -signed= -force= -message= -username= -list= -verify= -LINES=0 -while test $# != 0 -do - case "$1" in - -a) - annotate=1 - shift - ;; - -s) - annotate=1 - signed=1 - shift - ;; - -f) - force=1 - shift - ;; - -n) - case "$#,$2" in - 1,* | *,-*) - LINES=1 # no argument - ;; - *) shift - LINES=$(expr "$1" : '\([0-9]*\)') - [ -z "$LINES" ] && LINES=1 # 1 line is default when -n is used - ;; - esac - shift - ;; - -l) - list=1 - shift - case $# in - 0) PATTERN= - ;; - *) - PATTERN="$1" # select tags by shell pattern, not re - shift - ;; - esac - git rev-parse --symbolic --tags | sort | - while read TAG - do - case "$TAG" in - *$PATTERN*) ;; - *) continue ;; - esac - [ "$LINES" -le 0 ] && { echo "$TAG"; continue ;} - OBJTYPE=$(git cat-file -t "$TAG") - case $OBJTYPE in - tag) - ANNOTATION=$(git cat-file tag "$TAG" | - sed -e '1,/^$/d' | - sed -n -e " - /^-----BEGIN PGP SIGNATURE-----\$/q - 2,\$s/^/ / - p - ${LINES}q - ") - printf "%-15s %s\n" "$TAG" "$ANNOTATION" - ;; - *) echo "$TAG" - ;; - esac - done - ;; - -m) - annotate=1 - shift - message="$1" - if test "$#" = "0"; then - die "error: option -m needs an argument" - else - message="$1" - message_given=1 - shift - fi - ;; - -F) - annotate=1 - shift - if test "$#" = "0"; then - die "error: option -F needs an argument" - else - message="$(cat "$1")" - message_given=1 - shift - fi - ;; - -u) - annotate=1 - signed=1 - shift - if test "$#" = "0"; then - die "error: option -u needs an argument" - else - username="$1" - shift - fi - ;; - -d) - shift - had_error=0 - for tag - do - cur=$(git show-ref --verify --hash -- "refs/tags/$tag") || { - echo >&2 "Seriously, what tag are you talking about?" - had_error=1 - continue - } - git update-ref -m 'tag: delete' -d "refs/tags/$tag" "$cur" || { - had_error=1 - continue - } - echo "Deleted tag $tag." - done - exit $had_error - ;; - -v) - shift - tag_name="$1" - tag=$(git show-ref --verify --hash -- "refs/tags/$tag_name") || - die "Seriously, what tag are you talking about?" - git-verify-tag -v "$tag" - exit $? - ;; - -*) - usage - ;; - *) - break - ;; - esac -done - -[ -n "$list" ] && exit 0 - -name="$1" -[ "$name" ] || usage -prev=0000000000000000000000000000000000000000 -if git show-ref --verify --quiet -- "refs/tags/$name" -then - test -n "$force" || die "tag '$name' already exists" - prev=$(git rev-parse "refs/tags/$name") -fi -shift -git check-ref-format "tags/$name" || - die "we do not like '$name' as a tag name." - -object=$(git rev-parse --verify --default HEAD "$@") || exit 1 -type=$(git cat-file -t $object) || exit 1 -tagger=$(git var GIT_COMMITTER_IDENT) || exit 1 - -test -n "$username" || - username=$(git config user.signingkey) || - username=$(expr "z$tagger" : 'z\(.*>\)') - -trap 'rm -f "$GIT_DIR"/TAG_TMP* "$GIT_DIR"/TAG_FINALMSG "$GIT_DIR"/TAG_EDITMSG' 0 - -if [ "$annotate" ]; then - if [ -z "$message_given" ]; then - ( echo "#" - echo "# Write a tag message" - echo "#" ) > "$GIT_DIR"/TAG_EDITMSG - git_editor "$GIT_DIR"/TAG_EDITMSG || exit - else - printf '%s\n' "$message" >"$GIT_DIR"/TAG_EDITMSG - fi - - grep -v '^#' <"$GIT_DIR"/TAG_EDITMSG | - git stripspace >"$GIT_DIR"/TAG_FINALMSG - - [ -s "$GIT_DIR"/TAG_FINALMSG -o -n "$message_given" ] || { - echo >&2 "No tag message?" - exit 1 - } - - ( printf 'object %s\ntype %s\ntag %s\ntagger %s\n\n' \ - "$object" "$type" "$name" "$tagger"; - cat "$GIT_DIR"/TAG_FINALMSG ) >"$GIT_DIR"/TAG_TMP - rm -f "$GIT_DIR"/TAG_TMP.asc "$GIT_DIR"/TAG_FINALMSG - if [ "$signed" ]; then - gpg -bsa -u "$username" "$GIT_DIR"/TAG_TMP && - cat "$GIT_DIR"/TAG_TMP.asc >>"$GIT_DIR"/TAG_TMP || - die "failed to sign the tag with GPG." - fi - object=$(git-mktag < "$GIT_DIR"/TAG_TMP) -fi - -git update-ref "refs/tags/$name" "$object" "$prev" diff --git a/contrib/examples/git-verify-tag.sh b/contrib/examples/git-verify-tag.sh deleted file mode 100755 index 0902a5c21a..0000000000 --- a/contrib/examples/git-verify-tag.sh +++ /dev/null @@ -1,45 +0,0 @@ -#!/bin/sh - -USAGE='' -SUBDIRECTORY_OK='Yes' -. git-sh-setup - -verbose= -while test $# != 0 -do - case "$1" in - -v|--v|--ve|--ver|--verb|--verbo|--verbos|--verbose) - verbose=t ;; - *) - break ;; - esac - shift -done - -if [ "$#" != "1" ] -then - usage -fi - -type="$(git cat-file -t "$1" 2>/dev/null)" || - die "$1: no such object." - -test "$type" = tag || - die "$1: cannot verify a non-tag object of type $type." - -case "$verbose" in -t) - git cat-file -p "$1" | - sed -n -e '/^-----BEGIN PGP SIGNATURE-----/q' -e p - ;; -esac - -trap 'rm -f "$GIT_DIR/.tmp-vtag"' 0 - -git cat-file tag "$1" >"$GIT_DIR/.tmp-vtag" || exit 1 -sed -n -e ' - /^-----BEGIN PGP SIGNATURE-----$/q - p -' <"$GIT_DIR/.tmp-vtag" | -gpg --verify "$GIT_DIR/.tmp-vtag" - || exit 1 -rm -f "$GIT_DIR/.tmp-vtag" diff --git a/contrib/examples/git-whatchanged.sh b/contrib/examples/git-whatchanged.sh deleted file mode 100755 index 2edbdc6d99..0000000000 --- a/contrib/examples/git-whatchanged.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/sh - -USAGE='[-p] [--max-count=] [..] [--pretty=] [-m] [git-diff-tree options] [git-rev-list options]' -SUBDIRECTORY_OK='Yes' -. git-sh-setup - -diff_tree_flags=$(git-rev-parse --sq --no-revs --flags "$@") || exit -case "$0" in -*whatchanged) - count= - test -z "$diff_tree_flags" && - diff_tree_flags=$(git config --get whatchanged.difftree) - diff_tree_default_flags='-c -M --abbrev' ;; -*show) - count=-n1 - test -z "$diff_tree_flags" && - diff_tree_flags=$(git config --get show.difftree) - diff_tree_default_flags='--cc --always' ;; -esac -test -z "$diff_tree_flags" && - diff_tree_flags="$diff_tree_default_flags" - -rev_list_args=$(git-rev-parse --sq --default HEAD --revs-only "$@") && -diff_tree_args=$(git-rev-parse --sq --no-revs --no-flags "$@") && - -eval "git-rev-list $count $rev_list_args" | -eval "git-diff-tree --stdin --pretty -r $diff_tree_flags $diff_tree_args" | -LESS="$LESS -S" ${PAGER:-less} diff --git a/contrib/update-unicode/README b/contrib/update-unicode/README index b9e2fc8540..151a197041 100644 --- a/contrib/update-unicode/README +++ b/contrib/update-unicode/README @@ -1,10 +1,10 @@ TL;DR: Run update_unicode.sh after the publication of a new Unicode -standard and commit the resulting unicode_widths.h file. +standard and commit the resulting unicode-widths.h file. The long version ================ -The Git source code ships the file unicode_widths.h which contains +The Git source code ships the file unicode-widths.h which contains tables of zero and double width Unicode code points, respectively. These tables are generated using update_unicode.sh in this directory. update_unicode.sh itself uses a third-party tool, uniset, to query two @@ -16,5 +16,5 @@ This requires a current-ish version of autoconf (2.69 works per December On each run, update_unicode.sh checks whether more recent Unicode data files are available from the Unicode consortium, and rebuilds the header -unicode_widths.h with the new data. The new header can then be +unicode-widths.h with the new data. The new header can then be committed. diff --git a/contrib/update-unicode/update_unicode.sh b/contrib/update-unicode/update_unicode.sh index e05db92d3f..aa90865bef 100755 --- a/contrib/update-unicode/update_unicode.sh +++ b/contrib/update-unicode/update_unicode.sh @@ -6,7 +6,7 @@ #Cf Format a format control character # cd "$(dirname "$0")" -UNICODEWIDTH_H=$(git rev-parse --show-toplevel)/unicode_width.h +UNICODEWIDTH_H=$(git rev-parse --show-toplevel)/unicode-width.h wget -N http://www.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt \ http://www.unicode.org/Public/UCD/latest/ucd/EastAsianWidth.txt && diff --git a/convert.c b/convert.c index cc562f6509..c480097a2a 100644 --- a/convert.c +++ b/convert.c @@ -914,7 +914,7 @@ static int ident_to_worktree(const char *path, const char *src, size_t len, to_free = strbuf_detach(buf, NULL); hash_object_file(src, len, "blob", &oid); - strbuf_grow(buf, len + cnt * 43); + strbuf_grow(buf, len + cnt * (the_hash_algo->hexsz + 3)); for (;;) { /* step 1: run to the next '$' */ dollar = memchr(src, '$', len); @@ -1510,7 +1510,7 @@ struct ident_filter { struct stream_filter filter; struct strbuf left; int state; - char ident[45]; /* ": x40 $" */ + char ident[GIT_MAX_HEXSZ + 5]; /* ": x40 $" */ }; static int is_foreign_ident(const char *str) @@ -1635,12 +1635,12 @@ static struct stream_filter_vtbl ident_vtbl = { ident_free_fn, }; -static struct stream_filter *ident_filter(const unsigned char *sha1) +static struct stream_filter *ident_filter(const struct object_id *oid) { struct ident_filter *ident = xmalloc(sizeof(*ident)); xsnprintf(ident->ident, sizeof(ident->ident), - ": %s $", sha1_to_hex(sha1)); + ": %s $", oid_to_hex(oid)); strbuf_init(&ident->left, 0); ident->filter.vtbl = &ident_vtbl; ident->state = 0; @@ -1655,7 +1655,7 @@ static struct stream_filter *ident_filter(const unsigned char *sha1) * Note that you would be crazy to set CRLF, smuge/clean or ident to a * large binary blob you would want us not to slurp into the memory! */ -struct stream_filter *get_stream_filter(const char *path, const unsigned char *sha1) +struct stream_filter *get_stream_filter(const char *path, const struct object_id *oid) { struct conv_attrs ca; struct stream_filter *filter = NULL; @@ -1668,7 +1668,7 @@ struct stream_filter *get_stream_filter(const char *path, const unsigned char *s return NULL; if (ca.ident) - filter = ident_filter(sha1); + filter = ident_filter(oid); if (output_eol(ca.crlf_action) == EOL_CRLF) filter = cascade_filter(filter, lf_to_crlf_filter()); diff --git a/convert.h b/convert.h index 65ab3e5167..2e9b4f49cc 100644 --- a/convert.h +++ b/convert.h @@ -93,7 +93,7 @@ extern int would_convert_to_git_filter_fd(const char *path); struct stream_filter; /* opaque */ -extern struct stream_filter *get_stream_filter(const char *path, const unsigned char *); +extern struct stream_filter *get_stream_filter(const char *path, const struct object_id *); extern void free_stream_filter(struct stream_filter *); extern int is_null_stream_filter(struct stream_filter *); diff --git a/credential.c b/credential.c index 9747f47b18..62be651b03 100644 --- a/credential.c +++ b/credential.c @@ -5,6 +5,7 @@ #include "run-command.h" #include "url.h" #include "prompt.h" +#include "sigchain.h" void credential_init(struct credential *c) { @@ -227,8 +228,10 @@ static int run_credential_helper(struct credential *c, return -1; fp = xfdopen(helper.in, "w"); + sigchain_push(SIGPIPE, SIG_IGN); credential_write(c, fp); fclose(fp); + sigchain_pop(SIGPIPE); if (want_output) { int r; diff --git a/daemon.c b/daemon.c index fe833ea7de..9d2e0d20ef 100644 --- a/daemon.c +++ b/daemon.c @@ -1459,7 +1459,7 @@ int cmd_main(int argc, const char **argv) die("base-path '%s' does not exist or is not a directory", base_path); - if (inetd_mode) { + if (log_destination != LOG_DESTINATION_STDERR) { if (!freopen("/dev/null", "w", stderr)) die_errno("failed to redirect stderr to /dev/null"); } diff --git a/diff.c b/diff.c index 4c59f5f5d3..1289df4b1f 100644 --- a/diff.c +++ b/diff.c @@ -3638,7 +3638,7 @@ int diff_populate_filespec(struct diff_filespec *s, unsigned int flags) else { enum object_type type; if (size_only || (flags & CHECK_BINARY)) { - type = sha1_object_info(s->oid.hash, &s->size); + type = oid_object_info(&s->oid, &s->size); if (type < 0) die("unable to read %s", oid_to_hex(&s->oid)); @@ -3649,7 +3649,7 @@ int diff_populate_filespec(struct diff_filespec *s, unsigned int flags) return 0; } } - s->data = read_sha1_file(s->oid.hash, &type, &s->size); + s->data = read_object_file(&s->oid, &type, &s->size); if (!s->data) die("unable to read %s", oid_to_hex(&s->oid)); s->should_free = 1; @@ -3834,7 +3834,7 @@ static int similarity_index(struct diff_filepair *p) static const char *diff_abbrev_oid(const struct object_id *oid, int abbrev) { if (startup_info->have_repository) - return find_unique_abbrev(oid->hash, abbrev); + return find_unique_abbrev(oid, abbrev); else { char *hex = oid_to_hex(oid); if (abbrev < 0) diff --git a/dir.c b/dir.c index dedbf5d476..63a917be45 100644 --- a/dir.c +++ b/dir.c @@ -243,7 +243,7 @@ static int do_read_blob(const struct object_id *oid, struct oid_stat *oid_stat, *size_out = 0; *data_out = NULL; - data = read_sha1_file(oid->hash, &type, &sz); + data = read_object_file(oid, &type, &sz); if (!data || type != OBJ_BLOB) { free(data); return -1; diff --git a/entry.c b/entry.c index 6c33112aea..2101201a11 100644 --- a/entry.c +++ b/entry.c @@ -85,7 +85,7 @@ static int create_file(const char *path, unsigned int mode) static void *read_blob_entry(const struct cache_entry *ce, unsigned long *size) { enum object_type type; - void *blob_data = read_sha1_file(ce->oid.hash, &type, size); + void *blob_data = read_object_file(&ce->oid, &type, size); if (blob_data) { if (type == OBJ_BLOB) @@ -266,7 +266,7 @@ static int write_entry(struct cache_entry *ce, if (ce_mode_s_ifmt == S_IFREG) { struct stream_filter *filter = get_stream_filter(ce->name, - ce->oid.hash); + &ce->oid); if (filter && !streaming_write_entry(ce, path, filter, state, to_tempfile, diff --git a/environment.c b/environment.c index d6dd64662c..fd970b81bd 100644 --- a/environment.c +++ b/environment.c @@ -13,6 +13,9 @@ #include "refs.h" #include "fmt-merge-msg.h" #include "commit.h" +#include "argv-array.h" +#include "object-store.h" +#include "chdir-notify.h" int trust_executable_bit = 1; int trust_ctime = 1; @@ -147,10 +150,35 @@ static char *expand_namespace(const char *raw_namespace) return strbuf_detach(&buf, NULL); } -void setup_git_env(void) +/* + * Wrapper of getenv() that returns a strdup value. This value is kept + * in argv to be freed later. + */ +static const char *getenv_safe(struct argv_array *argv, const char *name) +{ + const char *value = getenv(name); + + if (!value) + return NULL; + + argv_array_push(argv, value); + return argv->argv[argv->argc - 1]; +} + +void setup_git_env(const char *git_dir) { const char *shallow_file; const char *replace_ref_base; + struct set_gitdir_args args = { NULL }; + struct argv_array to_free = ARGV_ARRAY_INIT; + + args.commondir = getenv_safe(&to_free, GIT_COMMON_DIR_ENVIRONMENT); + args.object_dir = getenv_safe(&to_free, DB_ENVIRONMENT); + args.graft_file = getenv_safe(&to_free, GRAFT_ENVIRONMENT); + args.index_file = getenv_safe(&to_free, INDEX_ENVIRONMENT); + args.alternate_db = getenv_safe(&to_free, ALTERNATE_DB_ENVIRONMENT); + repo_set_gitdir(the_repository, git_dir, &args); + argv_array_clear(&to_free); if (getenv(NO_REPLACE_OBJECTS_ENVIRONMENT)) check_replace_refs = 0; @@ -244,9 +272,9 @@ const char *get_git_work_tree(void) char *get_object_directory(void) { - if (!the_repository->objectdir) + if (!the_repository->objects->objectdir) BUG("git environment hasn't been setup"); - return the_repository->objectdir; + return the_repository->objects->objectdir; } int odb_mkstemp(struct strbuf *temp_filename, const char *pattern) @@ -296,13 +324,31 @@ char *get_graft_file(void) return the_repository->graft_file; } -int set_git_dir(const char *path) +static void set_git_dir_1(const char *path) { if (setenv(GIT_DIR_ENVIRONMENT, path, 1)) - return error("Could not set GIT_DIR to '%s'", path); - repo_set_gitdir(the_repository, path); - setup_git_env(); - return 0; + die("could not set GIT_DIR to '%s'", path); + setup_git_env(path); +} + +static void update_relative_gitdir(const char *name, + const char *old_cwd, + const char *new_cwd, + void *data) +{ + char *path = reparent_relative_path(old_cwd, new_cwd, get_git_dir()); + trace_printf_key(&trace_setup_key, + "setup: move $GIT_DIR to '%s'", + path); + set_git_dir_1(path); + free(path); +} + +void set_git_dir(const char *path) +{ + set_git_dir_1(path); + if (!is_absolute_path(path)) + chdir_notify_register(NULL, update_relative_gitdir, NULL); } const char *get_log_output_encoding(void) diff --git a/exec-cmd.c b/exec-cmd.c new file mode 100644 index 0000000000..8a8261746a --- /dev/null +++ b/exec-cmd.c @@ -0,0 +1,165 @@ +#include "cache.h" +#include "exec-cmd.h" +#include "quote.h" +#include "argv-array.h" +#define MAX_ARGS 32 + +static const char *argv_exec_path; + +#ifdef RUNTIME_PREFIX +static const char *argv0_path; + +static const char *system_prefix(void) +{ + static const char *prefix; + + assert(argv0_path); + assert(is_absolute_path(argv0_path)); + + if (!prefix && + !(prefix = strip_path_suffix(argv0_path, GIT_EXEC_PATH)) && + !(prefix = strip_path_suffix(argv0_path, BINDIR)) && + !(prefix = strip_path_suffix(argv0_path, "git"))) { + prefix = PREFIX; + trace_printf("RUNTIME_PREFIX requested, " + "but prefix computation failed. " + "Using static fallback '%s'.\n", prefix); + } + return prefix; +} + +void git_extract_argv0_path(const char *argv0) +{ + const char *slash; + + if (!argv0 || !*argv0) + return; + + slash = find_last_dir_sep(argv0); + + if (slash) + argv0_path = xstrndup(argv0, slash - argv0); +} + +#else + +static const char *system_prefix(void) +{ + return PREFIX; +} + +void git_extract_argv0_path(const char *argv0) +{ +} + +#endif /* RUNTIME_PREFIX */ + +char *system_path(const char *path) +{ + struct strbuf d = STRBUF_INIT; + + if (is_absolute_path(path)) + return xstrdup(path); + + strbuf_addf(&d, "%s/%s", system_prefix(), path); + return strbuf_detach(&d, NULL); +} + +void git_set_argv_exec_path(const char *exec_path) +{ + argv_exec_path = exec_path; + /* + * Propagate this setting to external programs. + */ + setenv(EXEC_PATH_ENVIRONMENT, exec_path, 1); +} + + +/* Returns the highest-priority, location to look for git programs. */ +const char *git_exec_path(void) +{ + static char *cached_exec_path; + + if (argv_exec_path) + return argv_exec_path; + + if (!cached_exec_path) { + const char *env = getenv(EXEC_PATH_ENVIRONMENT); + if (env && *env) + cached_exec_path = xstrdup(env); + else + cached_exec_path = system_path(GIT_EXEC_PATH); + } + return cached_exec_path; +} + +static void add_path(struct strbuf *out, const char *path) +{ + if (path && *path) { + strbuf_add_absolute_path(out, path); + strbuf_addch(out, PATH_SEP); + } +} + +void setup_path(void) +{ + const char *old_path = getenv("PATH"); + struct strbuf new_path = STRBUF_INIT; + + add_path(&new_path, git_exec_path()); + + if (old_path) + strbuf_addstr(&new_path, old_path); + else + strbuf_addstr(&new_path, _PATH_DEFPATH); + + setenv("PATH", new_path.buf, 1); + + strbuf_release(&new_path); +} + +const char **prepare_git_cmd(struct argv_array *out, const char **argv) +{ + argv_array_push(out, "git"); + argv_array_pushv(out, argv); + return out->argv; +} + +int execv_git_cmd(const char **argv) { + struct argv_array nargv = ARGV_ARRAY_INIT; + + prepare_git_cmd(&nargv, argv); + trace_argv_printf(nargv.argv, "trace: exec:"); + + /* execvp() can only ever return if it fails */ + sane_execvp("git", (char **)nargv.argv); + + trace_printf("trace: exec failed: %s\n", strerror(errno)); + + argv_array_clear(&nargv); + return -1; +} + + +int execl_git_cmd(const char *cmd,...) +{ + int argc; + const char *argv[MAX_ARGS + 1]; + const char *arg; + va_list param; + + va_start(param, cmd); + argv[0] = cmd; + argc = 1; + while (argc < MAX_ARGS) { + arg = argv[argc++] = va_arg(param, char *); + if (!arg) + break; + } + va_end(param); + if (MAX_ARGS <= argc) + return error("too many args to run %s", cmd); + + argv[argc] = NULL; + return execv_git_cmd(argv); +} diff --git a/exec-cmd.h b/exec-cmd.h new file mode 100644 index 0000000000..ff0b48048a --- /dev/null +++ b/exec-cmd.h @@ -0,0 +1,16 @@ +#ifndef GIT_EXEC_CMD_H +#define GIT_EXEC_CMD_H + +struct argv_array; + +extern void git_set_argv_exec_path(const char *exec_path); +extern void git_extract_argv0_path(const char *path); +extern const char *git_exec_path(void); +extern void setup_path(void); +extern const char **prepare_git_cmd(struct argv_array *out, const char **argv); +extern int execv_git_cmd(const char **argv); /* NULL terminated */ +LAST_ARG_MUST_BE_NULL +extern int execl_git_cmd(const char *cmd, ...); +extern char *system_path(const char *path); + +#endif /* GIT_EXEC_CMD_H */ diff --git a/exec_cmd.c b/exec_cmd.c deleted file mode 100644 index ce192a2d64..0000000000 --- a/exec_cmd.c +++ /dev/null @@ -1,165 +0,0 @@ -#include "cache.h" -#include "exec_cmd.h" -#include "quote.h" -#include "argv-array.h" -#define MAX_ARGS 32 - -static const char *argv_exec_path; - -#ifdef RUNTIME_PREFIX -static const char *argv0_path; - -static const char *system_prefix(void) -{ - static const char *prefix; - - assert(argv0_path); - assert(is_absolute_path(argv0_path)); - - if (!prefix && - !(prefix = strip_path_suffix(argv0_path, GIT_EXEC_PATH)) && - !(prefix = strip_path_suffix(argv0_path, BINDIR)) && - !(prefix = strip_path_suffix(argv0_path, "git"))) { - prefix = PREFIX; - trace_printf("RUNTIME_PREFIX requested, " - "but prefix computation failed. " - "Using static fallback '%s'.\n", prefix); - } - return prefix; -} - -void git_extract_argv0_path(const char *argv0) -{ - const char *slash; - - if (!argv0 || !*argv0) - return; - - slash = find_last_dir_sep(argv0); - - if (slash) - argv0_path = xstrndup(argv0, slash - argv0); -} - -#else - -static const char *system_prefix(void) -{ - return PREFIX; -} - -void git_extract_argv0_path(const char *argv0) -{ -} - -#endif /* RUNTIME_PREFIX */ - -char *system_path(const char *path) -{ - struct strbuf d = STRBUF_INIT; - - if (is_absolute_path(path)) - return xstrdup(path); - - strbuf_addf(&d, "%s/%s", system_prefix(), path); - return strbuf_detach(&d, NULL); -} - -void git_set_argv_exec_path(const char *exec_path) -{ - argv_exec_path = exec_path; - /* - * Propagate this setting to external programs. - */ - setenv(EXEC_PATH_ENVIRONMENT, exec_path, 1); -} - - -/* Returns the highest-priority, location to look for git programs. */ -const char *git_exec_path(void) -{ - static char *cached_exec_path; - - if (argv_exec_path) - return argv_exec_path; - - if (!cached_exec_path) { - const char *env = getenv(EXEC_PATH_ENVIRONMENT); - if (env && *env) - cached_exec_path = xstrdup(env); - else - cached_exec_path = system_path(GIT_EXEC_PATH); - } - return cached_exec_path; -} - -static void add_path(struct strbuf *out, const char *path) -{ - if (path && *path) { - strbuf_add_absolute_path(out, path); - strbuf_addch(out, PATH_SEP); - } -} - -void setup_path(void) -{ - const char *old_path = getenv("PATH"); - struct strbuf new_path = STRBUF_INIT; - - add_path(&new_path, git_exec_path()); - - if (old_path) - strbuf_addstr(&new_path, old_path); - else - strbuf_addstr(&new_path, _PATH_DEFPATH); - - setenv("PATH", new_path.buf, 1); - - strbuf_release(&new_path); -} - -const char **prepare_git_cmd(struct argv_array *out, const char **argv) -{ - argv_array_push(out, "git"); - argv_array_pushv(out, argv); - return out->argv; -} - -int execv_git_cmd(const char **argv) { - struct argv_array nargv = ARGV_ARRAY_INIT; - - prepare_git_cmd(&nargv, argv); - trace_argv_printf(nargv.argv, "trace: exec:"); - - /* execvp() can only ever return if it fails */ - sane_execvp("git", (char **)nargv.argv); - - trace_printf("trace: exec failed: %s\n", strerror(errno)); - - argv_array_clear(&nargv); - return -1; -} - - -int execl_git_cmd(const char *cmd,...) -{ - int argc; - const char *argv[MAX_ARGS + 1]; - const char *arg; - va_list param; - - va_start(param, cmd); - argv[0] = cmd; - argc = 1; - while (argc < MAX_ARGS) { - arg = argv[argc++] = va_arg(param, char *); - if (!arg) - break; - } - va_end(param); - if (MAX_ARGS <= argc) - return error("too many args to run %s", cmd); - - argv[argc] = NULL; - return execv_git_cmd(argv); -} diff --git a/exec_cmd.h b/exec_cmd.h deleted file mode 100644 index ff0b48048a..0000000000 --- a/exec_cmd.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef GIT_EXEC_CMD_H -#define GIT_EXEC_CMD_H - -struct argv_array; - -extern void git_set_argv_exec_path(const char *exec_path); -extern void git_extract_argv0_path(const char *path); -extern const char *git_exec_path(void); -extern void setup_path(void); -extern const char **prepare_git_cmd(struct argv_array *out, const char **argv); -extern int execv_git_cmd(const char **argv); /* NULL terminated */ -LAST_ARG_MUST_BE_NULL -extern int execl_git_cmd(const char *cmd, ...); -extern char *system_path(const char *path); - -#endif /* GIT_EXEC_CMD_H */ diff --git a/fast-import.c b/fast-import.c index ba0cb4bdfb..05d1079d23 100644 --- a/fast-import.c +++ b/fast-import.c @@ -154,6 +154,7 @@ Format of STDIN stream: #include "builtin.h" #include "cache.h" +#include "repository.h" #include "config.h" #include "lockfile.h" #include "object.h" @@ -168,6 +169,7 @@ Format of STDIN stream: #include "dir.h" #include "run-command.h" #include "packfile.h" +#include "object-store.h" #include "mem-pool.h" #define PACK_ID_BITS 16 @@ -991,7 +993,7 @@ static void end_packfile(void) if (!new_p) die("core git rejected index %s", idx_name); all_packs[pack_id] = new_p; - install_packed_git(new_p); + install_packed_git(the_repository, new_p); free(idx_name); /* Print the boundary */ @@ -1065,7 +1067,8 @@ static int store_object( if (e->idx.offset) { duplicate_count_by_type[type]++; return 1; - } else if (find_sha1_pack(oid.hash, packed_git)) { + } else if (find_sha1_pack(oid.hash, + get_packed_git(the_repository))) { e->type = type; e->pack_id = MAX_PACK_ID; e->idx.offset = 1; /* just not zero! */ @@ -1262,7 +1265,8 @@ static void stream_blob(uintmax_t len, struct object_id *oidout, uintmax_t mark) duplicate_count_by_type[OBJ_BLOB]++; truncate_pack(&checkpoint); - } else if (find_sha1_pack(oid.hash, packed_git)) { + } else if (find_sha1_pack(oid.hash, + get_packed_git(the_repository))) { e->type = OBJ_BLOB; e->pack_id = MAX_PACK_ID; e->idx.offset = 1; /* just not zero! */ @@ -1367,7 +1371,7 @@ static void load_tree(struct tree_entry *root) die("Can't load tree %s", oid_to_hex(oid)); } else { enum object_type type; - buf = read_sha1_file(oid->hash, &type, &size); + buf = read_object_file(oid, &type, &size); if (!buf || type != OBJ_TREE) die("Can't load tree %s", oid_to_hex(oid)); } @@ -1868,7 +1872,7 @@ static void read_marks(void) die("corrupt mark line: %s", line); e = find_object(&oid); if (!e) { - enum object_type type = sha1_object_info(oid.hash, NULL); + enum object_type type = oid_object_info(&oid, NULL); if (type < 0) die("object not found: %s", oid_to_hex(&oid)); e = insert_object(&oid); @@ -2398,7 +2402,7 @@ static void file_change_m(const char *p, struct branch *b) enum object_type expected = S_ISDIR(mode) ? OBJ_TREE: OBJ_BLOB; enum object_type type = oe ? oe->type : - sha1_object_info(oid.hash, NULL); + oid_object_info(&oid, NULL); if (type < 0) die("%s not found: %s", S_ISDIR(mode) ? "Tree" : "Blob", @@ -2538,8 +2542,9 @@ static void note_change_n(const char *p, struct branch *b, unsigned char *old_fa oidcpy(&commit_oid, &commit_oe->idx.oid); } else if (!get_oid(p, &commit_oid)) { unsigned long size; - char *buf = read_object_with_reference(commit_oid.hash, - commit_type, &size, commit_oid.hash); + char *buf = read_object_with_reference(&commit_oid, + commit_type, &size, + &commit_oid); if (!buf || size < 46) die("Not a valid commit: %s", p); free(buf); @@ -2558,7 +2563,7 @@ static void note_change_n(const char *p, struct branch *b, unsigned char *old_fa die("Not a blob (actually a %s): %s", type_name(oe->type), command_buf.buf); } else if (!is_null_oid(&oid)) { - enum object_type type = sha1_object_info(oid.hash, NULL); + enum object_type type = oid_object_info(&oid, NULL); if (type < 0) die("Blob not found: %s", command_buf.buf); if (type != OBJ_BLOB) @@ -2608,9 +2613,8 @@ static void parse_from_existing(struct branch *b) unsigned long size; char *buf; - buf = read_object_with_reference(b->oid.hash, - commit_type, &size, - b->oid.hash); + buf = read_object_with_reference(&b->oid, commit_type, &size, + &b->oid); parse_from_commit(b, buf, size); free(buf); } @@ -2687,8 +2691,9 @@ static struct hash_list *parse_merge(unsigned int *count) oidcpy(&n->oid, &oe->idx.oid); } else if (!get_oid(from, &n->oid)) { unsigned long size; - char *buf = read_object_with_reference(n->oid.hash, - commit_type, &size, n->oid.hash); + char *buf = read_object_with_reference(&n->oid, + commit_type, + &size, &n->oid); if (!buf || size < 46) die("Not a valid commit: %s", from); free(buf); @@ -2845,7 +2850,7 @@ static void parse_new_tag(const char *arg) } else if (!get_oid(from, &oid)) { struct object_entry *oe = find_object(&oid); if (!oe) { - type = sha1_object_info(oid.hash, NULL); + type = oid_object_info(&oid, NULL); if (type < 0) die("Not a valid object: %s", from); } else @@ -2921,7 +2926,7 @@ static void cat_blob(struct object_entry *oe, struct object_id *oid) char *buf; if (!oe || oe->pack_id == MAX_PACK_ID) { - buf = read_sha1_file(oid->hash, &type, &size); + buf = read_object_file(oid, &type, &size); } else { type = oe->type; buf = gfi_unpack_entry(oe, &size); @@ -3003,7 +3008,7 @@ static struct object_entry *dereference(struct object_entry *oe, unsigned long size; char *buf = NULL; if (!oe) { - enum object_type type = sha1_object_info(oid->hash, NULL); + enum object_type type = oid_object_info(oid, NULL); if (type < 0) die("object not found: %s", oid_to_hex(oid)); /* cache it! */ @@ -3026,7 +3031,7 @@ static struct object_entry *dereference(struct object_entry *oe, buf = gfi_unpack_entry(oe, &size); } else { enum object_type unused; - buf = read_sha1_file(oid->hash, &unused, &size); + buf = read_object_file(oid, &unused, &size); } if (!buf) die("Can't load object %s", oid_to_hex(oid)); @@ -3426,7 +3431,6 @@ int cmd_main(int argc, const char **argv) rc_free[i].next = &rc_free[i + 1]; rc_free[cmd_save - 1].next = NULL; - prepare_packed_git(); start_packfile(); set_die_routine(die_nicely); set_checkpoint_signal(); diff --git a/fetch-pack.c b/fetch-pack.c index 1d6117565c..4a8bad8487 100644 --- a/fetch-pack.c +++ b/fetch-pack.c @@ -1,11 +1,12 @@ #include "cache.h" +#include "repository.h" #include "config.h" #include "lockfile.h" #include "refs.h" #include "pkt-line.h" #include "commit.h" #include "tag.h" -#include "exec_cmd.h" +#include "exec-cmd.h" #include "pack.h" #include "sideband.h" #include "fetch-pack.h" @@ -711,6 +712,28 @@ static void mark_alternate_complete(struct object *obj) mark_complete(&obj->oid); } +struct loose_object_iter { + struct oidset *loose_object_set; + struct ref *refs; +}; + +/* + * If the number of refs is not larger than the number of loose objects, + * this function stops inserting. + */ +static int add_loose_objects_to_set(const struct object_id *oid, + const char *path, + void *data) +{ + struct loose_object_iter *iter = data; + oidset_insert(iter->loose_object_set, oid); + if (iter->refs == NULL) + return 1; + + iter->refs = iter->refs->next; + return 0; +} + static int everything_local(struct fetch_pack_args *args, struct ref **refs, struct ref **sought, int nr_sought) @@ -719,16 +742,31 @@ static int everything_local(struct fetch_pack_args *args, int retval; int old_save_commit_buffer = save_commit_buffer; timestamp_t cutoff = 0; + struct oidset loose_oid_set = OIDSET_INIT; + int use_oidset = 0; + struct loose_object_iter iter = {&loose_oid_set, *refs}; + + /* Enumerate all loose objects or know refs are not so many. */ + use_oidset = !for_each_loose_object(add_loose_objects_to_set, + &iter, 0); save_commit_buffer = 0; for (ref = *refs; ref; ref = ref->next) { struct object *o; + unsigned int flags = OBJECT_INFO_QUICK; - if (!has_object_file_with_flags(&ref->old_oid, - OBJECT_INFO_QUICK)) - continue; + if (use_oidset && + !oidset_contains(&loose_oid_set, &ref->old_oid)) { + /* + * I know this does not exist in the loose form, + * so check if it exists in a non-loose form. + */ + flags |= OBJECT_INFO_IGNORE_LOOSE; + } + if (!has_object_file_with_flags(&ref->old_oid, flags)) + continue; o = parse_object(&ref->old_oid); if (!o) continue; @@ -744,6 +782,8 @@ static int everything_local(struct fetch_pack_args *args, } } + oidset_clear(&loose_oid_set); + if (!args->no_dependents) { if (!args->deepen) { for_each_ref(mark_complete_oid, NULL); @@ -1201,7 +1241,7 @@ struct ref *fetch_pack(struct fetch_pack_args *args, prepare_shallow_info(&si, shallow); ref_cpy = do_fetch_pack(args, fd, ref, sought, nr_sought, &si, pack_lockfile); - reprepare_packed_git(); + reprepare_packed_git(the_repository); update_shallow(args, sought, nr_sought, &si); clear_shallow_info(&si); return ref_cpy; diff --git a/fsck.c b/fsck.c index 5c8c12dde3..9218c2a643 100644 --- a/fsck.c +++ b/fsck.c @@ -811,7 +811,7 @@ static int fsck_tag_buffer(struct tag *tag, const char *data, enum object_type type; buffer = to_free = - read_sha1_file(tag->object.oid.hash, &type, &size); + read_object_file(&tag->object.oid, &type, &size); if (!buffer) return report(options, &tag->object, FSCK_MSG_MISSING_TAG_OBJECT, diff --git a/fsmonitor.c b/fsmonitor.c index 6d7bcd5d0e..ed3d1a074d 100644 --- a/fsmonitor.c +++ b/fsmonitor.c @@ -104,7 +104,7 @@ static int query_fsmonitor(int version, uint64_t last_update, struct strbuf *que if (!(argv[0] = core_fsmonitor)) return -1; - snprintf(ver, sizeof(version), "%d", version); + snprintf(ver, sizeof(ver), "%d", version); snprintf(date, sizeof(date), "%" PRIuMAX, (uintmax_t)last_update); argv[1] = ver; argv[2] = date; @@ -185,6 +185,9 @@ void refresh_fsmonitor(struct index_state *istate) for (i = 0; i < istate->cache_nr; i++) istate->cache[i]->ce_flags &= ~CE_FSMONITOR_VALID; + /* If we're going to check every file, ensure we save the results */ + istate->cache_changed |= FSMONITOR_CHANGED; + if (istate->untracked) istate->untracked->use_fsmonitor = 0; } diff --git a/git-add--interactive.perl b/git-add--interactive.perl index d190469cd8..c1f52e457f 100755 --- a/git-add--interactive.perl +++ b/git-add--interactive.perl @@ -1564,7 +1564,7 @@ sub patch_update_file { error_msg __("No other hunks to search\n"); next; } - if ($1 eq "") { + if ($regex eq "") { print colored $prompt_color, __("search for regex? "); $regex = ; if (defined $regex) { diff --git a/git-filter-branch.sh b/git-filter-branch.sh index 98c76ec589..64f21547c1 100755 --- a/git-filter-branch.sh +++ b/git-filter-branch.sh @@ -251,8 +251,18 @@ done < "$tempdir"/backup-refs # The refs should be updated if their heads were rewritten git rev-parse --no-flags --revs-only --symbolic-full-name \ - --default HEAD "$@" > "$tempdir"/raw-heads || exit -sed -e '/^^/d' "$tempdir"/raw-heads >"$tempdir"/heads + --default HEAD "$@" > "$tempdir"/raw-refs || exit +while read ref +do + case "$ref" in ^?*) continue ;; esac + + if git rev-parse --verify "$ref"^0 >/dev/null 2>&1 + then + echo "$ref" + else + warn "WARNING: not rewriting '$ref' (not a committish)" + fi +done >"$tempdir"/heads <"$tempdir"/raw-refs test -s "$tempdir"/heads || die "You must specify a ref to rewrite." @@ -310,7 +320,7 @@ git rev-list --reverse --topo-order --default HEAD \ die "Could not get the commits" commits=$(wc -l <../revs | tr -d " ") -test $commits -eq 0 && die "Found nothing to rewrite" +test $commits -eq 0 && die_with_status 2 "Found nothing to rewrite" # Rewrite the commits report_progress () diff --git a/git-gui/git-gui.sh b/git-gui/git-gui.sh index 91c00e6489..6de74ce639 100755 --- a/git-gui/git-gui.sh +++ b/git-gui/git-gui.sh @@ -3867,6 +3867,7 @@ bind . <$M1B-Key-equal> {show_more_context;break} bind . <$M1B-Key-plus> {show_more_context;break} bind . <$M1B-Key-KP_Add> {show_more_context;break} bind . <$M1B-Key-Return> do_commit +bind . <$M1B-Key-KP_Enter> do_commit foreach i [list $ui_index $ui_workdir] { bind $i { toggle_or_diff click %W %x %y; break } bind $i <$M1B-Button-1> { add_one_to_selection %W %x %y; break } diff --git a/git-gui/lib/sshkey.tcl b/git-gui/lib/sshkey.tcl index aa6457bbb5..589ff8f78a 100644 --- a/git-gui/lib/sshkey.tcl +++ b/git-gui/lib/sshkey.tcl @@ -2,7 +2,10 @@ # Copyright (C) 2006, 2007 Shawn Pearce proc find_ssh_key {} { - foreach name {~/.ssh/id_dsa.pub ~/.ssh/id_rsa.pub ~/.ssh/identity.pub} { + foreach name { + ~/.ssh/id_dsa.pub ~/.ssh/id_ecdsa.pub ~/.ssh/id_ed25519.pub + ~/.ssh/id_rsa.pub ~/.ssh/identity.pub + } { if {[file exists $name]} { set fh [open $name r] set cont [read $fh] diff --git a/git-gui/lib/themed.tcl b/git-gui/lib/themed.tcl index 351a712c8c..88b3119a75 100644 --- a/git-gui/lib/themed.tcl +++ b/git-gui/lib/themed.tcl @@ -1,6 +1,14 @@ # Functions for supporting the use of themed Tk widgets in git-gui. # Copyright (C) 2009 Pat Thoyts +proc ttk_get_current_theme {} { + # Handle either current Tk or older versions of 8.5 + if {[catch {set theme [ttk::style theme use]}]} { + set theme $::ttk::currentTheme + } + return $theme +} + proc InitTheme {} { # Create a color label style (bg can be overridden by widget option) ttk::style layout Color.TLabel { @@ -28,10 +36,7 @@ proc InitTheme {} { } } - # Handle either current Tk or older versions of 8.5 - if {[catch {set theme [ttk::style theme use]}]} { - set theme $::ttk::currentTheme - } + set theme [ttk_get_current_theme] if {[lsearch -exact {default alt classic clam} $theme] != -1} { # Simple override of standard ttk::entry to change the field @@ -248,7 +253,7 @@ proc tspinbox {w args} { proc ttext {w args} { global use_ttk if {$use_ttk} { - switch -- [ttk::style theme use] { + switch -- [ttk_get_current_theme] { "vista" - "xpnative" { lappend args -highlightthickness 0 -borderwidth 0 } diff --git a/git-rebase--am.sh b/git-rebase--am.sh index be3f068922..99b8c17787 100644 --- a/git-rebase--am.sh +++ b/git-rebase--am.sh @@ -4,15 +4,6 @@ # Copyright (c) 2010 Junio C Hamano. # -# The whole contents of this file is run by dot-sourcing it from -# inside a shell function. It used to be that "return"s we see -# below were not inside any function, and expected to return -# to the function that dot-sourced us. -# -# However, older (9.x) versions of FreeBSD /bin/sh misbehave on such a -# construct and continue to run the statements that follow such a "return". -# As a work-around, we introduce an extra layer of a function -# here, and immediately call it after defining it. git_rebase__am () { case "$action" in @@ -41,60 +32,47 @@ else fi ret=0 -if test -n "$keep_empty" -then - # we have to do this the hard way. git format-patch completely squashes - # empty commits and even if it didn't the format doesn't really lend - # itself well to recording empty patches. fortunately, cherry-pick - # makes this easy - git cherry-pick ${gpg_sign_opt:+"$gpg_sign_opt"} --allow-empty \ - $allow_rerere_autoupdate --right-only "$revisions" \ - $allow_empty_message \ - ${restrict_revision+^$restrict_revision} - ret=$? -else - rm -f "$GIT_DIR/rebased-patches" +rm -f "$GIT_DIR/rebased-patches" - git format-patch -k --stdout --full-index --cherry-pick --right-only \ - --src-prefix=a/ --dst-prefix=b/ --no-renames --no-cover-letter \ - --pretty=mboxrd \ - $git_format_patch_opt \ - "$revisions" ${restrict_revision+^$restrict_revision} \ - >"$GIT_DIR/rebased-patches" - ret=$? +git format-patch -k --stdout --full-index --cherry-pick --right-only \ + --src-prefix=a/ --dst-prefix=b/ --no-renames --no-cover-letter \ + --pretty=mboxrd \ + $git_format_patch_opt \ + "$revisions" ${restrict_revision+^$restrict_revision} \ + >"$GIT_DIR/rebased-patches" +ret=$? - if test 0 != $ret - then - rm -f "$GIT_DIR/rebased-patches" - case "$head_name" in - refs/heads/*) - git checkout -q "$head_name" - ;; - *) - git checkout -q "$orig_head" - ;; - esac +if test 0 != $ret +then + rm -f "$GIT_DIR/rebased-patches" + case "$head_name" in + refs/heads/*) + git checkout -q "$head_name" + ;; + *) + git checkout -q "$orig_head" + ;; + esac - cat >&2 <<-EOF + cat >&2 <<-EOF - git encountered an error while preparing the patches to replay - these revisions: + git encountered an error while preparing the patches to replay + these revisions: - $revisions + $revisions - As a result, git cannot rebase them. - EOF - return $ret - fi + As a result, git cannot rebase them. + EOF + return $ret +fi - git am $git_am_opt --rebasing --resolvemsg="$resolvemsg" \ - --patch-format=mboxrd \ - $allow_rerere_autoupdate \ - ${gpg_sign_opt:+"$gpg_sign_opt"} <"$GIT_DIR/rebased-patches" - ret=$? +git am $git_am_opt --rebasing --resolvemsg="$resolvemsg" \ + --patch-format=mboxrd \ + $allow_rerere_autoupdate \ + ${gpg_sign_opt:+"$gpg_sign_opt"} <"$GIT_DIR/rebased-patches" +ret=$? - rm -f "$GIT_DIR/rebased-patches" -fi +rm -f "$GIT_DIR/rebased-patches" if test 0 != $ret then @@ -105,5 +83,3 @@ fi move_to_original_branch } -# ... and then we call the whole thing. -git_rebase__am diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index 331c8dfeac..9947e6265f 100644 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -285,7 +285,7 @@ pick_one () { pick_one_preserving_merges "$@" && return output eval git cherry-pick $allow_rerere_autoupdate $allow_empty_message \ ${gpg_sign_opt:+$(git rev-parse --sq-quote "$gpg_sign_opt")} \ - "$strategy_args" $empty_args $ff "$@" + $signoff "$strategy_args" $empty_args $ff "$@" # If cherry-pick dies it leaves the to-be-picked commit unrecorded. Reschedule # previous task so this commit is not lost. @@ -307,17 +307,14 @@ pick_one_preserving_merges () { esac sha1=$(git rev-parse $sha1) - if test -f "$state_dir"/current-commit + if test -f "$state_dir"/current-commit && test "$fast_forward" = t then - if test "$fast_forward" = t - then - while read current_commit - do - git rev-parse HEAD > "$rewritten"/$current_commit - done <"$state_dir"/current-commit - rm "$state_dir"/current-commit || - die "$(gettext "Cannot write current commit's replacement sha1")" - fi + while read current_commit + do + git rev-parse HEAD > "$rewritten"/$current_commit + done <"$state_dir"/current-commit + rm "$state_dir"/current-commit || + die "$(gettext "Cannot write current commit's replacement sha1")" fi echo $sha1 >> "$state_dir"/current-commit @@ -527,10 +524,10 @@ do_pick () { # resolve before manually running git commit --amend then git # rebase --continue. git commit --allow-empty --allow-empty-message --amend \ - --no-post-rewrite -n -q -C $sha1 && + --no-post-rewrite -n -q -C $sha1 $signoff && pick_one -n $sha1 && git commit --allow-empty --allow-empty-message \ - --amend --no-post-rewrite -n -q -C $sha1 \ + --amend --no-post-rewrite -n -q -C $sha1 $signoff \ ${gpg_sign_opt:+"$gpg_sign_opt"} || die_with_patch $sha1 "$(eval_gettext "Could not apply \$sha1... \$rest")" else @@ -743,37 +740,39 @@ get_missing_commit_check_level () { printf '%s' "$check_level" | tr 'A-Z' 'a-z' } -# The whole contents of this file is run by dot-sourcing it from -# inside a shell function. It used to be that "return"s we see -# below were not inside any function, and expected to return -# to the function that dot-sourced us. +# Initiate an action. If the cannot be any +# further action it may exec a command +# or exit and not return. # -# However, older (9.x) versions of FreeBSD /bin/sh misbehave on such a -# construct and continue to run the statements that follow such a "return". -# As a work-around, we introduce an extra layer of a function -# here, and immediately call it after defining it. -git_rebase__interactive () { - -case "$action" in -continue) - if test ! -d "$rewritten" - then - exec git rebase--helper ${force_rebase:+--no-ff} $allow_empty_message \ - --continue - fi - # do we have anything to commit? - if git diff-index --cached --quiet HEAD -- - then - # Nothing to commit -- skip this commit - - test ! -f "$GIT_DIR"/CHERRY_PICK_HEAD || - rm "$GIT_DIR"/CHERRY_PICK_HEAD || - die "$(gettext "Could not remove CHERRY_PICK_HEAD")" - else - if ! test -f "$author_script" +# TODO: Consider a cleaner return model so it +# never exits and always return 0 if process +# is complete. +# +# Parameter 1 is the action to initiate. +# +# Returns 0 if the action was able to complete +# and if 1 if further processing is required. +initiate_action () { + case "$1" in + continue) + if test ! -d "$rewritten" + then + exec git rebase--helper ${force_rebase:+--no-ff} $allow_empty_message \ + --continue + fi + # do we have anything to commit? + if git diff-index --cached --quiet HEAD -- then - gpg_sign_opt_quoted=${gpg_sign_opt:+$(git rev-parse --sq-quote "$gpg_sign_opt")} - die "$(eval_gettext "\ + # Nothing to commit -- skip this commit + + test ! -f "$GIT_DIR"/CHERRY_PICK_HEAD || + rm "$GIT_DIR"/CHERRY_PICK_HEAD || + die "$(gettext "Could not remove CHERRY_PICK_HEAD")" + else + if ! test -f "$author_script" + then + gpg_sign_opt_quoted=${gpg_sign_opt:+$(git rev-parse --sq-quote "$gpg_sign_opt")} + die "$(eval_gettext "\ You have staged changes in your working tree. If these changes are meant to be squashed into the previous commit, run: @@ -788,88 +787,199 @@ In both cases, once you're done, continue with: git rebase --continue ")" - fi - . "$author_script" || - die "$(gettext "Error trying to find the author identity to amend commit")" - if test -f "$amend" - then - current_head=$(git rev-parse --verify HEAD) - test "$current_head" = $(cat "$amend") || - die "$(gettext "\ + fi + . "$author_script" || + die "$(gettext "Error trying to find the author identity to amend commit")" + if test -f "$amend" + then + current_head=$(git rev-parse --verify HEAD) + test "$current_head" = $(cat "$amend") || + die "$(gettext "\ You have uncommitted changes in your working tree. Please commit them first and then run 'git rebase --continue' again.")" - do_with_author git commit --amend --no-verify -F "$msg" -e \ - ${gpg_sign_opt:+"$gpg_sign_opt"} $allow_empty_message || - die "$(gettext "Could not commit staged changes.")" - else - do_with_author git commit --no-verify -F "$msg" -e \ - ${gpg_sign_opt:+"$gpg_sign_opt"} $allow_empty_message || - die "$(gettext "Could not commit staged changes.")" + do_with_author git commit --amend --no-verify -F "$msg" -e \ + ${gpg_sign_opt:+"$gpg_sign_opt"} $allow_empty_message || + die "$(gettext "Could not commit staged changes.")" + else + do_with_author git commit --no-verify -F "$msg" -e \ + ${gpg_sign_opt:+"$gpg_sign_opt"} $allow_empty_message || + die "$(gettext "Could not commit staged changes.")" + fi fi - fi - if test -r "$state_dir"/stopped-sha + if test -r "$state_dir"/stopped-sha + then + record_in_rewritten "$(cat "$state_dir"/stopped-sha)" + fi + + require_clean_work_tree "rebase" + do_rest + return 0 + ;; + skip) + git rerere clear + + if test ! -d "$rewritten" + then + exec git rebase--helper ${force_rebase:+--no-ff} $allow_empty_message \ + --continue + fi + do_rest + return 0 + ;; + edit-todo) + git stripspace --strip-comments <"$todo" >"$todo".new + mv -f "$todo".new "$todo" + collapse_todo_ids + append_todo_help + gettext " +You are editing the todo file of an ongoing interactive rebase. +To continue rebase after editing, run: + git rebase --continue + +" | git stripspace --comment-lines >>"$todo" + + git_sequence_editor "$todo" || + die "$(gettext "Could not execute editor")" + expand_todo_ids + + exit + ;; + show-current-patch) + exec git show REBASE_HEAD -- + ;; + *) + return 1 # continue + ;; + esac +} + +setup_reflog_action () { + comment_for_reflog start + + if test ! -z "$switch_to" then - record_in_rewritten "$(cat "$state_dir"/stopped-sha)" + GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION: checkout $switch_to" + output git checkout "$switch_to" -- || + die "$(eval_gettext "Could not checkout \$switch_to")" + + comment_for_reflog start fi +} - require_clean_work_tree "rebase" - do_rest - return 0 - ;; -skip) - git rerere clear +init_basic_state () { + orig_head=$(git rev-parse --verify HEAD) || die "$(gettext "No HEAD?")" + mkdir -p "$state_dir" || die "$(eval_gettext "Could not create temporary \$state_dir")" + rm -f "$(git rev-parse --git-path REBASE_HEAD)" - if test ! -d "$rewritten" + : > "$state_dir"/interactive || die "$(gettext "Could not mark as interactive")" + write_basic_state +} + +init_revisions_and_shortrevisions () { + shorthead=$(git rev-parse --short $orig_head) + shortonto=$(git rev-parse --short $onto) + if test -z "$rebase_root" + # this is now equivalent to ! -z "$upstream" then - exec git rebase--helper ${force_rebase:+--no-ff} $allow_empty_message \ - --continue + shortupstream=$(git rev-parse --short $upstream) + revisions=$upstream...$orig_head + shortrevisions=$shortupstream..$shorthead + else + revisions=$onto...$orig_head + shortrevisions=$shorthead fi - do_rest - return 0 - ;; -edit-todo) - git stripspace --strip-comments <"$todo" >"$todo".new - mv -f "$todo".new "$todo" - collapse_todo_ids +} + +complete_action() { + test -s "$todo" || echo noop >> "$todo" + test -z "$autosquash" || git rebase--helper --rearrange-squash || exit + test -n "$cmd" && git rebase--helper --add-exec-commands "$cmd" + + todocount=$(git stripspace --strip-comments <"$todo" | wc -l) + todocount=${todocount##* } + +cat >>"$todo" <>"$todo" + + if test -z "$keep_empty" + then + printf '%s\n' "$comment_char $(gettext "Note that empty commits are commented out")" >>"$todo" + fi -" | git stripspace --comment-lines >>"$todo" + has_action "$todo" || + return 2 + + cp "$todo" "$todo".backup + collapse_todo_ids git_sequence_editor "$todo" || - die "$(gettext "Could not execute editor")" + die_abort "$(gettext "Could not execute editor")" + + has_action "$todo" || + return 2 + + git rebase--helper --check-todo-list || { + ret=$? + checkout_onto + exit $ret + } + expand_todo_ids - exit - ;; -show-current-patch) - exec git show REBASE_HEAD -- - ;; -esac + test -d "$rewritten" || test -n "$force_rebase" || + onto="$(git rebase--helper --skip-unnecessary-picks)" || + die "Could not skip unnecessary pick commands" -comment_for_reflog start + checkout_onto + if test -z "$rebase_root" && test ! -d "$rewritten" + then + require_clean_work_tree "rebase" + exec git rebase--helper ${force_rebase:+--no-ff} $allow_empty_message \ + --continue + fi + do_rest +} -if test ! -z "$switch_to" -then - GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION: checkout $switch_to" - output git checkout "$switch_to" -- || - die "$(eval_gettext "Could not checkout \$switch_to")" +git_rebase__interactive () { + initiate_action "$action" + ret=$? + if test $ret = 0; then + return 0 + fi - comment_for_reflog start -fi + setup_reflog_action + init_basic_state -orig_head=$(git rev-parse --verify HEAD) || die "$(gettext "No HEAD?")" -mkdir -p "$state_dir" || die "$(eval_gettext "Could not create temporary \$state_dir")" -rm -f "$(git rev-parse --git-path REBASE_HEAD)" + init_revisions_and_shortrevisions + + git rebase--helper --make-script ${keep_empty:+--keep-empty} \ + $revisions ${restrict_revision+^$restrict_revision} >"$todo" || + die "$(gettext "Could not generate todo list")" + + complete_action +} + +git_rebase__interactive__preserve_merges () { + initiate_action "$action" + ret=$? + if test $ret = 0; then + return 0 + fi + + setup_reflog_action + init_basic_state -: > "$state_dir"/interactive || die "$(gettext "Could not mark as interactive")" -write_basic_state -if test t = "$preserve_merges" -then if test -z "$rebase_root" then mkdir "$rewritten" && @@ -883,41 +993,17 @@ then echo $onto > "$rewritten"/root || die "$(gettext "Could not init rewritten commits")" fi - # No cherry-pick because our first pass is to determine - # parents to rewrite and skipping dropped commits would - # prematurely end our probe - merges_option= -else - merges_option="--no-merges --cherry-pick" -fi - -shorthead=$(git rev-parse --short $orig_head) -shortonto=$(git rev-parse --short $onto) -if test -z "$rebase_root" - # this is now equivalent to ! -z "$upstream" -then - shortupstream=$(git rev-parse --short $upstream) - revisions=$upstream...$orig_head - shortrevisions=$shortupstream..$shorthead -else - revisions=$onto...$orig_head - shortrevisions=$shorthead -fi -if test t != "$preserve_merges" -then - git rebase--helper --make-script ${keep_empty:+--keep-empty} \ - $revisions ${restrict_revision+^$restrict_revision} >"$todo" || - die "$(gettext "Could not generate todo list")" -else + + init_revisions_and_shortrevisions + format=$(git config --get rebase.instructionFormat) # the 'rev-list .. | sed' requires %m to parse; the instruction requires %H to parse - git rev-list $merges_option --format="%m%H ${format:-%s}" \ + git rev-list --format="%m%H ${format:-%s}" \ --reverse --left-right --topo-order \ $revisions ${restrict_revision+^$restrict_revision} | \ sed -n "s/^>//p" | while read -r sha1 rest do - if test -z "$keep_empty" && is_empty_commit $sha1 && ! is_merge_commit $sha1 then comment_out="$comment_char " @@ -944,11 +1030,8 @@ else printf '%s\n' "${comment_out}pick $sha1 $rest" >>"$todo" fi done -fi -# Watch for commits that been dropped by --cherry-pick -if test t = "$preserve_merges" -then + # Watch for commits that been dropped by --cherry-pick mkdir "$dropped" # Save all non-cherry-picked changes git rev-list $revisions --left-right --cherry-pick | \ @@ -971,66 +1054,6 @@ then rm "$rewritten"/$rev fi done -fi - -test -s "$todo" || echo noop >> "$todo" -test -z "$autosquash" || git rebase--helper --rearrange-squash || exit -test -n "$cmd" && git rebase--helper --add-exec-commands "$cmd" - -todocount=$(git stripspace --strip-comments <"$todo" | wc -l) -todocount=${todocount##* } - -cat >>"$todo" <>"$todo" - -if test -z "$keep_empty" -then - printf '%s\n' "$comment_char $(gettext "Note that empty commits are commented out")" >>"$todo" -fi - - -has_action "$todo" || - return 2 - -cp "$todo" "$todo".backup -collapse_todo_ids -git_sequence_editor "$todo" || - die_abort "$(gettext "Could not execute editor")" - -has_action "$todo" || - return 2 - -git rebase--helper --check-todo-list || { - ret=$? - checkout_onto - exit $ret -} - -expand_todo_ids - -test -d "$rewritten" || test -n "$force_rebase" || -onto="$(git rebase--helper --skip-unnecessary-picks)" || -die "Could not skip unnecessary pick commands" - -checkout_onto -if test -z "$rebase_root" && test ! -d "$rewritten" -then - require_clean_work_tree "rebase" - exec git rebase--helper ${force_rebase:+--no-ff} $allow_empty_message \ - --continue -fi -do_rest + complete_action } -# ... and then we call the whole thing. -git_rebase__interactive diff --git a/git-rebase--merge.sh b/git-rebase--merge.sh index ceb715453c..cf4c042214 100644 --- a/git-rebase--merge.sh +++ b/git-rebase--merge.sh @@ -27,7 +27,7 @@ continue_merge () { cmt=$(cat "$state_dir/current") if ! git diff-index --quiet --ignore-submodules HEAD -- then - if ! git commit ${gpg_sign_opt:+"$gpg_sign_opt"} $allow_empty_message \ + if ! git commit ${gpg_sign_opt:+"$gpg_sign_opt"} $signoff $allow_empty_message \ --no-verify -C "$cmt" then echo "Commit failed, please do not call \"git commit\"" @@ -104,15 +104,6 @@ finish_rb_merge () { say All done. } -# The whole contents of this file is run by dot-sourcing it from -# inside a shell function. It used to be that "return"s we see -# below were not inside any function, and expected to return -# to the function that dot-sourced us. -# -# However, older (9.x) versions of FreeBSD /bin/sh misbehave on such a -# construct and continue to run the statements that follow such a "return". -# As a work-around, we introduce an extra layer of a function -# here, and immediately call it after defining it. git_rebase__merge () { case "$action" in @@ -171,5 +162,3 @@ done finish_rb_merge } -# ... and then we call the whole thing. -git_rebase__merge diff --git a/git-rebase.sh b/git-rebase.sh index a1f6e5de6a..ded5de085a 100755 --- a/git-rebase.sh +++ b/git-rebase.sh @@ -62,6 +62,7 @@ $(gettext 'Resolve all conflicts manually, mark them as resolved with You can instead skip this commit: run "git rebase --skip". To abort and get back to the state before "git rebase", run "git rebase --abort".') " +squash_onto= unset onto unset restrict_revision cmd= @@ -92,6 +93,7 @@ preserve_merges= autosquash= keep_empty= allow_empty_message= +signoff= test "$(git config --bool rebase.autosquash)" = "true" && autosquash=t case "$(git config --bool commit.gpgsign)" in true) gpg_sign_opt=-S ;; @@ -121,6 +123,10 @@ read_basic_state () { allow_rerere_autoupdate="$(cat "$state_dir"/allow_rerere_autoupdate)" test -f "$state_dir"/gpg_sign_opt && gpg_sign_opt="$(cat "$state_dir"/gpg_sign_opt)" + test -f "$state_dir"/signoff && { + signoff="$(cat "$state_dir"/signoff)" + force_rebase=t + } } write_basic_state () { @@ -135,6 +141,7 @@ write_basic_state () { test -n "$allow_rerere_autoupdate" && echo "$allow_rerere_autoupdate" > \ "$state_dir"/allow_rerere_autoupdate test -n "$gpg_sign_opt" && echo "$gpg_sign_opt" > "$state_dir"/gpg_sign_opt + test -n "$signoff" && echo "$signoff" >"$state_dir"/signoff } output () { @@ -197,6 +204,7 @@ run_specific_rebase () { autosquash= fi . git-rebase--$type + git_rebase__$type${preserve_merges:+__preserve_merges} ret=$? if test $ret -eq 0 then @@ -269,6 +277,9 @@ do --allow-empty-message) allow_empty_message=--allow-empty-message ;; + --no-keep-empty) + keep_empty= + ;; --preserve-merges) preserve_merges=t test -z "$interactive_rebase" && interactive_rebase=implied @@ -331,7 +342,13 @@ do --ignore-whitespace) git_am_opt="$git_am_opt $1" ;; - --committer-date-is-author-date|--ignore-date|--signoff|--no-signoff) + --signoff) + signoff=--signoff + ;; + --no-signoff) + signoff= + ;; + --committer-date-is-author-date|--ignore-date) git_am_opt="$git_am_opt $1" force_rebase=t ;; @@ -447,6 +464,11 @@ then test -z "$interactive_rebase" && interactive_rebase=implied fi +if test -n "$keep_empty" +then + test -z "$interactive_rebase" && interactive_rebase=implied +fi + if test -n "$interactive_rebase" then type=interactive @@ -465,6 +487,14 @@ then git_format_patch_opt="$git_format_patch_opt --progress" fi +if test -n "$signoff" +then + test -n "$preserve_merges" && + die "$(gettext "error: cannot combine '--signoff' with '--preserve-merges'")" + git_am_opt="$git_am_opt $signoff" + force_rebase=t +fi + if test -z "$rebase_root" then case "$#" in diff --git a/git-stash.sh b/git-stash.sh index fc8f8ae640..94793c1a91 100755 --- a/git-stash.sh +++ b/git-stash.sh @@ -39,7 +39,7 @@ fi no_changes () { git diff-index --quiet --cached HEAD --ignore-submodules -- "$@" && git diff-files --quiet --ignore-submodules -- "$@" && - (test -z "$untracked" || test -z "$(untracked_files)") + (test -z "$untracked" || test -z "$(untracked_files "$@")") } untracked_files () { @@ -315,16 +315,18 @@ push_stash () { if test -z "$patch_mode" then test "$untracked" = "all" && CLEAN_X_OPTION=-x || CLEAN_X_OPTION= - if test -n "$untracked" + if test -n "$untracked" && test $# = 0 then - git clean --force --quiet -d $CLEAN_X_OPTION -- "$@" + git clean --force --quiet -d $CLEAN_X_OPTION fi if test $# != 0 then - git add -u -- "$@" | - git checkout-index -z --force --stdin - git diff-index -p --cached --binary HEAD -- "$@" | git apply --index -R + test -z "$untracked" && UPDATE_OPTION="-u" || UPDATE_OPTION= + test "$untracked" = "all" && FORCE_OPTION="--force" || FORCE_OPTION= + git add $UPDATE_OPTION $FORCE_OPTION -- "$@" + git diff-index -p --cached --binary HEAD -- "$@" | + git apply --index -R else git reset --hard -q fi diff --git a/git-svn.perl b/git-svn.perl index a6b6c3e40c..050f2a36f4 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -374,7 +374,8 @@ sub term_init { usage(1) unless defined $cmd; load_authors() if $_authors; if (defined $_authors_prog) { - $_authors_prog = "'" . File::Spec->rel2abs($_authors_prog) . "'"; + my $abs_file = File::Spec->rel2abs($_authors_prog); + $_authors_prog = "'" . $abs_file . "'" if -x $abs_file; } unless ($cmd =~ /^(?:clone|init|multi-init|commit-diff)$/) { diff --git a/git.c b/git.c index ceaa58ef40..f598fae7b7 100644 --- a/git.c +++ b/git.c @@ -1,9 +1,27 @@ #include "builtin.h" #include "config.h" -#include "exec_cmd.h" +#include "exec-cmd.h" #include "help.h" #include "run-command.h" +#define RUN_SETUP (1<<0) +#define RUN_SETUP_GENTLY (1<<1) +#define USE_PAGER (1<<2) +/* + * require working tree to be present -- anything uses this needs + * RUN_SETUP for reading from the configuration file. + */ +#define NEED_WORK_TREE (1<<3) +#define SUPPORT_SUPER_PREFIX (1<<4) +#define DELAY_PAGER_CONFIG (1<<5) +#define NO_PARSEOPT (1<<6) /* parse-options is not used */ + +struct cmd_struct { + const char *cmd; + int (*fn)(int, const char **, const char *); + unsigned int option; +}; + const char git_usage_string[] = N_("git [--version] [--help] [-C ] [-c =]\n" " [--exec-path[=]] [--html-path] [--man-path] [--info-path]\n" @@ -18,7 +36,7 @@ const char git_more_info_string[] = static int use_pager = -1; -static void list_builtins(void); +static void list_builtins(unsigned int exclude_option, char sep); static void commit_pager_choice(void) { switch (use_pager) { @@ -206,7 +224,10 @@ static int handle_options(const char ***argv, int *argc, int *envchanged) (*argv)++; (*argc)--; } else if (!strcmp(cmd, "--list-builtins")) { - list_builtins(); + list_builtins(0, '\n'); + exit(0); + } else if (!strcmp(cmd, "--list-parseopt-builtins")) { + list_builtins(NO_PARSEOPT, ' '); exit(0); } else { fprintf(stderr, _("unknown option: %s\n"), cmd); @@ -288,23 +309,6 @@ static int handle_alias(int *argcp, const char ***argv) return ret; } -#define RUN_SETUP (1<<0) -#define RUN_SETUP_GENTLY (1<<1) -#define USE_PAGER (1<<2) -/* - * require working tree to be present -- anything uses this needs - * RUN_SETUP for reading from the configuration file. - */ -#define NEED_WORK_TREE (1<<3) -#define SUPPORT_SUPER_PREFIX (1<<4) -#define DELAY_PAGER_CONFIG (1<<5) - -struct cmd_struct { - const char *cmd; - int (*fn)(int, const char **, const char *); - int option; -}; - static int run_builtin(struct cmd_struct *p, int argc, const char **argv) { int status, help; @@ -367,18 +371,18 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv) static struct cmd_struct commands[] = { { "add", cmd_add, RUN_SETUP | NEED_WORK_TREE }, { "am", cmd_am, RUN_SETUP | NEED_WORK_TREE }, - { "annotate", cmd_annotate, RUN_SETUP }, + { "annotate", cmd_annotate, RUN_SETUP | NO_PARSEOPT }, { "apply", cmd_apply, RUN_SETUP_GENTLY }, { "archive", cmd_archive, RUN_SETUP_GENTLY }, { "bisect--helper", cmd_bisect__helper, RUN_SETUP }, { "blame", cmd_blame, RUN_SETUP }, { "branch", cmd_branch, RUN_SETUP | DELAY_PAGER_CONFIG }, - { "bundle", cmd_bundle, RUN_SETUP_GENTLY }, + { "bundle", cmd_bundle, RUN_SETUP_GENTLY | NO_PARSEOPT }, { "cat-file", cmd_cat_file, RUN_SETUP }, { "check-attr", cmd_check_attr, RUN_SETUP }, { "check-ignore", cmd_check_ignore, RUN_SETUP | NEED_WORK_TREE }, { "check-mailmap", cmd_check_mailmap, RUN_SETUP }, - { "check-ref-format", cmd_check_ref_format }, + { "check-ref-format", cmd_check_ref_format, NO_PARSEOPT }, { "checkout", cmd_checkout, RUN_SETUP | NEED_WORK_TREE }, { "checkout-index", cmd_checkout_index, RUN_SETUP | NEED_WORK_TREE}, @@ -388,30 +392,30 @@ static struct cmd_struct commands[] = { { "clone", cmd_clone }, { "column", cmd_column, RUN_SETUP_GENTLY }, { "commit", cmd_commit, RUN_SETUP | NEED_WORK_TREE }, - { "commit-tree", cmd_commit_tree, RUN_SETUP }, + { "commit-tree", cmd_commit_tree, RUN_SETUP | NO_PARSEOPT }, { "config", cmd_config, RUN_SETUP_GENTLY | DELAY_PAGER_CONFIG }, { "count-objects", cmd_count_objects, RUN_SETUP }, - { "credential", cmd_credential, RUN_SETUP_GENTLY }, + { "credential", cmd_credential, RUN_SETUP_GENTLY | NO_PARSEOPT }, { "describe", cmd_describe, RUN_SETUP }, - { "diff", cmd_diff }, - { "diff-files", cmd_diff_files, RUN_SETUP | NEED_WORK_TREE }, - { "diff-index", cmd_diff_index, RUN_SETUP }, - { "diff-tree", cmd_diff_tree, RUN_SETUP }, + { "diff", cmd_diff, NO_PARSEOPT }, + { "diff-files", cmd_diff_files, RUN_SETUP | NEED_WORK_TREE | NO_PARSEOPT }, + { "diff-index", cmd_diff_index, RUN_SETUP | NO_PARSEOPT }, + { "diff-tree", cmd_diff_tree, RUN_SETUP | NO_PARSEOPT }, { "difftool", cmd_difftool, RUN_SETUP | NEED_WORK_TREE }, { "fast-export", cmd_fast_export, RUN_SETUP }, { "fetch", cmd_fetch, RUN_SETUP }, - { "fetch-pack", cmd_fetch_pack, RUN_SETUP }, + { "fetch-pack", cmd_fetch_pack, RUN_SETUP | NO_PARSEOPT }, { "fmt-merge-msg", cmd_fmt_merge_msg, RUN_SETUP }, { "for-each-ref", cmd_for_each_ref, RUN_SETUP }, { "format-patch", cmd_format_patch, RUN_SETUP }, { "fsck", cmd_fsck, RUN_SETUP }, { "fsck-objects", cmd_fsck, RUN_SETUP }, { "gc", cmd_gc, RUN_SETUP }, - { "get-tar-commit-id", cmd_get_tar_commit_id }, + { "get-tar-commit-id", cmd_get_tar_commit_id, NO_PARSEOPT }, { "grep", cmd_grep, RUN_SETUP_GENTLY }, { "hash-object", cmd_hash_object }, { "help", cmd_help }, - { "index-pack", cmd_index_pack, RUN_SETUP_GENTLY }, + { "index-pack", cmd_index_pack, RUN_SETUP_GENTLY | NO_PARSEOPT }, { "init", cmd_init_db }, { "init-db", cmd_init_db }, { "interpret-trailers", cmd_interpret_trailers, RUN_SETUP_GENTLY }, @@ -419,27 +423,27 @@ static struct cmd_struct commands[] = { { "ls-files", cmd_ls_files, RUN_SETUP }, { "ls-remote", cmd_ls_remote, RUN_SETUP_GENTLY }, { "ls-tree", cmd_ls_tree, RUN_SETUP }, - { "mailinfo", cmd_mailinfo, RUN_SETUP_GENTLY }, - { "mailsplit", cmd_mailsplit }, + { "mailinfo", cmd_mailinfo, RUN_SETUP_GENTLY | NO_PARSEOPT }, + { "mailsplit", cmd_mailsplit, NO_PARSEOPT }, { "merge", cmd_merge, RUN_SETUP | NEED_WORK_TREE }, { "merge-base", cmd_merge_base, RUN_SETUP }, { "merge-file", cmd_merge_file, RUN_SETUP_GENTLY }, - { "merge-index", cmd_merge_index, RUN_SETUP }, - { "merge-ours", cmd_merge_ours, RUN_SETUP }, - { "merge-recursive", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE }, - { "merge-recursive-ours", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE }, - { "merge-recursive-theirs", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE }, - { "merge-subtree", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE }, - { "merge-tree", cmd_merge_tree, RUN_SETUP }, - { "mktag", cmd_mktag, RUN_SETUP }, + { "merge-index", cmd_merge_index, RUN_SETUP | NO_PARSEOPT }, + { "merge-ours", cmd_merge_ours, RUN_SETUP | NO_PARSEOPT }, + { "merge-recursive", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE | NO_PARSEOPT }, + { "merge-recursive-ours", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE | NO_PARSEOPT }, + { "merge-recursive-theirs", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE | NO_PARSEOPT }, + { "merge-subtree", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE | NO_PARSEOPT }, + { "merge-tree", cmd_merge_tree, RUN_SETUP | NO_PARSEOPT }, + { "mktag", cmd_mktag, RUN_SETUP | NO_PARSEOPT }, { "mktree", cmd_mktree, RUN_SETUP }, { "mv", cmd_mv, RUN_SETUP | NEED_WORK_TREE }, { "name-rev", cmd_name_rev, RUN_SETUP }, { "notes", cmd_notes, RUN_SETUP }, { "pack-objects", cmd_pack_objects, RUN_SETUP }, - { "pack-redundant", cmd_pack_redundant, RUN_SETUP }, + { "pack-redundant", cmd_pack_redundant, RUN_SETUP | NO_PARSEOPT }, { "pack-refs", cmd_pack_refs, RUN_SETUP }, - { "patch-id", cmd_patch_id, RUN_SETUP_GENTLY }, + { "patch-id", cmd_patch_id, RUN_SETUP_GENTLY | NO_PARSEOPT }, { "pickaxe", cmd_blame, RUN_SETUP }, { "prune", cmd_prune, RUN_SETUP }, { "prune-packed", cmd_prune_packed, RUN_SETUP }, @@ -450,14 +454,14 @@ static struct cmd_struct commands[] = { { "receive-pack", cmd_receive_pack }, { "reflog", cmd_reflog, RUN_SETUP }, { "remote", cmd_remote, RUN_SETUP }, - { "remote-ext", cmd_remote_ext }, - { "remote-fd", cmd_remote_fd }, + { "remote-ext", cmd_remote_ext, NO_PARSEOPT }, + { "remote-fd", cmd_remote_fd, NO_PARSEOPT }, { "repack", cmd_repack, RUN_SETUP }, { "replace", cmd_replace, RUN_SETUP }, { "rerere", cmd_rerere, RUN_SETUP }, { "reset", cmd_reset, RUN_SETUP }, - { "rev-list", cmd_rev_list, RUN_SETUP }, - { "rev-parse", cmd_rev_parse }, + { "rev-list", cmd_rev_list, RUN_SETUP | NO_PARSEOPT }, + { "rev-parse", cmd_rev_parse, NO_PARSEOPT }, { "revert", cmd_revert, RUN_SETUP | NEED_WORK_TREE }, { "rm", cmd_rm, RUN_SETUP }, { "send-pack", cmd_send_pack, RUN_SETUP }, @@ -468,23 +472,23 @@ static struct cmd_struct commands[] = { { "stage", cmd_add, RUN_SETUP | NEED_WORK_TREE }, { "status", cmd_status, RUN_SETUP | NEED_WORK_TREE }, { "stripspace", cmd_stripspace }, - { "submodule--helper", cmd_submodule__helper, RUN_SETUP | SUPPORT_SUPER_PREFIX}, + { "submodule--helper", cmd_submodule__helper, RUN_SETUP | SUPPORT_SUPER_PREFIX | NO_PARSEOPT }, { "symbolic-ref", cmd_symbolic_ref, RUN_SETUP }, { "tag", cmd_tag, RUN_SETUP | DELAY_PAGER_CONFIG }, - { "unpack-file", cmd_unpack_file, RUN_SETUP }, - { "unpack-objects", cmd_unpack_objects, RUN_SETUP }, + { "unpack-file", cmd_unpack_file, RUN_SETUP | NO_PARSEOPT }, + { "unpack-objects", cmd_unpack_objects, RUN_SETUP | NO_PARSEOPT }, { "update-index", cmd_update_index, RUN_SETUP }, { "update-ref", cmd_update_ref, RUN_SETUP }, { "update-server-info", cmd_update_server_info, RUN_SETUP }, - { "upload-archive", cmd_upload_archive }, - { "upload-archive--writer", cmd_upload_archive_writer }, - { "var", cmd_var, RUN_SETUP_GENTLY }, + { "upload-archive", cmd_upload_archive, NO_PARSEOPT }, + { "upload-archive--writer", cmd_upload_archive_writer, NO_PARSEOPT }, + { "var", cmd_var, RUN_SETUP_GENTLY | NO_PARSEOPT }, { "verify-commit", cmd_verify_commit, RUN_SETUP }, { "verify-pack", cmd_verify_pack }, { "verify-tag", cmd_verify_tag, RUN_SETUP }, { "version", cmd_version }, { "whatchanged", cmd_whatchanged, RUN_SETUP }, - { "worktree", cmd_worktree, RUN_SETUP }, + { "worktree", cmd_worktree, RUN_SETUP | NO_PARSEOPT }, { "write-tree", cmd_write_tree, RUN_SETUP }, }; @@ -504,11 +508,15 @@ int is_builtin(const char *s) return !!get_builtin(s); } -static void list_builtins(void) +static void list_builtins(unsigned int exclude_option, char sep) { int i; - for (i = 0; i < ARRAY_SIZE(commands); i++) - printf("%s\n", commands[i].cmd); + for (i = 0; i < ARRAY_SIZE(commands); i++) { + if (exclude_option && + (commands[i].option & exclude_option)) + continue; + printf("%s%c", commands[i].cmd, sep); + } } #ifdef STRIP_EXTENSION diff --git a/grep.c b/grep.c index 834b8eb439..65b90c10a3 100644 --- a/grep.c +++ b/grep.c @@ -2015,7 +2015,7 @@ static int grep_source_load_oid(struct grep_source *gs) enum object_type type; grep_read_lock(); - gs->buf = read_sha1_file(gs->identifier, &type, &gs->size); + gs->buf = read_object_file(gs->identifier, &type, &gs->size); grep_read_unlock(); if (!gs->buf) diff --git a/help.c b/help.c index 60071a9bea..a4feef2ffe 100644 --- a/help.c +++ b/help.c @@ -1,7 +1,7 @@ #include "cache.h" #include "config.h" #include "builtin.h" -#include "exec_cmd.h" +#include "exec-cmd.h" #include "run-command.h" #include "levenshtein.h" #include "help.h" diff --git a/http-backend.c b/http-backend.c index f3dc218b2a..cc16cd04ad 100644 --- a/http-backend.c +++ b/http-backend.c @@ -1,15 +1,17 @@ #include "cache.h" #include "config.h" +#include "repository.h" #include "refs.h" #include "pkt-line.h" #include "object.h" #include "tag.h" -#include "exec_cmd.h" +#include "exec-cmd.h" #include "run-command.h" #include "string-list.h" #include "url.h" #include "argv-array.h" #include "packfile.h" +#include "object-store.h" static const char content_type[] = "Content-Type"; static const char content_length[] = "Content-Length"; @@ -517,14 +519,13 @@ static void get_info_packs(struct strbuf *hdr, char *arg) size_t cnt = 0; select_getanyfile(hdr); - prepare_packed_git(); - for (p = packed_git; p; p = p->next) { + for (p = get_packed_git(the_repository); p; p = p->next) { if (p->pack_local) cnt++; } strbuf_grow(&buf, cnt * 53 + 2); - for (p = packed_git; p; p = p->next) { + for (p = get_packed_git(the_repository); p; p = p->next) { if (p->pack_local) strbuf_addf(&buf, "P %s\n", p->pack_name + objdirlen + 6); } diff --git a/http-fetch.c b/http-fetch.c index 8af380050c..885e471501 100644 --- a/http-fetch.c +++ b/http-fetch.c @@ -1,6 +1,6 @@ #include "cache.h" #include "config.h" -#include "exec_cmd.h" +#include "exec-cmd.h" #include "http.h" #include "walker.h" diff --git a/http-push.c b/http-push.c index 7dcd9daf62..f308ce0195 100644 --- a/http-push.c +++ b/http-push.c @@ -6,12 +6,13 @@ #include "refs.h" #include "diff.h" #include "revision.h" -#include "exec_cmd.h" +#include "exec-cmd.h" #include "remote.h" #include "list-objects.h" #include "sigchain.h" #include "argv-array.h" #include "packfile.h" +#include "object-store.h" #ifdef EXPAT_NEEDS_XMLPARSE_H #include @@ -361,7 +362,7 @@ static void start_put(struct transfer_request *request) ssize_t size; git_zstream stream; - unpacked = read_sha1_file(request->obj->oid.hash, &type, &len); + unpacked = read_object_file(&request->obj->oid, &type, &len); hdrlen = xsnprintf(hdr, sizeof(hdr), "%s %lu", type_name(type), len) + 1; /* Set it up */ diff --git a/http-walker.c b/http-walker.c index 07c2b1af82..7cdfb2f24c 100644 --- a/http-walker.c +++ b/http-walker.c @@ -1,10 +1,12 @@ #include "cache.h" +#include "repository.h" #include "commit.h" #include "walker.h" #include "http.h" #include "list.h" #include "transport.h" #include "packfile.h" +#include "object-store.h" struct alt_base { char *base; @@ -22,7 +24,7 @@ enum object_request_state { struct object_request { struct walker *walker; - unsigned char sha1[20]; + struct object_id oid; struct alt_base *repo; enum object_request_state state; struct http_object_request *req; @@ -56,7 +58,7 @@ static void start_object_request(struct walker *walker, struct active_request_slot *slot; struct http_object_request *req; - req = new_http_object_request(obj_req->repo->base, obj_req->sha1); + req = new_http_object_request(obj_req->repo->base, obj_req->oid.hash); if (req == NULL) { obj_req->state = ABORTED; return; @@ -82,7 +84,7 @@ static void finish_object_request(struct object_request *obj_req) return; if (obj_req->req->rename == 0) - walker_say(obj_req->walker, "got %s\n", sha1_to_hex(obj_req->sha1)); + walker_say(obj_req->walker, "got %s\n", oid_to_hex(&obj_req->oid)); } static void process_object_response(void *callback_data) @@ -129,7 +131,7 @@ static int fill_active_slot(struct walker *walker) list_for_each_safe(pos, tmp, head) { obj_req = list_entry(pos, struct object_request, node); if (obj_req->state == WAITING) { - if (has_sha1_file(obj_req->sha1)) + if (has_sha1_file(obj_req->oid.hash)) obj_req->state = COMPLETE; else { start_object_request(walker, obj_req); @@ -148,7 +150,7 @@ static void prefetch(struct walker *walker, unsigned char *sha1) newreq = xmalloc(sizeof(*newreq)); newreq->walker = walker; - hashcpy(newreq->sha1, sha1); + hashcpy(newreq->oid.hash, sha1); newreq->repo = data->alt; newreq->state = WAITING; newreq->req = NULL; @@ -481,13 +483,13 @@ static int fetch_object(struct walker *walker, unsigned char *sha1) list_for_each(pos, head) { obj_req = list_entry(pos, struct object_request, node); - if (!hashcmp(obj_req->sha1, sha1)) + if (!hashcmp(obj_req->oid.hash, sha1)) break; } if (obj_req == NULL) return error("Couldn't find request for %s in the queue", hex); - if (has_sha1_file(obj_req->sha1)) { + if (has_sha1_file(obj_req->oid.hash)) { if (obj_req->req != NULL) abort_http_object_request(obj_req->req); abort_object_request(obj_req); @@ -541,11 +543,11 @@ static int fetch_object(struct walker *walker, unsigned char *sha1) } else if (req->zret != Z_STREAM_END) { walker->corrupt_object_found++; ret = error("File %s (%s) corrupt", hex, req->url); - } else if (hashcmp(obj_req->sha1, req->real_sha1)) { + } else if (hashcmp(obj_req->oid.hash, req->real_sha1)) { ret = error("File %s has bad hash", hex); } else if (req->rename < 0) { struct strbuf buf = STRBUF_INIT; - sha1_file_name(&buf, req->sha1); + sha1_file_name(the_repository, &buf, req->sha1); ret = error("unable to write sha1 filename %s", buf.buf); strbuf_release(&buf); } diff --git a/http.c b/http.c index a5bd5d62c2..3034d10b68 100644 --- a/http.c +++ b/http.c @@ -14,6 +14,7 @@ #include "packfile.h" #include "protocol.h" #include "string-list.h" +#include "object-store.h" static struct trace_key trace_curl = TRACE_KEY_INIT(CURL); static int trace_curl_data = 1; @@ -62,6 +63,9 @@ static struct { { "tlsv1.1", CURL_SSLVERSION_TLSv1_1 }, { "tlsv1.2", CURL_SSLVERSION_TLSv1_2 }, #endif +#if LIBCURL_VERSION_NUM >= 0x073400 + { "tlsv1.3", CURL_SSLVERSION_TLSv1_3 }, +#endif }; #if LIBCURL_VERSION_NUM >= 0x070903 static const char *ssl_key; @@ -2135,7 +2139,7 @@ int finish_http_pack_request(struct http_pack_request *preq) return -1; } - install_packed_git(p); + install_packed_git(the_repository, p); free(tmp_idx); return 0; } @@ -2248,7 +2252,7 @@ struct http_object_request *new_http_object_request(const char *base_url, hashcpy(freq->sha1, sha1); freq->localfile = -1; - sha1_file_name(&filename, sha1); + sha1_file_name(the_repository, &filename, sha1); snprintf(freq->tmpfile, sizeof(freq->tmpfile), "%s.temp", filename.buf); @@ -2397,8 +2401,7 @@ int finish_http_object_request(struct http_object_request *freq) unlink_or_warn(freq->tmpfile); return -1; } - - sha1_file_name(&filename, freq->sha1); + sha1_file_name(the_repository, &filename, freq->sha1); freq->rename = finalize_object_file(freq->tmpfile, filename.buf); strbuf_release(&filename); diff --git a/imap-send.c b/imap-send.c index ffb0a6eca8..3573cbfb0f 100644 --- a/imap-send.c +++ b/imap-send.c @@ -24,7 +24,7 @@ #include "cache.h" #include "config.h" #include "credential.h" -#include "exec_cmd.h" +#include "exec-cmd.h" #include "run-command.h" #include "parse-options.h" #ifdef NO_OPENSSL diff --git a/line-log.c b/line-log.c index cdc2257db5..ecdce08c4b 100644 --- a/line-log.c +++ b/line-log.c @@ -501,8 +501,7 @@ static void fill_blob_sha1(struct commit *commit, struct diff_filespec *spec) unsigned mode; struct object_id oid; - if (get_tree_entry(commit->object.oid.hash, spec->path, - oid.hash, &mode)) + if (get_tree_entry(&commit->object.oid, spec->path, &oid, &mode)) die("There is no path %s in the commit", spec->path); fill_filespec(spec, &oid, 1, mode); diff --git a/list-objects-filter.c b/list-objects-filter.c index 4356c45368..247717561f 100644 --- a/list-objects-filter.c +++ b/list-objects-filter.c @@ -19,7 +19,7 @@ * in the traversal (until we mark it SEEN). This is a way to * let us silently de-dup calls to show() in the caller. This * is subtly different from the "revision.h:SHOWN" and the - * "sha1_name.c:ONELINE_SEEN" bits. And also different from + * "sha1-name.c:ONELINE_SEEN" bits. And also different from * the non-de-dup usage in pack-bitmap.c */ #define FILTER_SHOWN_BUT_REVISIT (1<<21) @@ -117,7 +117,7 @@ static enum list_objects_filter_result filter_blobs_limit( assert(obj->type == OBJ_BLOB); assert((obj->flags & SEEN) == 0); - t = sha1_object_info(obj->oid.hash, &object_length); + t = oid_object_info(&obj->oid, &object_length); if (t != OBJ_BLOB) { /* probably OBJ_NONE */ /* * We DO NOT have the blob locally, so we cannot diff --git a/log-tree.c b/log-tree.c index bdf23c5f7b..d1c0bedf24 100644 --- a/log-tree.c +++ b/log-tree.c @@ -177,7 +177,7 @@ static void show_parents(struct commit *commit, int abbrev, FILE *file) struct commit_list *p; for (p = commit->parents; p ; p = p->next) { struct commit *parent = p->item; - fprintf(file, " %s", find_unique_abbrev(parent->object.oid.hash, abbrev)); + fprintf(file, " %s", find_unique_abbrev(&parent->object.oid, abbrev)); } } @@ -185,7 +185,7 @@ static void show_children(struct rev_info *opt, struct commit *commit, int abbre { struct commit_list *p = lookup_decoration(&opt->children, &commit->object); for ( ; p; p = p->next) { - fprintf(opt->diffopt.file, " %s", find_unique_abbrev(p->item->object.oid.hash, abbrev)); + fprintf(opt->diffopt.file, " %s", find_unique_abbrev(&p->item->object.oid, abbrev)); } } @@ -558,7 +558,7 @@ void show_log(struct rev_info *opt) if (!opt->graph) put_revision_mark(opt, commit); - fputs(find_unique_abbrev(commit->object.oid.hash, abbrev_commit), opt->diffopt.file); + fputs(find_unique_abbrev(&commit->object.oid, abbrev_commit), opt->diffopt.file); if (opt->print_parents) show_parents(commit, abbrev_commit, opt->diffopt.file); if (opt->children.name) @@ -620,7 +620,8 @@ void show_log(struct rev_info *opt) if (!opt->graph) put_revision_mark(opt, commit); - fputs(find_unique_abbrev(commit->object.oid.hash, abbrev_commit), + fputs(find_unique_abbrev(&commit->object.oid, + abbrev_commit), opt->diffopt.file); if (opt->print_parents) show_parents(commit, abbrev_commit, opt->diffopt.file); @@ -628,8 +629,7 @@ void show_log(struct rev_info *opt) show_children(opt, commit, abbrev_commit); if (parent) fprintf(opt->diffopt.file, " (from %s)", - find_unique_abbrev(parent->object.oid.hash, - abbrev_commit)); + find_unique_abbrev(&parent->object.oid, abbrev_commit)); fputs(diff_get_color_opt(&opt->diffopt, DIFF_RESET), opt->diffopt.file); show_decorations(opt, commit); if (opt->commit_format == CMIT_FMT_ONELINE) { diff --git a/mailmap.c b/mailmap.c index cb921b4db6..13f0d2884e 100644 --- a/mailmap.c +++ b/mailmap.c @@ -224,7 +224,7 @@ static int read_mailmap_blob(struct string_list *map, if (get_oid(name, &oid) < 0) return 0; - buf = read_sha1_file(oid.hash, &type, &size); + buf = read_object_file(&oid, &type, &size); if (!buf) return error("unable to read mailmap object at %s", name); if (type != OBJ_BLOB) diff --git a/match-trees.c b/match-trees.c index 0ca99d5162..72cc2baa3f 100644 --- a/match-trees.c +++ b/match-trees.c @@ -54,7 +54,7 @@ static void *fill_tree_desc_strict(struct tree_desc *desc, enum object_type type; unsigned long size; - buffer = read_sha1_file(hash->hash, &type, &size); + buffer = read_object_file(hash, &type, &size); if (!buffer) die("unable to read tree (%s)", oid_to_hex(hash)); if (type != OBJ_TREE) @@ -180,7 +180,7 @@ static int splice_tree(const struct object_id *oid1, const char *prefix, if (*subpath) subpath++; - buf = read_sha1_file(oid1->hash, &type, &sz); + buf = read_object_file(oid1, &type, &sz); if (!buf) die("cannot read tree %s", oid_to_hex(oid1)); init_tree_desc(&desc, buf, sz); @@ -269,7 +269,7 @@ void shift_tree(const struct object_id *hash1, if (!*del_prefix) return; - if (get_tree_entry(hash2->hash, del_prefix, shifted->hash, &mode)) + if (get_tree_entry(hash2, del_prefix, shifted, &mode)) die("cannot find path %s in tree %s", del_prefix, oid_to_hex(hash2)); return; @@ -296,12 +296,12 @@ void shift_tree_by(const struct object_id *hash1, unsigned candidate = 0; /* Can hash2 be a tree at shift_prefix in tree hash1? */ - if (!get_tree_entry(hash1->hash, shift_prefix, sub1.hash, &mode1) && + if (!get_tree_entry(hash1, shift_prefix, &sub1, &mode1) && S_ISDIR(mode1)) candidate |= 1; /* Can hash1 be a tree at shift_prefix in tree hash2? */ - if (!get_tree_entry(hash2->hash, shift_prefix, sub2.hash, &mode2) && + if (!get_tree_entry(hash2, shift_prefix, &sub2, &mode2) && S_ISDIR(mode2)) candidate |= 2; diff --git a/merge-blobs.c b/merge-blobs.c index 9b6eac22e4..fa49c17287 100644 --- a/merge-blobs.c +++ b/merge-blobs.c @@ -11,7 +11,7 @@ static int fill_mmfile_blob(mmfile_t *f, struct blob *obj) unsigned long size; enum object_type type; - buf = read_sha1_file(obj->object.oid.hash, &type, &size); + buf = read_object_file(&obj->object.oid, &type, &size); if (!buf) return -1; if (type != OBJ_BLOB) { @@ -66,7 +66,7 @@ void *merge_blobs(const char *path, struct blob *base, struct blob *our, struct return NULL; if (!our) our = their; - return read_sha1_file(our->object.oid.hash, &type, size); + return read_object_file(&our->object.oid, &type, size); } if (fill_mmfile_blob(&f1, our) < 0) diff --git a/merge-recursive.c b/merge-recursive.c index 869092f7b9..0c0d48624d 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -228,7 +228,7 @@ static void output_commit_title(struct merge_options *o, struct commit *commit) strbuf_addf(&o->obuf, "virtual %s\n", merge_remote_util(commit)->name); else { - strbuf_add_unique_abbrev(&o->obuf, commit->object.oid.hash, + strbuf_add_unique_abbrev(&o->obuf, &commit->object.oid, DEFAULT_ABBREV); strbuf_addch(&o->obuf, ' '); if (parse_commit(commit) != 0) @@ -335,7 +335,7 @@ struct tree *write_tree_from_memory(struct merge_options *o) return result; } -static int save_files_dirs(const unsigned char *sha1, +static int save_files_dirs(const struct object_id *oid, struct strbuf *base, const char *path, unsigned int mode, int stage, void *context) { @@ -370,12 +370,12 @@ static struct stage_data *insert_stage_data(const char *path, { struct string_list_item *item; struct stage_data *e = xcalloc(1, sizeof(struct stage_data)); - get_tree_entry(o->object.oid.hash, path, - e->stages[1].oid.hash, &e->stages[1].mode); - get_tree_entry(a->object.oid.hash, path, - e->stages[2].oid.hash, &e->stages[2].mode); - get_tree_entry(b->object.oid.hash, path, - e->stages[3].oid.hash, &e->stages[3].mode); + get_tree_entry(&o->object.oid, path, + &e->stages[1].oid, &e->stages[1].mode); + get_tree_entry(&a->object.oid, path, + &e->stages[2].oid, &e->stages[2].mode); + get_tree_entry(&b->object.oid, path, + &e->stages[3].oid, &e->stages[3].mode); item = string_list_insert(entries, path); item->util = e; return e; @@ -842,7 +842,7 @@ static int update_file_flags(struct merge_options *o, goto update_index; } - buf = read_sha1_file(oid->hash, &type, &size); + buf = read_object_file(oid, &type, &size); if (!buf) return err(o, _("cannot read object %s '%s'"), oid_to_hex(oid), path); if (type != OBJ_BLOB) { @@ -1656,7 +1656,7 @@ static int read_oid_strbuf(struct merge_options *o, void *buf; enum object_type type; unsigned long size; - buf = read_sha1_file(oid->hash, &type, &size); + buf = read_object_file(oid, &type, &size); if (!buf) return err(o, _("cannot read object %s"), oid_to_hex(oid)); if (type != OBJ_BLOB) { diff --git a/mergetools/guiffy b/mergetools/guiffy new file mode 100644 index 0000000000..8b23a13c41 --- /dev/null +++ b/mergetools/guiffy @@ -0,0 +1,18 @@ +diff_cmd () { + "$merge_tool_path" "$LOCAL" "$REMOTE" +} + +merge_cmd () { + if $base_present + then + "$merge_tool_path" -s "$LOCAL" \ + "$REMOTE" "$BASE" "$MERGED" + else + "$merge_tool_path" -m "$LOCAL" \ + "$REMOTE" "$MERGED" + fi +} + +exit_code_trustable () { + true +} diff --git a/notes-cache.c b/notes-cache.c index 398e61d5e9..e61988e503 100644 --- a/notes-cache.c +++ b/notes-cache.c @@ -77,7 +77,7 @@ char *notes_cache_get(struct notes_cache *c, struct object_id *key_oid, value_oid = get_note(&c->tree, key_oid); if (!value_oid) return NULL; - value = read_sha1_file(value_oid->hash, &type, &size); + value = read_object_file(value_oid, &type, &size); *outsize = size; return value; diff --git a/notes-merge.c b/notes-merge.c index c09c5e0e47..8e0726a941 100644 --- a/notes-merge.c +++ b/notes-merge.c @@ -322,7 +322,7 @@ static void write_note_to_worktree(const struct object_id *obj, { enum object_type type; unsigned long size; - void *buf = read_sha1_file(note->hash, &type, &size); + void *buf = read_object_file(note, &type, &size); if (!buf) die("cannot read note %s for object %s", diff --git a/notes.c b/notes.c index ce9a8f53f8..a386d450c4 100644 --- a/notes.c +++ b/notes.c @@ -796,13 +796,13 @@ int combine_notes_concatenate(struct object_id *cur_oid, /* read in both note blob objects */ if (!is_null_oid(new_oid)) - new_msg = read_sha1_file(new_oid->hash, &new_type, &new_len); + new_msg = read_object_file(new_oid, &new_type, &new_len); if (!new_msg || !new_len || new_type != OBJ_BLOB) { free(new_msg); return 0; } if (!is_null_oid(cur_oid)) - cur_msg = read_sha1_file(cur_oid->hash, &cur_type, &cur_len); + cur_msg = read_object_file(cur_oid, &cur_type, &cur_len); if (!cur_msg || !cur_len || cur_type != OBJ_BLOB) { free(cur_msg); free(new_msg); @@ -858,7 +858,7 @@ static int string_list_add_note_lines(struct string_list *list, return 0; /* read_sha1_file NUL-terminates */ - data = read_sha1_file(oid->hash, &t, &len); + data = read_object_file(oid, &t, &len); if (t != OBJ_BLOB || !data || !len) { free(data); return t != OBJ_BLOB || !data; @@ -1012,7 +1012,7 @@ void init_notes(struct notes_tree *t, const char *notes_ref, return; if (flags & NOTES_INIT_WRITABLE && read_ref(notes_ref, &object_oid)) die("Cannot use notes ref %s", notes_ref); - if (get_tree_entry(object_oid.hash, "", oid.hash, &mode)) + if (get_tree_entry(&object_oid, "", &oid, &mode)) die("Failed to read notes tree referenced by %s (%s)", notes_ref, oid_to_hex(&object_oid)); @@ -1217,7 +1217,7 @@ static void format_note(struct notes_tree *t, const struct object_id *object_oid if (!oid) return; - if (!(msg = read_sha1_file(oid->hash, &type, &msglen)) || type != OBJ_BLOB) { + if (!(msg = read_object_file(oid, &type, &msglen)) || type != OBJ_BLOB) { free(msg); return; } diff --git a/object-store.h b/object-store.h new file mode 100644 index 0000000000..fef33f345f --- /dev/null +++ b/object-store.h @@ -0,0 +1,132 @@ +#ifndef OBJECT_STORE_H +#define OBJECT_STORE_H + +struct alternate_object_database { + struct alternate_object_database *next; + + /* see alt_scratch_buf() */ + struct strbuf scratch; + size_t base_len; + + /* + * Used to store the results of readdir(3) calls when searching + * for unique abbreviated hashes. This cache is never + * invalidated, thus it's racy and not necessarily accurate. + * That's fine for its purpose; don't use it for tasks requiring + * greater accuracy! + */ + char loose_objects_subdir_seen[256]; + struct oid_array loose_objects_cache; + + /* + * Path to the alternative object store. If this is a relative path, + * it is relative to the current working directory. + */ + char path[FLEX_ARRAY]; +}; +void prepare_alt_odb(struct repository *r); +char *compute_alternate_path(const char *path, struct strbuf *err); +typedef int alt_odb_fn(struct alternate_object_database *, void *); +int foreach_alt_odb(alt_odb_fn, void*); + +/* + * Allocate a "struct alternate_object_database" but do _not_ actually + * add it to the list of alternates. + */ +struct alternate_object_database *alloc_alt_odb(const char *dir); + +/* + * Add the directory to the on-disk alternates file; the new entry will also + * take effect in the current process. + */ +void add_to_alternates_file(const char *dir); + +/* + * Add the directory to the in-memory list of alternates (along with any + * recursive alternates it points to), but do not modify the on-disk alternates + * file. + */ +void add_to_alternates_memory(const char *dir); + +/* + * Returns a scratch strbuf pre-filled with the alternate object directory, + * including a trailing slash, which can be used to access paths in the + * alternate. Always use this over direct access to alt->scratch, as it + * cleans up any previous use of the scratch buffer. + */ +struct strbuf *alt_scratch_buf(struct alternate_object_database *alt); + +struct packed_git { + struct packed_git *next; + struct list_head mru; + struct pack_window *windows; + off_t pack_size; + const void *index_data; + size_t index_size; + uint32_t num_objects; + uint32_t num_bad_objects; + unsigned char *bad_object_sha1; + int index_version; + time_t mtime; + int pack_fd; + unsigned pack_local:1, + pack_keep:1, + freshened:1, + do_not_close:1, + pack_promisor:1; + unsigned char sha1[20]; + struct revindex_entry *revindex; + /* something like ".git/objects/pack/xxxxx.pack" */ + char pack_name[FLEX_ARRAY]; /* more */ +}; + +struct raw_object_store { + /* + * Path to the repository's object store. + * Cannot be NULL after initialization. + */ + char *objectdir; + + /* Path to extra alternate object database if not NULL */ + char *alternate_db; + + struct alternate_object_database *alt_odb_list; + struct alternate_object_database **alt_odb_tail; + + /* + * private data + * + * should only be accessed directly by packfile.c + */ + + struct packed_git *packed_git; + /* A most-recently-used ordered version of the packed_git list. */ + struct list_head packed_git_mru; + + /* + * A fast, rough count of the number of objects in the repository. + * These two fields are not meant for direct access. Use + * approximate_object_count() instead. + */ + unsigned long approximate_object_count; + unsigned approximate_object_count_valid : 1; + + /* + * Whether packed_git has already been populated with this repository's + * packs. + */ + unsigned packed_git_initialized : 1; +}; + +struct raw_object_store *raw_object_store_new(void); +void raw_object_store_clear(struct raw_object_store *o); + +/* + * Put in `buf` the name of the file in the local object database that + * would be used to store a loose object with the specified sha1. + */ +void sha1_file_name(struct repository *r, struct strbuf *buf, const unsigned char *sha1); + +void *map_sha1_file(struct repository *r, const unsigned char *sha1, unsigned long *size); + +#endif /* OBJECT_STORE_H */ diff --git a/object.c b/object.c index e6ad3f61f0..a0a756f24f 100644 --- a/object.c +++ b/object.c @@ -4,6 +4,8 @@ #include "tree.h" #include "commit.h" #include "tag.h" +#include "object-store.h" +#include "packfile.h" static struct object **obj_hash; static int nr_objs, obj_hash_size; @@ -244,7 +246,7 @@ struct object *parse_object(const struct object_id *oid) unsigned long size; enum object_type type; int eaten; - const unsigned char *repl = lookup_replace_object(oid->hash); + const struct object_id *repl = lookup_replace_object(oid); void *buffer; struct object *obj; @@ -254,8 +256,8 @@ struct object *parse_object(const struct object_id *oid) if ((obj && obj->type == OBJ_BLOB && has_object_file(oid)) || (!obj && has_object_file(oid) && - sha1_object_info(oid->hash, NULL) == OBJ_BLOB)) { - if (check_sha1_signature(repl, NULL, 0, NULL) < 0) { + oid_object_info(oid, NULL) == OBJ_BLOB)) { + if (check_object_signature(repl, NULL, 0, NULL) < 0) { error("sha1 mismatch %s", oid_to_hex(oid)); return NULL; } @@ -263,11 +265,11 @@ struct object *parse_object(const struct object_id *oid) return lookup_object(oid->hash); } - buffer = read_sha1_file(oid->hash, &type, &size); + buffer = read_object_file(oid, &type, &size); if (buffer) { - if (check_sha1_signature(repl, buffer, size, type_name(type)) < 0) { + if (check_object_signature(repl, buffer, size, type_name(type)) < 0) { free(buffer); - error("sha1 mismatch %s", sha1_to_hex(repl)); + error("sha1 mismatch %s", oid_to_hex(repl)); return NULL; } @@ -445,3 +447,43 @@ void clear_commit_marks_all(unsigned int flags) obj->flags &= ~flags; } } + +struct raw_object_store *raw_object_store_new(void) +{ + struct raw_object_store *o = xmalloc(sizeof(*o)); + + memset(o, 0, sizeof(*o)); + INIT_LIST_HEAD(&o->packed_git_mru); + return o; +} + +static void free_alt_odb(struct alternate_object_database *alt) +{ + strbuf_release(&alt->scratch); + oid_array_clear(&alt->loose_objects_cache); + free(alt); +} + +static void free_alt_odbs(struct raw_object_store *o) +{ + while (o->alt_odb_list) { + struct alternate_object_database *next; + + next = o->alt_odb_list->next; + free_alt_odb(o->alt_odb_list); + o->alt_odb_list = next; + } +} + +void raw_object_store_clear(struct raw_object_store *o) +{ + FREE_AND_NULL(o->objectdir); + FREE_AND_NULL(o->alternate_db); + + free_alt_odbs(o); + o->alt_odb_tail = NULL; + + INIT_LIST_HEAD(&o->packed_git_mru); + close_all_packs(o); + o->packed_git = NULL; +} diff --git a/object.h b/object.h index f13f85b2a9..b8e70e5519 100644 --- a/object.h +++ b/object.h @@ -37,7 +37,7 @@ struct object_array { * bundle.c: 16 * http-push.c: 16-----19 * commit.c: 16-----19 - * sha1_name.c: 20 + * sha1-name.c: 20 * list-objects-filter.c: 21 * builtin/fsck.c: 0--3 * builtin/index-pack.c: 2021 diff --git a/pack-bitmap-write.c b/pack-bitmap-write.c index e01f992884..41ae27fb19 100644 --- a/pack-bitmap-write.c +++ b/pack-bitmap-write.c @@ -73,8 +73,7 @@ void bitmap_writer_build_type_index(struct pack_idx_entry **index, break; default: - real_type = sha1_object_info(entry->idx.oid.hash, - NULL); + real_type = oid_object_info(&entry->idx.oid, NULL); break; } diff --git a/pack-bitmap.c b/pack-bitmap.c index 9270983e5f..3f2dab340f 100644 --- a/pack-bitmap.c +++ b/pack-bitmap.c @@ -10,6 +10,8 @@ #include "pack-revindex.h" #include "pack-objects.h" #include "packfile.h" +#include "repository.h" +#include "object-store.h" /* * An entry on the bitmap index, representing the bitmap for a given @@ -334,8 +336,7 @@ static int open_pack_bitmap(void) assert(!bitmap_git.map && !bitmap_git.loaded); - prepare_packed_git(); - for (p = packed_git; p; p = p->next) { + for (p = get_packed_git(the_repository); p; p = p->next) { if (open_pack_bitmap_1(p) == 0) ret = 0; } diff --git a/pack-check.c b/pack-check.c index 8fc7dd1694..385d964bdd 100644 --- a/pack-check.c +++ b/pack-check.c @@ -3,6 +3,7 @@ #include "pack-revindex.h" #include "progress.h" #include "packfile.h" +#include "object-store.h" struct idx_entry { off_t offset; @@ -126,7 +127,7 @@ static int verify_packfile(struct packed_git *p, if (type == OBJ_BLOB && big_file_threshold <= size) { /* - * Let check_sha1_signature() check it with + * Let check_object_signature() check it with * the streaming interface; no point slurping * the data in-core only to discard. */ @@ -141,7 +142,7 @@ static int verify_packfile(struct packed_git *p, err = error("cannot unpack %s from %s at offset %"PRIuMAX"", oid_to_hex(entries[i].oid.oid), p->pack_name, (uintmax_t)entries[i].offset); - else if (check_sha1_signature(entries[i].oid.hash, data, size, type_name(type))) + else if (check_object_signature(entries[i].oid.oid, data, size, type_name(type))) err = error("packed %s from %s is corrupt", oid_to_hex(entries[i].oid.oid), p->pack_name); else if (fn) { diff --git a/pack-revindex.c b/pack-revindex.c index ff5f62c033..bb521cf7fb 100644 --- a/pack-revindex.c +++ b/pack-revindex.c @@ -1,5 +1,6 @@ #include "cache.h" #include "pack-revindex.h" +#include "object-store.h" /* * Pack index for existing packs give us easy access to the offsets into diff --git a/packfile.c b/packfile.c index 7c1a2519fc..0bc67d0e00 100644 --- a/packfile.c +++ b/packfile.c @@ -1,6 +1,7 @@ #include "cache.h" #include "list.h" #include "pack.h" +#include "repository.h" #include "dir.h" #include "mergesort.h" #include "packfile.h" @@ -13,6 +14,7 @@ #include "tag.h" #include "tree-walk.h" #include "tree.h" +#include "object-store.h" char *odb_pack_name(struct strbuf *buf, const unsigned char *sha1, @@ -44,8 +46,6 @@ static unsigned int pack_open_fds; static unsigned int pack_max_fds; static size_t peak_pack_mapped; static size_t pack_mapped; -struct packed_git *packed_git; -LIST_HEAD(packed_git_mru); #define SZ_FMT PRIuMAX static inline uintmax_t sz_fmt(size_t s) { return s; } @@ -245,7 +245,7 @@ static int unuse_one_window(struct packed_git *current) if (current) scan_windows(current, &lru_p, &lru_w, &lru_l); - for (p = packed_git; p; p = p->next) + for (p = the_repository->objects->packed_git; p; p = p->next) scan_windows(p, &lru_p, &lru_w, &lru_l); if (lru_p) { munmap(lru_w->base, lru_w->len); @@ -311,11 +311,11 @@ static void close_pack(struct packed_git *p) close_pack_index(p); } -void close_all_packs(void) +void close_all_packs(struct raw_object_store *o) { struct packed_git *p; - for (p = packed_git; p; p = p->next) + for (p = o->packed_git; p; p = p->next) if (p->do_not_close) die("BUG: want to close pack marked 'do-not-close'"); else @@ -383,7 +383,7 @@ static int close_one_pack(void) struct pack_window *mru_w = NULL; int accept_windows_inuse = 1; - for (p = packed_git; p; p = p->next) { + for (p = the_repository->objects->packed_git; p; p = p->next) { if (p->pack_fd == -1) continue; find_lru_pack(p, &lru_p, &mru_w, &accept_windows_inuse); @@ -680,13 +680,13 @@ struct packed_git *add_packed_git(const char *path, size_t path_len, int local) return p; } -void install_packed_git(struct packed_git *pack) +void install_packed_git(struct repository *r, struct packed_git *pack) { if (pack->pack_fd != -1) pack_open_fds++; - pack->next = packed_git; - packed_git = pack; + pack->next = r->objects->packed_git; + r->objects->packed_git = pack; } void (*report_garbage)(unsigned seen_bits, const char *path); @@ -735,7 +735,7 @@ static void report_pack_garbage(struct string_list *list) report_helper(list, seen_bits, first, list->nr); } -static void prepare_packed_git_one(char *objdir, int local) +static void prepare_packed_git_one(struct repository *r, char *objdir, int local) { struct strbuf path = STRBUF_INIT; size_t dirnamelen; @@ -768,7 +768,8 @@ static void prepare_packed_git_one(char *objdir, int local) base_len = path.len; if (strip_suffix_mem(path.buf, &base_len, ".idx")) { /* Don't reopen a pack we already have. */ - for (p = packed_git; p; p = p->next) { + for (p = r->objects->packed_git; p; + p = p->next) { size_t len; if (strip_suffix(p->pack_name, ".pack", &len) && len == base_len && @@ -781,7 +782,7 @@ static void prepare_packed_git_one(char *objdir, int local) * corresponding .pack file that we can map. */ (p = add_packed_git(path.buf, path.len, local)) != NULL) - install_packed_git(p); + install_packed_git(r, p); } if (!report_garbage) @@ -802,8 +803,7 @@ static void prepare_packed_git_one(char *objdir, int local) strbuf_release(&path); } -static int approximate_object_count_valid; - +static void prepare_packed_git(struct repository *r); /* * Give a fast, rough count of the number of objects in the repository. This * ignores loose objects completely. If you have a lot of them, then either @@ -813,19 +813,20 @@ static int approximate_object_count_valid; */ unsigned long approximate_object_count(void) { - static unsigned long count; - if (!approximate_object_count_valid) { + if (!the_repository->objects->approximate_object_count_valid) { + unsigned long count; struct packed_git *p; - prepare_packed_git(); + prepare_packed_git(the_repository); count = 0; - for (p = packed_git; p; p = p->next) { + for (p = the_repository->objects->packed_git; p; p = p->next) { if (open_pack_index(p)) continue; count += p->num_objects; } + the_repository->objects->approximate_object_count = count; } - return count; + return the_repository->objects->approximate_object_count; } static void *get_next_packed_git(const void *p) @@ -866,43 +867,55 @@ static int sort_pack(const void *a_, const void *b_) return -1; } -static void rearrange_packed_git(void) +static void rearrange_packed_git(struct repository *r) { - packed_git = llist_mergesort(packed_git, get_next_packed_git, - set_next_packed_git, sort_pack); + r->objects->packed_git = llist_mergesort( + r->objects->packed_git, get_next_packed_git, + set_next_packed_git, sort_pack); } -static void prepare_packed_git_mru(void) +static void prepare_packed_git_mru(struct repository *r) { struct packed_git *p; - INIT_LIST_HEAD(&packed_git_mru); + INIT_LIST_HEAD(&r->objects->packed_git_mru); - for (p = packed_git; p; p = p->next) - list_add_tail(&p->mru, &packed_git_mru); + for (p = r->objects->packed_git; p; p = p->next) + list_add_tail(&p->mru, &r->objects->packed_git_mru); } -static int prepare_packed_git_run_once = 0; -void prepare_packed_git(void) +static void prepare_packed_git(struct repository *r) { struct alternate_object_database *alt; - if (prepare_packed_git_run_once) + if (r->objects->packed_git_initialized) return; - prepare_packed_git_one(get_object_directory(), 1); - prepare_alt_odb(); - for (alt = alt_odb_list; alt; alt = alt->next) - prepare_packed_git_one(alt->path, 0); - rearrange_packed_git(); - prepare_packed_git_mru(); - prepare_packed_git_run_once = 1; + prepare_packed_git_one(r, r->objects->objectdir, 1); + prepare_alt_odb(r); + for (alt = r->objects->alt_odb_list; alt; alt = alt->next) + prepare_packed_git_one(r, alt->path, 0); + rearrange_packed_git(r); + prepare_packed_git_mru(r); + r->objects->packed_git_initialized = 1; +} + +void reprepare_packed_git(struct repository *r) +{ + r->objects->approximate_object_count_valid = 0; + r->objects->packed_git_initialized = 0; + prepare_packed_git(r); +} + +struct packed_git *get_packed_git(struct repository *r) +{ + prepare_packed_git(r); + return r->objects->packed_git; } -void reprepare_packed_git(void) +struct list_head *get_packed_git_mru(struct repository *r) { - approximate_object_count_valid = 0; - prepare_packed_git_run_once = 0; - prepare_packed_git(); + prepare_packed_git(r); + return &r->objects->packed_git_mru; } unsigned long unpack_object_header_buffer(const unsigned char *buf, @@ -1013,7 +1026,7 @@ const struct packed_git *has_packed_and_bad(const unsigned char *sha1) struct packed_git *p; unsigned i; - for (p = packed_git; p; p = p->next) + for (p = the_repository->objects->packed_git; p; p = p->next) for (i = 0; i < p->num_bad_objects; i++) if (!hashcmp(sha1, p->bad_object_sha1 + 20 * i)) return p; @@ -1095,13 +1108,13 @@ static int retry_bad_packed_offset(struct packed_git *p, off_t obj_offset) { int type; struct revindex_entry *revidx; - const unsigned char *sha1; + struct object_id oid; revidx = find_pack_revindex(p, obj_offset); if (!revidx) return OBJ_BAD; - sha1 = nth_packed_object_sha1(p, revidx->nr); - mark_bad_packed_object(p, sha1); - type = sha1_object_info(sha1, NULL); + nth_packed_object_oid(&oid, p, revidx->nr); + mark_bad_packed_object(p, oid.hash); + type = oid_object_info(&oid, NULL); if (type <= OBJ_NONE) return OBJ_BAD; return type; @@ -1452,7 +1465,7 @@ struct unpack_entry_stack_ent { unsigned long size; }; -static void *read_object(const unsigned char *sha1, enum object_type *type, +static void *read_object(const struct object_id *oid, enum object_type *type, unsigned long *size) { struct object_info oi = OBJECT_INFO_INIT; @@ -1461,7 +1474,7 @@ static void *read_object(const unsigned char *sha1, enum object_type *type, oi.sizep = size; oi.contentp = &content; - if (sha1_object_info_extended(sha1, &oi, 0) < 0) + if (oid_object_info_extended(oid, &oi, 0) < 0) return NULL; return content; } @@ -1501,11 +1514,11 @@ void *unpack_entry(struct packed_git *p, off_t obj_offset, struct revindex_entry *revidx = find_pack_revindex(p, obj_offset); off_t len = revidx[1].offset - obj_offset; if (check_pack_crc(p, &w_curs, obj_offset, len, revidx->nr)) { - const unsigned char *sha1 = - nth_packed_object_sha1(p, revidx->nr); + struct object_id oid; + nth_packed_object_oid(&oid, p, revidx->nr); error("bad packed object CRC for %s", - sha1_to_hex(sha1)); - mark_bad_packed_object(p, sha1); + oid_to_hex(&oid)); + mark_bad_packed_object(p, oid.hash); data = NULL; goto out; } @@ -1588,16 +1601,16 @@ void *unpack_entry(struct packed_git *p, off_t obj_offset, * of a corrupted pack, and is better than failing outright. */ struct revindex_entry *revidx; - const unsigned char *base_sha1; + struct object_id base_oid; revidx = find_pack_revindex(p, obj_offset); if (revidx) { - base_sha1 = nth_packed_object_sha1(p, revidx->nr); + nth_packed_object_oid(&base_oid, p, revidx->nr); error("failed to read delta base object %s" " at offset %"PRIuMAX" from %s", - sha1_to_hex(base_sha1), (uintmax_t)obj_offset, + oid_to_hex(&base_oid), (uintmax_t)obj_offset, p->pack_name); - mark_bad_packed_object(p, base_sha1); - base = read_object(base_sha1, &type, &base_size); + mark_bad_packed_object(p, base_oid.hash); + base = read_object(&base_oid, &type, &base_size); external_base = base; } } @@ -1654,6 +1667,29 @@ void *unpack_entry(struct packed_git *p, off_t obj_offset, return data; } +int bsearch_pack(const struct object_id *oid, const struct packed_git *p, uint32_t *result) +{ + const unsigned char *index_fanout = p->index_data; + const unsigned char *index_lookup; + int index_lookup_width; + + if (!index_fanout) + BUG("bsearch_pack called without a valid pack-index"); + + index_lookup = index_fanout + 4 * 256; + if (p->index_version == 1) { + index_lookup_width = 24; + index_lookup += 4; + } else { + index_lookup_width = 20; + index_fanout += 8; + index_lookup += 8; + } + + return bsearch_hash(oid->hash, (const uint32_t*)index_fanout, + index_lookup, index_lookup_width, result); +} + const unsigned char *nth_packed_object_sha1(struct packed_git *p, uint32_t n) { @@ -1720,30 +1756,17 @@ off_t nth_packed_object_offset(const struct packed_git *p, uint32_t n) off_t find_pack_entry_one(const unsigned char *sha1, struct packed_git *p) { - const uint32_t *level1_ofs = p->index_data; const unsigned char *index = p->index_data; - unsigned stride; + struct object_id oid; uint32_t result; if (!index) { if (open_pack_index(p)) return 0; - level1_ofs = p->index_data; - index = p->index_data; - } - if (p->index_version > 1) { - level1_ofs += 2; - index += 8; - } - index += 4 * 256; - if (p->index_version > 1) { - stride = 20; - } else { - stride = 24; - index += 4; } - if (bsearch_hash(sha1, level1_ofs, index, stride, &result)) + hashcpy(oid.hash, sha1); + if (bsearch_pack(&oid, p, &result)) return nth_packed_object_offset(p, result); return 0; } @@ -1814,22 +1837,18 @@ static int fill_pack_entry(const unsigned char *sha1, return 1; } -/* - * Iff a pack file contains the object named by sha1, return true and - * store its location to e. - */ -int find_pack_entry(const unsigned char *sha1, struct pack_entry *e) +int find_pack_entry(struct repository *r, const unsigned char *sha1, struct pack_entry *e) { struct list_head *pos; - prepare_packed_git(); - if (!packed_git) + prepare_packed_git(r); + if (!r->objects->packed_git) return 0; - list_for_each(pos, &packed_git_mru) { + list_for_each(pos, &r->objects->packed_git_mru) { struct packed_git *p = list_entry(pos, struct packed_git, mru); if (fill_pack_entry(sha1, e, p)) { - list_move(&p->mru, &packed_git_mru); + list_move(&p->mru, &r->objects->packed_git_mru); return 1; } } @@ -1839,7 +1858,7 @@ int find_pack_entry(const unsigned char *sha1, struct pack_entry *e) int has_sha1_pack(const unsigned char *sha1) { struct pack_entry e; - return find_pack_entry(sha1, &e); + return find_pack_entry(the_repository, sha1, &e); } int has_pack_index(const unsigned char *sha1) @@ -1875,8 +1894,8 @@ int for_each_packed_object(each_packed_object_fn cb, void *data, unsigned flags) int r = 0; int pack_errors = 0; - prepare_packed_git(); - for (p = packed_git; p; p = p->next) { + prepare_packed_git(the_repository); + for (p = the_repository->objects->packed_git; p; p = p->next) { if ((flags & FOR_EACH_OBJECT_LOCAL_ONLY) && !p->pack_local) continue; if ((flags & FOR_EACH_OBJECT_PROMISOR_ONLY) && @@ -1907,7 +1926,7 @@ static int add_promisor_object(const struct object_id *oid, /* * If this is a tree, commit, or tag, the objects it refers - * to are also promisor objects. (Blobs refer to no objects.) + * to are also promisor objects. (Blobs refer to no objects->) */ if (obj->type == OBJ_TREE) { struct tree *tree = (struct tree *)obj; diff --git a/packfile.h b/packfile.h index a7fca598d6..a92c0b241c 100644 --- a/packfile.h +++ b/packfile.h @@ -34,9 +34,11 @@ extern struct packed_git *parse_pack_index(unsigned char *sha1, const char *idx_ #define PACKDIR_FILE_GARBAGE 4 extern void (*report_garbage)(unsigned seen_bits, const char *path); -extern void prepare_packed_git(void); -extern void reprepare_packed_git(void); -extern void install_packed_git(struct packed_git *pack); +extern void reprepare_packed_git(struct repository *r); +extern void install_packed_git(struct repository *r, struct packed_git *pack); + +struct packed_git *get_packed_git(struct repository *r); +struct list_head *get_packed_git_mru(struct repository *r); /* * Give a rough count of objects in the repository. This sacrifices accuracy @@ -63,7 +65,7 @@ extern void close_pack_index(struct packed_git *); extern unsigned char *use_pack(struct packed_git *, struct pack_window **, off_t, unsigned long *); extern void close_pack_windows(struct packed_git *); -extern void close_all_packs(void); +extern void close_all_packs(struct raw_object_store *o); extern void unuse_pack(struct pack_window **); extern void clear_delta_base_cache(void); extern struct packed_git *add_packed_git(const char *path, size_t path_len, int local); @@ -78,6 +80,14 @@ extern struct packed_git *add_packed_git(const char *path, size_t path_len, int */ extern void check_pack_index_ptr(const struct packed_git *p, const void *ptr); +/* + * Perform binary search on a pack-index for a given oid. Packfile is expected to + * have a valid pack-index. + * + * See 'bsearch_hash' for more information. + */ +int bsearch_pack(const struct object_id *oid, const struct packed_git *p, uint32_t *result); + /* * Return the SHA-1 of the nth object within the specified packfile. * Open the index if it is not already open. The return value points @@ -120,7 +130,11 @@ extern int packed_object_info(struct packed_git *pack, off_t offset, struct obje extern void mark_bad_packed_object(struct packed_git *p, const unsigned char *sha1); extern const struct packed_git *has_packed_and_bad(const unsigned char *sha1); -extern int find_pack_entry(const unsigned char *sha1, struct pack_entry *e); +/* + * Iff a pack file in the given repository contains the object named by sha1, + * return true and store its location to e. + */ +extern int find_pack_entry(struct repository *r, const unsigned char *sha1, struct pack_entry *e); extern int has_sha1_pack(const unsigned char *sha1); diff --git a/parse-options.c b/parse-options.c index 125e84f984..0f7059a8ab 100644 --- a/parse-options.c +++ b/parse-options.c @@ -317,14 +317,16 @@ static int parse_long_opt(struct parse_opt_ctx_t *p, const char *arg, return get_value(p, options, all_opts, flags ^ opt_flags); } - if (ambiguous_option) - return error("Ambiguous option: %s " + if (ambiguous_option) { + error("Ambiguous option: %s " "(could be --%s%s or --%s%s)", arg, (ambiguous_flags & OPT_UNSET) ? "no-" : "", ambiguous_option->long_name, (abbrev_flags & OPT_UNSET) ? "no-" : "", abbrev_option->long_name); + return -3; + } if (abbrev_option) return get_value(p, abbrev_option, all_opts, abbrev_flags); return -2; @@ -476,7 +478,6 @@ int parse_options_step(struct parse_opt_ctx_t *ctx, const char * const usagestr[]) { int internal_help = !(ctx->flags & PARSE_OPT_NO_INTERNAL_HELP); - int err = 0; /* we must reset ->opt, unknown short option leave it dangling */ ctx->opt = NULL; @@ -505,7 +506,7 @@ int parse_options_step(struct parse_opt_ctx_t *ctx, ctx->opt = arg + 1; switch (parse_short_opt(ctx, options)) { case -1: - goto show_usage_error; + return PARSE_OPT_ERROR; case -2: if (ctx->opt) check_typos(arg + 1, options); @@ -518,7 +519,7 @@ int parse_options_step(struct parse_opt_ctx_t *ctx, while (ctx->opt) { switch (parse_short_opt(ctx, options)) { case -1: - goto show_usage_error; + return PARSE_OPT_ERROR; case -2: if (internal_help && *ctx->opt == 'h') goto show_usage; @@ -550,9 +551,11 @@ int parse_options_step(struct parse_opt_ctx_t *ctx, goto show_usage; switch (parse_long_opt(ctx, arg + 2, options)) { case -1: - goto show_usage_error; + return PARSE_OPT_ERROR; case -2: goto unknown; + case -3: + goto show_usage; } continue; unknown: @@ -563,10 +566,8 @@ int parse_options_step(struct parse_opt_ctx_t *ctx, } return PARSE_OPT_DONE; - show_usage_error: - err = 1; show_usage: - return usage_with_options_internal(ctx, usagestr, options, 0, err); + return usage_with_options_internal(ctx, usagestr, options, 0, 0); } int parse_options_end(struct parse_opt_ctx_t *ctx) @@ -585,6 +586,7 @@ int parse_options(int argc, const char **argv, const char *prefix, parse_options_start(&ctx, argc, argv, prefix, options, flags); switch (parse_options_step(&ctx, options, usagestr)) { case PARSE_OPT_HELP: + case PARSE_OPT_ERROR: exit(129); case PARSE_OPT_NON_OPTION: case PARSE_OPT_DONE: diff --git a/parse-options.h b/parse-options.h index ab1cc362bf..dd14911a29 100644 --- a/parse-options.h +++ b/parse-options.h @@ -200,6 +200,7 @@ enum { PARSE_OPT_HELP = -1, PARSE_OPT_DONE, PARSE_OPT_NON_OPTION, + PARSE_OPT_ERROR, PARSE_OPT_UNKNOWN }; diff --git a/path.c b/path.c index da8b655730..3308b7b958 100644 --- a/path.c +++ b/path.c @@ -10,6 +10,7 @@ #include "submodule-config.h" #include "path.h" #include "packfile.h" +#include "object-store.h" static int get_st_mode_bits(const char *path, int *mode) { @@ -382,7 +383,7 @@ static void adjust_git_path(const struct repository *repo, strbuf_splice(buf, 0, buf->len, repo->index_file, strlen(repo->index_file)); else if (dir_prefix(base, "objects")) - replace_dir(buf, git_dir_len + 7, repo->objectdir); + replace_dir(buf, git_dir_len + 7, repo->objects->objectdir); else if (git_hooks_path && dir_prefix(base, "hooks")) replace_dir(buf, git_dir_len + 5, git_hooks_path); else if (repo->different_commondir) diff --git a/perl/Git/SVN.pm b/perl/Git/SVN.pm index 991a5885e9..76b2965905 100644 --- a/perl/Git/SVN.pm +++ b/perl/Git/SVN.pm @@ -1482,7 +1482,6 @@ sub call_authors_prog { } if ($author =~ /^\s*(.+?)\s*<(.*)>\s*$/) { my ($name, $email) = ($1, $2); - $email = undef if length $2 == 0; return [$name, $email]; } else { die "Author: $orig_author: $::_authors_prog returned " @@ -2020,8 +2019,8 @@ sub make_log_entry { remove_username($full_url); $log_entry{metadata} = "$full_url\@$r $uuid"; $log_entry{svm_revision} = $r; - $email ||= "$author\@$uuid"; - $commit_email ||= "$author\@$uuid"; + $email = "$author\@$uuid" unless defined $email; + $commit_email = "$author\@$uuid" unless defined $commit_email; } elsif ($self->use_svnsync_props) { my $full_url = canonicalize_url( add_path_to_url( $self->svnsync->{url}, $self->path ) @@ -2029,15 +2028,15 @@ sub make_log_entry { remove_username($full_url); my $uuid = $self->svnsync->{uuid}; $log_entry{metadata} = "$full_url\@$rev $uuid"; - $email ||= "$author\@$uuid"; - $commit_email ||= "$author\@$uuid"; + $email = "$author\@$uuid" unless defined $email; + $commit_email = "$author\@$uuid" unless defined $commit_email; } else { my $url = $self->metadata_url; remove_username($url); my $uuid = $self->rewrite_uuid || $self->ra->get_uuid; $log_entry{metadata} = "$url\@$rev " . $uuid; - $email ||= "$author\@" . $uuid; - $commit_email ||= "$author\@" . $uuid; + $email = "$author\@$uuid" unless defined $email; + $commit_email = "$author\@$uuid" unless defined $commit_email; } $log_entry{name} = $name; $log_entry{email} = $email; diff --git a/po/bg.po b/po/bg.po index a37d5df651..48fe3158e5 100644 --- a/po/bg.po +++ b/po/bg.po @@ -70,6 +70,8 @@ # linked checkout свързано изтегляне # term управляваща дума (за git-bisect) # mergetag етикет при сливане +# packfile пакет +# promisory гаратиращ, гарант promisory packfile гарантиращ пакет, promisory remote хранилище-гарант # delta - разлика, делта, обект-разлика # peeled tag - проследен етикет - когато етикет сочи към друг етикет, а не подаване и проследяваме подобно на символна връзка # strip - премахвам (за компонент при филтриране) @@ -88,6 +90,7 @@ # ignored (file) игнориран, понякога - пропуснат # manual, man page ръководство # guide въведение +# partial clone непълно хранилище # ------------------------ # „$var“ - може да не сработва за shell има gettext и eval_gettext - проверка - намират се лесно по „$ # ------------------------ @@ -100,8 +103,8 @@ msgid "" msgstr "" "Project-Id-Version: git master\n" "Report-Msgid-Bugs-To: Git Mailing List \n" -"POT-Creation-Date: 2018-01-07 07:50+0800\n" -"PO-Revision-Date: 2018-01-11 22:01+0100\n" +"POT-Creation-Date: 2018-03-16 07:29+0800\n" +"PO-Revision-Date: 2018-03-16 09:53+0100\n" "Last-Translator: Alexander Shopov \n" "Language-Team: Bulgarian \n" "Language: bg\n" @@ -152,7 +155,7 @@ msgstr "" msgid "Exiting because of an unresolved conflict." msgstr "Изход от програмата заради некоригиран конфликт." -#: advice.c:121 builtin/merge.c:1213 +#: advice.c:121 builtin/merge.c:1251 msgid "You have not concluded your merge (MERGE_HEAD exists)." msgstr "Не сте завършили сливане. (Указателят „MERGE_HEAD“ съществува)." @@ -573,7 +576,7 @@ msgstr "смяна на режима на достъпа на „%s“, койт msgid "sha1 information is lacking or useless (%s)." msgstr "информацията за сумата по SHA1 липсва или не е достатъчна (%s)." -#: apply.c:4095 builtin/checkout.c:236 builtin/reset.c:148 +#: apply.c:4095 builtin/checkout.c:235 builtin/reset.c:140 #, c-format msgid "make_cache_entry failed for path '%s'" msgstr "неуспешно създаване на запис в кеша чрез „make_cache_entry“ за „%s“" @@ -651,7 +654,7 @@ msgstr[1] "Прилагане на кръпката „%%s“ с %d отхвър msgid "truncating .rej filename to %.*s.rej" msgstr "съкращаване на името на файла с отхвърлените парчета на „ %.*s.rej“" -#: apply.c:4545 builtin/fetch.c:761 builtin/fetch.c:1011 +#: apply.c:4545 builtin/fetch.c:775 builtin/fetch.c:1025 #, c-format msgid "cannot open %s" msgstr "„%s“ не може да бъде отворен" @@ -711,11 +714,11 @@ msgstr[1] "" msgid "Unable to write new index file" msgstr "Новият индекс не може да бъде записан" -#: apply.c:4921 apply.c:4924 builtin/am.c:2220 builtin/am.c:2223 -#: builtin/clone.c:116 builtin/fetch.c:116 builtin/pull.c:193 -#: builtin/submodule--helper.c:369 builtin/submodule--helper.c:860 -#: builtin/submodule--helper.c:863 builtin/submodule--helper.c:1230 -#: builtin/submodule--helper.c:1233 builtin/submodule--helper.c:1450 +#: apply.c:4921 apply.c:4924 builtin/am.c:2254 builtin/am.c:2257 +#: builtin/clone.c:118 builtin/fetch.c:127 builtin/pull.c:193 +#: builtin/submodule--helper.c:403 builtin/submodule--helper.c:1197 +#: builtin/submodule--helper.c:1200 builtin/submodule--helper.c:1567 +#: builtin/submodule--helper.c:1570 builtin/submodule--helper.c:1787 #: git-add--interactive.perl:197 msgid "path" msgstr "път" @@ -728,7 +731,7 @@ msgstr "без прилагане на промените напасващи н msgid "apply changes matching the given path" msgstr "прилагане на промените напасващи на дадения път" -#: apply.c:4927 builtin/am.c:2229 +#: apply.c:4927 builtin/am.c:2263 msgid "num" msgstr "БРОЙ" @@ -768,79 +771,79 @@ msgstr "прилагане на кръпката без промяна на ра msgid "accept a patch that touches outside the working area" msgstr "прилагане на кръпка, която променя и файлове извън работното дърво" -#: apply.c:4949 +#: apply.c:4950 msgid "also apply the patch (use with --stat/--summary/--check)" msgstr "" "кръпката да бъде приложена. Опцията се комбинира с „--check“/„--stat“/„--" "summary“" -#: apply.c:4951 +#: apply.c:4952 msgid "attempt three-way merge if a patch does not apply" msgstr "пробване с тройно сливане, ако кръпката не може да се приложи директно" -#: apply.c:4953 +#: apply.c:4954 msgid "build a temporary index based on embedded index information" msgstr "" "създаване на временен индекс на база на включената информация за индекса" -#: apply.c:4956 builtin/checkout-index.c:168 builtin/ls-files.c:515 +#: apply.c:4957 builtin/checkout-index.c:168 builtin/ls-files.c:515 msgid "paths are separated with NUL character" msgstr "разделяне на пътищата с нулевия знак „NUL“" -#: apply.c:4958 +#: apply.c:4959 msgid "ensure at least lines of context match" msgstr "да се осигури контекст от поне такъв БРОЙ съвпадащи редове" -#: apply.c:4959 builtin/am.c:2208 builtin/interpret-trailers.c:95 +#: apply.c:4960 builtin/am.c:2242 builtin/interpret-trailers.c:95 #: builtin/interpret-trailers.c:97 builtin/interpret-trailers.c:99 -#: builtin/pack-objects.c:3009 +#: builtin/pack-objects.c:3035 msgid "action" msgstr "действие" -#: apply.c:4960 +#: apply.c:4961 msgid "detect new or modified lines that have whitespace errors" msgstr "засичане на нови или променени редове с грешки в знаците за интервали" -#: apply.c:4963 apply.c:4966 +#: apply.c:4964 apply.c:4967 msgid "ignore changes in whitespace when finding context" msgstr "" "игнориране на промените в знаците за интервали при откриване на контекста" -#: apply.c:4969 +#: apply.c:4970 msgid "apply the patch in reverse" msgstr "прилагане на кръпката в обратна посока" -#: apply.c:4971 +#: apply.c:4972 msgid "don't expect at least one line of context" msgstr "без изискване на дори и един ред контекст" -#: apply.c:4973 +#: apply.c:4974 msgid "leave the rejected hunks in corresponding *.rej files" msgstr "оставяне на отхвърлените парчета във файлове с разширение „.rej“" -#: apply.c:4975 +#: apply.c:4976 msgid "allow overlapping hunks" msgstr "позволяване на застъпващи се парчета" -#: apply.c:4976 builtin/add.c:292 builtin/check-ignore.c:21 -#: builtin/commit.c:1361 builtin/count-objects.c:96 builtin/fsck.c:640 -#: builtin/log.c:1896 builtin/mv.c:123 builtin/read-tree.c:125 +#: apply.c:4977 builtin/add.c:292 builtin/check-ignore.c:21 +#: builtin/commit.c:1276 builtin/count-objects.c:96 builtin/fsck.c:665 +#: builtin/log.c:1901 builtin/mv.c:123 builtin/read-tree.c:125 msgid "be verbose" msgstr "повече подробности" -#: apply.c:4978 +#: apply.c:4979 msgid "tolerate incorrectly detected missing new-line at the end of file" msgstr "пренебрегване на неправилно липсващ знак за нов ред в края на файл" -#: apply.c:4981 +#: apply.c:4982 msgid "do not trust the line counts in the hunk headers" msgstr "без доверяване на номерата на редовете в заглавните части на парчетата" -#: apply.c:4983 builtin/am.c:2217 +#: apply.c:4984 builtin/am.c:2251 msgid "root" msgstr "НАЧАЛНА_ДИРЕКТОРИЯ" -#: apply.c:4984 +#: apply.c:4985 msgid "prepend to all filenames" msgstr "добавяне на тази НАЧАЛНА_ДИРЕКТОРИЯ към имената на всички файлове" @@ -876,7 +879,7 @@ msgstr "ФОРМАТ" msgid "archive format" msgstr "ФОРМАТ на архива" -#: archive.c:437 builtin/log.c:1459 +#: archive.c:437 builtin/log.c:1462 msgid "prefix" msgstr "ПРЕФИКС" @@ -884,11 +887,11 @@ msgstr "ПРЕФИКС" msgid "prepend prefix to each pathname in the archive" msgstr "добавяне на този ПРЕФИКС към всеки път в архива" -#: archive.c:439 builtin/blame.c:693 builtin/blame.c:694 builtin/config.c:62 -#: builtin/fast-export.c:1005 builtin/fast-export.c:1007 builtin/grep.c:861 -#: builtin/hash-object.c:102 builtin/ls-files.c:551 builtin/ls-files.c:554 +#: archive.c:439 builtin/blame.c:702 builtin/blame.c:703 builtin/config.c:62 +#: builtin/fast-export.c:1005 builtin/fast-export.c:1007 builtin/grep.c:869 +#: builtin/hash-object.c:103 builtin/ls-files.c:551 builtin/ls-files.c:554 #: builtin/notes.c:405 builtin/notes.c:568 builtin/read-tree.c:120 -#: parse-options.h:153 +#: parse-options.h:165 msgid "file" msgstr "ФАЙЛ" @@ -920,8 +923,8 @@ msgstr "добро компресиране" msgid "list supported archive formats" msgstr "извеждане на списъка с поддържаните формати" -#: archive.c:458 builtin/archive.c:90 builtin/clone.c:106 builtin/clone.c:109 -#: builtin/submodule--helper.c:872 builtin/submodule--helper.c:1239 +#: archive.c:458 builtin/archive.c:90 builtin/clone.c:108 builtin/clone.c:111 +#: builtin/submodule--helper.c:1209 builtin/submodule--helper.c:1576 msgid "repo" msgstr "хранилище" @@ -972,22 +975,22 @@ msgstr "" "Отрицателните шаблони се игнорират в атрибутите на git.\n" "Ако ви трябва начална удивителна, ползвайте „\\!“." -#: bisect.c:458 +#: bisect.c:460 #, c-format msgid "Badly quoted content in file '%s': %s" msgstr "Неправилно цитирано съдържание във файла „%s“: %s" -#: bisect.c:666 +#: bisect.c:668 #, c-format msgid "We cannot bisect more!\n" msgstr "Повече не може да се търси двоично!\n" -#: bisect.c:720 +#: bisect.c:722 #, c-format msgid "Not a valid commit name %s" msgstr "Неправилно име на подаване „%s“" -#: bisect.c:744 +#: bisect.c:746 #, c-format msgid "" "The merge base %s is bad.\n" @@ -996,7 +999,7 @@ msgstr "" "Неправилна база за сливане: %s.\n" "Следователно грешката е коригирана между „%s“ и [%s].\n" -#: bisect.c:749 +#: bisect.c:751 #, c-format msgid "" "The merge base %s is new.\n" @@ -1005,7 +1008,7 @@ msgstr "" "Нова база за сливане: %s.\n" "Свойството е променено между „%s“ и [%s].\n" -#: bisect.c:754 +#: bisect.c:756 #, c-format msgid "" "The merge base %s is %s.\n" @@ -1014,7 +1017,7 @@ msgstr "" "Базата за сливане „%s“ е %s.\n" "Следователно първото %s подаване е между „%s“ и [%s].\n" -#: bisect.c:762 +#: bisect.c:764 #, c-format msgid "" "Some %s revs are not ancestors of the %s rev.\n" @@ -1025,7 +1028,7 @@ msgstr "" "Двоичното търсене с git bisect няма да работи правилно.\n" "Дали не сте объркали указателите „%s“ и „%s“?\n" -#: bisect.c:775 +#: bisect.c:777 #, c-format msgid "" "the merge base between %s and [%s] must be skipped.\n" @@ -1041,31 +1044,31 @@ msgstr "" msgid "Bisecting: a merge base must be tested\n" msgstr "Двоично търсене: трябва да се провери база за сливане\n" -#: bisect.c:862 +#: bisect.c:850 #, c-format msgid "a %s revision is needed" msgstr "необходима е версия „%s“" -#: bisect.c:879 builtin/notes.c:175 builtin/tag.c:234 +#: bisect.c:869 builtin/notes.c:175 builtin/tag.c:235 #, c-format msgid "could not create file '%s'" msgstr "файлът „%s“ не може да бъде създаден" -#: bisect.c:930 +#: bisect.c:920 #, c-format msgid "could not read file '%s'" msgstr "файлът „%s“ не може да бъде прочетен" -#: bisect.c:960 +#: bisect.c:950 msgid "reading bisect refs failed" msgstr "неуспешно прочитане на указателите за двоично търсене" -#: bisect.c:979 +#: bisect.c:969 #, c-format msgid "%s was both %s and %s\n" msgstr "„%s“ e както „%s“, така и „%s“\n" -#: bisect.c:987 +#: bisect.c:977 #, c-format msgid "" "No testable commit found.\n" @@ -1074,7 +1077,7 @@ msgstr "" "Липсва подходящо за тестване подаване.\n" "Проверете параметрите за пътищата.\n" -#: bisect.c:1006 +#: bisect.c:996 #, c-format msgid "(roughly %d step)" msgid_plural "(roughly %d steps)" @@ -1084,47 +1087,47 @@ msgstr[1] "(приблизително %d стъпки)" #. TRANSLATORS: the last %s will be replaced with "(roughly %d #. steps)" translation. #. -#: bisect.c:1012 +#: bisect.c:1002 #, c-format msgid "Bisecting: %d revision left to test after this %s\n" msgid_plural "Bisecting: %d revisions left to test after this %s\n" msgstr[0] "Двоично търсене: остава %d версия след тази %s\n" msgstr[1] "Двоично търсене: остават %d версии след тази %s\n" -#: blame.c:1757 +#: blame.c:1758 msgid "--contents and --reverse do not blend well." msgstr "Опциите „--contents“ и „--reverse“ са несъвместими" -#: blame.c:1768 +#: blame.c:1769 msgid "cannot use --contents with final commit object name" msgstr "Опцията „--contents“ е несъвместима с име на обект от крайно подаване" -#: blame.c:1788 +#: blame.c:1789 msgid "--reverse and --first-parent together require specified latest commit" msgstr "" "Едновременното задаване на опциите „--reverse“ и „--first-parent“ изисква " "указването на крайно подаване" -#: blame.c:1797 bundle.c:169 ref-filter.c:1981 sequencer.c:1177 -#: sequencer.c:2370 builtin/commit.c:1066 builtin/log.c:364 builtin/log.c:918 -#: builtin/log.c:1368 builtin/log.c:1697 builtin/log.c:1945 builtin/merge.c:369 +#: blame.c:1798 bundle.c:160 ref-filter.c:1978 sequencer.c:1699 +#: sequencer.c:2901 builtin/commit.c:976 builtin/log.c:366 builtin/log.c:920 +#: builtin/log.c:1371 builtin/log.c:1702 builtin/log.c:1950 builtin/merge.c:370 #: builtin/shortlog.c:191 msgid "revision walk setup failed" msgstr "неуспешно настройване на обхождането на версиите" -#: blame.c:1815 +#: blame.c:1816 msgid "" "--reverse --first-parent together require range along first-parent chain" msgstr "" "Едновременното задаване на опциите „--reverse“ и „--first-parent“ изисква " "указването на диапазон по веригата на първите наследници" -#: blame.c:1826 +#: blame.c:1827 #, c-format msgid "no such path %s in %s" msgstr "няма път на име „%s“ в „%s“" -#: blame.c:1837 +#: blame.c:1838 #, c-format msgid "cannot read blob %s for path %s" msgstr "обектът BLOB „%s“ в пътя %s не може да бъде прочетен" @@ -1277,77 +1280,76 @@ msgstr "Файлът „%s“ не изглежда да е пратка на gi msgid "unrecognized header: %s%s (%d)" msgstr "непозната заглавна част: %s%s (%d)" -#: bundle.c:88 sequencer.c:1360 sequencer.c:1807 sequencer.c:2637 -#: sequencer.c:2663 sequencer.c:2754 sequencer.c:2856 builtin/commit.c:782 +#: bundle.c:88 sequencer.c:1879 sequencer.c:2337 builtin/commit.c:750 #, c-format msgid "could not open '%s'" msgstr "„%s“ не може да се отвори" -#: bundle.c:140 +#: bundle.c:139 msgid "Repository lacks these prerequisite commits:" msgstr "В хранилището липсват следните необходими подавания:" -#: bundle.c:193 +#: bundle.c:190 #, c-format msgid "The bundle contains this ref:" msgid_plural "The bundle contains these %d refs:" msgstr[0] "Пратката съдържа следния указател:" msgstr[1] "Пратката съдържа следните %d указатели:" -#: bundle.c:200 +#: bundle.c:197 msgid "The bundle records a complete history." msgstr "Пратката съдържа пълна история." -#: bundle.c:202 +#: bundle.c:199 #, c-format msgid "The bundle requires this ref:" msgid_plural "The bundle requires these %d refs:" msgstr[0] "Пратката изисква следния указател:" msgstr[1] "Пратката изисква следните %d указатели:" -#: bundle.c:261 +#: bundle.c:258 msgid "Could not spawn pack-objects" msgstr "Командата „git pack-objects“ не може да бъде стартирана" -#: bundle.c:272 +#: bundle.c:269 msgid "pack-objects died" msgstr "Командата „git pack-objects“ не завърши успешно" -#: bundle.c:314 +#: bundle.c:311 msgid "rev-list died" msgstr "Командата „git rev-list“ не завърши успешно" -#: bundle.c:363 +#: bundle.c:360 #, c-format msgid "ref '%s' is excluded by the rev-list options" msgstr "" "указателят „%s“ не е бил включен поради опциите зададени на „git rev-list“" -#: bundle.c:453 builtin/log.c:181 builtin/log.c:1604 builtin/shortlog.c:296 +#: bundle.c:450 builtin/log.c:183 builtin/log.c:1607 builtin/shortlog.c:296 #, c-format msgid "unrecognized argument: %s" msgstr "непознат аргумент: %s" -#: bundle.c:461 +#: bundle.c:458 msgid "Refusing to create empty bundle." msgstr "Създаването на празна пратка е невъзможно." -#: bundle.c:473 +#: bundle.c:470 #, c-format msgid "cannot create '%s'" msgstr "Файлът „%s“ не може да бъде създаден" -#: bundle.c:501 +#: bundle.c:498 msgid "index-pack died" msgstr "Командата „git index-pack“ не завърши успешно" -#: color.c:301 +#: color.c:296 #, c-format msgid "invalid color value: %.*s" msgstr "неправилна стойност за цвят: %.*s" -#: commit.c:41 sequencer.c:1614 builtin/am.c:421 builtin/am.c:465 -#: builtin/am.c:1434 builtin/am.c:2069 +#: commit.c:41 sequencer.c:2141 builtin/am.c:421 builtin/am.c:465 +#: builtin/am.c:1436 builtin/am.c:2072 #, c-format msgid "could not parse %s" msgstr "„%s“ не може да се анализира" @@ -1357,7 +1359,7 @@ msgstr "„%s“ не може да се анализира" msgid "%s %s is not a commit!" msgstr "%s %s не е подаване!" -#: commit.c:1524 +#: commit.c:1506 msgid "" "Warning: commit message did not conform to UTF-8.\n" "You may want to amend it after fixing the message, or set the config\n" @@ -1463,69 +1465,69 @@ msgstr "„%s“ не е правилна стойност за време за msgid "bad zlib compression level %d" msgstr "неправилно ниво на компресиране: %d" -#: config.c:1222 +#: config.c:1225 #, c-format msgid "invalid mode for object creation: %s" msgstr "неправилен режим за създаването на обекти: %s" -#: config.c:1378 +#: config.c:1386 #, c-format msgid "bad pack compression level %d" msgstr "неправилно ниво на компресиране при пакетиране: %d" -#: config.c:1574 +#: config.c:1582 msgid "unable to parse command-line config" msgstr "неправилни настройки от командния ред" -#: config.c:1906 +#: config.c:1914 msgid "unknown error occurred while reading the configuration files" msgstr "неочаквана грешка при изчитането на конфигурационните файлове" -#: config.c:2093 +#: config.c:2101 #, c-format msgid "Invalid %s: '%s'" msgstr "Неправилен %s: „%s“" -#: config.c:2136 +#: config.c:2144 #, c-format msgid "unknown core.untrackedCache value '%s'; using 'keep' default value" msgstr "" "непозната стойност „%s“ за настройката „core.untrackedCache“. Ще се ползва " "стандартната стойност „keep“ (запазване)" -#: config.c:2162 +#: config.c:2170 #, c-format msgid "splitIndex.maxPercentChange value '%d' should be between 0 and 100" msgstr "" "стойността на „splitIndex.maxPercentChange“ трябва да е между 1 и 100, а не " "%d" -#: config.c:2187 +#: config.c:2195 #, c-format msgid "unable to parse '%s' from command-line config" msgstr "неразпозната стойност „%s“ от командния ред" -#: config.c:2189 +#: config.c:2197 #, c-format msgid "bad config variable '%s' in file '%s' at line %d" msgstr "неправилна настройка „%s“ във файла „%s“ на ред №%d" -#: config.c:2248 +#: config.c:2256 #, c-format msgid "%s has multiple values" msgstr "зададени са няколко стойности за „%s“" -#: config.c:2591 config.c:2808 +#: config.c:2599 config.c:2816 #, c-format msgid "fstat on %s failed" msgstr "неуспешно изпълнение на „fstat“ върху „%s“" -#: config.c:2698 +#: config.c:2706 #, c-format msgid "could not set '%s' to '%s'" msgstr "„%s“ не може да се зададе да е „%s“" -#: config.c:2700 builtin/remote.c:776 +#: config.c:2708 builtin/remote.c:776 #, c-format msgid "could not unset '%s'" msgstr "„%s“ не може да се премахне" @@ -1546,24 +1548,29 @@ msgstr "" "Проверете дали то съществува и дали имате права\n" "за достъп." -#: connected.c:64 builtin/fsck.c:183 builtin/prune.c:141 +#: connected.c:66 builtin/fsck.c:198 builtin/prune.c:144 msgid "Checking connectivity" msgstr "Проверка на връзката" -#: connected.c:76 +#: connected.c:78 msgid "Could not run 'git rev-list'" msgstr "Командата „git rev-list“ не може да бъде изпълнена." -#: connected.c:96 +#: connected.c:98 msgid "failed write to rev-list" msgstr "неуспешен запис на списъка с версиите" -#: connected.c:103 +#: connected.c:105 msgid "failed to close rev-list's stdin" msgstr "стандартният вход на списъка с версиите не може да бъде затворен" #: convert.c:205 #, c-format +msgid "CRLF would be replaced by LF in %s." +msgstr "Всяка последователност от знаци „CRLF“ ще бъдe заменена с „LF“ в „%s“." + +#: convert.c:207 +#, c-format msgid "" "CRLF will be replaced by LF in %s.\n" "The file will have its original line endings in your working directory." @@ -1572,12 +1579,13 @@ msgstr "" "Файлът ще остане с първоначалните знаци за край на ред в работната ви " "директория." -#: convert.c:209 +#: convert.c:215 #, c-format -msgid "CRLF would be replaced by LF in %s." -msgstr "Всяка последователност от знаци „CRLF“ ще бъдe заменена с „LF“ в „%s“." +msgid "LF would be replaced by CRLF in %s" +msgstr "" +"Всеки знак „LF“ ще бъдe заменен с последователността от знаци „CRLF“ в „%s“." -#: convert.c:215 +#: convert.c:217 #, c-format msgid "" "LF will be replaced by CRLF in %s.\n" @@ -1588,12 +1596,6 @@ msgstr "" "Файлът ще остане с първоначалните знаци за край на ред в работната ви " "директория." -#: convert.c:219 -#, c-format -msgid "LF would be replaced by CRLF in %s" -msgstr "" -"Всеки знак „LF“ ще бъдe заменен с последователността от знаци „CRLF“ в „%s“." - #: date.c:116 msgid "in the future" msgstr "в бъдещето" @@ -1694,7 +1696,7 @@ msgid "" "'plain'" msgstr "" "настройката за цвят за преместване трябва да е една от: „no“ (без), " -"„default“ (стандартно), „zebra“ (райе), „dimmed_zebra“ (притъмнено райе), " +"„default“ (стандартно), „zebra“ (райе), „dimmed_zebra“ (тъмно райе), " "„plain“ (обикновено)" #: diff.c:341 @@ -1711,23 +1713,27 @@ msgstr "" "Грешки в настройката „diff.dirstat“:\n" "%s" -#: diff.c:3799 +#: diff.c:3822 #, c-format msgid "external diff died, stopping at %s" msgstr "" "външната програма за разлики завърши неуспешно. Спиране на работата при „%s“" -#: diff.c:4127 +#: diff.c:4146 msgid "--name-only, --name-status, --check and -s are mutually exclusive" msgstr "" "Опциите „--name-only“, „--name-status“, „--check“ и „-s“ са несъвместими " "една с друга" -#: diff.c:4215 +#: diff.c:4149 +msgid "-G, -S and --find-object are mutually exclusive" +msgstr "Опциите „-G“, „-S“ и „--find-object“ са несъвместими една с друга" + +#: diff.c:4237 msgid "--follow requires exactly one pathspec" msgstr "Опцията „--follow“ изисква точно един път" -#: diff.c:4381 +#: diff.c:4403 #, c-format msgid "" "Failed to parse --dirstat/-X option parameter:\n" @@ -1736,43 +1742,48 @@ msgstr "" "Неразпознат параметър към опцията „--dirstat/-X“:\n" "%s" -#: diff.c:4395 +#: diff.c:4417 #, c-format msgid "Failed to parse --submodule option parameter: '%s'" msgstr "Неразпознат параметър към опцията „--submodule“: „%s“" -#: diff.c:5446 +#: diff.c:5493 msgid "inexact rename detection was skipped due to too many files." msgstr "" "търсенето на преименувания на обекти съчетани с промени се прескача поради " "многото файлове." -#: diff.c:5449 +#: diff.c:5496 msgid "only found copies from modified paths due to too many files." msgstr "" "установени са точните копия на променените пътища поради многото файлове." -#: diff.c:5452 +#: diff.c:5499 #, c-format msgid "" "you may want to set your %s variable to at least %d and retry the command." msgstr "задайте променливата „%s“ да е поне %d и отново изпълнете командата." -#: dir.c:2100 +#: dir.c:1866 +#, c-format +msgid "could not open directory '%s'" +msgstr "директорията „%s“ не може да бъде отворена" + +#: dir.c:2108 msgid "failed to get kernel name and information" msgstr "името и версията на ядрото не бяха получени" -#: dir.c:2219 +#: dir.c:2232 msgid "Untracked cache is disabled on this system or location." msgstr "" "Кеша за неследените файлове е изключен на тази система или местоположение." -#: dir.c:3002 dir.c:3007 +#: dir.c:3024 dir.c:3029 #, c-format msgid "could not create directories for %s" msgstr "директориите за „%s“ не може да бъдат създадени" -#: dir.c:3032 +#: dir.c:3054 #, c-format msgid "could not migrate git directory from '%s' to '%s'" msgstr "директорията на git не може да се мигрира от „%s“ до „%s“" @@ -1791,184 +1802,193 @@ msgstr "Филтриране на съдържанието" msgid "could not stat file '%s'" msgstr "неуспешно изпълнение на „stat“ върху файла „%s“" -#: fetch-pack.c:252 +#: fetch-object.c:17 +msgid "Remote with no URL" +msgstr "Липсва адрес за отдалеченото хранилище" + +#: fetch-pack.c:253 msgid "git fetch-pack: expected shallow list" msgstr "git fetch-pack: очаква се плитък списък" -#: fetch-pack.c:264 -msgid "git fetch-pack: expected ACK/NAK, got EOF" -msgstr "git fetch-pack: очакваше се „ACK“/„NAK“, а бе получен „EOF“" +#: fetch-pack.c:265 +msgid "git fetch-pack: expected ACK/NAK, got a flush packet" +msgstr "" +"git fetch-pack: очакваше се „ACK“/„NAK“, а бе получен изчистващ пакет „flush“" -#: fetch-pack.c:283 builtin/archive.c:63 +#: fetch-pack.c:284 builtin/archive.c:63 #, c-format msgid "remote error: %s" msgstr "отдалечена грешка: %s" -#: fetch-pack.c:284 +#: fetch-pack.c:285 #, c-format msgid "git fetch-pack: expected ACK/NAK, got '%s'" msgstr "git fetch-pack: очакваше се „ACK“/„NAK“, а бе получен „%s“" -#: fetch-pack.c:336 +#: fetch-pack.c:337 msgid "--stateless-rpc requires multi_ack_detailed" msgstr "опцията „--stateless-rpc“ изисква „multi_ack_detailed“" -#: fetch-pack.c:422 +#: fetch-pack.c:428 #, c-format msgid "invalid shallow line: %s" msgstr "неправилен плитък ред: „%s“" -#: fetch-pack.c:428 +#: fetch-pack.c:434 #, c-format msgid "invalid unshallow line: %s" msgstr "неправилен неплитък ред: „%s“" -#: fetch-pack.c:430 +#: fetch-pack.c:436 #, c-format msgid "object not found: %s" msgstr "обектът „%s“ липсва" -#: fetch-pack.c:433 +#: fetch-pack.c:439 #, c-format msgid "error in object: %s" msgstr "грешка в обекта: „%s“" -#: fetch-pack.c:435 +#: fetch-pack.c:441 #, c-format msgid "no shallow found: %s" msgstr "не е открит плитък обект: %s" -#: fetch-pack.c:438 +#: fetch-pack.c:444 #, c-format msgid "expected shallow/unshallow, got %s" msgstr "очаква се плитък или не обект, а бе получено: %s" -#: fetch-pack.c:477 +#: fetch-pack.c:485 #, c-format msgid "got %s %d %s" msgstr "получено бе %s %d %s" -#: fetch-pack.c:491 +#: fetch-pack.c:499 #, c-format msgid "invalid commit %s" msgstr "неправилно подаване: „%s“" -#: fetch-pack.c:524 +#: fetch-pack.c:532 msgid "giving up" msgstr "преустановяване" -#: fetch-pack.c:534 progress.c:229 +#: fetch-pack.c:542 progress.c:229 msgid "done" msgstr "действието завърши" -#: fetch-pack.c:546 +#: fetch-pack.c:554 #, c-format msgid "got %s (%d) %s" msgstr "получено бе %s (%d) %s" -#: fetch-pack.c:592 +#: fetch-pack.c:600 #, c-format msgid "Marking %s as complete" msgstr "Отбелязване на „%s“ като пълно" -#: fetch-pack.c:777 +#: fetch-pack.c:788 #, c-format msgid "already have %s (%s)" msgstr "вече има „%s“ (%s)" -#: fetch-pack.c:815 +#: fetch-pack.c:829 msgid "fetch-pack: unable to fork off sideband demultiplexer" msgstr "fetch-pack: не може да се създаде процес за демултиплексора" -#: fetch-pack.c:823 +#: fetch-pack.c:837 msgid "protocol error: bad pack header" msgstr "протоколна грешка: неправилна заглавна част на пакет" -#: fetch-pack.c:879 +#: fetch-pack.c:895 #, c-format msgid "fetch-pack: unable to fork off %s" msgstr "fetch-pack: не може да се създаде процес за „%s“" -#: fetch-pack.c:895 +#: fetch-pack.c:911 #, c-format msgid "%s failed" msgstr "неуспешно изпълнение на „%s“" -#: fetch-pack.c:897 +#: fetch-pack.c:913 msgid "error in sideband demultiplexer" msgstr "грешка в демултиплексора" -#: fetch-pack.c:924 +#: fetch-pack.c:940 msgid "Server does not support shallow clients" msgstr "Сървърът не поддържа плитки клиенти" -#: fetch-pack.c:928 +#: fetch-pack.c:944 msgid "Server supports multi_ack_detailed" msgstr "Сървърът поддържа „multi_ack_detailed“" -#: fetch-pack.c:931 +#: fetch-pack.c:947 msgid "Server supports no-done" msgstr "Сървърът поддържа „no-done“" -#: fetch-pack.c:937 +#: fetch-pack.c:953 msgid "Server supports multi_ack" msgstr "Сървърът поддържа „multi_ack“" -#: fetch-pack.c:941 +#: fetch-pack.c:957 msgid "Server supports side-band-64k" msgstr "Сървърът поддържа „side-band-64k“" -#: fetch-pack.c:945 +#: fetch-pack.c:961 msgid "Server supports side-band" msgstr "Сървърът поддържа „side-band“" -#: fetch-pack.c:949 +#: fetch-pack.c:965 msgid "Server supports allow-tip-sha1-in-want" msgstr "Сървърът поддържа „allow-tip-sha1-in-want“" -#: fetch-pack.c:953 +#: fetch-pack.c:969 msgid "Server supports allow-reachable-sha1-in-want" msgstr "Сървърът поддържа „allow-reachable-sha1-in-want“" -#: fetch-pack.c:963 +#: fetch-pack.c:979 msgid "Server supports ofs-delta" msgstr "Сървърът поддържа „ofs-delta“" -#: fetch-pack.c:970 +#: fetch-pack.c:985 +msgid "Server supports filter" +msgstr "Сървърът поддържа филтри" + +#: fetch-pack.c:993 #, c-format msgid "Server version is %.*s" msgstr "Версията на сървъра е: %.*s" -#: fetch-pack.c:976 +#: fetch-pack.c:999 msgid "Server does not support --shallow-since" msgstr "Сървърът не поддържа опцията „--shallow-since“" -#: fetch-pack.c:980 +#: fetch-pack.c:1003 msgid "Server does not support --shallow-exclude" msgstr "Сървърът не поддържа опцията „--shallow-exclude“" -#: fetch-pack.c:982 +#: fetch-pack.c:1005 msgid "Server does not support --deepen" msgstr "Сървърът не поддържа опцията „--deepen“" -#: fetch-pack.c:993 +#: fetch-pack.c:1016 msgid "no common commits" msgstr "няма общи подавания" -#: fetch-pack.c:1005 +#: fetch-pack.c:1028 msgid "git fetch-pack: fetch failed." msgstr "git fetch-pack: неуспешно доставяне." -#: fetch-pack.c:1167 +#: fetch-pack.c:1190 msgid "no matching remote head" msgstr "не може да бъде открит подходящ връх от отдалеченото хранилище" -#: fetch-pack.c:1189 +#: fetch-pack.c:1212 #, c-format msgid "no such remote ref %s" msgstr "такъв отдалечен указател няма: %s" -#: fetch-pack.c:1192 +#: fetch-pack.c:1215 #, c-format msgid "Server does not allow request for unadvertised object %s" msgstr "Сървърът не позволява заявка за необявен „%s“" @@ -1991,17 +2011,18 @@ msgstr "Програмата не успя да запише самостоят msgid "ignore invalid color '%.*s' in log.graphColors" msgstr "прескачане на неправилния цвят „%.*s“ в „log.graphColors“" -#: grep.c:2017 +#: grep.c:2022 #, c-format msgid "'%s': unable to read %s" msgstr "„%s“: файлът сочен от „%s“ не може да бъде прочетен" -#: grep.c:2034 builtin/clone.c:404 builtin/diff.c:81 builtin/rm.c:134 +#: grep.c:2039 setup.c:163 builtin/clone.c:407 builtin/diff.c:81 +#: builtin/rm.c:134 #, c-format msgid "failed to stat '%s'" msgstr "не може да бъде получена информация чрез „stat“ за „%s“" -#: grep.c:2045 +#: grep.c:2050 #, c-format msgid "'%s': short read" msgstr "„%s“: изчитането върна по-малко байтове от очакваното" @@ -2151,19 +2172,18 @@ msgstr "не може да се ползва празно име като иде msgid "name consists only of disallowed characters: %s" msgstr "името съдържа само непозволени знаци: „%s“" -#: ident.c:416 builtin/commit.c:616 +#: ident.c:416 builtin/commit.c:582 #, c-format msgid "invalid date format: %s" msgstr "неправилен формат на дата: %s" -#: list-objects-filter-options.c:30 -msgid "multiple object filter types cannot be combined" -msgstr "не може да комбинирате филтри по различен вид обекти" +#: list-objects-filter-options.c:36 +msgid "multiple filter-specs cannot be combined" +msgstr "не може да комбинирате множество филтри" -#: list-objects-filter-options.c:41 list-objects-filter-options.c:68 -#, c-format -msgid "invalid filter-spec expression '%s'" -msgstr "указан е неправилен израз за филтър: „%s“" +#: list-objects-filter-options.c:126 +msgid "cannot change partial clone promisor remote" +msgstr "не може да промените хранилището-гарант на непълно хранилище" #: lockfile.c:151 #, c-format @@ -2193,8 +2213,8 @@ msgstr "Файлът-ключалка „%s.lock“ не може да бъде msgid "failed to read the cache" msgstr "кешът не може да бъде прочетен" -#: merge.c:128 builtin/am.c:1943 builtin/am.c:1977 builtin/checkout.c:379 -#: builtin/checkout.c:600 builtin/clone.c:754 +#: merge.c:134 builtin/am.c:1946 builtin/am.c:1980 builtin/checkout.c:378 +#: builtin/checkout.c:599 builtin/clone.c:759 msgid "unable to write new index file" msgstr "неуспешно записване на новия индекс" @@ -2211,62 +2231,62 @@ msgstr "неуспешно изпълнение на „addinfo_cache“ за п msgid "error building trees" msgstr "грешка при изграждане на дърветата" -#: merge-recursive.c:752 +#: merge-recursive.c:771 #, c-format msgid "failed to create path '%s'%s" msgstr "грешка при създаването на пътя „%s“%s" -#: merge-recursive.c:763 +#: merge-recursive.c:782 #, c-format msgid "Removing %s to make room for subdirectory\n" msgstr "Изтриване на „%s“, за да се освободи място за поддиректория\n" -#: merge-recursive.c:777 merge-recursive.c:796 +#: merge-recursive.c:796 merge-recursive.c:815 msgid ": perhaps a D/F conflict?" msgstr ": възможно е да има конфликт директория/файл." -#: merge-recursive.c:786 +#: merge-recursive.c:805 #, c-format msgid "refusing to lose untracked file at '%s'" msgstr "" "преустановяване на действието, за да не се изтрие неследеният файл „%s“" -#: merge-recursive.c:828 builtin/cat-file.c:37 +#: merge-recursive.c:847 builtin/cat-file.c:37 #, c-format msgid "cannot read object %s '%s'" msgstr "обектът „%s“ (%s) не може да бъде прочетен" -#: merge-recursive.c:830 +#: merge-recursive.c:849 #, c-format msgid "blob expected for %s '%s'" msgstr "обектът „%s“ (%s) се очакваше да е BLOB, а не е" -#: merge-recursive.c:854 +#: merge-recursive.c:873 #, c-format msgid "failed to open '%s': %s" msgstr "„%s“ не може да се отвори: %s" -#: merge-recursive.c:865 +#: merge-recursive.c:884 #, c-format msgid "failed to symlink '%s': %s" msgstr "неуспешно създаване на символната връзка „%s“: %s" -#: merge-recursive.c:870 +#: merge-recursive.c:889 #, c-format msgid "do not know what to do with %06o %s '%s'" msgstr "" "не е ясно какво да се прави с обекта „%2$s“ (%3$s) с права за достъп „%1$06o“" -#: merge-recursive.c:1010 +#: merge-recursive.c:1029 msgid "Failed to execute internal merge" msgstr "Неуспешно вътрешно сливане" -#: merge-recursive.c:1014 +#: merge-recursive.c:1034 #, c-format msgid "Unable to add %s to database" msgstr "„%s“ не може да се добави в базата с данни" -#: merge-recursive.c:1117 +#: merge-recursive.c:1146 #, c-format msgid "" "CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left " @@ -2275,7 +2295,7 @@ msgstr "" "КОНФЛИКТ (%s/изтриване): „%s“ е изтрит в %s, а „%s“ в %s. Версия %s на „%s“ " "е оставена в дървото." -#: merge-recursive.c:1122 +#: merge-recursive.c:1151 #, c-format msgid "" "CONFLICT (%s/delete): %s deleted in %s and %s to %s in %s. Version %s of %s " @@ -2284,7 +2304,7 @@ msgstr "" "КОНФЛИКТ (%s/изтриване): „%s“ е изтрит в %s, а „%s“ е преименуван на „%s“ в " "%s. Версия %s на „%s“ е оставена в дървото." -#: merge-recursive.c:1129 +#: merge-recursive.c:1158 #, c-format msgid "" "CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left " @@ -2293,7 +2313,7 @@ msgstr "" "КОНФЛИКТ (%s/изтриване): „%s“ е изтрит в %s, а „%s“ в %s. Версия %s на „%s“ " "е оставена в дървото: %s." -#: merge-recursive.c:1134 +#: merge-recursive.c:1163 #, c-format msgid "" "CONFLICT (%s/delete): %s deleted in %s and %s to %s in %s. Version %s of %s " @@ -2302,20 +2322,20 @@ msgstr "" "КОНФЛИКТ (%s/изтриване): „%s“ е изтрит в %s, а „%s“ е преименуван на „%s“ в " "%s. Версия %s на „%s“ е оставена в дървото: %s." -#: merge-recursive.c:1168 +#: merge-recursive.c:1197 msgid "rename" msgstr "преименуване" -#: merge-recursive.c:1168 +#: merge-recursive.c:1197 msgid "renamed" msgstr "преименуван" -#: merge-recursive.c:1225 +#: merge-recursive.c:1254 #, c-format msgid "%s is a directory in %s adding as %s instead" msgstr "„%s“ е директория в „%s“, затова се добавя като „%s“" -#: merge-recursive.c:1250 +#: merge-recursive.c:1279 #, c-format msgid "" "CONFLICT (rename/rename): Rename \"%s\"->\"%s\" in branch \"%s\" rename \"%s" @@ -2324,145 +2344,145 @@ msgstr "" "КОНФЛИКТ (преименуване/преименуване): „%s“ е преименуван на „%s“ в клон " "„%s“, а „%s“ е преименуван на „%s“ в „%s“/%s." -#: merge-recursive.c:1255 +#: merge-recursive.c:1284 msgid " (left unresolved)" msgstr " (некоригиран конфликт)" -#: merge-recursive.c:1317 +#: merge-recursive.c:1346 #, c-format msgid "CONFLICT (rename/rename): Rename %s->%s in %s. Rename %s->%s in %s" msgstr "" "КОНФЛИКТ (преименуване/преименуване): „%s“ е преименуван на „%s“ в клон " "„%s“, а „%s“ е преименуван на „%s“ в „%s“" -#: merge-recursive.c:1350 +#: merge-recursive.c:1379 #, c-format msgid "Renaming %s to %s and %s to %s instead" msgstr "Преименуване на „%s“ на „%s“, а „%s“ на „%s“" -#: merge-recursive.c:1553 +#: merge-recursive.c:1582 #, c-format msgid "CONFLICT (rename/add): Rename %s->%s in %s. %s added in %s" msgstr "" "КОНФЛИКТ (преименуване/добавяне): „%s“ е преименуван на „%s“ в клон „%s“, а " "„%s“ е добавен в „%s“" -#: merge-recursive.c:1568 +#: merge-recursive.c:1597 #, c-format msgid "Adding merged %s" msgstr "Добавяне на слетия „%s“" -#: merge-recursive.c:1575 merge-recursive.c:1805 +#: merge-recursive.c:1604 merge-recursive.c:1834 #, c-format msgid "Adding as %s instead" msgstr "Добавяне като „%s“" -#: merge-recursive.c:1632 +#: merge-recursive.c:1661 #, c-format msgid "cannot read object %s" msgstr "обектът „%s“ не може да се прочете" -#: merge-recursive.c:1635 +#: merge-recursive.c:1664 #, c-format msgid "object %s is not a blob" msgstr "обектът „%s“ не е BLOB" -#: merge-recursive.c:1704 +#: merge-recursive.c:1733 msgid "modify" msgstr "промяна" -#: merge-recursive.c:1704 +#: merge-recursive.c:1733 msgid "modified" msgstr "променен" -#: merge-recursive.c:1714 +#: merge-recursive.c:1743 msgid "content" msgstr "съдържание" -#: merge-recursive.c:1721 +#: merge-recursive.c:1750 msgid "add/add" msgstr "добавяне/добавяне" -#: merge-recursive.c:1757 +#: merge-recursive.c:1786 #, c-format msgid "Skipped %s (merged same as existing)" msgstr "Прескачане на „%s“ (слетият резултат е идентичен със сегашния)" -#: merge-recursive.c:1771 +#: merge-recursive.c:1800 #, c-format msgid "Auto-merging %s" msgstr "Автоматично сливане на „%s“" -#: merge-recursive.c:1775 git-submodule.sh:932 +#: merge-recursive.c:1804 git-submodule.sh:879 msgid "submodule" msgstr "ПОДМОДУЛ" -#: merge-recursive.c:1776 +#: merge-recursive.c:1805 #, c-format msgid "CONFLICT (%s): Merge conflict in %s" msgstr "КОНФЛИКТ (%s): Конфликт при сливане на „%s“" -#: merge-recursive.c:1870 +#: merge-recursive.c:1899 #, c-format msgid "Removing %s" msgstr "Изтриване на „%s“" -#: merge-recursive.c:1896 +#: merge-recursive.c:1925 msgid "file/directory" msgstr "файл/директория" -#: merge-recursive.c:1902 +#: merge-recursive.c:1931 msgid "directory/file" msgstr "директория/файл" -#: merge-recursive.c:1909 +#: merge-recursive.c:1938 #, c-format msgid "CONFLICT (%s): There is a directory with name %s in %s. Adding %s as %s" msgstr "" "КОНФЛИКТ (%s): Съществува директория на име „%s“ в „%s“. Добавяне на „%s“ " "като „%s“" -#: merge-recursive.c:1918 +#: merge-recursive.c:1947 #, c-format msgid "Adding %s" msgstr "Добавяне на „%s“" -#: merge-recursive.c:1958 +#: merge-recursive.c:1987 #, c-format msgid "Dirty index: cannot merge (dirty: %s)" msgstr "" "Индексът не е чист: кръпките не могат да бъдат приложени (замърсени са: %s)" -#: merge-recursive.c:1962 +#: merge-recursive.c:1991 msgid "Already up to date!" msgstr "Вече е обновено!" -#: merge-recursive.c:1971 +#: merge-recursive.c:2000 #, c-format msgid "merging of trees %s and %s failed" msgstr "неуспешно сливане на дърветата „%s“ и „%s“" -#: merge-recursive.c:2068 +#: merge-recursive.c:2097 msgid "Merging:" msgstr "Сливане:" -#: merge-recursive.c:2081 +#: merge-recursive.c:2110 #, c-format msgid "found %u common ancestor:" msgid_plural "found %u common ancestors:" msgstr[0] "открит е %u общ предшественик:" msgstr[1] "открити са %u общи предшественици:" -#: merge-recursive.c:2120 +#: merge-recursive.c:2149 msgid "merge returned no commit" msgstr "сливането не върна подаване" -#: merge-recursive.c:2183 +#: merge-recursive.c:2212 #, c-format msgid "Could not parse object '%s'" msgstr "Неуспешен анализ на обекта „%s“" -#: merge-recursive.c:2197 builtin/merge.c:656 builtin/merge.c:815 +#: merge-recursive.c:2228 builtin/merge.c:657 builtin/merge.c:816 msgid "Unable to write index." msgstr "Индексът не може да бъде прочетен" @@ -2489,17 +2509,17 @@ msgid "You have not concluded your notes merge (%s exists)." msgstr "" "Не сте завършили сливането на бележките. (Указателят „%s“ съществува)." -#: notes-utils.c:42 +#: notes-utils.c:43 msgid "Cannot commit uninitialized/unreferenced notes tree" msgstr "" "Неинициализирано или нереферирано дърво за бележки не може да бъде подадено" -#: notes-utils.c:101 +#: notes-utils.c:102 #, c-format msgid "Bad notes.rewriteMode value: '%s'" msgstr "Неправилна стойност за „notes.rewriteMode“: „%s“" -#: notes-utils.c:111 +#: notes-utils.c:112 #, c-format msgid "Refusing to rewrite notes in %s (outside of refs/notes/)" msgstr "" @@ -2509,7 +2529,7 @@ msgstr "" #. the environment variable, the second %s is #. its value. #. -#: notes-utils.c:141 +#: notes-utils.c:142 #, c-format msgid "Bad %s value: '%s'" msgstr "Зададена е лоша стойност на променливата „%s“: „%s“" @@ -2519,30 +2539,30 @@ msgstr "Зададена е лоша стойност на променлива msgid "unable to parse object: %s" msgstr "обектът „%s“ не може да бъде анализиран" -#: packfile.c:556 +#: packfile.c:561 msgid "offset before end of packfile (broken .idx?)" msgstr "" "отместване преди края на пакетния файл (възможно е индексът да е повреден)" -#: packfile.c:1683 +#: packfile.c:1694 #, c-format msgid "offset before start of pack index for %s (corrupt index?)" msgstr "" "отместване преди началото на индекса на пакетния файл „%s“ (възможно е " "индексът да е повреден)" -#: packfile.c:1687 +#: packfile.c:1698 #, c-format msgid "offset beyond end of pack index for %s (truncated index?)" msgstr "" "отместване преди края на индекса на пакетния файл „%s“ (възможно е индексът " "да е отрязан)" -#: parse-options.c:573 +#: parse-options.c:619 msgid "..." msgstr "…" -#: parse-options.c:592 +#: parse-options.c:638 #, c-format msgid "usage: %s" msgstr "употреба: %s" @@ -2550,17 +2570,17 @@ msgstr "употреба: %s" #. TRANSLATORS: the colon here should align with the #. one in "usage: %s" translation. #. -#: parse-options.c:598 +#: parse-options.c:644 #, c-format msgid " or: %s" msgstr " или: %s" -#: parse-options.c:601 +#: parse-options.c:647 #, c-format msgid " %s" msgstr " %s" -#: parse-options.c:640 +#: parse-options.c:686 msgid "-NUM" msgstr "-ЧИСЛО" @@ -2652,7 +2672,7 @@ msgstr "пътят „%s“ е след символна връзка" msgid "unable to parse --pretty format" msgstr "аргументът към опцията „--pretty“ не може да се анализира" -#: read-cache.c:1472 +#: read-cache.c:1473 #, c-format msgid "" "index.version set, but the value is invalid.\n" @@ -2661,7 +2681,7 @@ msgstr "" "Зададена е неправилна стойност на настройката „index.version“.\n" "Ще се ползва версия %i" -#: read-cache.c:1482 +#: read-cache.c:1483 #, c-format msgid "" "GIT_INDEX_VERSION set, but the value is invalid.\n" @@ -2671,22 +2691,22 @@ msgstr "" "„GIT_INDEX_VERSION“.\n" "Ще се ползва версия %i" -#: read-cache.c:2370 sequencer.c:2731 wrapper.c:658 builtin/merge.c:1048 +#: read-cache.c:2375 sequencer.c:3248 wrapper.c:658 builtin/merge.c:1049 #, c-format msgid "could not close '%s'" msgstr "„%s“ не може да се затвори" -#: read-cache.c:2442 sequencer.c:1369 sequencer.c:2096 +#: read-cache.c:2448 sequencer.c:1900 sequencer.c:2627 #, c-format msgid "could not stat '%s'" msgstr "неуспешно изпълнение на „stat“ върху „%s“" -#: read-cache.c:2455 +#: read-cache.c:2461 #, c-format msgid "unable to open git dir: %s" msgstr "не може да се отвори директорията на git: %s" -#: read-cache.c:2467 +#: read-cache.c:2473 #, c-format msgid "unable to unlink: %s" msgstr "неуспешно изтриване на „%s“" @@ -2705,18 +2725,18 @@ msgstr "обновяванията на указатели са забранен msgid "could not remove reference %s" msgstr "Указателят „%s“ не може да бъде изтрит" -#: refs/files-backend.c:1203 refs/packed-backend.c:1524 -#: refs/packed-backend.c:1534 +#: refs/files-backend.c:1203 refs/packed-backend.c:1528 +#: refs/packed-backend.c:1538 #, c-format msgid "could not delete reference %s: %s" msgstr "Указателят „%s“ не може да бъде изтрит: %s" -#: refs/files-backend.c:1206 refs/packed-backend.c:1537 +#: refs/files-backend.c:1206 refs/packed-backend.c:1541 #, c-format msgid "could not delete references: %s" msgstr "Указателите не може да бъдат изтрити: %s" -#: ref-filter.c:35 wt-status.c:1816 +#: ref-filter.c:35 wt-status.c:1842 msgid "gone" msgstr "изтрит" @@ -2910,130 +2930,140 @@ msgstr "Указателят „HEAD“ не е свързан и е отдел msgid "(no branch)" msgstr "(извън клон)" -#: ref-filter.c:1488 ref-filter.c:1519 +#: ref-filter.c:1364 #, c-format msgid "missing object %s for %s" msgstr "обектът „%s“ липсва за „%s“" -#: ref-filter.c:1491 ref-filter.c:1522 +#: ref-filter.c:1367 #, c-format msgid "parse_object_buffer failed on %s for %s" msgstr "неуспешно анализиране чрез „parse_object_buffer“ на „%s“ за „%s“" -#: ref-filter.c:1822 +#: ref-filter.c:1819 #, c-format msgid "malformed object at '%s'" msgstr "обект със сгрешен формат при „%s“" -#: ref-filter.c:1889 +#: ref-filter.c:1886 #, c-format msgid "ignoring ref with broken name %s" msgstr "игнориране на указателя с грешно име „%s“" -#: ref-filter.c:1894 +#: ref-filter.c:1891 #, c-format msgid "ignoring broken ref %s" msgstr "игнориране на повредения указател „%s“" -#: ref-filter.c:2156 +#: ref-filter.c:2152 #, c-format msgid "format: %%(end) atom missing" msgstr "грешка във форма̀та: липсва лексемата %%(end)" -#: ref-filter.c:2250 +#: ref-filter.c:2246 #, c-format msgid "malformed object name %s" msgstr "неправилно име на обект „%s“" -#: remote.c:780 +#: remote.c:795 #, c-format msgid "Cannot fetch both %s and %s to %s" msgstr "Невъзможно е да се доставят едновременно и „%s“, и „%s“ към „%s“" -#: remote.c:784 +#: remote.c:799 #, c-format msgid "%s usually tracks %s, not %s" msgstr "„%s“ обикновено следи „%s“, а не „%s“" -#: remote.c:788 +#: remote.c:803 #, c-format msgid "%s tracks both %s and %s" msgstr "„%s“ следи както „%s“, така и „%s“" -#: remote.c:796 +#: remote.c:811 msgid "Internal error" msgstr "Вътрешна грешка" -#: remote.c:1711 remote.c:1813 +#: remote.c:1726 remote.c:1828 msgid "HEAD does not point to a branch" msgstr "Указателят „HEAD“ не сочи към клон" -#: remote.c:1720 +#: remote.c:1735 #, c-format msgid "no such branch: '%s'" msgstr "няма клон на име „%s“" -#: remote.c:1723 +#: remote.c:1738 #, c-format msgid "no upstream configured for branch '%s'" msgstr "не е зададен клон-източник за клона „%s“" -#: remote.c:1729 +#: remote.c:1744 #, c-format msgid "upstream branch '%s' not stored as a remote-tracking branch" msgstr "клонът-източник „%s“ не е съхранен като следящ клон" -#: remote.c:1744 +#: remote.c:1759 #, c-format msgid "push destination '%s' on remote '%s' has no local tracking branch" msgstr "" "липсва локален следящ клон за местоположението за изтласкване „%s“ в " "хранилището „%s“" -#: remote.c:1756 +#: remote.c:1771 #, c-format msgid "branch '%s' has no remote for pushing" msgstr "няма информация клонът „%s“ да следи някой друг" -#: remote.c:1767 +#: remote.c:1782 #, c-format msgid "push refspecs for '%s' do not include '%s'" msgstr "указателят за изтласкване на „%s“ не включва „%s“" -#: remote.c:1780 +#: remote.c:1795 msgid "push has no destination (push.default is 'nothing')" msgstr "указателят за изтласкване не включва цел („push.default“ е „nothing“)" -#: remote.c:1802 +#: remote.c:1817 msgid "cannot resolve 'simple' push to a single destination" msgstr "простото (simple) изтласкване не съответства на една цел" -#: remote.c:2106 +#: remote.c:2132 #, c-format msgid "Your branch is based on '%s', but the upstream is gone.\n" msgstr "Този клон следи „%s“, но следеният клон е изтрит.\n" -#: remote.c:2110 +#: remote.c:2136 msgid " (use \"git branch --unset-upstream\" to fixup)\n" msgstr " (за да коригирате това, използвайте „git branch --unset-upstream“)\n" -#: remote.c:2113 +#: remote.c:2139 #, c-format msgid "Your branch is up to date with '%s'.\n" msgstr "Клонът е актуализиран към „%s“.\n" -#: remote.c:2117 +#: remote.c:2143 +#, c-format +msgid "Your branch and '%s' refer to different commits.\n" +msgstr "Клонът ви и „%s“ сочат към различни подавания.\n" + +#: remote.c:2146 +#, c-format +msgid " (use \"%s\" for details)\n" +msgstr " (за повече информация ползвайте „%s“)\n" + +#: remote.c:2150 #, 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] "Клонът ви е с %2$d подаване пред „%1$s“.\n" msgstr[1] "Клонът ви е с %2$d подавания пред „%1$s“.\n" -#: remote.c:2123 +#: remote.c:2156 msgid " (use \"git push\" to publish your local commits)\n" msgstr " (публикувайте локалните си промени чрез „git push“)\n" -#: remote.c:2126 +#: remote.c:2159 #, c-format msgid "Your branch is behind '%s' by %d commit, and can be fast-forwarded.\n" msgid_plural "" @@ -3041,11 +3071,11 @@ msgid_plural "" msgstr[0] "Клонът ви е с %2$d подаване зад „%1$s“ и може да бъде превъртян.\n" msgstr[1] "Клонът ви е с %2$d подавания зад „%1$s“ и може да бъде превъртян.\n" -#: remote.c:2134 +#: remote.c:2167 msgid " (use \"git pull\" to update your local branch)\n" msgstr " (обновете локалния си клон чрез „git pull“)\n" -#: remote.c:2137 +#: remote.c:2170 #, c-format msgid "" "Your branch and '%s' have diverged,\n" @@ -3060,28 +3090,28 @@ msgstr[1] "" "Текущият клон се е отделил от „%s“,\n" "двата имат съответно по %d и %d несъвпадащи подавания.\n" -#: remote.c:2147 +#: remote.c:2180 msgid " (use \"git pull\" to merge the remote branch into yours)\n" msgstr " (слейте отдалечения клон в локалния чрез „git pull“)\n" -#: revision.c:2268 +#: revision.c:2277 msgid "your current branch appears to be broken" msgstr "Текущият клон е повреден" -#: revision.c:2271 +#: revision.c:2280 #, c-format msgid "your current branch '%s' does not have any commits yet" msgstr "Текущият клон „%s“ е без подавания " -#: revision.c:2465 +#: revision.c:2477 msgid "--first-parent is incompatible with --bisect" msgstr "опциите „--first-parent“ и „--bisect“ са несъвместими" -#: run-command.c:645 +#: run-command.c:731 msgid "open /dev/null failed" msgstr "неуспешно отваряне на „/dev/null“" -#: run-command.c:1188 +#: run-command.c:1274 #, c-format msgid "" "The '%s' hook was ignored because it's not set as executable.\n" @@ -3092,25 +3122,31 @@ msgstr "" " git config advice.ignoredHook false" #: send-pack.c:141 +msgid "unexpected flush packet while reading remote unpack status" +msgstr "" +"неочакван изчистващ пакет „flush“ при изчитане на състоянието от " +"отдалеченото разпакетиране" + +#: send-pack.c:143 #, c-format msgid "unable to parse remote unpack status: %s" msgstr "" "състоянието от отдалеченото разпакетиране не може да бъде анализирано: %s" -#: send-pack.c:143 +#: send-pack.c:145 #, c-format msgid "remote unpack failed: %s" msgstr "неуспешно отдалечено разпакетиране: %s" -#: send-pack.c:306 +#: send-pack.c:308 msgid "failed to sign the push certificate" msgstr "сертификатът за изтласкване не може да бъде подписан" -#: send-pack.c:419 +#: send-pack.c:421 msgid "the receiving end does not support --signed push" msgstr "отсрещната страна не поддържа изтласкване с опцията „--signed“" -#: send-pack.c:421 +#: send-pack.c:423 msgid "" "not sending a push certificate since the receiving end does not support --" "signed push" @@ -3118,32 +3154,37 @@ msgstr "" "отсрещната страна не поддържа изтласкване с опцията „--signed“, затова не се " "използва сертификат" -#: send-pack.c:433 +#: send-pack.c:435 msgid "the receiving end does not support --atomic push" msgstr "получаващата страна не поддържа изтласкване с опцията „--atomic“" -#: send-pack.c:438 +#: send-pack.c:440 msgid "the receiving end does not support push options" msgstr "отсрещната страна не поддържа опции при изтласкване" -#: sequencer.c:218 +#: sequencer.c:158 +#, c-format +msgid "invalid commit message cleanup mode '%s'" +msgstr "несъществуващ режим на изчистване „%s“ на съобщение при подаване" + +#: sequencer.c:267 msgid "revert" msgstr "отмяна" -#: sequencer.c:220 +#: sequencer.c:269 msgid "cherry-pick" msgstr "отбиране" -#: sequencer.c:222 +#: sequencer.c:271 msgid "rebase -i" msgstr "rebase -i" -#: sequencer.c:224 +#: sequencer.c:273 #, c-format msgid "Unknown action: %d" msgstr "Неизвестно действие: %d" -#: sequencer.c:281 +#: sequencer.c:330 msgid "" "after resolving the conflicts, mark the corrected paths\n" "with 'git add ' or 'git rm '" @@ -3151,7 +3192,7 @@ msgstr "" "след коригирането на конфликтите, отбележете съответните\n" "пътища с „git add ПЪТ…“ или „git rm ПЪТ…“." -#: sequencer.c:284 +#: sequencer.c:333 msgid "" "after resolving the conflicts, mark the corrected paths\n" "with 'git add ' or 'git rm '\n" @@ -3161,43 +3202,43 @@ msgstr "" "пътища с „git add ПЪТ…“ или „git rm ПЪТ…“, след което\n" "подайте резултата с командата „git commit'“." -#: sequencer.c:297 sequencer.c:1718 +#: sequencer.c:346 sequencer.c:2245 #, c-format msgid "could not lock '%s'" msgstr "„%s“ не може да се заключи" -#: sequencer.c:300 sequencer.c:1595 sequencer.c:1723 sequencer.c:1737 -#: sequencer.c:2729 sequencer.c:2800 wrapper.c:656 +#: sequencer.c:349 sequencer.c:2124 sequencer.c:2250 sequencer.c:2264 +#: sequencer.c:3246 sequencer.c:3310 wrapper.c:656 #, c-format msgid "could not write to '%s'" msgstr "в „%s“ не може да се пише" -#: sequencer.c:304 +#: sequencer.c:353 #, c-format msgid "could not write eol to '%s'" msgstr "краят на ред не може да се запише в „%s“" -#: sequencer.c:308 sequencer.c:1600 sequencer.c:1725 +#: sequencer.c:356 sequencer.c:2128 sequencer.c:2252 #, c-format -msgid "failed to finalize '%s'." -msgstr "„%s“ не може да се завърши." +msgid "failed to finalize '%s'" +msgstr "„%s“ не може да се завърши" -#: sequencer.c:332 sequencer.c:829 sequencer.c:1621 builtin/am.c:259 -#: builtin/commit.c:754 builtin/merge.c:1046 +#: sequencer.c:379 sequencer.c:1340 sequencer.c:2148 builtin/am.c:259 +#: builtin/commit.c:722 builtin/merge.c:1047 #, c-format msgid "could not read '%s'" msgstr "файлът „%s“ не може да бъде прочетен" -#: sequencer.c:358 +#: sequencer.c:405 #, c-format msgid "your local changes would be overwritten by %s." msgstr "локалните ви промени ще бъдат презаписани при %s." -#: sequencer.c:362 +#: sequencer.c:409 msgid "commit your changes or stash them to proceed." msgstr "подайте или скатайте промените, за да продължите" -#: sequencer.c:391 +#: sequencer.c:438 #, c-format msgid "%s: fast-forward" msgstr "%s: превъртане" @@ -3205,20 +3246,20 @@ msgstr "%s: превъртане" #. TRANSLATORS: %s will be "revert", "cherry-pick" or #. "rebase -i". #. -#: sequencer.c:477 +#: sequencer.c:526 #, c-format msgid "%s: Unable to write new index file" msgstr "%s: новият индекс не може да бъде запазен" -#: sequencer.c:496 +#: sequencer.c:542 msgid "could not resolve HEAD commit" msgstr "подаването, сочено от указателя „HEAD“, не може да бъде открито" -#: sequencer.c:516 +#: sequencer.c:562 msgid "unable to update cache tree" msgstr "дървото на кеша не може да бъде обновено" -#: sequencer.c:600 +#: sequencer.c:658 #, c-format msgid "" "you have staged changes in your working tree\n" @@ -3247,17 +3288,131 @@ msgstr "" "\n" " git rebase --continue\n" -#: sequencer.c:702 +#: sequencer.c:915 +msgid "'prepare-commit-msg' hook failed" +msgstr "" +"неуспешно изпълнение на куката при промяна на съобщението при подаване " +"(prepare-commit-msg)" + +#: sequencer.c:922 +msgid "" +"Your name and email address were configured automatically based\n" +"on your username and hostname. Please check that they are accurate.\n" +"You can suppress this message by setting them explicitly. Run the\n" +"following command and follow the instructions in your editor to edit\n" +"your configuration file:\n" +"\n" +" git config --global --edit\n" +"\n" +"After doing this, you may fix the identity used for this commit with:\n" +"\n" +" git commit --amend --reset-author\n" +msgstr "" +"Името и адресът за е-поща са настроени автоматично на базата на името на\n" +"потребителя и името на машината. Проверете дали са верни. Можете да " +"спрете\n" +"това съобщение като изрично зададете стойностите. Изпълнете следната " +"команда\n" +"и следвайте инструкциите в текстовия ви редактор, за да редактирате\n" +"конфигурационния файл:\n" +"\n" +" git config --global --edit\n" +"\n" +"След като направите това, можете да коригирате информацията за автора на\n" +"текущото подаване чрез:\n" +"\n" +" git commit --amend --reset-author\n" + +#: sequencer.c:935 +msgid "" +"Your name and email address were configured automatically based\n" +"on your username and hostname. Please check that they are accurate.\n" +"You can suppress this message by setting them explicitly:\n" +"\n" +" git config --global user.name \"Your Name\"\n" +" git config --global user.email you@example.com\n" +"\n" +"After doing this, you may fix the identity used for this commit with:\n" +"\n" +" git commit --amend --reset-author\n" +msgstr "" +"Името и адресът за е-поща са настроени автоматично на базата на името на\n" +"потребителя и името на машината. Проверете дали са верни. Можете да " +"спрете\n" +"това съобщение като изрично зададете стойностите:\n" +"\n" +" git config --global user.name \"Вашето Име\"\n" +" git config --global user.email пенчо@example.com\n" +"\n" +"След като направите това, можете да коригирате информацията за автора на\n" +"текущото подаване чрез:\n" +"\n" +" git commit --amend --reset-author\n" + +#: sequencer.c:975 +msgid "couldn't look up newly created commit" +msgstr "току що създаденото подаване не може да бъде открито" + +#: sequencer.c:977 +msgid "could not parse newly created commit" +msgstr "току що създаденото подаване не може да бъде анализирано" + +#: sequencer.c:1023 +msgid "unable to resolve HEAD after creating commit" +msgstr "" +"състоянието сочено от указателя „HEAD“ не може да бъде открито след " +"подаването" + +#: sequencer.c:1025 +msgid "detached HEAD" +msgstr "несвързан връх „HEAD“" + +#: sequencer.c:1029 +msgid " (root-commit)" +msgstr " (начално подаване)" + +#: sequencer.c:1050 +msgid "could not parse HEAD" +msgstr "указателят „HEAD“ не може да бъде анализиран" + +#: sequencer.c:1052 +#, c-format +msgid "HEAD %s is not a commit!" +msgstr "указателят „HEAD“ „%s“ сочи към нещо, което не е подаване!" + +#: sequencer.c:1056 builtin/commit.c:1491 +msgid "could not parse HEAD commit" +msgstr "върховото подаване „HEAD“ не може да бъде прочетено" + +#: sequencer.c:1107 sequencer.c:1673 +msgid "unable to parse commit author" +msgstr "авторът на подаването не може да бъде анализиран" + +#: sequencer.c:1117 builtin/am.c:1630 builtin/merge.c:643 +msgid "git write-tree failed to write a tree" +msgstr "Командата „git write-tree“ не успя да запише обект-дърво" + +#: sequencer.c:1134 sequencer.c:1186 +#, c-format +msgid "unable to read commit message from '%s'" +msgstr "съобщението за подаване не може да бъде прочетено от „%s“" + +#: sequencer.c:1154 builtin/am.c:1650 builtin/commit.c:1594 builtin/merge.c:826 +#: builtin/merge.c:851 +msgid "failed to write commit object" +msgstr "обектът за подаването не може да бъде записан" + +#: sequencer.c:1213 #, c-format msgid "could not parse commit %s" msgstr "подаването „%s“ не може да бъде анализирано" -#: sequencer.c:707 +#: sequencer.c:1218 #, c-format msgid "could not parse parent commit %s" msgstr "родителското подаване „%s“ не може да бъде анализирано" -#: sequencer.c:836 +#: sequencer.c:1347 #, c-format msgid "" "unexpected 1st line of squash message:\n" @@ -3268,7 +3423,7 @@ msgstr "" "\n" " %.*s" -#: sequencer.c:842 +#: sequencer.c:1353 #, c-format msgid "" "invalid 1st line of squash message:\n" @@ -3279,250 +3434,254 @@ msgstr "" "\n" " %.*s" -#: sequencer.c:848 sequencer.c:873 +#: sequencer.c:1359 sequencer.c:1384 #, c-format msgid "This is a combination of %d commits." msgstr "Това е обединение от %d подавания" -#: sequencer.c:857 sequencer.c:2748 +#: sequencer.c:1368 sequencer.c:3265 msgid "need a HEAD to fixup" msgstr "За смачкване ви трябва указател „HEAD“" -#: sequencer.c:859 +#: sequencer.c:1370 msgid "could not read HEAD" msgstr "указателят „HEAD“ не може да се прочете" -#: sequencer.c:861 +#: sequencer.c:1372 msgid "could not read HEAD's commit message" msgstr "" "съобщението за подаване към указателя „HEAD“ не може да бъде прочетено: %s" -#: sequencer.c:867 +#: sequencer.c:1378 #, c-format msgid "cannot write '%s'" msgstr "„%s“ не може да се запази" -#: sequencer.c:876 git-rebase--interactive.sh:446 +#: sequencer.c:1387 git-rebase--interactive.sh:452 msgid "This is the 1st commit message:" msgstr "Това е 1-то съобщение при подаване:" -#: sequencer.c:884 +#: sequencer.c:1395 #, c-format msgid "could not read commit message of %s" msgstr "съобщението за подаване към „%s“ не може да бъде прочетено" -#: sequencer.c:891 +#: sequencer.c:1402 #, c-format msgid "This is the commit message #%d:" msgstr "Това е съобщение при подаване №%d:" -#: sequencer.c:896 +#: sequencer.c:1407 #, c-format msgid "The commit message #%d will be skipped:" msgstr "Съобщение при подаване №%d ще бъде прескочено:" -#: sequencer.c:901 +#: sequencer.c:1412 #, c-format msgid "unknown command: %d" msgstr "непозната команда: %d" -#: sequencer.c:967 +#: sequencer.c:1479 msgid "your index file is unmerged." msgstr "индексът не е слят." -#: sequencer.c:986 +#: sequencer.c:1498 #, c-format msgid "commit %s is a merge but no -m option was given." msgstr "подаването „%s“ е сливане, но не е дадена опцията „-m“" -#: sequencer.c:994 +#: sequencer.c:1506 #, c-format msgid "commit %s does not have parent %d" msgstr "подаването „%s“ няма родител %d" -#: sequencer.c:998 +#: sequencer.c:1510 #, c-format msgid "mainline was specified but commit %s is not a merge." msgstr "указано е базово подаване, но подаването „%s“ не е сливане." -#: sequencer.c:1004 +#: sequencer.c:1516 #, c-format msgid "cannot get commit message for %s" msgstr "неуспешно извличане на съобщението за подаване на „%s“" #. TRANSLATORS: The first %s will be a "todo" command like #. "revert" or "pick", the second %s a SHA1. -#: sequencer.c:1023 +#: sequencer.c:1535 #, c-format msgid "%s: cannot parse parent commit %s" msgstr "%s: неразпозната стойност за родителското подаване „%s“" -#: sequencer.c:1086 sequencer.c:1867 +#: sequencer.c:1600 sequencer.c:2397 #, c-format msgid "could not rename '%s' to '%s'" msgstr "„%s“ не може да се преименува на „%s“" -#: sequencer.c:1137 +#: sequencer.c:1654 #, c-format msgid "could not revert %s... %s" msgstr "подаването „%s“… не може да бъде отменено: „%s“" -#: sequencer.c:1138 +#: sequencer.c:1655 #, c-format msgid "could not apply %s... %s" msgstr "подаването „%s“… не може да бъде приложено: „%s“" -#: sequencer.c:1180 +#: sequencer.c:1702 msgid "empty commit set passed" msgstr "зададено е празно множество от подавания" -#: sequencer.c:1190 +#: sequencer.c:1712 #, c-format msgid "git %s: failed to read the index" msgstr "git %s: неуспешно изчитане на индекса" -#: sequencer.c:1196 +#: sequencer.c:1718 #, c-format msgid "git %s: failed to refresh the index" msgstr "git %s: неуспешно обновяване на индекса" -#: sequencer.c:1270 +#: sequencer.c:1792 #, c-format msgid "%s does not accept arguments: '%s'" msgstr "„%s“ не приема аргументи: „%s“" -#: sequencer.c:1279 +#: sequencer.c:1801 #, c-format msgid "missing arguments for %s" msgstr "„%s“ изисква аргументи" -#: sequencer.c:1322 +#: sequencer.c:1844 #, c-format msgid "invalid line %d: %.*s" msgstr "неправилен ред %d: %.*s" -#: sequencer.c:1330 +#: sequencer.c:1852 #, c-format msgid "cannot '%s' without a previous commit" msgstr "Без предишно подаване не може да се изпълни „%s“" -#: sequencer.c:1363 sequencer.c:2525 sequencer.c:2560 sequencer.c:2642 -#: sequencer.c:2668 sequencer.c:2758 sequencer.c:2859 +#: sequencer.c:1883 sequencer.c:3056 sequencer.c:3091 #, c-format msgid "could not read '%s'." msgstr "от „%s“ не може да се чете." -#: sequencer.c:1375 +#: sequencer.c:1906 msgid "please fix this using 'git rebase --edit-todo'." msgstr "коригирайте това чрез „git rebase --edit-todo“." -#: sequencer.c:1377 +#: sequencer.c:1908 #, c-format msgid "unusable instruction sheet: '%s'" msgstr "неизползваем файл с описание на предстоящите действия: „%s“" -#: sequencer.c:1382 +#: sequencer.c:1913 msgid "no commits parsed." msgstr "никое от подаванията не може да се разпознае." -#: sequencer.c:1393 +#: sequencer.c:1924 msgid "cannot cherry-pick during a revert." msgstr "" "по време на отмяна на подаване не може да се извърши отбиране на подаване." -#: sequencer.c:1395 +#: sequencer.c:1926 msgid "cannot revert during a cherry-pick." msgstr "по време на отбиране не може да се извърши отмяна на подаване." -#: sequencer.c:1462 +#: sequencer.c:1993 #, c-format msgid "invalid key: %s" msgstr "неправилен ключ: „%s“" -#: sequencer.c:1465 +#: sequencer.c:1996 #, c-format msgid "invalid value for %s: %s" msgstr "неправилна стойност за „%s“: „%s“" -#: sequencer.c:1531 +#: sequencer.c:2062 #, c-format msgid "malformed options sheet: '%s'" msgstr "неправилен файл с опции: „%s“" -#: sequencer.c:1569 +#: sequencer.c:2100 msgid "a cherry-pick or revert is already in progress" msgstr "" "в момента вече се извършва отбиране на подавания или пребазиране на клона" -#: sequencer.c:1570 +#: sequencer.c:2101 msgid "try \"git cherry-pick (--continue | --quit | --abort)\"" msgstr "използвайте „git cherry-pick (--continue | --quit | --abort)“" -#: sequencer.c:1573 +#: sequencer.c:2104 #, c-format msgid "could not create sequencer directory '%s'" msgstr "директорията за секвенсора „%s“ не може да бъде създадена" -#: sequencer.c:1588 +#: sequencer.c:2118 msgid "could not lock HEAD" msgstr "указателят „HEAD“ не може да се заключи" -#: sequencer.c:1646 sequencer.c:2230 +#: sequencer.c:2173 sequencer.c:2761 msgid "no cherry-pick or revert in progress" msgstr "" "в момента не се извършва отбиране на подавания или пребазиране на клона" -#: sequencer.c:1648 +#: sequencer.c:2175 msgid "cannot resolve HEAD" msgstr "Подаването сочено от указателя „HEAD“ не може да бъде открито" -#: sequencer.c:1650 sequencer.c:1685 +#: sequencer.c:2177 sequencer.c:2212 msgid "cannot abort from a branch yet to be born" msgstr "" "действието не може да бъде преустановено, когато сте на клон, който тепърва " "предстои да бъде създаден" -#: sequencer.c:1671 builtin/grep.c:713 +#: sequencer.c:2198 builtin/grep.c:720 #, c-format msgid "cannot open '%s'" msgstr "„%s“ не може да бъде отворен" -#: sequencer.c:1673 +#: sequencer.c:2200 #, c-format msgid "cannot read '%s': %s" msgstr "„%s“ не може да бъде прочетен: %s" -#: sequencer.c:1674 +#: sequencer.c:2201 msgid "unexpected end of file" msgstr "неочакван край на файл" -#: sequencer.c:1680 +#: sequencer.c:2207 #, c-format msgid "stored pre-cherry-pick HEAD file '%s' is corrupt" msgstr "" "запазеният преди започването на отбирането файл за указателя „HEAD“ — „%s“ е " "повреден" -#: sequencer.c:1691 +#: sequencer.c:2218 msgid "You seem to have moved HEAD. Not rewinding, check your HEAD!" msgstr "" "Изглежда указателят „HEAD“ е променен. Проверете към какво сочи.\n" "Не се правят промени." -#: sequencer.c:1832 sequencer.c:2128 +#: sequencer.c:2324 sequencer.c:2679 +#, c-format +msgid "could not update %s" +msgstr "„%s“ не може да се обнови" + +#: sequencer.c:2362 sequencer.c:2659 msgid "cannot read HEAD" msgstr "указателят „HEAD“ не може да бъде прочетен" -#: sequencer.c:1872 builtin/difftool.c:639 +#: sequencer.c:2402 builtin/difftool.c:639 #, c-format msgid "could not copy '%s' to '%s'" msgstr "„%s“ не може да се копира като „%s“" -#: sequencer.c:1891 +#: sequencer.c:2421 msgid "could not read index" msgstr "индексът не може да бъде прочетен" -#: sequencer.c:1896 +#: sequencer.c:2426 #, c-format msgid "" "execution failed: %s\n" @@ -3537,11 +3696,11 @@ msgstr "" " git rebase --continue\n" "\n" -#: sequencer.c:1902 +#: sequencer.c:2432 msgid "and made changes to the index and/or the working tree\n" msgstr "и промени индекса и/или работното дърво\n" -#: sequencer.c:1908 +#: sequencer.c:2438 #, c-format msgid "" "execution succeeded: %s\n" @@ -3558,17 +3717,17 @@ msgstr "" " git rebase --continue\n" "\n" -#: sequencer.c:1967 +#: sequencer.c:2497 #, c-format msgid "Applied autostash.\n" msgstr "Автоматично скатаното е приложено.\n" -#: sequencer.c:1979 +#: sequencer.c:2509 #, c-format msgid "cannot store %s" msgstr "„%s“ не може да бъде запазен" -#: sequencer.c:1982 git-rebase.sh:175 +#: sequencer.c:2512 git-rebase.sh:178 #, c-format msgid "" "Applying autostash resulted in conflicts.\n" @@ -3579,57 +3738,52 @@ msgstr "" "надеждно скатани. Можете да пробвате да ги приложите чрез „git stash pop“\n" "или да ги изхвърлите чрез „git stash drop“, когато поискате.\n" -#: sequencer.c:2064 +#: sequencer.c:2595 #, c-format msgid "Stopped at %s... %.*s\n" msgstr "Спиране при „%s“… %.*s\n" -#: sequencer.c:2106 +#: sequencer.c:2637 #, c-format msgid "unknown command %d" msgstr "непозната команда %d" -#: sequencer.c:2136 +#: sequencer.c:2667 msgid "could not read orig-head" msgstr "указателят за „orig-head“ не може да се прочете" -#: sequencer.c:2141 sequencer.c:2745 +#: sequencer.c:2672 sequencer.c:3262 msgid "could not read 'onto'" msgstr "указателят за „onto“ не може да се прочете" -#: sequencer.c:2148 -#, c-format -msgid "could not update %s" -msgstr "„%s“ не може да се обнови" - -#: sequencer.c:2155 +#: sequencer.c:2686 #, c-format msgid "could not update HEAD to %s" msgstr "„HEAD“ не може да бъде обновен до „%s“" -#: sequencer.c:2239 +#: sequencer.c:2770 msgid "cannot rebase: You have unstaged changes." msgstr "не може да пребазирате, защото има промени, които не са в индекса." -#: sequencer.c:2244 +#: sequencer.c:2775 msgid "could not remove CHERRY_PICK_HEAD" msgstr "указателят „CHERRY_PICK_HEAD“ не може да бъде изтрит" -#: sequencer.c:2253 +#: sequencer.c:2784 msgid "cannot amend non-existing commit" msgstr "несъществуващо подаване не може да се поправи" -#: sequencer.c:2255 +#: sequencer.c:2786 #, c-format msgid "invalid file: '%s'" msgstr "неправилен файл: „%s“" -#: sequencer.c:2257 +#: sequencer.c:2788 #, c-format msgid "invalid contents: '%s'" msgstr "неправилно съдържание: „%s“" -#: sequencer.c:2260 +#: sequencer.c:2791 msgid "" "\n" "You have uncommitted changes in your working tree. Please, commit them\n" @@ -3639,38 +3793,38 @@ msgstr "" "В работното дърво има неподадени промени. Първо ги подайте, а след това\n" "отново изпълнете „git rebase --continue“." -#: sequencer.c:2270 +#: sequencer.c:2801 msgid "could not commit staged changes." msgstr "промените в индекса не могат да бъдат подадени." -#: sequencer.c:2350 +#: sequencer.c:2881 #, c-format msgid "%s: can't cherry-pick a %s" msgstr "%s: не може да се отбере „%s“" -#: sequencer.c:2354 +#: sequencer.c:2885 #, c-format msgid "%s: bad revision" msgstr "%s: неправилна версия" -#: sequencer.c:2387 +#: sequencer.c:2918 msgid "can't revert as initial commit" msgstr "първоначалното подаване не може да бъде отменено" -#: sequencer.c:2492 +#: sequencer.c:3023 msgid "make_script: unhandled options" msgstr "make_script: неподдържани опции" -#: sequencer.c:2495 +#: sequencer.c:3026 msgid "make_script: error preparing revisions" msgstr "make_script: грешка при подготовката на версии" -#: sequencer.c:2529 sequencer.c:2564 +#: sequencer.c:3060 sequencer.c:3095 #, c-format msgid "unusable todo list: '%s'" msgstr "неуспешно изтриване на списъка за изпълнение: „%s“" -#: sequencer.c:2615 +#: sequencer.c:3146 #, c-format msgid "" "unrecognized setting %s for option rebase.missingCommitsCheck. Ignoring." @@ -3678,7 +3832,7 @@ msgstr "" "Непозната стойност „%s“ за настройката „rebase.missingCommitsCheck“. " "Настройката се прескача." -#: sequencer.c:2695 +#: sequencer.c:3212 #, c-format msgid "" "Warning: some commits may have been dropped accidentally.\n" @@ -3687,7 +3841,7 @@ msgstr "" "Предупреждение: някои подавания може да са пропуснати.\n" "Пропуснати подавания (новите са най-отгоре):\n" -#: sequencer.c:2702 +#: sequencer.c:3219 #, c-format msgid "" "To avoid this message, use \"drop\" to explicitly remove a commit.\n" @@ -3704,7 +3858,7 @@ msgstr "" "предупреждение)\n" "или „error“ (считане за грешка).\n" -#: sequencer.c:2714 +#: sequencer.c:3231 #, c-format msgid "" "You can fix this with 'git rebase --edit-todo' and then run 'git rebase --" @@ -3715,21 +3869,26 @@ msgstr "" "continue“ след това.\n" "Може и да преустановите пребазирането с командата „git rebase --abort“.\n" -#: sequencer.c:2727 sequencer.c:2794 wrapper.c:225 wrapper.c:395 +#: sequencer.c:3244 sequencer.c:3304 wrapper.c:225 wrapper.c:395 #: builtin/am.c:779 #, c-format msgid "could not open '%s' for writing" msgstr "„%s“ не може да бъде отворен за запис" -#: sequencer.c:2775 +#: sequencer.c:3285 #, c-format msgid "could not parse commit '%s'" msgstr "подаването „%s“ не може да бъде анализирано" -#: sequencer.c:2897 +#: sequencer.c:3401 msgid "the script was already rearranged." msgstr "скриптът вече е преподреден." +#: setup.c:122 +#, c-format +msgid "'%s' is outside repository" +msgstr "„%s“ е извън хранилището" + #: setup.c:171 #, c-format msgid "" @@ -3754,6 +3913,11 @@ msgstr "" "\n" " git КОМАНДА [ВЕРСИЯ…] -- [ФАЙЛ…]" +#: setup.c:233 +#, c-format +msgid "option '%s' must come before non-option arguments" +msgstr "опцията „%s“ трябва да е преди първия аргумент, който не е опция" + #: setup.c:252 #, c-format msgid "" @@ -3761,82 +3925,153 @@ msgid "" "Use '--' to separate paths from revisions, like this:\n" "'git [...] -- [...]'" msgstr "" -"нееднозначен аргумент „%s: както версия, така и път.\n" +"нееднозначен аргумент „%s“: както версия, така и път.\n" "Разделяйте пътищата от версиите с „--“, ето така:\n" "\n" " git КОМАНДА [ВЕРСИЯ…] -- [ФАЙЛ…]" -#: setup.c:501 +#: setup.c:388 +msgid "unable to set up work tree using invalid config" +msgstr "" +"не може да се зададе текуща работна директория при неправилни настройки" + +#: setup.c:395 +msgid "this operation must be run in a work tree" +msgstr "тази команда трябва да се изпълни в работно дърво" + +#: setup.c:506 #, c-format msgid "Expected git repo version <= %d, found %d" msgstr "Очаква се версия на хранилището на git <= %d, а не %d" -#: setup.c:509 +#: setup.c:514 msgid "unknown repository extensions found:" msgstr "открити са непознати разширения в хранилището:" -#: setup.c:811 +#: setup.c:533 +#, c-format +msgid "error opening '%s'" +msgstr "„%s“ не може да се отвори" + +#: setup.c:535 +#, c-format +msgid "too large to be a .git file: '%s'" +msgstr "прекалено голям файл „.git“: „%s“" + +#: setup.c:537 +#, c-format +msgid "error reading %s" +msgstr "грешка при прочитане на „%s“" + +#: setup.c:539 +#, c-format +msgid "invalid gitfile format: %s" +msgstr "неправилен формат на gitfile: %s" + +#: setup.c:541 +#, c-format +msgid "no path in gitfile: %s" +msgstr "липсва път в gitfile: „%s“" + +#: setup.c:543 +#, c-format +msgid "not a git repository: %s" +msgstr "не е хранилище на Git: %s" + +#: setup.c:642 #, c-format -msgid "Not a git repository (or any of the parent directories): %s" +msgid "'$%s' too big" +msgstr "„%s“ е прекалено голям" + +#: setup.c:656 +#, c-format +msgid "not a git repository: '%s'" +msgstr "не е хранилище на git: „%s“" + +#: setup.c:685 setup.c:687 setup.c:718 +#, c-format +msgid "cannot chdir to '%s'" +msgstr "не може да се влезе в директорията „%s“" + +#: setup.c:690 setup.c:746 setup.c:756 setup.c:795 setup.c:803 setup.c:818 +msgid "cannot come back to cwd" +msgstr "процесът не може да се върне към предишната работна директория" + +#: setup.c:816 +#, c-format +msgid "not a git repository (or any of the parent directories): %s" msgstr "" -"Нито тази, нито която и да е от по-горните директории, не е хранилище на " +"нито тази, нито която и да е от по-горните директории, не е хранилище на " "git: %s" -#: setup.c:813 builtin/index-pack.c:1653 -msgid "Cannot come back to cwd" -msgstr "Процесът не може да се върне към предишната работна директория" +#: setup.c:827 +#, c-format +msgid "failed to stat '%*s%s%s'" +msgstr "не може да бъде получена информация чрез „stat“ за „%*s%s%s“" -#: setup.c:1052 +#: setup.c:1057 msgid "Unable to read current working directory" msgstr "Текущата работна директория не може да бъде прочетена" -#: setup.c:1064 setup.c:1070 +#: setup.c:1069 setup.c:1075 #, c-format -msgid "Cannot change to '%s'" -msgstr "Не може да се влезе в директорията „%s“" +msgid "cannot change to '%s'" +msgstr "не може да се влезе в директорията „%s“" -#: setup.c:1083 +#: setup.c:1088 #, c-format msgid "" -"Not a git repository (or any parent up to mount point %s)\n" +"not a git repository (or any parent up to mount point %s)\n" "Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set)." msgstr "" -"Нито тази, нито която и да е от по-горните директории (до точката на " +"нито тази, нито която и да е от по-горните директории (до точката на " "монтиране „%s“), не е хранилище на git.\n" "Git работи в рамките на една файлова система, защото променливата на средата " "„GIT_DISCOVERY_ACROSS_FILESYSTEM“ не е зададена." -#: setup.c:1167 +#: setup.c:1172 #, c-format msgid "" -"Problem with core.sharedRepository filemode value (0%.3o).\n" +"problem with core.sharedRepository filemode value (0%.3o).\n" "The owner of files must always have read and write permissions." msgstr "" -"Зададеният в „core.sharedRepository“ режим за достъп до файлове е неправилен " +"зададеният в „core.sharedRepository“ режим за достъп до файлове е неправилен " "(0%.3o).\n" "Собственикът на файла трябва да има права за писане и четене." -#: sha1_file.c:598 +#: setup.c:1215 +msgid "open /dev/null or dup failed" +msgstr "неуспешно изпълнение на „open“ или „dup“ върху „/dev/null“" + +#: setup.c:1230 +msgid "fork failed" +msgstr "неуспешно изпълнение на „fork“" + +#: setup.c:1235 +msgid "setsid failed" +msgstr "неуспешно изпълнение на „setsid“" + +#: sha1_file.c:592 #, c-format msgid "path '%s' does not exist" msgstr "пътят „%s“ не съществува." -#: sha1_file.c:624 +#: sha1_file.c:618 #, c-format msgid "reference repository '%s' as a linked checkout is not supported yet." msgstr "все още не се поддържа еталонно хранилище „%s“ като свързано." -#: sha1_file.c:630 +#: sha1_file.c:624 #, c-format msgid "reference repository '%s' is not a local repository." msgstr "еталонното хранилище „%s“ не е локално" -#: sha1_file.c:636 +#: sha1_file.c:630 #, c-format msgid "reference repository '%s' is shallow" msgstr "еталонното хранилище „%s“ е плитко" -#: sha1_file.c:644 +#: sha1_file.c:638 #, c-format msgid "reference repository '%s' is grafted" msgstr "еталонното хранилище „%s“ е с присаждане" @@ -3914,7 +4149,7 @@ msgstr "Пътят „%s“ е в подмодула „%.*s“" msgid "submodule entry '%s' (%s) is a %s, not a commit" msgstr "записът за подмодула „%s“ (%s) е %s, а не подаване!" -#: submodule.c:1065 builtin/branch.c:648 builtin/submodule--helper.c:1387 +#: submodule.c:1065 builtin/branch.c:648 builtin/submodule--helper.c:1724 msgid "Failed to resolve HEAD as a valid ref." msgstr "Не може да се открие към какво сочи указателят „HEAD“" @@ -3938,7 +4173,7 @@ msgstr "командата „git status“ не може да се изпълн msgid "submodule '%s' has dirty index" msgstr "индексът на подмодула „%s“ не е чист" -#: submodule.c:1876 +#: submodule.c:1878 #, c-format msgid "" "relocate_gitdir for submodule '%s' with more than one worktree not supported" @@ -3946,18 +4181,18 @@ msgstr "" "не се поддържа „relocate_gitdir“ за подмодула „%s“, който има повече от едно " "работно дърво" -#: submodule.c:1888 submodule.c:1944 +#: submodule.c:1890 submodule.c:1946 #, c-format msgid "could not lookup name for submodule '%s'" msgstr "името на подмодула „%s“ не може да бъде намерено" -#: submodule.c:1892 builtin/submodule--helper.c:909 -#: builtin/submodule--helper.c:919 +#: submodule.c:1894 builtin/submodule--helper.c:1246 +#: builtin/submodule--helper.c:1256 #, c-format msgid "could not create directory '%s'" msgstr "Директорията „%s“ не може да бъде създадена" -#: submodule.c:1895 +#: submodule.c:1897 #, c-format msgid "" "Migrating git directory of '%s%s' from\n" @@ -3968,20 +4203,20 @@ msgstr "" "„%s“ към\n" "„%s“\n" -#: submodule.c:1979 +#: submodule.c:1981 #, c-format msgid "could not recurse into submodule '%s'" msgstr "неуспешна обработка на поддиректориите в подмодула „%s“" -#: submodule.c:2023 +#: submodule.c:2025 msgid "could not start ls-files in .." msgstr "„ls-stat“ не може да се стартира в „..“" -#: submodule.c:2043 +#: submodule.c:2045 msgid "BUG: returned path string doesn't match cwd?" msgstr "ГРЕШКА: полученият низ за пътя не съвпада с върнатото от „cwd“" -#: submodule.c:2062 +#: submodule.c:2064 #, c-format msgid "ls-tree returned unexpected return code %d" msgstr "„ls-tree“ завърши с неочакван изходен код: %d" @@ -4059,7 +4294,7 @@ msgstr "Клонът „%s“ ще следи „%s“ от „%s“\n" msgid "transport: invalid depth option '%s'" msgstr "transport: неправилна опция за дълбочина: %s" -#: transport.c:904 +#: transport.c:916 #, c-format msgid "" "The following submodule paths contain changes that can\n" @@ -4068,7 +4303,7 @@ msgstr "" "Следните пътища за подмодули съдържат промени,\n" "които липсват от всички отдалечени хранилища:\n" -#: transport.c:908 +#: transport.c:920 #, c-format msgid "" "\n" @@ -4093,11 +4328,11 @@ msgstr "" " git push\n" "\n" -#: transport.c:916 +#: transport.c:928 msgid "Aborting." msgstr "Преустановяване на действието." -#: transport-helper.c:1074 +#: transport-helper.c:1079 #, c-format msgid "Could not read ref %s" msgstr "Указателят „%s“ не може да се прочете." @@ -4118,7 +4353,7 @@ msgstr "празно име на файл в запис в дърво" msgid "too-short tree file" msgstr "прекалено кратък файл-дърво" -#: unpack-trees.c:107 +#: unpack-trees.c:108 #, c-format msgid "" "Your local changes to the following files would be overwritten by checkout:\n" @@ -4127,7 +4362,7 @@ msgstr "" "Изтеглянето ще презапише локалните промени на тези файлове:\n" "%%sПодайте или скатайте промените, за да преминете към нов клон." -#: unpack-trees.c:109 +#: unpack-trees.c:110 #, c-format msgid "" "Your local changes to the following files would be overwritten by checkout:\n" @@ -4136,7 +4371,7 @@ msgstr "" "Изтеглянето ще презапише локалните промени на тези файлове:\n" "%%s" -#: unpack-trees.c:112 +#: unpack-trees.c:113 #, c-format msgid "" "Your local changes to the following files would be overwritten by merge:\n" @@ -4145,7 +4380,7 @@ msgstr "" "Сливането ще презапише локалните промени на тези файлове:\n" "%%sПодайте или скатайте промените, за да слеете." -#: unpack-trees.c:114 +#: unpack-trees.c:115 #, c-format msgid "" "Your local changes to the following files would be overwritten by merge:\n" @@ -4154,7 +4389,7 @@ msgstr "" "Сливането ще презапише локалните промени на тези файлове:\n" "%%s" -#: unpack-trees.c:117 +#: unpack-trees.c:118 #, c-format msgid "" "Your local changes to the following files would be overwritten by %s:\n" @@ -4163,7 +4398,7 @@ msgstr "" "„%s“ ще презапише локалните промени на тези файлове:\n" "%%sПодайте или скатайте промените, за да извършите „%s“." -#: unpack-trees.c:119 +#: unpack-trees.c:120 #, c-format msgid "" "Your local changes to the following files would be overwritten by %s:\n" @@ -4172,7 +4407,7 @@ msgstr "" "„%s“ ще презапише локалните промени на тези файлове:\n" "%%s" -#: unpack-trees.c:124 +#: unpack-trees.c:125 #, c-format msgid "" "Updating the following directories would lose untracked files in them:\n" @@ -4181,7 +4416,7 @@ msgstr "" "Обновяването на следните директории ще изтрие неследените файлове в тях:\n" "%s" -#: unpack-trees.c:128 +#: unpack-trees.c:129 #, c-format msgid "" "The following untracked working tree files would be removed by checkout:\n" @@ -4190,7 +4425,7 @@ msgstr "" "Изтеглянето ще изтрие тези неследени файлове в работното дърво:\n" "%%sПреместете ги или ги изтрийте, за да преминете на друг клон." -#: unpack-trees.c:130 +#: unpack-trees.c:131 #, c-format msgid "" "The following untracked working tree files would be removed by checkout:\n" @@ -4199,7 +4434,7 @@ msgstr "" "Изтеглянето ще изтрие тези неследени файлове в работното дърво:\n" "%%s" -#: unpack-trees.c:133 +#: unpack-trees.c:134 #, c-format msgid "" "The following untracked working tree files would be removed by merge:\n" @@ -4208,7 +4443,7 @@ msgstr "" "Сливането ще изтрие тези неследени файлове в работното дърво:\n" "%%sПреместете ги или ги изтрийте, за да слеете." -#: unpack-trees.c:135 +#: unpack-trees.c:136 #, c-format msgid "" "The following untracked working tree files would be removed by merge:\n" @@ -4217,7 +4452,7 @@ msgstr "" "Сливането ще изтрие тези неследени файлове в работното дърво:\n" "%%s" -#: unpack-trees.c:138 +#: unpack-trees.c:139 #, c-format msgid "" "The following untracked working tree files would be removed by %s:\n" @@ -4226,7 +4461,7 @@ msgstr "" "„%s“ ще изтрие тези неследени файлове в работното дърво:\n" "%%sПреместете ги или ги изтрийте, за да извършите „%s“." -#: unpack-trees.c:140 +#: unpack-trees.c:141 #, c-format msgid "" "The following untracked working tree files would be removed by %s:\n" @@ -4235,7 +4470,7 @@ msgstr "" "„%s“ ще изтрие тези неследени файлове в работното дърво:\n" "%%s" -#: unpack-trees.c:145 +#: unpack-trees.c:146 #, c-format msgid "" "The following untracked working tree files would be overwritten by " @@ -4245,7 +4480,7 @@ msgstr "" "Изтеглянето ще презапише тези неследени файлове в работното дърво:\n" "%%sПреместете ги или ги изтрийте, за да смените клон." -#: unpack-trees.c:147 +#: unpack-trees.c:148 #, c-format msgid "" "The following untracked working tree files would be overwritten by " @@ -4255,7 +4490,7 @@ msgstr "" "Изтеглянето ще презапише тези неследени файлове в работното дърво:\n" "%%s" -#: unpack-trees.c:150 +#: unpack-trees.c:151 #, c-format msgid "" "The following untracked working tree files would be overwritten by merge:\n" @@ -4264,7 +4499,7 @@ msgstr "" "Сливането ще презапише тези неследени файлове в работното дърво:\n" "%%sПреместете ги или ги изтрийте, за да слеете." -#: unpack-trees.c:152 +#: unpack-trees.c:153 #, c-format msgid "" "The following untracked working tree files would be overwritten by merge:\n" @@ -4273,7 +4508,7 @@ msgstr "" "Сливането ще презапише тези неследени файлове в работното дърво:\n" "%%s" -#: unpack-trees.c:155 +#: unpack-trees.c:156 #, c-format msgid "" "The following untracked working tree files would be overwritten by %s:\n" @@ -4282,7 +4517,7 @@ msgstr "" "„%s“ ще презапише тези неследени файлове в работното дърво:\n" "%%sПреместете ги или ги изтрийте, за да извършите „%s“." -#: unpack-trees.c:157 +#: unpack-trees.c:158 #, c-format msgid "" "The following untracked working tree files would be overwritten by %s:\n" @@ -4291,12 +4526,12 @@ msgstr "" "„%s“ ще презапише тези неследени файлове в работното дърво:\n" "%%s" -#: unpack-trees.c:164 +#: unpack-trees.c:165 #, c-format msgid "Entry '%s' overlaps with '%s'. Cannot bind." msgstr "Записът за „%s“ съвпада с този за „%s“. Не може да се присвои." -#: unpack-trees.c:167 +#: unpack-trees.c:168 #, c-format msgid "" "Cannot update sparse checkout: the following entries are not up to date:\n" @@ -4306,7 +4541,7 @@ msgstr "" "актуални:\n" "%s" -#: unpack-trees.c:169 +#: unpack-trees.c:170 #, c-format msgid "" "The following working tree files would be overwritten by sparse checkout " @@ -4317,7 +4552,7 @@ msgstr "" "дърво:\n" "%s" -#: unpack-trees.c:171 +#: unpack-trees.c:172 #, c-format msgid "" "The following working tree files would be removed by sparse checkout " @@ -4328,7 +4563,7 @@ msgstr "" "дърво:\n" "%s" -#: unpack-trees.c:173 +#: unpack-trees.c:174 #, c-format msgid "" "Cannot update submodule:\n" @@ -4337,12 +4572,12 @@ msgstr "" "Подмодулът не може да бъде обновен:\n" "„%s“" -#: unpack-trees.c:250 +#: unpack-trees.c:251 #, c-format msgid "Aborting\n" msgstr "Преустановяване на действието\n" -#: unpack-trees.c:332 +#: unpack-trees.c:333 msgid "Checking out files" msgstr "Изтегляне на файлове" @@ -4375,18 +4610,44 @@ msgstr "неправилен номер на порт" msgid "invalid '..' path segment" msgstr "неправилна част от пътя „..“" -#: worktree.c:245 +#: worktree.c:245 builtin/am.c:2147 #, c-format msgid "failed to read '%s'" msgstr "„%s“ не може да бъде прочетен" +#: worktree.c:291 +#, c-format +msgid "'%s' at main working tree is not the repository directory" +msgstr "„%s“ в основното работно дърво не е директорията на хранилището" + +#: worktree.c:302 +#, c-format +msgid "'%s' file does not contain absolute path to the working tree location" +msgstr "" +"файлът „%s“ не съдържа абсолютния път към местоположението на работното дърво" + +#: worktree.c:314 +#, c-format +msgid "'%s' does not exist" +msgstr "„%s“ не съществува." + +#: worktree.c:320 +#, c-format +msgid "'%s' is not a .git file, error code %d" +msgstr "„%s“ не е файл на .git, код за грешка: %d" + +#: worktree.c:328 +#, c-format +msgid "'%s' does not point back to '%s'" +msgstr "„%s“ не сочи към обратно към „%s“" + #: wrapper.c:223 wrapper.c:393 #, c-format msgid "could not open '%s' for reading and writing" msgstr "„%s“ не може да бъде отворен и за четене, и за запис" #: wrapper.c:227 wrapper.c:397 builtin/am.c:320 builtin/am.c:770 -#: builtin/am.c:862 builtin/merge.c:1043 +#: builtin/am.c:862 builtin/merge.c:1044 #, c-format msgid "could not open '%s' for reading" msgstr "файлът не може да бъде прочетен: „%s“" @@ -4400,161 +4661,161 @@ msgstr "няма достъп до „%s“" msgid "unable to get current working directory" msgstr "текущата работна директория е недостъпна" -#: wt-status.c:150 +#: wt-status.c:151 msgid "Unmerged paths:" msgstr "Неслети пътища:" -#: wt-status.c:177 wt-status.c:204 +#: wt-status.c:178 wt-status.c:205 #, c-format msgid " (use \"git reset %s ...\" to unstage)" msgstr " (използвайте „git reset %s ФАЙЛ…“, за да извадите ФАЙЛа от индекса)" -#: wt-status.c:179 wt-status.c:206 +#: wt-status.c:180 wt-status.c:207 msgid " (use \"git rm --cached ...\" to unstage)" msgstr "" " (използвайте „git rm --cached %s ФАЙЛ…“, за да извадите ФАЙЛа от индекса)" -#: wt-status.c:183 +#: wt-status.c:184 msgid " (use \"git add ...\" to mark resolution)" msgstr "" " (използвайте „git add ФАЙЛ…“, за да укажете разрешаването на конфликта)" -#: wt-status.c:185 wt-status.c:189 +#: wt-status.c:186 wt-status.c:190 msgid " (use \"git add/rm ...\" as appropriate to mark resolution)" msgstr "" " (използвайте „git add/rm ФАЙЛ…“, според решението, което избирате за " "конфликта)" -#: wt-status.c:187 +#: wt-status.c:188 msgid " (use \"git rm ...\" to mark resolution)" msgstr "" " (използвайте „git rm ФАЙЛ…“, за да укажете разрешаването на конфликта)" -#: wt-status.c:198 wt-status.c:984 +#: wt-status.c:199 wt-status.c:1007 msgid "Changes to be committed:" msgstr "Промени, които ще бъдат подадени:" -#: wt-status.c:216 wt-status.c:993 +#: wt-status.c:217 wt-status.c:1016 msgid "Changes not staged for commit:" msgstr "Промени, които не са в индекса за подаване:" -#: wt-status.c:220 +#: wt-status.c:221 msgid " (use \"git add ...\" to update what will be committed)" msgstr "" " (използвайте „git add ФАЙЛ…“, за да обновите съдържанието за подаване)" -#: wt-status.c:222 +#: wt-status.c:223 msgid " (use \"git add/rm ...\" to update what will be committed)" msgstr "" " (използвайте „git add/rm ФАЙЛ…“, за да обновите съдържанието за подаване)" -#: wt-status.c:223 +#: wt-status.c:224 msgid "" " (use \"git checkout -- ...\" to discard changes in working directory)" msgstr "" " (използвайте „git checkout -- ФАЙЛ…“, за да отхвърлите промените в " "работното дърво)" -#: wt-status.c:225 +#: wt-status.c:226 msgid " (commit or discard the untracked or modified content in submodules)" msgstr "" " (подайте или отхвърлете неследеното или промененото съдържание в " "подмодулите)" -#: wt-status.c:237 +#: wt-status.c:238 #, c-format msgid " (use \"git %s ...\" to include in what will be committed)" msgstr "" " (използвайте „git %s ФАЙЛ…“, за да определите какво включвате в подаването)" -#: wt-status.c:252 +#: wt-status.c:253 msgid "both deleted:" msgstr "изтрити в двата случая:" -#: wt-status.c:254 +#: wt-status.c:255 msgid "added by us:" msgstr "добавени от вас:" -#: wt-status.c:256 +#: wt-status.c:257 msgid "deleted by them:" msgstr "изтрити от тях:" -#: wt-status.c:258 +#: wt-status.c:259 msgid "added by them:" msgstr "добавени от тях:" -#: wt-status.c:260 +#: wt-status.c:261 msgid "deleted by us:" msgstr "изтрити от вас:" -#: wt-status.c:262 +#: wt-status.c:263 msgid "both added:" msgstr "добавени и в двата случая:" -#: wt-status.c:264 +#: wt-status.c:265 msgid "both modified:" msgstr "променени и в двата случая:" -#: wt-status.c:274 +#: wt-status.c:275 msgid "new file:" msgstr "нов файл:" -#: wt-status.c:276 +#: wt-status.c:277 msgid "copied:" msgstr "копиран:" -#: wt-status.c:278 +#: wt-status.c:279 msgid "deleted:" msgstr "изтрит:" -#: wt-status.c:280 +#: wt-status.c:281 msgid "modified:" msgstr "променен:" -#: wt-status.c:282 +#: wt-status.c:283 msgid "renamed:" msgstr "преименуван:" -#: wt-status.c:284 +#: wt-status.c:285 msgid "typechange:" msgstr "смяна на вида:" -#: wt-status.c:286 +#: wt-status.c:287 msgid "unknown:" msgstr "непозната промяна:" -#: wt-status.c:288 +#: wt-status.c:289 msgid "unmerged:" msgstr "неслят:" -#: wt-status.c:370 +#: wt-status.c:369 msgid "new commits, " msgstr "нови подавания, " -#: wt-status.c:372 +#: wt-status.c:371 msgid "modified content, " msgstr "променено съдържание, " -#: wt-status.c:374 +#: wt-status.c:373 msgid "untracked content, " msgstr "неследено съдържание, " -#: wt-status.c:824 +#: wt-status.c:847 #, c-format msgid "Your stash currently has %d entry" msgid_plural "Your stash currently has %d entries" msgstr[0] "Има %d скатаване." msgstr[1] "Има %d скатавания." -#: wt-status.c:856 +#: wt-status.c:879 msgid "Submodules changed but not updated:" msgstr "Подмодулите са променени, но не са обновени:" -#: wt-status.c:858 +#: wt-status.c:881 msgid "Submodule changes to be committed:" msgstr "Промени в подмодулите за подаване:" -#: wt-status.c:940 +#: wt-status.c:963 msgid "" "Do not modify or remove the line above.\n" "Everything below it will be ignored." @@ -4562,241 +4823,241 @@ msgstr "" "Не променяйте и не изтривайте горния ред.\n" "Всичко отдолу ще бъде изтрито." -#: wt-status.c:1053 +#: wt-status.c:1076 msgid "You have unmerged paths." msgstr "Някои пътища не са слети." -#: wt-status.c:1056 +#: wt-status.c:1079 msgid " (fix conflicts and run \"git commit\")" msgstr " (коригирайте конфликтите и изпълнете „git commit“)" -#: wt-status.c:1058 +#: wt-status.c:1081 msgid " (use \"git merge --abort\" to abort the merge)" msgstr " (използвайте „git merge --abort“, за да преустановите сливането)" -#: wt-status.c:1063 +#: wt-status.c:1086 msgid "All conflicts fixed but you are still merging." msgstr "Всички конфликти са решени, но продължавате сливането." -#: wt-status.c:1066 +#: wt-status.c:1089 msgid " (use \"git commit\" to conclude merge)" msgstr " (използвайте „git commit“, за да завършите сливането)" -#: wt-status.c:1076 +#: wt-status.c:1099 msgid "You are in the middle of an am session." msgstr "В момента прилагате поредица от кръпки чрез „git am“." -#: wt-status.c:1079 +#: wt-status.c:1102 msgid "The current patch is empty." msgstr "Текущата кръпка е празна." -#: wt-status.c:1083 +#: wt-status.c:1106 msgid " (fix conflicts and then run \"git am --continue\")" msgstr " (коригирайте конфликтите и изпълнете „git am --continue“)" -#: wt-status.c:1085 +#: wt-status.c:1108 msgid " (use \"git am --skip\" to skip this patch)" msgstr " (използвайте „git am --skip“, за да пропуснете тази кръпка)" -#: wt-status.c:1087 +#: wt-status.c:1110 msgid " (use \"git am --abort\" to restore the original branch)" msgstr "" " (използвайте „git am --abort“, за да възстановите първоначалния клон)" -#: wt-status.c:1219 +#: wt-status.c:1242 msgid "git-rebase-todo is missing." msgstr "„git-rebase-todo“ липсва." -#: wt-status.c:1221 +#: wt-status.c:1244 msgid "No commands done." msgstr "Не са изпълнени команди." -#: wt-status.c:1224 +#: wt-status.c:1247 #, c-format msgid "Last command done (%d command done):" msgid_plural "Last commands done (%d commands done):" msgstr[0] "Последна изпълнена команда (изпълнена е общо %d команда):" msgstr[1] "Последна изпълнена команда (изпълнени са общо %d команди):" -#: wt-status.c:1235 +#: wt-status.c:1258 #, c-format msgid " (see more in file %s)" msgstr " повече информация има във файла „%s“)" -#: wt-status.c:1240 +#: wt-status.c:1263 msgid "No commands remaining." msgstr "Не остават повече команди." -#: wt-status.c:1243 +#: wt-status.c:1266 #, c-format msgid "Next command to do (%d remaining command):" msgid_plural "Next commands to do (%d remaining commands):" msgstr[0] "Следваща команда за изпълнение (остава още %d команда):" msgstr[1] "Следваща команда за изпълнение (остават още %d команди):" -#: wt-status.c:1251 +#: wt-status.c:1274 msgid " (use \"git rebase --edit-todo\" to view and edit)" msgstr "" " (използвайте „git rebase --edit-todo“, за да разгледате и редактирате)" -#: wt-status.c:1264 +#: wt-status.c:1287 #, c-format msgid "You are currently rebasing branch '%s' on '%s'." msgstr "В момента пребазирате клона „%s“ върху „%s“." -#: wt-status.c:1269 +#: wt-status.c:1292 msgid "You are currently rebasing." msgstr "В момента пребазирате." -#: wt-status.c:1283 +#: wt-status.c:1306 msgid " (fix conflicts and then run \"git rebase --continue\")" msgstr " (коригирайте конфликтите и използвайте „git rebase --continue“)" -#: wt-status.c:1285 +#: wt-status.c:1308 msgid " (use \"git rebase --skip\" to skip this patch)" msgstr " (използвайте „git rebase --skip“, за да пропуснете тази кръпка)" -#: wt-status.c:1287 +#: wt-status.c:1310 msgid " (use \"git rebase --abort\" to check out the original branch)" msgstr "" " (използвайте „git rebase --abort“, за да възстановите първоначалния клон)" -#: wt-status.c:1293 +#: wt-status.c:1316 msgid " (all conflicts fixed: run \"git rebase --continue\")" msgstr " (всички конфликти са коригирани: изпълнете „git rebase --continue“)" -#: wt-status.c:1297 +#: wt-status.c:1320 #, c-format msgid "" "You are currently splitting a commit while rebasing branch '%s' on '%s'." msgstr "В момента разделяте подаване докато пребазирате клона „%s“ върху „%s“." -#: wt-status.c:1302 +#: wt-status.c:1325 msgid "You are currently splitting a commit during a rebase." msgstr "В момента разделяте подаване докато пребазирате." -#: wt-status.c:1305 +#: wt-status.c:1328 msgid " (Once your working directory is clean, run \"git rebase --continue\")" msgstr "" " (След като работното ви дърво стане чисто, използвайте „git rebase --" "continue“)" -#: wt-status.c:1309 +#: wt-status.c:1332 #, c-format msgid "You are currently editing a commit while rebasing branch '%s' on '%s'." msgstr "" "В момента редактирате подаване докато пребазирате клона „%s“ върху „%s“." -#: wt-status.c:1314 +#: wt-status.c:1337 msgid "You are currently editing a commit during a rebase." msgstr "В момента редактирате подаване докато пребазирате." -#: wt-status.c:1317 +#: wt-status.c:1340 msgid " (use \"git commit --amend\" to amend the current commit)" msgstr "" " (използвайте „git commit --amend“, за да редактирате текущото подаване)" -#: wt-status.c:1319 +#: wt-status.c:1342 msgid "" " (use \"git rebase --continue\" once you are satisfied with your changes)" msgstr "" " (използвайте „git rebase --continue“, след като завършите промените си)" -#: wt-status.c:1329 +#: wt-status.c:1352 #, c-format msgid "You are currently cherry-picking commit %s." msgstr "В момента отбирате подаването „%s“." -#: wt-status.c:1334 +#: wt-status.c:1357 msgid " (fix conflicts and run \"git cherry-pick --continue\")" msgstr " (коригирайте конфликтите и изпълнете „git cherry-pick --continue“)" -#: wt-status.c:1337 +#: wt-status.c:1360 msgid " (all conflicts fixed: run \"git cherry-pick --continue\")" msgstr "" " (всички конфликти са коригирани, изпълнете „git cherry-pick --continue“)" -#: wt-status.c:1339 +#: wt-status.c:1362 msgid " (use \"git cherry-pick --abort\" to cancel the cherry-pick operation)" msgstr "" " (използвайте „git cherry-pick --abort“, за да отмените всички действия с " "отбиране)" -#: wt-status.c:1348 +#: wt-status.c:1371 #, c-format msgid "You are currently reverting commit %s." msgstr "В момента отменяте подаване „%s“." -#: wt-status.c:1353 +#: wt-status.c:1376 msgid " (fix conflicts and run \"git revert --continue\")" msgstr " (коригирайте конфликтите и изпълнете „git revert --continue“)" -#: wt-status.c:1356 +#: wt-status.c:1379 msgid " (all conflicts fixed: run \"git revert --continue\")" msgstr " (всички конфликти са коригирани, изпълнете „git revert --continue“)" -#: wt-status.c:1358 +#: wt-status.c:1381 msgid " (use \"git revert --abort\" to cancel the revert operation)" msgstr "" " (използвайте „git revert --abort“, за да преустановите отмяната на " "подаване)" -#: wt-status.c:1369 +#: wt-status.c:1392 #, c-format msgid "You are currently bisecting, started from branch '%s'." msgstr "В момента търсите двоично, като сте стартирали от клон „%s“." -#: wt-status.c:1373 +#: wt-status.c:1396 msgid "You are currently bisecting." msgstr "В момента търсите двоично." -#: wt-status.c:1376 +#: wt-status.c:1399 msgid " (use \"git bisect reset\" to get back to the original branch)" msgstr "" " (използвайте „git bisect reset“, за да се върнете към първоначалното " "състояние и клон)" -#: wt-status.c:1573 +#: wt-status.c:1596 msgid "On branch " msgstr "На клон " -#: wt-status.c:1579 +#: wt-status.c:1602 msgid "interactive rebase in progress; onto " msgstr "извършвате интерактивно пребазиране върху " -#: wt-status.c:1581 +#: wt-status.c:1604 msgid "rebase in progress; onto " msgstr "извършвате пребазиране върху " -#: wt-status.c:1586 +#: wt-status.c:1609 msgid "HEAD detached at " msgstr "Указателят „HEAD“ не е свързан и е при " -#: wt-status.c:1588 +#: wt-status.c:1611 msgid "HEAD detached from " msgstr "Указателят „HEAD“ не е свързан и е отделѐн от " -#: wt-status.c:1591 +#: wt-status.c:1614 msgid "Not currently on any branch." msgstr "Извън всички клони." -#: wt-status.c:1611 +#: wt-status.c:1634 msgid "Initial commit" msgstr "Първоначално подаване" -#: wt-status.c:1612 +#: wt-status.c:1635 msgid "No commits yet" msgstr "Все още липсват подавания" -#: wt-status.c:1626 +#: wt-status.c:1649 msgid "Untracked files" msgstr "Неследени файлове" -#: wt-status.c:1628 +#: wt-status.c:1651 msgid "Ignored files" msgstr "Игнорирани файлове" -#: wt-status.c:1632 +#: wt-status.c:1655 #, c-format msgid "" "It took %.2f seconds to enumerate untracked files. 'status -uno'\n" @@ -4808,32 +5069,32 @@ msgstr "" "изпълнението, но не трябва да забравяте ръчно да добавяте новите файлове.\n" "За повече подробности погледнете „git status help“." -#: wt-status.c:1638 +#: wt-status.c:1661 #, c-format msgid "Untracked files not listed%s" msgstr "Неследените файлове не са изведени%s" -#: wt-status.c:1640 +#: wt-status.c:1663 msgid " (use -u option to show untracked files)" msgstr " (използвайте опцията „-u“, за да изведете неследените файлове)" -#: wt-status.c:1646 +#: wt-status.c:1669 msgid "No changes" msgstr "Няма промени" -#: wt-status.c:1651 +#: wt-status.c:1674 #, c-format msgid "no changes added to commit (use \"git add\" and/or \"git commit -a\")\n" msgstr "" "към индекса за подаване не са добавени промени (използвайте „git add“ и/или " "„git commit -a“)\n" -#: wt-status.c:1654 +#: wt-status.c:1677 #, c-format msgid "no changes added to commit\n" msgstr "към индекса за подаване не са добавени промени\n" -#: wt-status.c:1657 +#: wt-status.c:1680 #, c-format msgid "" "nothing added to commit but untracked files present (use \"git add\" to " @@ -4842,67 +5103,71 @@ msgstr "" "към индекса за подаване не са добавени промени, но има нови файлове " "(използвайте „git add“, за да започне тяхното следене)\n" -#: wt-status.c:1660 +#: wt-status.c:1683 #, c-format msgid "nothing added to commit but untracked files present\n" msgstr "към индекса за подаване не са добавени промени, но има нови файлове\n" -#: wt-status.c:1663 +#: wt-status.c:1686 #, c-format msgid "nothing to commit (create/copy files and use \"git add\" to track)\n" msgstr "" "липсват каквито и да е промени (създайте или копирайте файлове и използвайте " "„git add“, за да започне тяхното следене)\n" -#: wt-status.c:1666 wt-status.c:1671 +#: wt-status.c:1689 wt-status.c:1694 #, c-format msgid "nothing to commit\n" msgstr "липсват каквито и да е промени\n" -#: wt-status.c:1669 +#: wt-status.c:1692 #, c-format msgid "nothing to commit (use -u to show untracked files)\n" msgstr "" "липсват каквито и да е промени (използвайте опцията „-u“, за да се изведат и " "неследените файлове)\n" -#: wt-status.c:1673 +#: wt-status.c:1696 #, c-format msgid "nothing to commit, working tree clean\n" msgstr "липсват каквито и да е промени, работното дърво е чисто\n" -#: wt-status.c:1785 +#: wt-status.c:1809 msgid "No commits yet on " msgstr "Все още липсват подавания в " -#: wt-status.c:1789 +#: wt-status.c:1813 msgid "HEAD (no branch)" msgstr "HEAD (извън клон)" -#: wt-status.c:1818 wt-status.c:1826 +#: wt-status.c:1844 +msgid "different" +msgstr "различен" + +#: wt-status.c:1846 wt-status.c:1854 msgid "behind " msgstr "назад с " -#: wt-status.c:1821 wt-status.c:1824 +#: wt-status.c:1849 wt-status.c:1852 msgid "ahead " msgstr "напред с " #. TRANSLATORS: the action is e.g. "pull with rebase" -#: wt-status.c:2318 +#: wt-status.c:2358 #, c-format msgid "cannot %s: You have unstaged changes." msgstr "не може да извършите „%s“, защото има промени, които не са в индекса." -#: wt-status.c:2324 +#: wt-status.c:2364 msgid "additionally, your index contains uncommitted changes." msgstr "освен това в индекса има неподадени промени." -#: wt-status.c:2326 +#: wt-status.c:2366 #, c-format msgid "cannot %s: Your index contains uncommitted changes." msgstr "не може да извършите „%s“, защото в индекса има неподадени промени." -#: compat/precompose_utf8.c:58 builtin/clone.c:437 +#: compat/precompose_utf8.c:58 builtin/clone.c:440 #, c-format msgid "failed to unlink '%s'" msgstr "неуспешно изтриване на „%s“" @@ -4916,7 +5181,7 @@ msgstr "git add [ОПЦИЯ…] [--] ПЪТ…" msgid "unexpected diff status %c" msgstr "неочакван изходен код при генериране на разлика: %c" -#: builtin/add.c:88 builtin/commit.c:291 +#: builtin/add.c:88 builtin/commit.c:257 msgid "updating files failed" msgstr "неуспешно обновяване на файловете" @@ -4965,7 +5230,7 @@ msgid "The following paths are ignored by one of your .gitignore files:\n" msgstr "" "Следните пътища ще бъдат игнорирани според някой от файловете „.gitignore“:\n" -#: builtin/add.c:291 builtin/clean.c:911 builtin/fetch.c:133 builtin/mv.c:124 +#: builtin/add.c:291 builtin/clean.c:911 builtin/fetch.c:146 builtin/mv.c:124 #: builtin/prune-packed.c:55 builtin/pull.c:207 builtin/push.c:541 #: builtin/remote.c:1333 builtin/rm.c:242 builtin/send-pack.c:164 msgid "dry run" @@ -4975,7 +5240,7 @@ msgstr "пробно изпълнение" msgid "interactive picking" msgstr "интерактивно отбиране на промени" -#: builtin/add.c:295 builtin/checkout.c:1137 builtin/reset.c:310 +#: builtin/add.c:295 builtin/checkout.c:1128 builtin/reset.c:302 msgid "select hunks interactively" msgstr "интерактивен избор на парчета код" @@ -5104,10 +5369,10 @@ msgstr "Нищо не е зададено и нищо не е добавено.\ msgid "Maybe you wanted to say 'git add .'?\n" msgstr "Вероятно искахте да използвате „git add .“?\n" -#: builtin/add.c:449 builtin/check-ignore.c:176 builtin/checkout.c:281 -#: builtin/checkout.c:484 builtin/clean.c:958 builtin/commit.c:350 -#: builtin/diff-tree.c:114 builtin/mv.c:143 builtin/reset.c:249 -#: builtin/rm.c:271 builtin/submodule--helper.c:311 +#: builtin/add.c:449 builtin/check-ignore.c:177 builtin/checkout.c:280 +#: builtin/checkout.c:483 builtin/clean.c:958 builtin/commit.c:316 +#: builtin/diff-tree.c:114 builtin/mv.c:144 builtin/reset.c:241 +#: builtin/rm.c:271 builtin/submodule--helper.c:326 msgid "index file corrupt" msgstr "файлът с индекса е повреден" @@ -5160,59 +5425,59 @@ msgstr "неправилно отместване на часовия пояс" msgid "Patch format detection failed." msgstr "Форматът на кръпката не може да бъде определен." -#: builtin/am.c:1013 builtin/clone.c:402 +#: builtin/am.c:1013 builtin/clone.c:405 #, c-format msgid "failed to create directory '%s'" msgstr "директорията „%s“ не може да бъде създадена" -#: builtin/am.c:1017 +#: builtin/am.c:1018 msgid "Failed to split patches." msgstr "Кръпките не могат да бъдат разделени." -#: builtin/am.c:1146 builtin/commit.c:376 +#: builtin/am.c:1148 builtin/commit.c:342 msgid "unable to write index file" msgstr "индексът не може да бъде записан" -#: builtin/am.c:1160 +#: builtin/am.c:1162 #, c-format msgid "When you have resolved this problem, run \"%s --continue\"." msgstr "След коригирането на този проблем изпълнете „%s --continue“." -#: builtin/am.c:1161 +#: builtin/am.c:1163 #, c-format msgid "If you prefer to skip this patch, run \"%s --skip\" instead." msgstr "Ако предпочитате да прескочите тази кръпка, изпълнете „%s --skip“." -#: builtin/am.c:1162 +#: builtin/am.c:1164 #, c-format msgid "To restore the original branch and stop patching, run \"%s --abort\"." msgstr "За да се върнете към първоначалното състояние, изпълнете „%s --abort“." -#: builtin/am.c:1269 +#: builtin/am.c:1271 msgid "Patch is empty." msgstr "Кръпката е празна." -#: builtin/am.c:1335 +#: builtin/am.c:1337 #, c-format msgid "invalid ident line: %.*s" msgstr "грешен ред с идентичност: %.*s" -#: builtin/am.c:1357 +#: builtin/am.c:1359 #, c-format msgid "unable to parse commit %s" msgstr "подаването не може да бъде анализирано: %s" -#: builtin/am.c:1550 +#: builtin/am.c:1554 msgid "Repository lacks necessary blobs to fall back on 3-way merge." msgstr "" "В хранилището липсват необходимите обекти BLOB, за да се премине към тройно " "сливане." -#: builtin/am.c:1552 +#: builtin/am.c:1556 msgid "Using index info to reconstruct a base tree..." msgstr "Базовото дърво се реконструира от информацията в индекса…" -#: builtin/am.c:1571 +#: builtin/am.c:1575 msgid "" "Did you hand edit your patch?\n" "It does not apply to blobs recorded in its index." @@ -5220,39 +5485,30 @@ msgstr "" "Кръпката не може да се приложи към обектите BLOB в индекса.\n" "Да не би да сте я редактирали на ръка?" -#: builtin/am.c:1577 +#: builtin/am.c:1581 msgid "Falling back to patching base and 3-way merge..." msgstr "Преминаване към прилагане на кръпка към базата и тройно сливане…" -#: builtin/am.c:1602 +#: builtin/am.c:1606 msgid "Failed to merge in the changes." msgstr "Неуспешно сливане на промените." -#: builtin/am.c:1626 builtin/merge.c:642 -msgid "git write-tree failed to write a tree" -msgstr "Командата „git write-tree“ не успя да запише обект-дърво" - -#: builtin/am.c:1633 +#: builtin/am.c:1637 msgid "applying to an empty history" msgstr "прилагане върху празна история" -#: builtin/am.c:1646 builtin/commit.c:1798 builtin/merge.c:825 -#: builtin/merge.c:850 -msgid "failed to write commit object" -msgstr "обектът за подаването не може да бъде записан" - -#: builtin/am.c:1679 builtin/am.c:1683 +#: builtin/am.c:1683 builtin/am.c:1687 #, c-format msgid "cannot resume: %s does not exist." msgstr "не може да се продължи — „%s“ не съществува." -#: builtin/am.c:1699 +#: builtin/am.c:1703 msgid "cannot be interactive without stdin connected to a terminal." msgstr "" "За интерактивно изпълнение е необходимо стандартният\n" "вход да е свързан с терминал, а в момента не е." -#: builtin/am.c:1704 +#: builtin/am.c:1708 msgid "Commit Body is:" msgstr "Тялото на кръпката за прилагане е:" @@ -5260,38 +5516,39 @@ msgstr "Тялото на кръпката за прилагане е:" #. in your translation. The program will only accept English #. input at this point. #. -#: builtin/am.c:1714 +#: builtin/am.c:1718 msgid "Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all: " msgstr "" "Прилагане? „y“ — да/„n“ — не/„e“ — редактиране/„v“ — преглед/„a“ — приемане " "на всичко:" -#: builtin/am.c:1764 +#: builtin/am.c:1768 #, c-format msgid "Dirty index: cannot apply patches (dirty: %s)" msgstr "" "Индексът не е чист: кръпките не могат да бъдат приложени (замърсени са: %s)" -#: builtin/am.c:1804 builtin/am.c:1876 +#: builtin/am.c:1808 builtin/am.c:1879 #, c-format msgid "Applying: %.*s" msgstr "Прилагане: %.*s" -#: builtin/am.c:1820 +#: builtin/am.c:1824 msgid "No changes -- Patch already applied." msgstr "Без промени — кръпката вече е приложена." -#: builtin/am.c:1828 +#: builtin/am.c:1832 #, c-format msgid "Patch failed at %s %.*s" msgstr "Неуспешно прилагане на кръпка при %s %.*s“" -#: builtin/am.c:1834 -#, c-format -msgid "The copy of the patch that failed is found in: %s" -msgstr "Дубликат на проблемната кръпка се намира в: %s" +#: builtin/am.c:1838 +msgid "Use 'git am --show-current-patch' to see the failed patch" +msgstr "" +"За да видите неуспешно приложени кръпки, използвайте опцията „git am --show-" +"current-patch“ to see the failed patch" -#: builtin/am.c:1879 +#: builtin/am.c:1882 msgid "" "No changes - did you forget to use 'git add'?\n" "If there is nothing left to stage, chances are that something else\n" @@ -5301,7 +5558,7 @@ msgstr "" "Ако няма друга промяна за включване в индекса, най-вероятно някоя друга\n" "кръпка е довела до същите промени и в такъв случай просто пропуснете тази." -#: builtin/am.c:1886 +#: builtin/am.c:1889 msgid "" "You still have unmerged paths in your index.\n" "You should 'git add' each file with resolved conflicts to mark them as " @@ -5312,17 +5569,17 @@ msgstr "" "След корекция на конфликтите изпълнете „git add“ върху поправените файлове.\n" "За да приемете „изтрити от тях“, изпълнете „git rm“ върху изтритите файлове." -#: builtin/am.c:1993 builtin/am.c:1997 builtin/am.c:2009 builtin/reset.c:332 -#: builtin/reset.c:340 +#: builtin/am.c:1996 builtin/am.c:2000 builtin/am.c:2012 builtin/reset.c:324 +#: builtin/reset.c:332 #, c-format msgid "Could not parse object '%s'." msgstr "„%s“ не е разпознат като обект." -#: builtin/am.c:2045 +#: builtin/am.c:2048 msgid "failed to clean index" msgstr "индексът не може да бъде изчистен" -#: builtin/am.c:2080 +#: builtin/am.c:2083 msgid "" "You seem to have moved HEAD since the last 'am' failure.\n" "Not rewinding to ORIG_HEAD" @@ -5333,138 +5590,147 @@ msgstr "" "сочи към\n" "„ORIG_HEAD“" -#: builtin/am.c:2143 +#: builtin/am.c:2174 #, c-format msgid "Invalid value for --patch-format: %s" msgstr "Неправилна стойност за „--patch-format“: „%s“" -#: builtin/am.c:2176 +#: builtin/am.c:2210 msgid "git am [] [( | )...]" msgstr "git am [ОПЦИЯ…] [(ФАЙЛ_С_ПОЩА|ДИРЕКТОРИЯ_С_ПОЩА)…]" -#: builtin/am.c:2177 +#: builtin/am.c:2211 msgid "git am [] (--continue | --skip | --abort)" msgstr "git am [ОПЦИЯ…] (--continue | --quit | --abort)" -#: builtin/am.c:2183 +#: builtin/am.c:2217 msgid "run interactively" msgstr "интерактивна работа" -#: builtin/am.c:2185 +#: builtin/am.c:2219 msgid "historical option -- no-op" msgstr "изоставена опция, съществува по исторически причини, нищо не прави" -#: builtin/am.c:2187 +#: builtin/am.c:2221 msgid "allow fall back on 3way merging if needed" msgstr "да се преминава към тройно сливане при нужда." -#: builtin/am.c:2188 builtin/init-db.c:484 builtin/prune-packed.c:57 -#: builtin/repack.c:180 +#: builtin/am.c:2222 builtin/init-db.c:484 builtin/prune-packed.c:57 +#: builtin/repack.c:182 msgid "be quiet" msgstr "без извеждане на информация" -#: builtin/am.c:2190 +#: builtin/am.c:2224 msgid "add a Signed-off-by line to the commit message" msgstr "добавяне на ред за подпис „Signed-off-by“ в съобщението за подаване" -#: builtin/am.c:2193 +#: builtin/am.c:2227 msgid "recode into utf8 (default)" msgstr "прекодиране в UTF-8 (стандартно)" -#: builtin/am.c:2195 +#: builtin/am.c:2229 msgid "pass -k flag to git-mailinfo" msgstr "подаване на опцията „-k“ на командата „git-mailinfo“" -#: builtin/am.c:2197 +#: builtin/am.c:2231 msgid "pass -b flag to git-mailinfo" msgstr "подаване на опцията „-b“ на командата „git-mailinfo“" -#: builtin/am.c:2199 +#: builtin/am.c:2233 msgid "pass -m flag to git-mailinfo" msgstr "подаване на опцията „-m“ на командата „git-mailinfo“" -#: builtin/am.c:2201 +#: builtin/am.c:2235 msgid "pass --keep-cr flag to git-mailsplit for mbox format" msgstr "" "подаване на опцията „--keep-cr“ на командата „git-mailsplit“ за формат „mbox“" -#: builtin/am.c:2204 +#: builtin/am.c:2238 msgid "do not pass --keep-cr flag to git-mailsplit independent of am.keepcr" msgstr "" "без подаване на опцията „--keep-cr“ на командата „git-mailsplit“ независимо " "от „am.keepcr“" -#: builtin/am.c:2207 +#: builtin/am.c:2241 msgid "strip everything before a scissors line" msgstr "пропускане на всичко преди реда за отрязване" -#: builtin/am.c:2209 builtin/am.c:2212 builtin/am.c:2215 builtin/am.c:2218 -#: builtin/am.c:2221 builtin/am.c:2224 builtin/am.c:2227 builtin/am.c:2230 -#: builtin/am.c:2236 +#: builtin/am.c:2243 builtin/am.c:2246 builtin/am.c:2249 builtin/am.c:2252 +#: builtin/am.c:2255 builtin/am.c:2258 builtin/am.c:2261 builtin/am.c:2264 +#: builtin/am.c:2270 msgid "pass it through git-apply" msgstr "прекарване през „git-apply“" -#: builtin/am.c:2226 builtin/fmt-merge-msg.c:665 builtin/fmt-merge-msg.c:668 -#: builtin/grep.c:845 builtin/merge.c:205 builtin/pull.c:145 builtin/pull.c:203 -#: builtin/repack.c:189 builtin/repack.c:193 builtin/repack.c:195 -#: builtin/show-branch.c:631 builtin/show-ref.c:169 builtin/tag.c:377 -#: parse-options.h:132 parse-options.h:134 parse-options.h:245 +#: builtin/am.c:2260 builtin/fmt-merge-msg.c:665 builtin/fmt-merge-msg.c:668 +#: builtin/grep.c:853 builtin/merge.c:206 builtin/pull.c:145 builtin/pull.c:203 +#: builtin/repack.c:191 builtin/repack.c:195 builtin/repack.c:197 +#: builtin/show-branch.c:631 builtin/show-ref.c:169 builtin/tag.c:382 +#: parse-options.h:144 parse-options.h:146 parse-options.h:257 msgid "n" msgstr "БРОЙ" -#: builtin/am.c:2232 builtin/branch.c:629 builtin/for-each-ref.c:38 -#: builtin/replace.c:444 builtin/tag.c:412 builtin/verify-tag.c:39 +#: builtin/am.c:2266 builtin/branch.c:629 builtin/for-each-ref.c:38 +#: builtin/replace.c:445 builtin/tag.c:418 builtin/verify-tag.c:39 msgid "format" msgstr "ФОРМАТ" -#: builtin/am.c:2233 +#: builtin/am.c:2267 msgid "format the patch(es) are in" msgstr "формат на кръпките" -#: builtin/am.c:2239 +#: builtin/am.c:2273 msgid "override error message when patch failure occurs" msgstr "избрано от вас съобщение за грешка при прилагане на кръпки" -#: builtin/am.c:2241 +#: builtin/am.c:2275 msgid "continue applying patches after resolving a conflict" msgstr "продължаване на прилагането на кръпки след коригирането на конфликт" -#: builtin/am.c:2244 +#: builtin/am.c:2278 msgid "synonyms for --continue" msgstr "синоними на „--continue“" -#: builtin/am.c:2247 +#: builtin/am.c:2281 msgid "skip the current patch" msgstr "прескачане на текущата кръпка" -#: builtin/am.c:2250 +#: builtin/am.c:2284 msgid "restore the original branch and abort the patching operation." msgstr "" "възстановяване на първоначалното състояние на клона и преустановяване на " "прилагането на кръпката." -#: builtin/am.c:2254 +#: builtin/am.c:2287 +msgid "abort the patching operation but keep HEAD where it is." +msgstr "" +"преустановяване на прилагането на кръпката без промяна към кое сочи „HEAD“." + +#: builtin/am.c:2290 +msgid "show the patch being applied." +msgstr "показване на прилаганата кръпка." + +#: builtin/am.c:2294 msgid "lie about committer date" msgstr "дата за подаване различна от първоначалната" -#: builtin/am.c:2256 +#: builtin/am.c:2296 msgid "use current timestamp for author date" msgstr "използване на текущото време като това за автор" -#: builtin/am.c:2258 builtin/commit.c:1636 builtin/merge.c:236 -#: builtin/pull.c:178 builtin/revert.c:112 builtin/tag.c:392 +#: builtin/am.c:2298 builtin/commit.c:1431 builtin/merge.c:237 +#: builtin/pull.c:178 builtin/revert.c:112 builtin/tag.c:398 msgid "key-id" msgstr "ИДЕНТИФИКАТОР_НА_КЛЮЧ" -#: builtin/am.c:2259 +#: builtin/am.c:2299 msgid "GPG-sign commits" msgstr "подписване на подаванията с GPG" -#: builtin/am.c:2262 +#: builtin/am.c:2302 msgid "(internal use for git-rebase)" msgstr "(ползва се вътрешно за „git-rebase“)" -#: builtin/am.c:2280 +#: builtin/am.c:2320 msgid "" "The -b/--binary option has been a no-op for long time, and\n" "it will be removed. Please do not use it anymore." @@ -5472,18 +5738,18 @@ msgstr "" "Опциите „-b“/„--binary“ отдавна не правят нищо и\n" "ще бъдат премахнати в бъдеще. Не ги ползвайте." -#: builtin/am.c:2287 +#: builtin/am.c:2327 msgid "failed to read the index" msgstr "неуспешно изчитане на индекса" -#: builtin/am.c:2302 +#: builtin/am.c:2342 #, c-format msgid "previous rebase directory %s still exists but mbox given." msgstr "" "предишната директория за пребазиране „%s“ все още съществува, а е зададен " "файл „mbox“." -#: builtin/am.c:2326 +#: builtin/am.c:2366 #, c-format msgid "" "Stray %s directory found.\n" @@ -5492,7 +5758,7 @@ msgstr "" "Открита е излишна директория „%s“.\n" "Можете да я изтриете с командата „git am --abort“." -#: builtin/am.c:2332 +#: builtin/am.c:2372 msgid "Resolve operation not in progress, we are not resuming." msgstr "В момента не тече операция по коригиране и няма как да се продължи." @@ -5514,8 +5780,9 @@ msgid "git archive: Remote with no URL" msgstr "git archive: Липсва адрес за отдалеченото хранилище" #: builtin/archive.c:58 -msgid "git archive: expected ACK/NAK, got EOF" -msgstr "git archive: очакваше се „ACK“/„NAK“, а бе получен „EOF“" +msgid "git archive: expected ACK/NAK, got a flush packet" +msgstr "" +"git archive: очакваше се „ACK“/„NAK“, а бе получен изчистващ пакет „flush“" #: builtin/archive.c:61 #, c-format @@ -5602,125 +5869,125 @@ msgstr "git blame [ОПЦИЯ…] [ОПЦИЯ_ЗА_ВЕРСИЯТА…] [ВЕР msgid " are documented in git-rev-list(1)" msgstr "ОПЦИИте_ЗА_ВЕРСИЯТА са документирани в ръководството git-rev-list(1)" -#: builtin/blame.c:668 +#: builtin/blame.c:677 msgid "Show blame entries as we find them, incrementally" msgstr "Извеждане на анотациите с намирането им, последователно" -#: builtin/blame.c:669 +#: builtin/blame.c:678 msgid "Show blank SHA-1 for boundary commits (Default: off)" msgstr "" "Извеждане на празни суми по SHA1 за граничните подавания (стандартно опцията " "е изключена)" -#: builtin/blame.c:670 +#: builtin/blame.c:679 msgid "Do not treat root commits as boundaries (Default: off)" msgstr "" "Началните подавания да не се считат за гранични (стандартно опцията е " "изключена)" -#: builtin/blame.c:671 +#: builtin/blame.c:680 msgid "Show work cost statistics" msgstr "Извеждане на статистика за извършените действия" -#: builtin/blame.c:672 +#: builtin/blame.c:681 msgid "Force progress reporting" msgstr "Принудително извеждане на напредъка" -#: builtin/blame.c:673 +#: builtin/blame.c:682 msgid "Show output score for blame entries" msgstr "Извеждане на допълнителна информация за определянето на анотациите" -#: builtin/blame.c:674 +#: builtin/blame.c:683 msgid "Show original filename (Default: auto)" msgstr "" "Извеждане на първоначалното име на файл (стандартно това е автоматично)" -#: builtin/blame.c:675 +#: builtin/blame.c:684 msgid "Show original linenumber (Default: off)" msgstr "" "Извеждане на първоначалният номер на ред (стандартно опцията е изключена)" -#: builtin/blame.c:676 +#: builtin/blame.c:685 msgid "Show in a format designed for machine consumption" msgstr "Извеждане във формат за по-нататъшна обработка" -#: builtin/blame.c:677 +#: builtin/blame.c:686 msgid "Show porcelain format with per-line commit information" msgstr "" "Извеждане във формат за команди от потребителско ниво с информация на всеки " "ред" -#: builtin/blame.c:678 +#: builtin/blame.c:687 msgid "Use the same output mode as git-annotate (Default: off)" msgstr "" "Използване на същия формат като „git-annotate“ (стандартно опцията е " "изключена)" -#: builtin/blame.c:679 +#: builtin/blame.c:688 msgid "Show raw timestamp (Default: off)" msgstr "Извеждане на неформатирани времена (стандартно опцията е изключена)" -#: builtin/blame.c:680 +#: builtin/blame.c:689 msgid "Show long commit SHA1 (Default: off)" msgstr "Извеждане на пълните суми по SHA1 (стандартно опцията е изключена)" -#: builtin/blame.c:681 +#: builtin/blame.c:690 msgid "Suppress author name and timestamp (Default: off)" msgstr "Без име на автор и време на промяна (стандартно опцията е изключена)" -#: builtin/blame.c:682 +#: builtin/blame.c:691 msgid "Show author email instead of name (Default: off)" msgstr "" "Извеждане на е-пощата на автора, а не името му (стандартно опцията е " "изключена)" -#: builtin/blame.c:683 +#: builtin/blame.c:692 msgid "Ignore whitespace differences" msgstr "Без разлики в знаците за интервали" -#: builtin/blame.c:690 +#: builtin/blame.c:699 msgid "Use an experimental heuristic to improve diffs" msgstr "Подобряване на разликите чрез експериментална евристика" -#: builtin/blame.c:692 +#: builtin/blame.c:701 msgid "Spend extra cycles to find better match" msgstr "Допълнителни изчисления за по-добри резултати" -#: builtin/blame.c:693 +#: builtin/blame.c:702 msgid "Use revisions from instead of calling git-rev-list" msgstr "Изчитане на версиите от ФАЙЛ, а не чрез изпълнение на „git-rev-list“" -#: builtin/blame.c:694 +#: builtin/blame.c:703 msgid "Use 's contents as the final image" msgstr "Използване на съдържанието на ФАЙЛа като крайно положение" -#: builtin/blame.c:695 builtin/blame.c:696 +#: builtin/blame.c:704 builtin/blame.c:705 msgid "score" msgstr "напасване на редовете" -#: builtin/blame.c:695 +#: builtin/blame.c:704 msgid "Find line copies within and across files" msgstr "" "Търсене на копирани редове както в рамките на един файл, така и от един файл " "към друг" -#: builtin/blame.c:696 +#: builtin/blame.c:705 msgid "Find line movements within and across files" msgstr "" "Търсене на преместени редове както в рамките на един файл, така и от един " "файл към друг" -#: builtin/blame.c:697 +#: builtin/blame.c:706 msgid "n,m" msgstr "n,m" -#: builtin/blame.c:697 +#: builtin/blame.c:706 msgid "Process only line range n,m, counting from 1" msgstr "" "Информация само за редовете в диапазона от n до m включително. Броенето " "започва от 1" -#: builtin/blame.c:744 +#: builtin/blame.c:753 msgid "--progress can't be used with --incremental or porcelain formats" msgstr "" "опцията „--progress“ е несъвместима с „--incremental“ и форма̀та на командите " @@ -5734,18 +6001,18 @@ msgstr "" #. your language may need more or fewer display #. columns. #. -#: builtin/blame.c:795 +#: builtin/blame.c:804 msgid "4 years, 11 months ago" msgstr "преди 4 години и 11 месеца" -#: builtin/blame.c:882 +#: builtin/blame.c:890 #, c-format msgid "file %s has only %lu line" msgid_plural "file %s has only %lu lines" msgstr[0] "има само %2$lu ред във файла „%1$s“" msgstr[1] "има само %2$lu реда във файла „%1$s“" -#: builtin/blame.c:928 +#: builtin/blame.c:936 msgid "Blaming lines" msgstr "Анотирани редове" @@ -6037,17 +6304,17 @@ msgstr "извеждане само на неслетите клони" msgid "list branches in columns" msgstr "извеждане по колони" -#: builtin/branch.c:622 builtin/for-each-ref.c:40 builtin/tag.c:405 +#: builtin/branch.c:622 builtin/for-each-ref.c:40 builtin/tag.c:411 msgid "key" msgstr "КЛЮЧ" -#: builtin/branch.c:623 builtin/for-each-ref.c:41 builtin/tag.c:406 +#: builtin/branch.c:623 builtin/for-each-ref.c:41 builtin/tag.c:412 msgid "field name to sort on" msgstr "име на полето, по което да е подредбата" #: builtin/branch.c:625 builtin/for-each-ref.c:43 builtin/notes.c:408 #: builtin/notes.c:411 builtin/notes.c:571 builtin/notes.c:574 -#: builtin/tag.c:408 +#: builtin/tag.c:414 msgid "object" msgstr "ОБЕКТ" @@ -6055,16 +6322,16 @@ msgstr "ОБЕКТ" msgid "print only branches of the object" msgstr "извеждане само на клоните на ОБЕКТА" -#: builtin/branch.c:628 builtin/for-each-ref.c:49 builtin/tag.c:415 +#: builtin/branch.c:628 builtin/for-each-ref.c:49 builtin/tag.c:421 msgid "sorting and filtering are case insensitive" msgstr "подредбата и филтрирането третират еднакво малките и главните букви" -#: builtin/branch.c:629 builtin/for-each-ref.c:38 builtin/tag.c:413 +#: builtin/branch.c:629 builtin/for-each-ref.c:38 builtin/tag.c:419 #: builtin/verify-tag.c:39 msgid "format to use for the output" msgstr "ФОРМАТ за изхода" -#: builtin/branch.c:652 builtin/clone.c:730 +#: builtin/branch.c:652 builtin/clone.c:735 msgid "HEAD not found below refs/heads!" msgstr "В директорията „refs/heads“ липсва файл „HEAD“" @@ -6163,7 +6430,7 @@ msgstr "За създаването на пратка е необходимо х msgid "Need a repository to unbundle." msgstr "За приемането на пратка е необходимо хранилище." -#: builtin/cat-file.c:521 +#: builtin/cat-file.c:523 msgid "" "git cat-file (-t [--allow-unknown-type] | -s [--allow-unknown-type] | -e | -" "p | | --textconv | --filters) [--path=] " @@ -6171,7 +6438,7 @@ msgstr "" "git cat-file (-t [--allow-unknown-type] | -s [--allow-unknown-type] | -e | -" "p | ВИД | --textconv --filters) [--path=ПЪТ] ОБЕКТ" -#: builtin/cat-file.c:522 +#: builtin/cat-file.c:524 msgid "" "git cat-file (--batch | --batch-check) [--follow-symlinks] [--textconv | --" "filters]" @@ -6179,71 +6446,71 @@ msgstr "" "git cat-file (--batch | --batch-check) [--follow-symlinks] [--textconv | --" "filters]" -#: builtin/cat-file.c:559 +#: builtin/cat-file.c:561 msgid " can be one of: blob, tree, commit, tag" msgstr "" "ВИДът може да е: „blob“ (обект BLOB), „tree“ (дърво), „commit“ (подаване), " "„tag“ (етикет)" -#: builtin/cat-file.c:560 +#: builtin/cat-file.c:562 msgid "show object type" msgstr "извеждане на вида на обект" -#: builtin/cat-file.c:561 +#: builtin/cat-file.c:563 msgid "show object size" msgstr "извеждане на размера на обект" -#: builtin/cat-file.c:563 +#: builtin/cat-file.c:565 msgid "exit with zero when there's no error" msgstr "изход с 0, когато няма грешка" -#: builtin/cat-file.c:564 +#: builtin/cat-file.c:566 msgid "pretty-print object's content" msgstr "форматирано извеждане на съдържанието на обекта" -#: builtin/cat-file.c:566 +#: builtin/cat-file.c:568 msgid "for blob objects, run textconv on object's content" msgstr "" "да се стартира програмата зададена в настройката „textconv“ за преобразуване " "на съдържанието на обекта BLOB" -#: builtin/cat-file.c:568 +#: builtin/cat-file.c:570 msgid "for blob objects, run filters on object's content" msgstr "" "да се стартират програмите за преобразуване на съдържанието на обектите BLOB" -#: builtin/cat-file.c:569 git-submodule.sh:931 +#: builtin/cat-file.c:571 git-submodule.sh:878 msgid "blob" msgstr "обект BLOB" -#: builtin/cat-file.c:570 +#: builtin/cat-file.c:572 msgid "use a specific path for --textconv/--filters" msgstr "опциите „--textconv“/„--filters“ изискват път" -#: builtin/cat-file.c:572 +#: builtin/cat-file.c:574 msgid "allow -s and -t to work with broken/corrupt objects" msgstr "позволяване на опциите „-s“ и „-t“ да работят с повредени обекти" -#: builtin/cat-file.c:573 +#: builtin/cat-file.c:575 msgid "buffer --batch output" msgstr "буфериране на изхода от „--batch“" -#: builtin/cat-file.c:575 +#: builtin/cat-file.c:577 msgid "show info and content of objects fed from the standard input" msgstr "" "извеждане на информация и съдържание на обектите подадени на стандартния вход" -#: builtin/cat-file.c:578 +#: builtin/cat-file.c:580 msgid "show info about objects fed from the standard input" msgstr "извеждане на информация за обектите подадени на стандартния вход" -#: builtin/cat-file.c:581 +#: builtin/cat-file.c:583 msgid "follow in-tree symlinks (used with --batch or --batch-check)" msgstr "" "следване на символните връзки сочещи в дървото (ползва се с „--batch“ или „--" "batch-check“)" -#: builtin/cat-file.c:583 +#: builtin/cat-file.c:585 msgid "show all objects with --batch or --batch-check" msgstr "извеждане на всички обекти с „--batch“ или „--batch-check“" @@ -6263,7 +6530,7 @@ msgstr "извеждане на всички атрибути, зададени msgid "use .gitattributes only from the index" msgstr "използване на файла „.gitattributes“ само от индекса" -#: builtin/check-attr.c:22 builtin/check-ignore.c:24 builtin/hash-object.c:99 +#: builtin/check-attr.c:22 builtin/check-ignore.c:24 builtin/hash-object.c:100 msgid "read file names from stdin" msgstr "изчитане на имената на файловете от стандартния вход" @@ -6271,7 +6538,7 @@ msgstr "изчитане на имената на файловете от ста msgid "terminate input and output records by a NUL character" msgstr "разделяне на входните и изходните записи с нулевия знак „NUL“" -#: builtin/check-ignore.c:20 builtin/checkout.c:1118 builtin/gc.c:358 +#: builtin/check-ignore.c:20 builtin/checkout.c:1106 builtin/gc.c:358 msgid "suppress progress reporting" msgstr "без показване на напредъка" @@ -6283,27 +6550,27 @@ msgstr "извеждане на несъвпадащите пътища" msgid "ignore index when checking" msgstr "прескачане на индекса при проверката" -#: builtin/check-ignore.c:158 +#: builtin/check-ignore.c:159 msgid "cannot specify pathnames with --stdin" msgstr "опцията „--stdin“ е несъвместима с имена на пътища" -#: builtin/check-ignore.c:161 +#: builtin/check-ignore.c:162 msgid "-z only makes sense with --stdin" msgstr "опцията „-z“ изисква „--stdin“" -#: builtin/check-ignore.c:163 +#: builtin/check-ignore.c:164 msgid "no path specified" msgstr "не е зададен път" -#: builtin/check-ignore.c:167 +#: builtin/check-ignore.c:168 msgid "--quiet is only valid with a single pathname" msgstr "опцията „--quiet“ изисква да е подаден точно един път" -#: builtin/check-ignore.c:169 +#: builtin/check-ignore.c:170 msgid "cannot have both --quiet and --verbose" msgstr "опциите „--quiet“ и „--verbose“ са несъвместими" -#: builtin/check-ignore.c:172 +#: builtin/check-ignore.c:173 msgid "--non-matching is only valid with --verbose" msgstr "опцията „--non-matching“ изисква „--verbose“" @@ -6361,9 +6628,9 @@ msgid "write the content to temporary files" msgstr "записване на съдържанието във временни файлове" #: builtin/checkout-index.c:173 builtin/column.c:31 -#: builtin/submodule--helper.c:866 builtin/submodule--helper.c:869 -#: builtin/submodule--helper.c:875 builtin/submodule--helper.c:1237 -#: builtin/worktree.c:552 +#: builtin/submodule--helper.c:1203 builtin/submodule--helper.c:1206 +#: builtin/submodule--helper.c:1212 builtin/submodule--helper.c:1574 +#: builtin/worktree.c:570 msgid "string" msgstr "НИЗ" @@ -6408,81 +6675,81 @@ msgstr "някоя от необходимите версии липсва в п msgid "path '%s': cannot merge" msgstr "пътят „%s“ не може да бъде слян" -#: builtin/checkout.c:232 +#: builtin/checkout.c:231 #, c-format msgid "Unable to add merge result for '%s'" msgstr "Резултатът за „%s“ не може да бъде слян" -#: builtin/checkout.c:254 builtin/checkout.c:257 builtin/checkout.c:260 -#: builtin/checkout.c:263 +#: builtin/checkout.c:253 builtin/checkout.c:256 builtin/checkout.c:259 +#: builtin/checkout.c:262 #, c-format msgid "'%s' cannot be used with updating paths" msgstr "Опцията „%s“ е несъвместима с обновяването на пътища" -#: builtin/checkout.c:266 builtin/checkout.c:269 +#: builtin/checkout.c:265 builtin/checkout.c:268 #, c-format msgid "'%s' cannot be used with %s" msgstr "Опцията „%s“ е несъвместима с „%s“" -#: builtin/checkout.c:272 +#: builtin/checkout.c:271 #, c-format msgid "Cannot update paths and switch to branch '%s' at the same time." msgstr "" "Невъзможно е едновременно да обновявате пътища и да преминете към клона „%s“." -#: builtin/checkout.c:341 builtin/checkout.c:348 +#: builtin/checkout.c:340 builtin/checkout.c:347 #, c-format msgid "path '%s' is unmerged" msgstr "пътят „%s“ не е слят" -#: builtin/checkout.c:506 +#: builtin/checkout.c:505 msgid "you need to resolve your current index first" msgstr "първо трябва да коригирате индекса си" -#: builtin/checkout.c:637 +#: builtin/checkout.c:636 #, c-format msgid "Can not do reflog for '%s': %s\n" msgstr "Журналът на указателите за „%s“ не може да се проследи: %s\n" -#: builtin/checkout.c:678 +#: builtin/checkout.c:677 msgid "HEAD is now at" msgstr "Указателят „HEAD“ в момента сочи към" -#: builtin/checkout.c:682 builtin/clone.c:684 +#: builtin/checkout.c:681 builtin/clone.c:689 msgid "unable to update HEAD" msgstr "Указателят „HEAD“ не може да бъде обновен" -#: builtin/checkout.c:686 +#: builtin/checkout.c:685 #, c-format msgid "Reset branch '%s'\n" msgstr "Зануляване на клона „%s“\n" -#: builtin/checkout.c:689 +#: builtin/checkout.c:688 #, c-format msgid "Already on '%s'\n" msgstr "Вече сте на „%s“\n" -#: builtin/checkout.c:693 +#: builtin/checkout.c:692 #, c-format msgid "Switched to and reset branch '%s'\n" msgstr "Преминаване към клона „%s“ и зануляване на промените\n" -#: builtin/checkout.c:695 builtin/checkout.c:1051 +#: builtin/checkout.c:694 builtin/checkout.c:1039 #, c-format msgid "Switched to a new branch '%s'\n" msgstr "Преминахте към новия клон „%s“\n" -#: builtin/checkout.c:697 +#: builtin/checkout.c:696 #, c-format msgid "Switched to branch '%s'\n" msgstr "Преминахте към клона „%s“\n" -#: builtin/checkout.c:748 +#: builtin/checkout.c:747 #, c-format msgid " ... and %d more.\n" msgstr "… и още %d.\n" -#: builtin/checkout.c:754 +#: builtin/checkout.c:753 #, c-format msgid "" "Warning: you are leaving %d commit behind, not connected to\n" @@ -6504,7 +6771,7 @@ msgstr[1] "" "\n" "%s\n" -#: builtin/checkout.c:773 +#: builtin/checkout.c:772 #, c-format msgid "" "If you want to keep it by creating a new branch, this may be a good time\n" @@ -6531,164 +6798,164 @@ msgstr[1] "" " git branch ИМЕ_НА_НОВИЯ_КЛОН %s\n" "\n" -#: builtin/checkout.c:814 +#: builtin/checkout.c:804 msgid "internal error in revision walk" msgstr "вътрешна грешка при обхождането на версиите" -#: builtin/checkout.c:818 +#: builtin/checkout.c:808 msgid "Previous HEAD position was" msgstr "Преди това „HEAD“ сочеше към" -#: builtin/checkout.c:848 builtin/checkout.c:1046 +#: builtin/checkout.c:836 builtin/checkout.c:1034 msgid "You are on a branch yet to be born" msgstr "В момента сте на клон, който предстои да бъде създаден" -#: builtin/checkout.c:952 +#: builtin/checkout.c:940 #, c-format msgid "only one reference expected, %d given." msgstr "очакваше се един указател, а сте подали %d." -#: builtin/checkout.c:992 builtin/worktree.c:247 +#: builtin/checkout.c:980 builtin/worktree.c:249 #, c-format msgid "invalid reference: %s" msgstr "неправилен указател: %s" -#: builtin/checkout.c:1021 +#: builtin/checkout.c:1009 #, c-format msgid "reference is not a tree: %s" msgstr "указателят не сочи към обект-дърво: %s" -#: builtin/checkout.c:1060 +#: builtin/checkout.c:1048 msgid "paths cannot be used with switching branches" msgstr "задаването на път е несъвместимо с преминаването от един клон към друг" -#: builtin/checkout.c:1063 builtin/checkout.c:1067 +#: builtin/checkout.c:1051 builtin/checkout.c:1055 #, c-format msgid "'%s' cannot be used with switching branches" msgstr "опцията „%s“ е несъвместима с преминаването от един клон към друг" -#: builtin/checkout.c:1071 builtin/checkout.c:1074 builtin/checkout.c:1079 -#: builtin/checkout.c:1082 +#: builtin/checkout.c:1059 builtin/checkout.c:1062 builtin/checkout.c:1067 +#: builtin/checkout.c:1070 #, c-format msgid "'%s' cannot be used with '%s'" msgstr "опцията „%s“ е несъвместима с „%s“" -#: builtin/checkout.c:1087 +#: builtin/checkout.c:1075 #, c-format msgid "Cannot switch branch to a non-commit '%s'" msgstr "" "За да преминете към клон, подайте указател, който сочи към подаване. „%s“ " "не е такъв" -#: builtin/checkout.c:1119 builtin/checkout.c:1121 builtin/clone.c:114 -#: builtin/remote.c:166 builtin/remote.c:168 builtin/worktree.c:369 -#: builtin/worktree.c:371 +#: builtin/checkout.c:1107 builtin/checkout.c:1109 builtin/clone.c:116 +#: builtin/remote.c:166 builtin/remote.c:168 builtin/worktree.c:387 +#: builtin/worktree.c:389 msgid "branch" msgstr "клон" -#: builtin/checkout.c:1120 +#: builtin/checkout.c:1108 msgid "create and checkout a new branch" msgstr "създаване и преминаване към нов клон" -#: builtin/checkout.c:1122 +#: builtin/checkout.c:1110 msgid "create/reset and checkout a branch" msgstr "създаване/зануляване на клон и преминаване към него" -#: builtin/checkout.c:1123 +#: builtin/checkout.c:1111 msgid "create reflog for new branch" msgstr "създаване на журнал на указателите за нов клон" -#: builtin/checkout.c:1124 builtin/worktree.c:373 +#: builtin/checkout.c:1112 builtin/worktree.c:391 msgid "detach HEAD at named commit" msgstr "отделяне на указателя „HEAD“ към указаното подаване" -#: builtin/checkout.c:1125 +#: builtin/checkout.c:1113 msgid "set upstream info for new branch" msgstr "задаване на кой клон бива следен при създаването на новия клон" -#: builtin/checkout.c:1127 +#: builtin/checkout.c:1115 msgid "new-branch" msgstr "НОВ_КЛОН" -#: builtin/checkout.c:1127 +#: builtin/checkout.c:1115 msgid "new unparented branch" msgstr "нов клон без родител" -#: builtin/checkout.c:1128 +#: builtin/checkout.c:1116 msgid "checkout our version for unmerged files" msgstr "изтегляне на вашата версия на неслетите файлове" -#: builtin/checkout.c:1130 +#: builtin/checkout.c:1118 msgid "checkout their version for unmerged files" msgstr "изтегляне на чуждата версия на неслетите файлове" -#: builtin/checkout.c:1132 +#: builtin/checkout.c:1120 msgid "force checkout (throw away local modifications)" msgstr "принудително изтегляне (вашите промени ще бъдат занулени)" -#: builtin/checkout.c:1133 +#: builtin/checkout.c:1122 msgid "perform a 3-way merge with the new branch" msgstr "извършване на тройно сливане с новия клон" -#: builtin/checkout.c:1134 builtin/merge.c:238 +#: builtin/checkout.c:1124 builtin/merge.c:239 msgid "update ignored files (default)" msgstr "обновяване на игнорираните файлове (стандартно)" -#: builtin/checkout.c:1135 builtin/log.c:1496 parse-options.h:251 +#: builtin/checkout.c:1126 builtin/log.c:1499 parse-options.h:263 msgid "style" msgstr "СТИЛ" -#: builtin/checkout.c:1136 +#: builtin/checkout.c:1127 msgid "conflict style (merge or diff3)" msgstr "действие при конфликт (сливане или тройна разлика)" -#: builtin/checkout.c:1139 +#: builtin/checkout.c:1130 msgid "do not limit pathspecs to sparse entries only" msgstr "без ограничаване на изброените пътища само до частично изтеглените" -#: builtin/checkout.c:1141 +#: builtin/checkout.c:1132 msgid "second guess 'git checkout '" msgstr "" "опит за отгатване на име на клон след неуспешен опит с „git checkout " "НЕСЪЩЕСТВУВАЩ_КЛОН“" -#: builtin/checkout.c:1143 +#: builtin/checkout.c:1134 msgid "do not check if another worktree is holding the given ref" msgstr "без проверка дали друго работно дърво държи указателя" -#: builtin/checkout.c:1147 builtin/clone.c:81 builtin/fetch.c:137 -#: builtin/merge.c:235 builtin/pull.c:123 builtin/push.c:556 +#: builtin/checkout.c:1138 builtin/clone.c:83 builtin/fetch.c:150 +#: builtin/merge.c:236 builtin/pull.c:123 builtin/push.c:556 #: builtin/send-pack.c:173 msgid "force progress reporting" msgstr "извеждане на напредъка" -#: builtin/checkout.c:1177 +#: builtin/checkout.c:1168 msgid "-b, -B and --orphan are mutually exclusive" msgstr "Опциите „-b“, „-B“ и „--orphan“ са несъвместими една с друга" -#: builtin/checkout.c:1194 +#: builtin/checkout.c:1185 msgid "--track needs a branch name" msgstr "опцията „--track“ изисква име на клон" -#: builtin/checkout.c:1199 +#: builtin/checkout.c:1190 msgid "Missing branch name; try -b" msgstr "Липсва име на клон, използвайте опцията „-b“" -#: builtin/checkout.c:1235 +#: builtin/checkout.c:1226 msgid "invalid path specification" msgstr "указан е неправилен път" -#: builtin/checkout.c:1242 +#: builtin/checkout.c:1233 #, c-format msgid "'%s' is not a commit and a branch '%s' cannot be created from it" msgstr "„%s“ не е подаване, затова от него не може да се създаде клон „%s“" -#: builtin/checkout.c:1246 +#: builtin/checkout.c:1237 #, c-format msgid "git checkout: --detach does not take a path argument '%s'" msgstr "git checkout: опцията „--detach“ не приема аргумент-път „%s“" -#: builtin/checkout.c:1250 +#: builtin/checkout.c:1241 msgid "" "git checkout: --ours/--theirs, --force and --merge are incompatible when\n" "checking out of the index." @@ -6787,7 +7054,7 @@ msgid "Remove %s [y/N]? " msgstr "Да се изтрие ли „%s“? „y“ — да, „N“ — НЕ" # -#: builtin/clean.c:788 git-add--interactive.perl:1616 +#: builtin/clean.c:788 git-add--interactive.perl:1710 #, c-format msgid "Bye.\n" msgstr "Изход.\n" @@ -6810,11 +7077,11 @@ msgstr "" "help — този край\n" "? — подсказка за шаблоните" -#: builtin/clean.c:823 git-add--interactive.perl:1692 +#: builtin/clean.c:823 git-add--interactive.perl:1786 msgid "*** Commands ***" msgstr "●●● Команди ●●●" -#: builtin/clean.c:824 git-add--interactive.perl:1689 +#: builtin/clean.c:824 git-add--interactive.perl:1783 msgid "What now" msgstr "Избор на следващо действие" @@ -6844,8 +7111,8 @@ msgstr "интерактивно изтриване" msgid "remove whole directories" msgstr "изтриване на цели директории" -#: builtin/clean.c:916 builtin/describe.c:530 builtin/describe.c:532 -#: builtin/grep.c:863 builtin/log.c:155 builtin/log.c:157 +#: builtin/clean.c:916 builtin/describe.c:533 builtin/describe.c:535 +#: builtin/grep.c:871 builtin/log.c:157 builtin/log.c:159 #: builtin/ls-files.c:548 builtin/name-rev.c:397 builtin/name-rev.c:399 #: builtin/show-ref.c:176 msgid "pattern" @@ -6884,148 +7151,148 @@ msgstr "" "което изисква някоя от опциите „-i“, „-n“ или „-f“. Няма да се извърши " "изчистване" -#: builtin/clone.c:39 +#: builtin/clone.c:40 msgid "git clone [] [--] []" msgstr "git clone [ОПЦИЯ…] [--] ХРАНИЛИЩЕ [ДИРЕКТОРИЯ]" -#: builtin/clone.c:83 +#: builtin/clone.c:85 msgid "don't create a checkout" msgstr "без създаване на работно дърво" -#: builtin/clone.c:84 builtin/clone.c:86 builtin/init-db.c:479 +#: builtin/clone.c:86 builtin/clone.c:88 builtin/init-db.c:479 msgid "create a bare repository" msgstr "създаване на голо хранилище" -#: builtin/clone.c:88 +#: builtin/clone.c:90 msgid "create a mirror repository (implies bare)" msgstr "" "създаване на хранилище-огледало (включва опцията „--bare“ за голо хранилище)" -#: builtin/clone.c:90 +#: builtin/clone.c:92 msgid "to clone from a local repository" msgstr "клониране от локално хранилище" -#: builtin/clone.c:92 +#: builtin/clone.c:94 msgid "don't use local hardlinks, always copy" msgstr "без твърди връзки, файловете винаги да се копират" -#: builtin/clone.c:94 +#: builtin/clone.c:96 msgid "setup as shared repository" msgstr "настройване за споделено хранилище" -#: builtin/clone.c:96 builtin/clone.c:100 +#: builtin/clone.c:98 builtin/clone.c:102 msgid "pathspec" msgstr "път" -#: builtin/clone.c:96 builtin/clone.c:100 +#: builtin/clone.c:98 builtin/clone.c:102 msgid "initialize submodules in the clone" msgstr "инициализиране на подмодулите при това клониране" -#: builtin/clone.c:103 +#: builtin/clone.c:105 msgid "number of submodules cloned in parallel" msgstr "брой подмодули, клонирани паралелно" -#: builtin/clone.c:104 builtin/init-db.c:476 +#: builtin/clone.c:106 builtin/init-db.c:476 msgid "template-directory" msgstr "директория с шаблони" -#: builtin/clone.c:105 builtin/init-db.c:477 +#: builtin/clone.c:107 builtin/init-db.c:477 msgid "directory from which templates will be used" msgstr "директория, която съдържа шаблоните, които да се ползват" -#: builtin/clone.c:107 builtin/clone.c:109 builtin/submodule--helper.c:873 -#: builtin/submodule--helper.c:1240 +#: builtin/clone.c:109 builtin/clone.c:111 builtin/submodule--helper.c:1210 +#: builtin/submodule--helper.c:1577 msgid "reference repository" msgstr "еталонно хранилище" -#: builtin/clone.c:111 +#: builtin/clone.c:113 msgid "use --reference only while cloning" msgstr "опцията „--reference“ може да се използва само при клониране" -#: builtin/clone.c:112 builtin/column.c:27 builtin/merge-file.c:44 +#: builtin/clone.c:114 builtin/column.c:27 builtin/merge-file.c:44 msgid "name" msgstr "ИМЕ" -#: builtin/clone.c:113 +#: builtin/clone.c:115 msgid "use instead of 'origin' to track upstream" msgstr "използване на това ИМЕ вместо „origin“ при проследяване на клони" -#: builtin/clone.c:115 +#: builtin/clone.c:117 msgid "checkout instead of the remote's HEAD" msgstr "изтегляне на този КЛОН, а не соченият от отдалечения указател „HEAD“" -#: builtin/clone.c:117 +#: builtin/clone.c:119 msgid "path to git-upload-pack on the remote" msgstr "път към командата „git-upload-pack“ на отдалеченото хранилище" -#: builtin/clone.c:118 builtin/fetch.c:138 builtin/grep.c:806 +#: builtin/clone.c:120 builtin/fetch.c:151 builtin/grep.c:813 #: builtin/pull.c:211 msgid "depth" msgstr "ДЪЛБОЧИНА" -#: builtin/clone.c:119 +#: builtin/clone.c:121 msgid "create a shallow clone of that depth" msgstr "плитко клониране до тази ДЪЛБОЧИНА" -#: builtin/clone.c:120 builtin/fetch.c:140 builtin/pack-objects.c:2991 -#: parse-options.h:142 +#: builtin/clone.c:122 builtin/fetch.c:153 builtin/pack-objects.c:3017 +#: parse-options.h:154 msgid "time" msgstr "ВРЕМЕ" -#: builtin/clone.c:121 +#: builtin/clone.c:123 msgid "create a shallow clone since a specific time" msgstr "плитко клониране до момент във времето" -#: builtin/clone.c:122 builtin/fetch.c:142 +#: builtin/clone.c:124 builtin/fetch.c:155 msgid "revision" msgstr "версия" -#: builtin/clone.c:123 builtin/fetch.c:143 +#: builtin/clone.c:125 builtin/fetch.c:156 msgid "deepen history of shallow clone, excluding rev" msgstr "задълбочаване на историята на плитко хранилище до изключващ указател" -#: builtin/clone.c:125 +#: builtin/clone.c:127 msgid "clone only one branch, HEAD or --branch" msgstr "" "клониране само на един клон — или сочения от отдалечения „HEAD“, или изрично " "зададения с „--branch“" -#: builtin/clone.c:127 +#: builtin/clone.c:129 msgid "don't clone any tags, and make later fetches not to follow them" msgstr "" "без клониране на етикети, като последващите доставяния няма да ги следят" -#: builtin/clone.c:129 +#: builtin/clone.c:131 msgid "any cloned submodules will be shallow" msgstr "всички клонирани подмодули ще са плитки" -#: builtin/clone.c:130 builtin/init-db.c:485 +#: builtin/clone.c:132 builtin/init-db.c:485 msgid "gitdir" msgstr "СЛУЖЕБНА_ДИРЕКТОРИЯ" -#: builtin/clone.c:131 builtin/init-db.c:486 +#: builtin/clone.c:133 builtin/init-db.c:486 msgid "separate git dir from working tree" msgstr "отделна СЛУЖЕБНА_ДИРЕКТОРИЯ за git извън работното дърво" -#: builtin/clone.c:132 +#: builtin/clone.c:134 msgid "key=value" msgstr "КЛЮЧ=СТОЙНОСТ" -#: builtin/clone.c:133 +#: builtin/clone.c:135 msgid "set config inside the new repository" msgstr "задаване на настройките на новото хранилище" -#: builtin/clone.c:134 builtin/fetch.c:160 builtin/pull.c:224 +#: builtin/clone.c:136 builtin/fetch.c:173 builtin/pull.c:224 #: builtin/push.c:567 msgid "use IPv4 addresses only" msgstr "само адреси IPv4" -#: builtin/clone.c:136 builtin/fetch.c:162 builtin/pull.c:227 +#: builtin/clone.c:138 builtin/fetch.c:175 builtin/pull.c:227 #: builtin/push.c:569 msgid "use IPv6 addresses only" msgstr "само адреси IPv6" -#: builtin/clone.c:273 +#: builtin/clone.c:276 msgid "" "No directory name could be guessed.\n" "Please specify a directory on the command line" @@ -7033,43 +7300,43 @@ msgstr "" "Името на директорията не може да бъде отгатнато.\n" "Задайте директорията изрично на командния ред" -#: builtin/clone.c:326 +#: builtin/clone.c:329 #, c-format msgid "info: Could not add alternate for '%s': %s\n" msgstr "" "ПРЕДУПРЕЖДЕНИЕ: не може да се добави алтернативен източник на „%s“: %s\n" -#: builtin/clone.c:398 +#: builtin/clone.c:401 #, c-format msgid "failed to open '%s'" msgstr "директорията „%s“ не може да бъде отворена" -#: builtin/clone.c:406 +#: builtin/clone.c:409 #, c-format msgid "%s exists and is not a directory" msgstr "„%s“ съществува и не е директория" -#: builtin/clone.c:420 +#: builtin/clone.c:423 #, c-format msgid "failed to stat %s\n" msgstr "не може да бъде получена информация чрез „stat“ за „%s“\n" -#: builtin/clone.c:442 +#: builtin/clone.c:445 #, c-format msgid "failed to create link '%s'" msgstr "връзката „%s“ не може да бъде създадена" -#: builtin/clone.c:446 +#: builtin/clone.c:449 #, c-format msgid "failed to copy file to '%s'" msgstr "файлът не може да бъде копиран като „%s“" -#: builtin/clone.c:472 +#: builtin/clone.c:475 #, c-format msgid "done.\n" msgstr "действието завърши.\n" -#: builtin/clone.c:484 +#: builtin/clone.c:489 msgid "" "Clone succeeded, but checkout failed.\n" "You can inspect what was checked out with 'git status'\n" @@ -7080,103 +7347,103 @@ msgstr "" "клон в момента са изтеглени с командата „git status“. Можете да\n" "завършите изтеглянето на клона с командата „git checkout -f HEAD“.\n" -#: builtin/clone.c:561 +#: builtin/clone.c:566 #, c-format msgid "Could not find remote branch %s to clone." msgstr "" "Клонът „%s“ от отдалеченото хранилище, което клонирате,\n" "и който следва да бъде изтеглен, не съществува." -#: builtin/clone.c:656 +#: builtin/clone.c:661 msgid "remote did not send all necessary objects" msgstr "отдалеченото хранилище не изпрати всички необходими обекти." -#: builtin/clone.c:672 +#: builtin/clone.c:677 #, c-format msgid "unable to update %s" msgstr "обектът „%s“ не може да бъде обновен" -#: builtin/clone.c:721 +#: builtin/clone.c:726 msgid "remote HEAD refers to nonexistent ref, unable to checkout.\n" msgstr "" "указателят „HEAD“ от отдалеченото хранилище сочи към нещо,\n" "което не съществува. Не може да се изтегли определен клон.\n" -#: builtin/clone.c:751 +#: builtin/clone.c:756 msgid "unable to checkout working tree" msgstr "работното дърво не може да бъде подготвено" -#: builtin/clone.c:796 +#: builtin/clone.c:801 msgid "unable to write parameters to config file" msgstr "настройките не могат да бъдат записани в конфигурационния файл" -#: builtin/clone.c:859 +#: builtin/clone.c:864 msgid "cannot repack to clean up" msgstr "не може да се извърши пакетиране за изчистване на файловете" -#: builtin/clone.c:861 +#: builtin/clone.c:866 msgid "cannot unlink temporary alternates file" msgstr "временният файл за алтернативни обекти не може да бъде изтрит" -#: builtin/clone.c:894 builtin/receive-pack.c:1945 +#: builtin/clone.c:906 builtin/receive-pack.c:1946 msgid "Too many arguments." msgstr "Прекалено много аргументи." -#: builtin/clone.c:898 +#: builtin/clone.c:910 msgid "You must specify a repository to clone." msgstr "Трябва да укажете кое хранилище искате да клонирате." -#: builtin/clone.c:911 +#: builtin/clone.c:923 #, c-format msgid "--bare and --origin %s options are incompatible." msgstr "опциите „--bare“ и „--origin %s“ са несъвместими." -#: builtin/clone.c:914 +#: builtin/clone.c:926 msgid "--bare and --separate-git-dir are incompatible." msgstr "опциите „--bare“ и „--separate-git-dir“ са несъвместими." -#: builtin/clone.c:927 +#: builtin/clone.c:939 #, c-format msgid "repository '%s' does not exist" msgstr "не съществува хранилище „%s“" -#: builtin/clone.c:933 builtin/fetch.c:1358 +#: builtin/clone.c:945 builtin/fetch.c:1455 #, c-format msgid "depth %s is not a positive number" msgstr "дълбочината трябва да е положително цяло число, а не „%s“" -#: builtin/clone.c:943 +#: builtin/clone.c:955 #, c-format msgid "destination path '%s' already exists and is not an empty directory." msgstr "целевият път „%s“ съществува и не е празна директория." -#: builtin/clone.c:953 +#: builtin/clone.c:965 #, c-format msgid "working tree '%s' already exists." msgstr "в „%s“ вече съществува работно дърво." -#: builtin/clone.c:968 builtin/clone.c:979 builtin/difftool.c:270 -#: builtin/worktree.c:253 builtin/worktree.c:283 +#: builtin/clone.c:980 builtin/clone.c:1001 builtin/difftool.c:270 +#: builtin/worktree.c:255 builtin/worktree.c:285 #, c-format msgid "could not create leading directories of '%s'" msgstr "родителските директории на „%s“ не могат да бъдат създадени" -#: builtin/clone.c:971 +#: builtin/clone.c:985 #, c-format msgid "could not create work tree dir '%s'" msgstr "работното дърво в „%s“ не може да бъде създадено." -#: builtin/clone.c:983 +#: builtin/clone.c:1005 #, c-format msgid "Cloning into bare repository '%s'...\n" msgstr "Клониране и създаване на голо хранилище в „%s“…\n" -#: builtin/clone.c:985 +#: builtin/clone.c:1007 #, c-format msgid "Cloning into '%s'...\n" msgstr "Клониране и създаване на хранилище в „%s“…\n" -#: builtin/clone.c:1009 +#: builtin/clone.c:1031 msgid "" "clone --recursive is not compatible with both --reference and --reference-if-" "able" @@ -7184,38 +7451,44 @@ msgstr "" "Опцията „--recursive“ е несъвместима с опциите „--reference“ и „--reference-" "if-able“" -#: builtin/clone.c:1071 +#: builtin/clone.c:1093 msgid "--depth is ignored in local clones; use file:// instead." msgstr "" "При локално клониране опцията „--depth“ се прескача. Ползвайте схемата " "„file://“." -#: builtin/clone.c:1073 +#: builtin/clone.c:1095 msgid "--shallow-since is ignored in local clones; use file:// instead." msgstr "" "При локално клониране опцията „--shallow-since“ се прескача. Ползвайте " "схемата „file://“." -#: builtin/clone.c:1075 +#: builtin/clone.c:1097 msgid "--shallow-exclude is ignored in local clones; use file:// instead." msgstr "" "При локално клониране опцията „--shallow-exclude“ се прескача. Ползвайте " "схемата „file://“." -#: builtin/clone.c:1078 +#: builtin/clone.c:1099 +msgid "--filter is ignored in local clones; use file:// instead." +msgstr "" +"При локално клониране опцията „--filter“ се прескача. Ползвайте схемата " +"„file://“." + +#: builtin/clone.c:1102 msgid "source repository is shallow, ignoring --local" msgstr "клонираното хранилище е плитко, затова опцията „--local“ се прескача" -#: builtin/clone.c:1083 +#: builtin/clone.c:1107 msgid "--local is ignored" msgstr "опцията „--local“ се прескача" -#: builtin/clone.c:1139 builtin/clone.c:1147 +#: builtin/clone.c:1169 builtin/clone.c:1177 #, c-format msgid "Remote branch %s not found in upstream %s" msgstr "Отдалеченият клон „%s“ липсва в клонираното хранилище „%s“" -#: builtin/clone.c:1150 +#: builtin/clone.c:1180 msgid "You appear to have cloned an empty repository." msgstr "Изглежда клонирахте празно хранилище." @@ -7251,70 +7524,15 @@ msgstr "Поле в знаци между колоните" msgid "--command must be the first argument" msgstr "опцията „--command“ трябва да е първият аргумент" -#: builtin/commit.c:39 +#: builtin/commit.c:37 msgid "git commit [] [--] ..." msgstr "git commit [ОПЦИЯ…] [--] ПЪТ…" -#: builtin/commit.c:44 +#: builtin/commit.c:42 msgid "git status [] [--] ..." msgstr "git status [ОПЦИЯ…] [--] ПЪТ…" -#: builtin/commit.c:49 -msgid "" -"Your name and email address were configured automatically based\n" -"on your username and hostname. Please check that they are accurate.\n" -"You can suppress this message by setting them explicitly. Run the\n" -"following command and follow the instructions in your editor to edit\n" -"your configuration file:\n" -"\n" -" git config --global --edit\n" -"\n" -"After doing this, you may fix the identity used for this commit with:\n" -"\n" -" git commit --amend --reset-author\n" -msgstr "" -"Името и адресът за е-поща са настроени автоматично на базата на името на\n" -"потребителя и името на машината. Проверете дали са верни. Можете да " -"спрете\n" -"това съобщение като изрично зададете стойностите. Изпълнете следната " -"команда\n" -"и следвайте инструкциите в текстовия ви редактор, за да редактирате\n" -"конфигурационния файл:\n" -"\n" -" git config --global --edit\n" -"\n" -"След като направите това, можете да коригирате информацията за автора на\n" -"текущото подаване чрез:\n" -"\n" -" git commit --amend --reset-author\n" - -#: builtin/commit.c:62 -msgid "" -"Your name and email address were configured automatically based\n" -"on your username and hostname. Please check that they are accurate.\n" -"You can suppress this message by setting them explicitly:\n" -"\n" -" git config --global user.name \"Your Name\"\n" -" git config --global user.email you@example.com\n" -"\n" -"After doing this, you may fix the identity used for this commit with:\n" -"\n" -" git commit --amend --reset-author\n" -msgstr "" -"Името и адресът за е-поща са настроени автоматично на базата на името на\n" -"потребителя и името на машината. Проверете дали са верни. Можете да " -"спрете\n" -"това съобщение като изрично зададете стойностите:\n" -"\n" -" git config --global user.name \"Вашето Име\"\n" -" git config --global user.email пенчо@example.com\n" -"\n" -"След като направите това, можете да коригирате информацията за автора на\n" -"текущото подаване чрез:\n" -"\n" -" git commit --amend --reset-author\n" - -#: builtin/commit.c:74 +#: builtin/commit.c:47 msgid "" "You asked to amend the most recent commit, but doing so would make\n" "it empty. You can repeat your command with --allow-empty, or you can\n" @@ -7326,7 +7544,7 @@ msgstr "" "с опцията „--allow-empty“, или да го изтриете от историята с командата:\n" "„git reset HEAD^“.\n" -#: builtin/commit.c:79 +#: builtin/commit.c:52 msgid "" "The previous cherry-pick is now empty, possibly due to conflict resolution.\n" "If you wish to commit it anyway, use:\n" @@ -7341,11 +7559,11 @@ msgstr "" " git commit --allow-empty\n" "\n" -#: builtin/commit.c:86 +#: builtin/commit.c:59 msgid "Otherwise, please use 'git reset'\n" msgstr "В противен случай използвайте командата „git reset“\n" -#: builtin/commit.c:89 +#: builtin/commit.c:62 msgid "" "If you wish to skip this commit, use:\n" "\n" @@ -7361,61 +7579,61 @@ msgstr "" "Чрез командата „git cherry-pick --continue“ ще продължите отбирането на\n" "останалите подавания.\n" -#: builtin/commit.c:318 +#: builtin/commit.c:284 msgid "failed to unpack HEAD tree object" msgstr "върховото дърво (HEAD tree object) не може да бъде извадено от пакет" -#: builtin/commit.c:359 +#: builtin/commit.c:325 msgid "unable to create temporary index" msgstr "временният индекс не може да бъде създаден" -#: builtin/commit.c:365 +#: builtin/commit.c:331 msgid "interactive add failed" msgstr "неуспешно интерактивно добавяне" -#: builtin/commit.c:378 +#: builtin/commit.c:344 msgid "unable to update temporary index" msgstr "временният индекс не може да бъде обновен" -#: builtin/commit.c:380 +#: builtin/commit.c:346 msgid "Failed to update main cache tree" msgstr "Дървото на основния кеш не може да бъде обновено" -#: builtin/commit.c:405 builtin/commit.c:429 builtin/commit.c:478 +#: builtin/commit.c:371 builtin/commit.c:395 builtin/commit.c:444 msgid "unable to write new_index file" msgstr "новият индекс не може да бъде записан" -#: builtin/commit.c:461 +#: builtin/commit.c:427 msgid "cannot do a partial commit during a merge." msgstr "по време на сливане не може да се извърши частично подаване." -#: builtin/commit.c:463 +#: builtin/commit.c:429 msgid "cannot do a partial commit during a cherry-pick." msgstr "по време на отбиране не може да се извърши частично подаване." -#: builtin/commit.c:471 +#: builtin/commit.c:437 msgid "cannot read the index" msgstr "индексът не може да бъде прочетен" -#: builtin/commit.c:490 +#: builtin/commit.c:456 msgid "unable to write temporary index file" msgstr "временният индекс не може да бъде записан" -#: builtin/commit.c:587 +#: builtin/commit.c:553 #, c-format msgid "commit '%s' lacks author header" msgstr "заглавната част за автор в подаването „%s“ липсва" -#: builtin/commit.c:589 +#: builtin/commit.c:555 #, c-format msgid "commit '%s' has malformed author line" msgstr "заглавната част за автор в подаването „%s“ е неправилна" -#: builtin/commit.c:608 +#: builtin/commit.c:574 msgid "malformed --author parameter" msgstr "неправилен параметър към опцията „--author“" -#: builtin/commit.c:660 +#: builtin/commit.c:626 msgid "" "unable to select a comment character that is not used\n" "in the current commit message" @@ -7423,38 +7641,38 @@ msgstr "" "не може да се избере знак за коментар — в текущото съобщение за подаване са " "използвани всички подобни знаци" -#: builtin/commit.c:697 builtin/commit.c:730 builtin/commit.c:1114 +#: builtin/commit.c:663 builtin/commit.c:696 builtin/commit.c:1024 #, c-format msgid "could not lookup commit %s" msgstr "следното подаване не може да бъде открито: %s" -#: builtin/commit.c:709 builtin/shortlog.c:309 +#: builtin/commit.c:675 builtin/shortlog.c:309 #, c-format msgid "(reading log message from standard input)\n" msgstr "(изчитане на съобщението за подаване от стандартния вход)\n" -#: builtin/commit.c:711 +#: builtin/commit.c:677 msgid "could not read log from standard input" msgstr "съобщението за подаване не бе прочетено стандартния вход" -#: builtin/commit.c:715 +#: builtin/commit.c:681 #, c-format msgid "could not read log file '%s'" msgstr "файлът със съобщението за подаване „%s“ не може да бъде прочетен" -#: builtin/commit.c:742 builtin/commit.c:750 +#: builtin/commit.c:710 builtin/commit.c:718 msgid "could not read SQUASH_MSG" msgstr "съобщението за смачкване SQUASH_MSG не може да бъде прочетено" -#: builtin/commit.c:747 +#: builtin/commit.c:715 msgid "could not read MERGE_MSG" msgstr "съобщението за сливане MERGE_MSG не може да бъде прочетено" -#: builtin/commit.c:801 +#: builtin/commit.c:769 msgid "could not write commit template" msgstr "шаблонът за подаване не може да бъде запазен" -#: builtin/commit.c:819 +#: builtin/commit.c:787 #, c-format msgid "" "\n" @@ -7469,7 +7687,7 @@ msgstr "" " %s\n" "и опитайте отново.\n" -#: builtin/commit.c:824 +#: builtin/commit.c:792 #, c-format msgid "" "\n" @@ -7485,7 +7703,7 @@ msgstr "" " %s\n" "и опитайте отново.\n" -#: builtin/commit.c:837 +#: builtin/commit.c:805 #, c-format msgid "" "Please enter the commit message for your changes. Lines starting\n" @@ -7494,7 +7712,7 @@ msgstr "" "Въведете съобщението за подаване на промените. Редовете, които започват\n" "с „%c“, ще бъдат пропуснати, а празно съобщение преустановява подаването.\n" -#: builtin/commit.c:844 +#: builtin/commit.c:813 #, c-format msgid "" "Please enter the commit message for your changes. Lines starting\n" @@ -7505,150 +7723,154 @@ msgstr "" "с „%c“, също ще бъдат включени — може да ги изтриете вие. Празно \n" "съобщение преустановява подаването.\n" -#: builtin/commit.c:861 +#: builtin/commit.c:830 #, c-format msgid "%sAuthor: %.*s <%.*s>" msgstr "%sАвтор: %.*s <%.*s>" -#: builtin/commit.c:869 +#: builtin/commit.c:838 #, c-format msgid "%sDate: %s" msgstr "%sДата: %s" -#: builtin/commit.c:876 +#: builtin/commit.c:845 #, c-format msgid "%sCommitter: %.*s <%.*s>" msgstr "%sПодаващ: %.*s <%.*s>" -#: builtin/commit.c:893 +#: builtin/commit.c:862 msgid "Cannot read index" msgstr "Индексът не може да бъде прочетен" -#: builtin/commit.c:959 +#: builtin/commit.c:928 msgid "Error building trees" msgstr "Грешка при изграждане на дърветата" -#: builtin/commit.c:973 builtin/tag.c:252 +#: builtin/commit.c:942 builtin/tag.c:256 #, c-format msgid "Please supply the message using either -m or -F option.\n" msgstr "Подайте съобщението с някоя от опциите „-m“ или „-F“.\n" -#: builtin/commit.c:1076 +#: builtin/commit.c:986 #, c-format msgid "--author '%s' is not 'Name ' and matches no existing author" msgstr "" "Опцията „--author '%s'“ не отговаря на форма̀та „Име <е-поща>“ и не съвпада с " "никой автор" -#: builtin/commit.c:1090 +#: builtin/commit.c:1000 #, c-format msgid "Invalid ignored mode '%s'" msgstr "Неправилен режим за игнорираните файлове: „%s“" -#: builtin/commit.c:1104 builtin/commit.c:1349 +#: builtin/commit.c:1014 builtin/commit.c:1264 #, c-format msgid "Invalid untracked files mode '%s'" msgstr "Неправилен режим за неследените файлове: „%s“" -#: builtin/commit.c:1142 +#: builtin/commit.c:1052 msgid "--long and -z are incompatible" msgstr "Опциите „--long“ и „-z“ са несъвместими." -#: builtin/commit.c:1172 +#: builtin/commit.c:1085 msgid "Using both --reset-author and --author does not make sense" msgstr "Опциите „--reset-author“ и „--author“ са несъвместими." -#: builtin/commit.c:1181 +#: builtin/commit.c:1094 msgid "You have nothing to amend." msgstr "Няма какво да бъде поправено." -#: builtin/commit.c:1184 +#: builtin/commit.c:1097 msgid "You are in the middle of a merge -- cannot amend." msgstr "В момента се извършва сливане, не можете да поправяте." -#: builtin/commit.c:1186 +#: builtin/commit.c:1099 msgid "You are in the middle of a cherry-pick -- cannot amend." msgstr "В момента се извършва отбиране на подаване, не можете да поправяте." -#: builtin/commit.c:1189 +#: builtin/commit.c:1102 msgid "Options --squash and --fixup cannot be used together" msgstr "Опциите „--squash“ и „--fixup“ са несъвместими." -#: builtin/commit.c:1199 +#: builtin/commit.c:1112 msgid "Only one of -c/-C/-F/--fixup can be used." msgstr "Опциите „-c“, „-C“, „-F“ и „--fixup““ са несъвместими." -#: builtin/commit.c:1201 -msgid "Option -m cannot be combined with -c/-C/-F/--fixup." -msgstr "Опцията „-m“ е несъвместима с „-c“, „-C“, „-F“ и „--fixup“." +#: builtin/commit.c:1114 +msgid "Option -m cannot be combined with -c/-C/-F." +msgstr "Опцията „-m“ е несъвместима с „-c“, „-C“ и „-F“." -#: builtin/commit.c:1209 +#: builtin/commit.c:1122 msgid "--reset-author can be used only with -C, -c or --amend." msgstr "" "Опцията „--reset-author“ може да се използва само заедно с „-C“, „-c“ или\n" "„--amend“." -#: builtin/commit.c:1226 +#: builtin/commit.c:1139 msgid "Only one of --include/--only/--all/--interactive/--patch can be used." msgstr "" "Опциите „--include“, „--only“, „--all“, „--interactive“ и „--patch“ са\n" "несъвместими." -#: builtin/commit.c:1228 +#: builtin/commit.c:1141 msgid "No paths with --include/--only does not make sense." msgstr "Опциите „--include“ и „--only“ изискват аргументи." -#: builtin/commit.c:1240 builtin/tag.c:535 +#: builtin/commit.c:1155 builtin/tag.c:542 #, c-format msgid "Invalid cleanup mode %s" msgstr "Несъществуващ режим на изчистване „%s“" -#: builtin/commit.c:1245 +#: builtin/commit.c:1160 msgid "Paths with -a does not make sense." msgstr "Опцията „-a“ е несъвместима със задаването на пътища." -#: builtin/commit.c:1363 builtin/commit.c:1648 +#: builtin/commit.c:1278 builtin/commit.c:1443 msgid "show status concisely" msgstr "кратка информация за състоянието" -#: builtin/commit.c:1365 builtin/commit.c:1650 +#: builtin/commit.c:1280 builtin/commit.c:1445 msgid "show branch information" msgstr "информация за клоните" -#: builtin/commit.c:1367 +#: builtin/commit.c:1282 msgid "show stash information" msgstr "информация за скатаното" -#: builtin/commit.c:1369 +#: builtin/commit.c:1284 builtin/commit.c:1447 +msgid "compute full ahead/behind values" +msgstr "изчисляване на точните стойности напред/назад" + +#: builtin/commit.c:1286 msgid "version" msgstr "версия" -#: builtin/commit.c:1369 builtin/commit.c:1652 builtin/push.c:542 -#: builtin/worktree.c:523 +#: builtin/commit.c:1286 builtin/commit.c:1449 builtin/push.c:542 +#: builtin/worktree.c:541 msgid "machine-readable output" msgstr "формат на изхода за четене от програма" -#: builtin/commit.c:1372 builtin/commit.c:1654 +#: builtin/commit.c:1289 builtin/commit.c:1451 msgid "show status in long format (default)" msgstr "подробна информация за състоянието (стандартно)" -#: builtin/commit.c:1375 builtin/commit.c:1657 +#: builtin/commit.c:1292 builtin/commit.c:1454 msgid "terminate entries with NUL" msgstr "разделяне на елементите с нулевия знак „NUL“" -#: builtin/commit.c:1377 builtin/commit.c:1381 builtin/commit.c:1660 -#: builtin/fast-export.c:999 builtin/fast-export.c:1002 builtin/tag.c:390 +#: builtin/commit.c:1294 builtin/commit.c:1298 builtin/commit.c:1457 +#: builtin/fast-export.c:999 builtin/fast-export.c:1002 builtin/tag.c:396 msgid "mode" msgstr "РЕЖИМ" -#: builtin/commit.c:1378 builtin/commit.c:1660 +#: builtin/commit.c:1295 builtin/commit.c:1457 msgid "show untracked files, optional modes: all, normal, no. (Default: all)" msgstr "" "извеждане на неследените файлове. Възможните РЕЖИМи са „all“ (подробна " "информация), „normal“ (кратка информация), „no“ (без неследените файлове). " "Стандартният РЕЖИМ е: „all“." -#: builtin/commit.c:1382 +#: builtin/commit.c:1299 msgid "" "show ignored files, optional modes: traditional, matching, no. (Default: " "traditional)" @@ -7657,11 +7879,11 @@ msgstr "" "„traditional“ (традиционен), „matching“ (напасващи), „no“ (без игнорираните " "файлове). Стандартният РЕЖИМ е: „traditional“." -#: builtin/commit.c:1384 parse-options.h:155 +#: builtin/commit.c:1301 parse-options.h:167 msgid "when" msgstr "КОГА" -#: builtin/commit.c:1385 +#: builtin/commit.c:1302 msgid "" "ignore changes to submodules, optional when: all, dirty, untracked. " "(Default: all)" @@ -7670,216 +7892,190 @@ msgstr "" "една от „all“ (всички), „dirty“ (тези с неподадени промени), " "„untracked“ (неследени)" -#: builtin/commit.c:1387 +#: builtin/commit.c:1304 msgid "list untracked files in columns" msgstr "извеждане на неследените файлове в колони" -#: builtin/commit.c:1406 +#: builtin/commit.c:1323 msgid "Unsupported combination of ignored and untracked-files arguments" msgstr "Неподдържана комбинация от аргументи за игнорирани и неследени файлове" -#: builtin/commit.c:1469 -msgid "couldn't look up newly created commit" -msgstr "току що създаденото подаване не може да бъде открито" - -#: builtin/commit.c:1471 -msgid "could not parse newly created commit" -msgstr "току що създаденото подаване не може да бъде анализирано" - -#: builtin/commit.c:1516 -msgid "unable to resolve HEAD after creating commit" -msgstr "" -"състоянието сочено от указателя „HEAD“ не може да бъде открито след " -"подаването" - -#: builtin/commit.c:1518 -msgid "detached HEAD" -msgstr "несвързан връх „HEAD“" - -#: builtin/commit.c:1521 -msgid " (root-commit)" -msgstr " (начално подаване)" - -#: builtin/commit.c:1618 +#: builtin/commit.c:1413 msgid "suppress summary after successful commit" msgstr "без информация след успешно подаване" -#: builtin/commit.c:1619 +#: builtin/commit.c:1414 msgid "show diff in commit message template" msgstr "добавяне на разликата към шаблона за съобщението при подаване" -#: builtin/commit.c:1621 +#: builtin/commit.c:1416 msgid "Commit message options" msgstr "Опции за съобщението при подаване" -#: builtin/commit.c:1622 builtin/tag.c:388 +#: builtin/commit.c:1417 builtin/tag.c:393 msgid "read message from file" msgstr "взимане на съобщението от ФАЙЛ" -#: builtin/commit.c:1623 +#: builtin/commit.c:1418 msgid "author" msgstr "АВТОР" -#: builtin/commit.c:1623 +#: builtin/commit.c:1418 msgid "override author for commit" msgstr "задаване на АВТОР за подаването" -#: builtin/commit.c:1624 builtin/gc.c:359 +#: builtin/commit.c:1419 builtin/gc.c:359 msgid "date" msgstr "ДАТА" -#: builtin/commit.c:1624 +#: builtin/commit.c:1419 msgid "override date for commit" msgstr "задаване на ДАТА за подаването" -#: builtin/commit.c:1625 builtin/merge.c:225 builtin/notes.c:402 -#: builtin/notes.c:565 builtin/tag.c:386 +#: builtin/commit.c:1420 builtin/merge.c:226 builtin/notes.c:402 +#: builtin/notes.c:565 builtin/tag.c:391 msgid "message" msgstr "СЪОБЩЕНИЕ" -#: builtin/commit.c:1625 +#: builtin/commit.c:1420 msgid "commit message" msgstr "СЪОБЩЕНИЕ при подаване" -#: builtin/commit.c:1626 builtin/commit.c:1627 builtin/commit.c:1628 -#: builtin/commit.c:1629 parse-options.h:257 ref-filter.h:92 +#: builtin/commit.c:1421 builtin/commit.c:1422 builtin/commit.c:1423 +#: builtin/commit.c:1424 parse-options.h:269 ref-filter.h:92 msgid "commit" msgstr "ПОДАВАНЕ" -#: builtin/commit.c:1626 +#: builtin/commit.c:1421 msgid "reuse and edit message from specified commit" msgstr "преизползване и редактиране на съобщението от указаното ПОДАВАНЕ" -#: builtin/commit.c:1627 +#: builtin/commit.c:1422 msgid "reuse message from specified commit" msgstr "преизползване на съобщението от указаното ПОДАВАНЕ" -#: builtin/commit.c:1628 +#: builtin/commit.c:1423 msgid "use autosquash formatted message to fixup specified commit" msgstr "" "използване на автоматичното съобщение при смачкване за вкарване на указаното " "ПОДАВАНЕ в предното без следа" -#: builtin/commit.c:1629 +#: builtin/commit.c:1424 msgid "use autosquash formatted message to squash specified commit" msgstr "" "използване на автоматичното съобщение при смачкване за смачкване на " "указаното ПОДАВАНЕ в предното" -#: builtin/commit.c:1630 +#: builtin/commit.c:1425 msgid "the commit is authored by me now (used with -C/-c/--amend)" msgstr "" "смяна на автора да съвпада с подаващия (използва се с „-C“/„-c“/„--amend“)" -#: builtin/commit.c:1631 builtin/log.c:1443 builtin/merge.c:239 +#: builtin/commit.c:1426 builtin/log.c:1446 builtin/merge.c:240 #: builtin/pull.c:149 builtin/revert.c:105 msgid "add Signed-off-by:" msgstr "добавяне на поле за подпис — „Signed-off-by:“" -#: builtin/commit.c:1632 +#: builtin/commit.c:1427 msgid "use specified template file" msgstr "използване на указания шаблонен ФАЙЛ" -#: builtin/commit.c:1633 +#: builtin/commit.c:1428 msgid "force edit of commit" msgstr "редактиране на подаване" -#: builtin/commit.c:1634 +#: builtin/commit.c:1429 msgid "default" msgstr "стандартно" -#: builtin/commit.c:1634 builtin/tag.c:391 +#: builtin/commit.c:1429 builtin/tag.c:397 msgid "how to strip spaces and #comments from message" msgstr "кои празни знаци и #коментари да се махат от съобщенията" -#: builtin/commit.c:1635 +#: builtin/commit.c:1430 msgid "include status in commit message template" msgstr "вмъкване на състоянието в шаблона за съобщението при подаване" -#: builtin/commit.c:1637 builtin/merge.c:237 builtin/pull.c:179 +#: builtin/commit.c:1432 builtin/merge.c:238 builtin/pull.c:179 #: builtin/revert.c:113 msgid "GPG sign commit" msgstr "подписване на подаването с GPG" -#: builtin/commit.c:1640 +#: builtin/commit.c:1435 msgid "Commit contents options" msgstr "Опции за избор на файлове при подаване" -#: builtin/commit.c:1641 +#: builtin/commit.c:1436 msgid "commit all changed files" msgstr "подаване на всички променени файлове" -#: builtin/commit.c:1642 +#: builtin/commit.c:1437 msgid "add specified files to index for commit" msgstr "добавяне на указаните файлове към индекса за подаване" -#: builtin/commit.c:1643 +#: builtin/commit.c:1438 msgid "interactively add files" msgstr "интерактивно добавяне на файлове" -#: builtin/commit.c:1644 +#: builtin/commit.c:1439 msgid "interactively add changes" msgstr "интерактивно добавяне на промени" -#: builtin/commit.c:1645 +#: builtin/commit.c:1440 msgid "commit only specified files" msgstr "подаване само на указаните файлове" -#: builtin/commit.c:1646 +#: builtin/commit.c:1441 msgid "bypass pre-commit and commit-msg hooks" msgstr "" "без изпълнение на куките преди подаване и при промяна на съобщението за " "подаване (pre-commit и commit-msg)" -#: builtin/commit.c:1647 +#: builtin/commit.c:1442 msgid "show what would be committed" msgstr "отпечатване на това, което би било подадено" -#: builtin/commit.c:1658 +#: builtin/commit.c:1455 msgid "amend previous commit" msgstr "поправяне на предишното подаване" -#: builtin/commit.c:1659 +#: builtin/commit.c:1456 msgid "bypass post-rewrite hook" msgstr "без изпълнение на куката след презаписване (post-rewrite)" -#: builtin/commit.c:1664 +#: builtin/commit.c:1461 msgid "ok to record an empty change" msgstr "позволяване на празни подавания" -#: builtin/commit.c:1666 +#: builtin/commit.c:1463 msgid "ok to record a change with an empty message" msgstr "позволяване на подавания с празни съобщения" -#: builtin/commit.c:1696 -msgid "could not parse HEAD commit" -msgstr "върховото подаване „HEAD“ не може да бъде прочетено" - -#: builtin/commit.c:1741 +#: builtin/commit.c:1536 #, c-format msgid "Corrupt MERGE_HEAD file (%s)" msgstr "Повреден файл за върха за сливането „MERGE_HEAD“ (%s)" -#: builtin/commit.c:1748 +#: builtin/commit.c:1543 msgid "could not read MERGE_MODE" msgstr "режимът на сливане „MERGE_MODE“ не може да бъде прочетен" -#: builtin/commit.c:1767 +#: builtin/commit.c:1562 #, c-format msgid "could not read commit message: %s" msgstr "съобщението за подаване не може да бъде прочетено: %s" -#: builtin/commit.c:1778 +#: builtin/commit.c:1573 #, c-format msgid "Aborting commit due to empty commit message.\n" msgstr "Неизвършване на подаване поради празно съобщение.\n" -#: builtin/commit.c:1783 +#: builtin/commit.c:1578 #, c-format msgid "Aborting commit; you did not edit the message.\n" msgstr "Неизвършване на подаване поради нередактирано съобщение.\n" -#: builtin/commit.c:1831 +#: builtin/commit.c:1613 msgid "" "Repository has been updated, but unable to write\n" "new_index file. Check that disk is not full and quota is\n" @@ -8080,7 +8276,7 @@ msgstr "извеждане на размерите на обектите във #: builtin/describe.c:22 msgid "git describe [] [...]" -msgstr "git describe [ОПЦИЯ…] УКАЗАТЕЛ_КЪМ_ПОДАВАНЕ…" +msgstr "git describe [ОПЦИЯ…] [УКАЗАТЕЛ_КЪМ_ПОДАВАНЕ…]" #: builtin/describe.c:23 msgid "git describe [] --dirty" @@ -8113,22 +8309,22 @@ msgstr "в анотирания етикет „%s“ липсва вграде msgid "tag '%s' is really '%s' here" msgstr "етикетът „%s“ тук е всъщност „%s“" -#: builtin/describe.c:314 +#: builtin/describe.c:317 #, c-format msgid "no tag exactly matches '%s'" msgstr "никой етикет не напасва точно „%s“" -#: builtin/describe.c:316 +#: builtin/describe.c:319 #, c-format msgid "No exact match on refs or tags, searching to describe\n" msgstr "Никоя версия и етикет не напасват точно. Търси се по описание\n" -#: builtin/describe.c:363 +#: builtin/describe.c:366 #, c-format msgid "finished search at %s\n" msgstr "търсенето приключи при „%s“\n" -#: builtin/describe.c:389 +#: builtin/describe.c:392 #, c-format msgid "" "No annotated tags can describe '%s'.\n" @@ -8137,7 +8333,7 @@ msgstr "" "Никой анотиран етикет не описва „%s“.\n" "Съществуват и неанотирани етикети. Пробвайте с опцията „--tags“." -#: builtin/describe.c:393 +#: builtin/describe.c:396 #, c-format msgid "" "No tags can describe '%s'.\n" @@ -8146,12 +8342,12 @@ msgstr "" "Никой етикет не описва „%s“.\n" "Пробвайте с опцията „--always“ или създайте етикети." -#: builtin/describe.c:423 +#: builtin/describe.c:426 #, c-format msgid "traversed %lu commits\n" msgstr "претърсени са %lu подавания\n" -#: builtin/describe.c:426 +#: builtin/describe.c:429 #, c-format msgid "" "more than %i tags found; listed %i most recent\n" @@ -8160,93 +8356,93 @@ msgstr "" "открити са над %i етикета, изведени са последните %i,\n" "търсенето бе прекратено при „%s“.\n" -#: builtin/describe.c:494 +#: builtin/describe.c:497 #, c-format msgid "describe %s\n" msgstr "описание на „%s“\n" -#: builtin/describe.c:497 builtin/log.c:500 +#: builtin/describe.c:500 builtin/log.c:502 #, c-format msgid "Not a valid object name %s" msgstr "Неправилно име на обект „%s“" -#: builtin/describe.c:505 +#: builtin/describe.c:508 #, c-format msgid "%s is neither a commit nor blob" msgstr "„%s“ не е нито подаване, нито обект BLOB" -#: builtin/describe.c:519 +#: builtin/describe.c:522 msgid "find the tag that comes after the commit" msgstr "откриване на етикета, който следва подаване" -#: builtin/describe.c:520 +#: builtin/describe.c:523 msgid "debug search strategy on stderr" msgstr "" "извеждане на информация за трасиране на стратегията за търсене на " "стандартната грешка" -#: builtin/describe.c:521 +#: builtin/describe.c:524 msgid "use any ref" msgstr "използване на произволен указател" -#: builtin/describe.c:522 +#: builtin/describe.c:525 msgid "use any tag, even unannotated" msgstr "използване на всеки етикет — включително и неанотираните" -#: builtin/describe.c:523 +#: builtin/describe.c:526 msgid "always use long format" msgstr "винаги да се ползва дългият формат" -#: builtin/describe.c:524 +#: builtin/describe.c:527 msgid "only follow first parent" msgstr "проследяване само на първия родител" -#: builtin/describe.c:527 +#: builtin/describe.c:530 msgid "only output exact matches" msgstr "извеждане само на точните съвпадения" -#: builtin/describe.c:529 +#: builtin/describe.c:532 msgid "consider most recent tags (default: 10)" msgstr "да се търси само в този БРОЙ последни етикети (стандартно: 10)" -#: builtin/describe.c:531 +#: builtin/describe.c:534 msgid "only consider tags matching " msgstr "да се търси само измежду етикетите напасващи този ШАБЛОН" -#: builtin/describe.c:533 +#: builtin/describe.c:536 msgid "do not consider tags matching " msgstr "да не се търси измежду етикетите напасващи този ШАБЛОН" -#: builtin/describe.c:535 builtin/name-rev.c:406 +#: builtin/describe.c:538 builtin/name-rev.c:406 msgid "show abbreviated commit object as fallback" msgstr "извеждане на съкратено име на обект като резервен вариант" -#: builtin/describe.c:536 builtin/describe.c:539 +#: builtin/describe.c:539 builtin/describe.c:542 msgid "mark" msgstr "МАРКЕР" -#: builtin/describe.c:537 +#: builtin/describe.c:540 msgid "append on dirty working tree (default: \"-dirty\")" msgstr "добавяне на такъв МАРКЕР на работното дърво (стандартно е „-dirty“)" -#: builtin/describe.c:540 +#: builtin/describe.c:543 msgid "append on broken working tree (default: \"-broken\")" msgstr "" "добавяне на такъв МАРКЕР на счупеното работно дърво (стандартно е „-broken“)" -#: builtin/describe.c:558 +#: builtin/describe.c:561 msgid "--long is incompatible with --abbrev=0" msgstr "Опциите „--long“ и „--abbrev=0“ са несъвместими" -#: builtin/describe.c:587 +#: builtin/describe.c:590 msgid "No names found, cannot describe anything." msgstr "Не са открити имена — нищо не може да бъде описано." -#: builtin/describe.c:637 +#: builtin/describe.c:640 msgid "--dirty is incompatible with commit-ishes" msgstr "опцията „--dirty“ е несъвместима с указател към подаване" -#: builtin/describe.c:639 +#: builtin/describe.c:642 msgid "--broken is incompatible with commit-ishes" msgstr "опцията „--broken“ е несъвместима с указател към подаване" @@ -8435,95 +8631,101 @@ msgstr "Прилагане на УКАЗАТЕЛя_НА_ВЕРСИЯ към из msgid "anonymize output" msgstr "анонимизиране на извежданата информация" -#: builtin/fetch.c:24 +#: builtin/fetch.c:25 msgid "git fetch [] [ [...]]" msgstr "git fetch [ОПЦИЯ…] [ХРАНИЛИЩЕ [УКАЗАТЕЛ…]]" -#: builtin/fetch.c:25 +#: builtin/fetch.c:26 msgid "git fetch [] " msgstr "git fetch [ОПЦИЯ…] ГРУПА" -#: builtin/fetch.c:26 +#: builtin/fetch.c:27 msgid "git fetch --multiple [] [( | )...]" msgstr "git fetch --multiple [ОПЦИЯ…] [(ХРАНИЛИЩЕ | ГРУПА)…]" -#: builtin/fetch.c:27 +#: builtin/fetch.c:28 msgid "git fetch --all []" msgstr "git fetch --all [ОПЦИЯ…]" -#: builtin/fetch.c:113 builtin/pull.c:188 +#: builtin/fetch.c:124 builtin/pull.c:188 msgid "fetch from all remotes" msgstr "доставяне от всички отдалечени хранилища" -#: builtin/fetch.c:115 builtin/pull.c:191 +#: builtin/fetch.c:126 builtin/pull.c:191 msgid "append to .git/FETCH_HEAD instead of overwriting" msgstr "добавяне към „.git/FETCH_HEAD“ вместо замяна" -#: builtin/fetch.c:117 builtin/pull.c:194 +#: builtin/fetch.c:128 builtin/pull.c:194 msgid "path to upload pack on remote end" msgstr "отдалечен път, където да се качи пакетът" -#: builtin/fetch.c:118 builtin/pull.c:196 +#: builtin/fetch.c:129 builtin/pull.c:196 msgid "force overwrite of local branch" msgstr "принудително презаписване на локалния клон" -#: builtin/fetch.c:120 +#: builtin/fetch.c:131 msgid "fetch from multiple remotes" msgstr "доставяне от множество отдалечени хранилища" -#: builtin/fetch.c:122 builtin/pull.c:198 +#: builtin/fetch.c:133 builtin/pull.c:198 msgid "fetch all tags and associated objects" msgstr "доставяне на всички етикети и принадлежащи обекти" -#: builtin/fetch.c:124 +#: builtin/fetch.c:135 msgid "do not fetch all tags (--no-tags)" msgstr "без доставянето на всички етикети „--no-tags“" -#: builtin/fetch.c:126 +#: builtin/fetch.c:137 msgid "number of submodules fetched in parallel" msgstr "брой подмодули доставени паралелно" -#: builtin/fetch.c:128 builtin/pull.c:201 +#: builtin/fetch.c:139 builtin/pull.c:201 msgid "prune remote-tracking branches no longer on remote" msgstr "окастряне на клоните следящи вече несъществуващи отдалечени клони" -#: builtin/fetch.c:129 builtin/fetch.c:152 builtin/pull.c:126 +#: builtin/fetch.c:141 +msgid "prune local tags no longer on remote and clobber changed tags" +msgstr "" +"окастряне на локалните етикети, които вече не съществуват в отдалеченото " +"хранилище и махане на променените" + +#: builtin/fetch.c:142 builtin/fetch.c:165 builtin/pull.c:126 msgid "on-demand" msgstr "ПРИ НУЖДА" -#: builtin/fetch.c:130 +#: builtin/fetch.c:143 msgid "control recursive fetching of submodules" msgstr "управление на рекурсивното доставяне на подмодулите" -#: builtin/fetch.c:134 builtin/pull.c:209 +#: builtin/fetch.c:147 builtin/pull.c:209 msgid "keep downloaded pack" msgstr "запазване на изтеглените пакети с обекти" -#: builtin/fetch.c:136 +#: builtin/fetch.c:149 msgid "allow updating of HEAD ref" msgstr "позволяване на обновяването на указателя „HEAD“" -#: builtin/fetch.c:139 builtin/fetch.c:145 builtin/pull.c:212 +#: builtin/fetch.c:152 builtin/fetch.c:158 builtin/pull.c:212 msgid "deepen history of shallow clone" msgstr "задълбочаване на историята на плитко хранилище" -#: builtin/fetch.c:141 +#: builtin/fetch.c:154 msgid "deepen history of shallow repository based on time" msgstr "задълбочаване на историята на плитко хранилище до определено време" -#: builtin/fetch.c:147 builtin/pull.c:215 +#: builtin/fetch.c:160 builtin/pull.c:215 msgid "convert to a complete repository" msgstr "превръщане в пълно хранилище" -#: builtin/fetch.c:149 builtin/log.c:1463 +#: builtin/fetch.c:162 builtin/log.c:1466 msgid "dir" msgstr "директория" -#: builtin/fetch.c:150 +#: builtin/fetch.c:163 msgid "prepend this to submodule path output" msgstr "добавяне на това пред пътя на подмодула" -#: builtin/fetch.c:153 +#: builtin/fetch.c:166 msgid "" "default for recursive fetching of submodules (lower priority than config " "files)" @@ -8531,91 +8733,91 @@ msgstr "" "стандартно рекурсивно изтегляне на подмодулите (файловете с настройки са с " "приоритет)" -#: builtin/fetch.c:157 builtin/pull.c:218 +#: builtin/fetch.c:170 builtin/pull.c:218 msgid "accept refs that update .git/shallow" msgstr "приемане на указатели, които обновяват „.git/shallow“" -#: builtin/fetch.c:158 builtin/pull.c:220 +#: builtin/fetch.c:171 builtin/pull.c:220 msgid "refmap" msgstr "КАРТА_С_УКАЗАТЕЛИ" -#: builtin/fetch.c:159 builtin/pull.c:221 +#: builtin/fetch.c:172 builtin/pull.c:221 msgid "specify fetch refmap" msgstr "указване на КАРТАта_С_УКАЗАТЕЛИ за доставяне" -#: builtin/fetch.c:417 +#: builtin/fetch.c:431 msgid "Couldn't find remote ref HEAD" msgstr "Указателят „HEAD“ в отдалеченото хранилище не може да бъде открит" -#: builtin/fetch.c:535 +#: builtin/fetch.c:549 #, c-format msgid "configuration fetch.output contains invalid value %s" msgstr "настройката „fetch.output“ е с неправилна стойност „%s“" -#: builtin/fetch.c:628 +#: builtin/fetch.c:642 #, c-format msgid "object %s not found" msgstr "обектът „%s“ липсва" -#: builtin/fetch.c:632 +#: builtin/fetch.c:646 msgid "[up to date]" msgstr "[актуализиран]" -#: builtin/fetch.c:645 builtin/fetch.c:725 +#: builtin/fetch.c:659 builtin/fetch.c:739 msgid "[rejected]" msgstr "[отхвърлен]" -#: builtin/fetch.c:646 +#: builtin/fetch.c:660 msgid "can't fetch in current branch" msgstr "в текущия клон не може да се доставя" -#: builtin/fetch.c:655 +#: builtin/fetch.c:669 msgid "[tag update]" msgstr "[обновяване на етикетите]" -#: builtin/fetch.c:656 builtin/fetch.c:689 builtin/fetch.c:705 -#: builtin/fetch.c:720 +#: builtin/fetch.c:670 builtin/fetch.c:703 builtin/fetch.c:719 +#: builtin/fetch.c:734 msgid "unable to update local ref" msgstr "локален указател не може да бъде обновен" -#: builtin/fetch.c:675 +#: builtin/fetch.c:689 msgid "[new tag]" msgstr "[нов етикет]" -#: builtin/fetch.c:678 +#: builtin/fetch.c:692 msgid "[new branch]" msgstr "[нов клон]" -#: builtin/fetch.c:681 +#: builtin/fetch.c:695 msgid "[new ref]" msgstr "[нов указател]" -#: builtin/fetch.c:720 +#: builtin/fetch.c:734 msgid "forced update" msgstr "принудително обновяване" -#: builtin/fetch.c:725 +#: builtin/fetch.c:739 msgid "non-fast-forward" msgstr "същинско сливане" -#: builtin/fetch.c:770 +#: builtin/fetch.c:784 #, c-format msgid "%s did not send all necessary objects\n" msgstr "хранилището „%s“ не изпрати всички необходими обекти\n" -#: builtin/fetch.c:790 +#: builtin/fetch.c:804 #, c-format msgid "reject %s because shallow roots are not allowed to be updated" msgstr "" "отхвърляне на върха „%s“, защото плитките хранилища не могат да бъдат " "обновявани" -#: builtin/fetch.c:878 builtin/fetch.c:974 +#: builtin/fetch.c:892 builtin/fetch.c:988 #, c-format msgid "From %.*s\n" msgstr "От %.*s\n" -#: builtin/fetch.c:889 +#: builtin/fetch.c:903 #, c-format msgid "" "some local refs could not be updated; try running\n" @@ -8625,50 +8827,57 @@ msgstr "" "„git remote prune %s“, за да премахнете остарелите клони, които\n" "предизвикват конфликта" -#: builtin/fetch.c:944 +#: builtin/fetch.c:958 #, c-format msgid " (%s will become dangling)" msgstr " (обектът „%s“ ще се окаже извън клон)" -#: builtin/fetch.c:945 +#: builtin/fetch.c:959 #, c-format msgid " (%s has become dangling)" msgstr " (обектът „%s“ вече е извън клон)" -#: builtin/fetch.c:977 +#: builtin/fetch.c:991 msgid "[deleted]" msgstr "[изтрит]" -#: builtin/fetch.c:978 builtin/remote.c:1024 +#: builtin/fetch.c:992 builtin/remote.c:1024 msgid "(none)" msgstr "(нищо)" -#: builtin/fetch.c:1001 +#: builtin/fetch.c:1015 #, c-format msgid "Refusing to fetch into current branch %s of non-bare repository" msgstr "Не може да доставите в текущия клон „%s“ на хранилище, което не е голо" -#: builtin/fetch.c:1020 +#: builtin/fetch.c:1034 #, c-format msgid "Option \"%s\" value \"%s\" is not valid for %s" msgstr "Стойността „%2$s“ за опцията „%1$s“ не е съвместима с „%3$s“" -#: builtin/fetch.c:1023 +#: builtin/fetch.c:1037 #, c-format msgid "Option \"%s\" is ignored for %s\n" msgstr "Опцията „%s“ се прескача при „%s“\n" -#: builtin/fetch.c:1256 +#: builtin/fetch.c:1277 #, c-format msgid "Fetching %s\n" msgstr "Доставяне на „%s“\n" -#: builtin/fetch.c:1258 builtin/remote.c:97 +#: builtin/fetch.c:1279 builtin/remote.c:97 #, c-format msgid "Could not fetch %s" msgstr "„%s“ не може да се достави" -#: builtin/fetch.c:1276 +#: builtin/fetch.c:1325 builtin/fetch.c:1498 +msgid "" +"--filter can only be used with the remote configured in core.partialClone" +msgstr "" +"опцията „--filter“ може да се ползва само с отдалеченото хранилище указано в " +"настройката „core.partialClone“" + +#: builtin/fetch.c:1350 msgid "" "No remote repository specified. Please, specify either a URL or a\n" "remote name from which new revisions should be fetched." @@ -8676,41 +8885,41 @@ msgstr "" "Не сте указали отдалечено хранилище. Задайте или адрес, или име\n" "на отдалечено хранилище, откъдето да се доставят новите версии." -#: builtin/fetch.c:1299 +#: builtin/fetch.c:1394 msgid "You need to specify a tag name." msgstr "Трябва да укажете име на етикет." -#: builtin/fetch.c:1342 +#: builtin/fetch.c:1439 msgid "Negative depth in --deepen is not supported" msgstr "Отрицателна дълбочина като аргумент на „--deepen“ не се поддържа" -#: builtin/fetch.c:1344 +#: builtin/fetch.c:1441 msgid "--deepen and --depth are mutually exclusive" msgstr "Опциите „--deepen“ и „--depth“ са несъвместими една с друга" -#: builtin/fetch.c:1349 +#: builtin/fetch.c:1446 msgid "--depth and --unshallow cannot be used together" msgstr "опциите „--depth“ и „--unshallow“ са несъвместими" -#: builtin/fetch.c:1351 +#: builtin/fetch.c:1448 msgid "--unshallow on a complete repository does not make sense" msgstr "не можете да използвате опцията „--unshallow“ върху пълно хранилище" -#: builtin/fetch.c:1364 +#: builtin/fetch.c:1464 msgid "fetch --all does not take a repository argument" msgstr "към „git fetch --all“ не можете да добавите аргумент — хранилище" -#: builtin/fetch.c:1366 +#: builtin/fetch.c:1466 msgid "fetch --all does not make sense with refspecs" msgstr "" "към „git fetch --all“ не можете да добавите аргумент — указател на версия" -#: builtin/fetch.c:1377 +#: builtin/fetch.c:1475 #, c-format msgid "No such remote or remote group: %s" msgstr "Няма нито отдалечено хранилище, нито група от хранилища на име „%s“" -#: builtin/fetch.c:1385 +#: builtin/fetch.c:1482 msgid "Fetching a group and specifying refspecs does not make sense" msgstr "Указването на група и указването на версия са несъвместими" @@ -8778,7 +8987,7 @@ msgstr "цитиране подходящо за tcl" msgid "show only matched refs" msgstr "извеждане само на този БРОЙ напаснати указатели" -#: builtin/for-each-ref.c:39 builtin/tag.c:414 +#: builtin/for-each-ref.c:39 builtin/tag.c:420 msgid "respect format colors" msgstr "спазване на цветовете на форма̀та" @@ -8802,64 +9011,64 @@ msgstr "извеждане само на указателите, които съ msgid "print only refs which don't contain the commit" msgstr "извеждане само на указателите, които не съдържат това ПОДАВАНЕ" -#: builtin/fsck.c:543 +#: builtin/fsck.c:568 msgid "Checking object directories" msgstr "Проверка на директориите с обекти" -#: builtin/fsck.c:635 +#: builtin/fsck.c:660 msgid "git fsck [] [...]" msgstr "git fsck [ОПЦИЯ…] [ОБЕКТ…]" -#: builtin/fsck.c:641 +#: builtin/fsck.c:666 msgid "show unreachable objects" msgstr "показване на недостижимите обекти" -#: builtin/fsck.c:642 +#: builtin/fsck.c:667 msgid "show dangling objects" msgstr "показване на обектите извън клоните" -#: builtin/fsck.c:643 +#: builtin/fsck.c:668 msgid "report tags" msgstr "показване на етикетите" -#: builtin/fsck.c:644 +#: builtin/fsck.c:669 msgid "report root nodes" msgstr "показване на кореновите възли" -#: builtin/fsck.c:645 +#: builtin/fsck.c:670 msgid "make index objects head nodes" msgstr "задаване на обекти от индекса да са коренови" # FIXME bad message -#: builtin/fsck.c:646 +#: builtin/fsck.c:671 msgid "make reflogs head nodes (default)" msgstr "проследяване на указателите от журнала като глави (стандартно)" -#: builtin/fsck.c:647 +#: builtin/fsck.c:672 msgid "also consider packs and alternate objects" msgstr "допълнително да се проверяват пакетите и алтернативните обекти" -#: builtin/fsck.c:648 +#: builtin/fsck.c:673 msgid "check only connectivity" msgstr "проверка само на връзката" -#: builtin/fsck.c:649 +#: builtin/fsck.c:674 msgid "enable more strict checking" msgstr "по-строги проверки" -#: builtin/fsck.c:651 +#: builtin/fsck.c:676 msgid "write dangling objects in .git/lost-found" msgstr "запазване на обектите извън клоните в директорията „.git/lost-found“" -#: builtin/fsck.c:652 builtin/prune.c:107 +#: builtin/fsck.c:677 builtin/prune.c:108 msgid "show progress" msgstr "показване на напредъка" -#: builtin/fsck.c:653 +#: builtin/fsck.c:678 msgid "show verbose names for reachable objects" msgstr "показване на подробни имена на достижимите обекти" -#: builtin/fsck.c:714 +#: builtin/fsck.c:742 msgid "Checking objects" msgstr "Проверка на обектите" @@ -8906,37 +9115,37 @@ msgstr "изчерпателно търсене на боклука (за сме msgid "enable auto-gc mode" msgstr "включване на автоматичното събиране на боклука (auto-gc)" -#: builtin/gc.c:364 +#: builtin/gc.c:366 msgid "force running gc even if there may be another gc running" msgstr "" "изрично стартиране на събирането на боклука, дори и ако вече работи друго " "събиране" -#: builtin/gc.c:381 +#: builtin/gc.c:384 #, c-format msgid "Failed to parse gc.logexpiry value %s" msgstr "Неразпозната стойност на „gc.logexpiry“: %s" -#: builtin/gc.c:409 +#: builtin/gc.c:412 #, c-format msgid "Auto packing the repository in background for optimum performance.\n" msgstr "" "Автоматично пакетиране на заден фон на хранилището за по-добра " "производителност.\n" -#: builtin/gc.c:411 +#: builtin/gc.c:414 #, c-format msgid "Auto packing the repository for optimum performance.\n" msgstr "Автоматично пакетиране на хранилището за по-добра производителност.\n" -#: builtin/gc.c:412 +#: builtin/gc.c:415 #, c-format msgid "See \"git help gc\" for manual housekeeping.\n" msgstr "" "Погледнете ръководството за повече информация как да изпълните „git help " "gc“.\n" -#: builtin/gc.c:437 +#: builtin/gc.c:440 #, c-format msgid "" "gc is already running on machine '%s' pid % (use --force if not)" @@ -8945,7 +9154,7 @@ msgstr "" "процеса: % (ако сте сигурни, че това не е вярно, това използвайте\n" "опцията „--force“)" -#: builtin/gc.c:481 +#: builtin/gc.c:487 msgid "" "There are too many unreachable loose objects; run 'git prune' to remove them." msgstr "" @@ -8956,12 +9165,12 @@ msgstr "" msgid "git grep [] [-e] [...] [[--] ...]" msgstr "git grep [ОПЦИЯ…] [-e] ШАБЛОН [ВЕРСИЯ…] [[--] ПЪТ…]" -#: builtin/grep.c:226 +#: builtin/grep.c:225 #, c-format msgid "grep: failed to create thread: %s" msgstr "grep: неуспешно създаване на нишка: %s" -#: builtin/grep.c:284 +#: builtin/grep.c:283 #, c-format msgid "invalid number of threads specified (%d) for %s" msgstr "зададен е неправилен брой нишки (%d) за %s" @@ -8970,259 +9179,259 @@ msgstr "зададен е неправилен брой нишки (%d) за %s" #. variable for tweaking threads, currently #. grep.threads #. -#: builtin/grep.c:293 builtin/index-pack.c:1495 builtin/index-pack.c:1688 +#: builtin/grep.c:292 builtin/index-pack.c:1523 builtin/index-pack.c:1712 #, c-format msgid "no threads support, ignoring %s" msgstr "липсва поддръжка за нишки. „%s“ ще се пренебрегне" -#: builtin/grep.c:453 builtin/grep.c:573 builtin/grep.c:615 +#: builtin/grep.c:460 builtin/grep.c:580 builtin/grep.c:622 #, c-format msgid "unable to read tree (%s)" msgstr "дървото не може да бъде прочетено (%s)" -#: builtin/grep.c:630 +#: builtin/grep.c:637 #, c-format msgid "unable to grep from object of type %s" msgstr "не може да се изпълни „grep“ от обект от вида %s" -#: builtin/grep.c:696 +#: builtin/grep.c:703 #, c-format msgid "switch `%c' expects a numerical value" msgstr "опцията „%c“ очаква число за аргумент" -#: builtin/grep.c:783 +#: builtin/grep.c:790 msgid "search in index instead of in the work tree" msgstr "търсене в индекса, а не в работното дърво" -#: builtin/grep.c:785 +#: builtin/grep.c:792 msgid "find in contents not managed by git" msgstr "търсене и във файловете, които не са под управлението на git" -#: builtin/grep.c:787 +#: builtin/grep.c:794 msgid "search in both tracked and untracked files" msgstr "търсене и в следените, и в неследените файлове" -#: builtin/grep.c:789 +#: builtin/grep.c:796 msgid "ignore files specified via '.gitignore'" msgstr "игнориране на файловете указани в „.gitignore“" -#: builtin/grep.c:791 +#: builtin/grep.c:798 msgid "recursively search in each submodule" msgstr "рекурсивно търсене във всички подмодули" -#: builtin/grep.c:794 +#: builtin/grep.c:801 msgid "show non-matching lines" msgstr "извеждане на редовете, които не съвпадат" -#: builtin/grep.c:796 +#: builtin/grep.c:803 msgid "case insensitive matching" msgstr "без значение на регистъра на буквите (главни/малки)" -#: builtin/grep.c:798 +#: builtin/grep.c:805 msgid "match patterns only at word boundaries" msgstr "напасване на шаблоните само по границите на думите" -#: builtin/grep.c:800 +#: builtin/grep.c:807 msgid "process binary files as text" msgstr "обработване на двоичните файлове като текстови" -#: builtin/grep.c:802 +#: builtin/grep.c:809 msgid "don't match patterns in binary files" msgstr "прескачане на двоичните файлове" -#: builtin/grep.c:805 +#: builtin/grep.c:812 msgid "process binary files with textconv filters" msgstr "" "обработване на двоичните файлове чрез филтри за преобразуване към текст" -#: builtin/grep.c:807 +#: builtin/grep.c:814 msgid "descend at most levels" msgstr "навлизане максимално на тази ДЪЛБОЧИНА в дървото" -#: builtin/grep.c:811 +#: builtin/grep.c:818 msgid "use extended POSIX regular expressions" msgstr "разширени регулярни изрази по POSIX" -#: builtin/grep.c:814 +#: builtin/grep.c:821 msgid "use basic POSIX regular expressions (default)" msgstr "основни регулярни изрази по POSIX (стандартно)" -#: builtin/grep.c:817 +#: builtin/grep.c:824 msgid "interpret patterns as fixed strings" msgstr "шаблоните са дословни низове" -#: builtin/grep.c:820 +#: builtin/grep.c:827 msgid "use Perl-compatible regular expressions" msgstr "регулярни изрази на Perl" -#: builtin/grep.c:823 +#: builtin/grep.c:830 msgid "show line numbers" msgstr "извеждане на номерата на редовете" -#: builtin/grep.c:824 +#: builtin/grep.c:831 msgid "don't show filenames" msgstr "без извеждане на имената на файловете" -#: builtin/grep.c:825 +#: builtin/grep.c:832 msgid "show filenames" msgstr "извеждане на имената на файловете" -#: builtin/grep.c:827 +#: builtin/grep.c:834 msgid "show filenames relative to top directory" msgstr "" "извеждане на относителните имена на файловете спрямо основната директория на " "хранилището" -#: builtin/grep.c:829 +#: builtin/grep.c:836 msgid "show only filenames instead of matching lines" msgstr "извеждане само на имената на файловете без напасващите редове" -#: builtin/grep.c:831 +#: builtin/grep.c:838 msgid "synonym for --files-with-matches" msgstr "синоним на „--files-with-matches“" -#: builtin/grep.c:834 +#: builtin/grep.c:841 msgid "show only the names of files without match" msgstr "" "извеждане само на имената на файловете, които не съдържат ред, напасващ на " "шаблона" -#: builtin/grep.c:836 +#: builtin/grep.c:843 msgid "print NUL after filenames" msgstr "извеждане на нулевия знак „NUL“ след всяко име на файл" -#: builtin/grep.c:838 +#: builtin/grep.c:846 msgid "show the number of matches instead of matching lines" msgstr "извеждане на броя на съвпаденията вместо напасващите редове" -#: builtin/grep.c:839 +#: builtin/grep.c:847 msgid "highlight matches" msgstr "оцветяване на напасванията" -#: builtin/grep.c:841 +#: builtin/grep.c:849 msgid "print empty line between matches from different files" msgstr "извеждане на празен ред между напасванията от различни файлове" -#: builtin/grep.c:843 +#: builtin/grep.c:851 msgid "show filename only once above matches from same file" msgstr "" "извеждане на името на файла само веднъж за всички напасвания от този файл" -#: builtin/grep.c:846 +#: builtin/grep.c:854 msgid "show context lines before and after matches" msgstr "извеждане на такъв БРОЙ редове преди и след напасванията" -#: builtin/grep.c:849 +#: builtin/grep.c:857 msgid "show context lines before matches" msgstr "извеждане на такъв БРОЙ редове преди напасванията" -#: builtin/grep.c:851 +#: builtin/grep.c:859 msgid "show context lines after matches" msgstr "извеждане на такъв БРОЙ редове след напасванията" -#: builtin/grep.c:853 +#: builtin/grep.c:861 msgid "use worker threads" msgstr "използване на такъв БРОЙ работещи нишки" -#: builtin/grep.c:854 +#: builtin/grep.c:862 msgid "shortcut for -C NUM" msgstr "синоним на „-C БРОЙ“" -#: builtin/grep.c:857 +#: builtin/grep.c:865 msgid "show a line with the function name before matches" msgstr "извеждане на ред с името на функцията, в която е напаснат шаблона" -#: builtin/grep.c:859 +#: builtin/grep.c:867 msgid "show the surrounding function" msgstr "извеждане на обхващащата функция" -#: builtin/grep.c:862 +#: builtin/grep.c:870 msgid "read patterns from file" msgstr "изчитане на шаблоните от ФАЙЛ" -#: builtin/grep.c:864 +#: builtin/grep.c:872 msgid "match " msgstr "напасване на ШАБЛОН" -#: builtin/grep.c:866 +#: builtin/grep.c:874 msgid "combine patterns specified with -e" msgstr "комбиниране на шаблоните указани с опцията „-e“" -#: builtin/grep.c:878 +#: builtin/grep.c:886 msgid "indicate hit with exit status without output" msgstr "" "без извеждане на стандартния изход. Изходният код указва наличието на " "напасване" -#: builtin/grep.c:880 +#: builtin/grep.c:888 msgid "show only matches from files that match all patterns" msgstr "" "извеждане на редове само от файловете, които напасват на всички шаблони" -#: builtin/grep.c:882 +#: builtin/grep.c:890 msgid "show parse tree for grep expression" msgstr "извеждане на дървото за анализ на регулярния израз" -#: builtin/grep.c:886 +#: builtin/grep.c:894 msgid "pager" msgstr "програма за преглед по страници" -#: builtin/grep.c:886 +#: builtin/grep.c:894 msgid "show matching files in the pager" msgstr "извеждане на съвпадащите файлове в програма за преглед по страници" -#: builtin/grep.c:889 +#: builtin/grep.c:898 msgid "allow calling of grep(1) (ignored by this build)" msgstr "" "позволяване на стартирането на grep(1) (текущият компилат пренебрегва тази " "опция)" -#: builtin/grep.c:952 +#: builtin/grep.c:962 msgid "no pattern given." msgstr "липсва шаблон." -#: builtin/grep.c:984 +#: builtin/grep.c:994 msgid "--no-index or --untracked cannot be used with revs" msgstr "опциите „--cached“ и „--untracked“ са несъвместими с версии." -#: builtin/grep.c:991 +#: builtin/grep.c:1001 #, c-format msgid "unable to resolve revision: %s" msgstr "версията „%s“ не може бъде открита" -#: builtin/grep.c:1026 builtin/index-pack.c:1491 +#: builtin/grep.c:1036 builtin/index-pack.c:1519 #, c-format msgid "invalid number of threads specified (%d)" msgstr "зададен е неправилен брой нишки: %d" -#: builtin/grep.c:1031 +#: builtin/grep.c:1041 msgid "no threads support, ignoring --threads" msgstr "липсва поддръжка за нишки. „--threads“ ще се пренебрегне" -#: builtin/grep.c:1055 +#: builtin/grep.c:1065 msgid "--open-files-in-pager only works on the worktree" msgstr "" "опцията „--open-files-in-pager“ е съвместима само с търсене в работното дърво" -#: builtin/grep.c:1078 +#: builtin/grep.c:1088 msgid "option not supported with --recurse-submodules." msgstr "опцията е несъвместима с „--recurse-submodules“." -#: builtin/grep.c:1084 +#: builtin/grep.c:1094 msgid "--cached or --untracked cannot be used with --no-index." msgstr "опциите „--cached“ и „--untracked“ са несъвместими с „--no-index“." -#: builtin/grep.c:1090 +#: builtin/grep.c:1100 msgid "--[no-]exclude-standard cannot be used for tracked contents." msgstr "" "опциите „--(no-)exclude-standard“ са несъвместими с търсене по следени " "файлове." -#: builtin/grep.c:1098 +#: builtin/grep.c:1108 msgid "both --cached and trees are given." msgstr "опцията „--cached“ е несъвместима със задаване на дърво." -#: builtin/hash-object.c:82 +#: builtin/hash-object.c:83 msgid "" "git hash-object [-t ] [-w] [--path= | --no-filters] [--stdin] " "[--] ..." @@ -9230,38 +9439,38 @@ msgstr "" "git hash-object [-t ВИД] [-w] [--path=ФАЙЛ | --no-filters] [--stdin] [--] " "ФАЙЛ…" -#: builtin/hash-object.c:83 +#: builtin/hash-object.c:84 msgid "git hash-object --stdin-paths" msgstr "git hash-object --stdin-paths" -#: builtin/hash-object.c:95 +#: builtin/hash-object.c:96 msgid "type" msgstr "ВИД" -#: builtin/hash-object.c:95 +#: builtin/hash-object.c:96 msgid "object type" msgstr "ВИД на обекта" -#: builtin/hash-object.c:96 +#: builtin/hash-object.c:97 msgid "write the object into the object database" msgstr "записване на обекта в базата от данни за обектите" -#: builtin/hash-object.c:98 +#: builtin/hash-object.c:99 msgid "read the object from stdin" msgstr "изчитане на обекта от стандартния вход" -#: builtin/hash-object.c:100 +#: builtin/hash-object.c:101 msgid "store file as is without filters" msgstr "запазване на файла както е — без филтри" -#: builtin/hash-object.c:101 +#: builtin/hash-object.c:102 msgid "" "just hash any random garbage to create corrupt objects for debugging Git" msgstr "" "създаване и хеширане на произволни данни за повредени обекти за трасиране на " "Git" -#: builtin/hash-object.c:102 +#: builtin/hash-object.c:103 msgid "process file as it were from this path" msgstr "обработване на ФАЙЛа все едно е с този път" @@ -9395,154 +9604,154 @@ msgstr "„%s“ е синоним на „%s“" msgid "usage: %s%s" msgstr "употреба: %s%s" -#: builtin/index-pack.c:156 +#: builtin/index-pack.c:157 #, c-format msgid "unable to open %s" msgstr "обектът „%s“ не може да бъде отворен" -#: builtin/index-pack.c:206 +#: builtin/index-pack.c:207 #, c-format msgid "object type mismatch at %s" msgstr "неправилен вид на обекта „%s“" -#: builtin/index-pack.c:226 +#: builtin/index-pack.c:227 #, c-format msgid "did not receive expected object %s" msgstr "очакваният обект „%s“ не бе получен" -#: builtin/index-pack.c:229 +#: builtin/index-pack.c:230 #, c-format msgid "object %s: expected type %s, found %s" msgstr "неправилен вид на обекта „%s“: очакваше се „%s“, а бе получен „%s“" -#: builtin/index-pack.c:271 +#: builtin/index-pack.c:272 #, c-format msgid "cannot fill %d byte" msgid_plural "cannot fill %d bytes" msgstr[0] "не може да се запълни %d байт" msgstr[1] "не може да се запълнят %d байта" -#: builtin/index-pack.c:281 +#: builtin/index-pack.c:282 msgid "early EOF" msgstr "неочакван край на файл" -#: builtin/index-pack.c:282 +#: builtin/index-pack.c:283 msgid "read error on input" msgstr "грешка при четене на входните данни" -#: builtin/index-pack.c:294 +#: builtin/index-pack.c:295 msgid "used more bytes than were available" msgstr "използвани са повече от наличните байтове" -#: builtin/index-pack.c:301 +#: builtin/index-pack.c:302 msgid "pack too large for current definition of off_t" msgstr "пакетният файл е прекалено голям за текущата стойност на типа „off_t“" -#: builtin/index-pack.c:304 builtin/unpack-objects.c:93 +#: builtin/index-pack.c:305 builtin/unpack-objects.c:93 msgid "pack exceeds maximum allowed size" msgstr "пакетният файл надвишава максималния възможен размер" -#: builtin/index-pack.c:319 +#: builtin/index-pack.c:320 #, c-format msgid "unable to create '%s'" msgstr "пакетният файл „%s“ не може да бъде създаден" -#: builtin/index-pack.c:325 +#: builtin/index-pack.c:326 #, c-format msgid "cannot open packfile '%s'" msgstr "пакетният файл „%s“ не може да бъде отворен" -#: builtin/index-pack.c:339 +#: builtin/index-pack.c:340 msgid "pack signature mismatch" msgstr "несъответствие в подписа към пакетния файл" -#: builtin/index-pack.c:341 +#: builtin/index-pack.c:342 #, c-format msgid "pack version % unsupported" msgstr "не се поддържа пакетиране вeрсия „%“" -#: builtin/index-pack.c:359 +#: builtin/index-pack.c:360 #, c-format msgid "pack has bad object at offset %: %s" msgstr "повреден обект в пакетния файл при отместване %: %s" -#: builtin/index-pack.c:480 +#: builtin/index-pack.c:481 #, c-format msgid "inflate returned %d" msgstr "декомпресирането с „inflate“ върна %d" -#: builtin/index-pack.c:529 +#: builtin/index-pack.c:530 msgid "offset value overflow for delta base object" msgstr "стойността на отместването за обекта-разлика води до препълване" -#: builtin/index-pack.c:537 +#: builtin/index-pack.c:538 msgid "delta base offset is out of bound" msgstr "стойността на отместването за обекта-разлика е извън диапазона" -#: builtin/index-pack.c:545 +#: builtin/index-pack.c:546 #, c-format msgid "unknown object type %d" msgstr "непознат вид обект %d" -#: builtin/index-pack.c:576 +#: builtin/index-pack.c:577 msgid "cannot pread pack file" msgstr "пакетният файл не може да бъде прочетен" -#: builtin/index-pack.c:578 +#: builtin/index-pack.c:579 #, c-format msgid "premature end of pack file, % byte missing" msgid_plural "premature end of pack file, % bytes missing" msgstr[0] "неочакван край на файл, липсва % байт" msgstr[1] "неочакван край на файл, липсват % байта" -#: builtin/index-pack.c:604 +#: builtin/index-pack.c:605 msgid "serious inflate inconsistency" msgstr "сериозна грешка при декомпресиране с „inflate“" -#: builtin/index-pack.c:749 builtin/index-pack.c:755 builtin/index-pack.c:778 -#: builtin/index-pack.c:817 builtin/index-pack.c:826 +#: builtin/index-pack.c:750 builtin/index-pack.c:756 builtin/index-pack.c:779 +#: builtin/index-pack.c:818 builtin/index-pack.c:827 #, c-format msgid "SHA1 COLLISION FOUND WITH %s !" msgstr "" "СЪВПАДЕНИЕ НА СТОЙНОСТИТЕ ЗА СУМИТЕ ЗА SHA1: „%s“ НА ДВА РАЗЛИЧНИ ОБЕКТА!" -#: builtin/index-pack.c:752 builtin/pack-objects.c:179 -#: builtin/pack-objects.c:273 +#: builtin/index-pack.c:753 builtin/pack-objects.c:182 +#: builtin/pack-objects.c:276 #, c-format msgid "unable to read %s" msgstr "обектът „%s“ не може да бъде прочетен" -#: builtin/index-pack.c:815 +#: builtin/index-pack.c:816 #, c-format msgid "cannot read existing object info %s" msgstr "съществуващият обект в „%s“ не може да бъде прочетен" -#: builtin/index-pack.c:823 +#: builtin/index-pack.c:824 #, c-format msgid "cannot read existing object %s" msgstr "съществуващият обект „%s“ не може да бъде прочетен" -#: builtin/index-pack.c:837 +#: builtin/index-pack.c:838 #, c-format msgid "invalid blob object %s" msgstr "неправилен обект BLOB „%s“" # FIXME perhaps invalid object -#: builtin/index-pack.c:852 +#: builtin/index-pack.c:853 #, c-format msgid "invalid %s" msgstr "неправилен обект „%s“" -#: builtin/index-pack.c:855 +#: builtin/index-pack.c:856 msgid "Error in object" msgstr "Грешка в обекта" -#: builtin/index-pack.c:857 +#: builtin/index-pack.c:858 #, c-format msgid "Not all child objects of %s are reachable" msgstr "Някои обекти, наследници на „%s“, не могат да бъдат достигнати" -#: builtin/index-pack.c:929 builtin/index-pack.c:960 +#: builtin/index-pack.c:930 builtin/index-pack.c:961 msgid "failed to apply delta" msgstr "разликата не може да бъде приложена" @@ -9620,80 +9829,81 @@ msgstr "добавеният обект не може да се компреси msgid "local object %s is corrupt" msgstr "локалният обект „%s“ е повреден" -#: builtin/index-pack.c:1409 -msgid "error while closing pack file" -msgstr "грешка при затварянето на пакетния файл" +#: builtin/index-pack.c:1397 +#, c-format +msgid "packfile name '%s' does not end with '.pack'" +msgstr "името на пакетния файл „%s“ не завършва на „.pack“" -#: builtin/index-pack.c:1421 +#: builtin/index-pack.c:1422 #, c-format -msgid "cannot write keep file '%s'" -msgstr "" -"грешка при записването на файла „%s“, осигуряващ запазване на директория" +msgid "cannot write %s file '%s'" +msgstr "грешка при запис на файла „%s“ „%s“" -#: builtin/index-pack.c:1429 +#: builtin/index-pack.c:1430 #, c-format -msgid "cannot close written keep file '%s'" -msgstr "" -"грешка при затварянето на записания файл „%s“, осигуряващ запазване на " -"директория" +msgid "cannot close written %s file '%s'" +msgstr "грешка при затварянето на записания файл „%s“ „%s“" + +#: builtin/index-pack.c:1454 +msgid "error while closing pack file" +msgstr "грешка при затварянето на пакетния файл" -#: builtin/index-pack.c:1439 +#: builtin/index-pack.c:1468 msgid "cannot store pack file" msgstr "пакетният файл не може да бъде запазен" -#: builtin/index-pack.c:1447 +#: builtin/index-pack.c:1476 msgid "cannot store index file" msgstr "файлът за индекса не може да бъде съхранен" -#: builtin/index-pack.c:1485 +#: builtin/index-pack.c:1513 #, c-format msgid "bad pack.indexversion=%" msgstr "зададена е неправилна версия пакетиране: „pack.indexversion=%“" -#: builtin/index-pack.c:1553 +#: builtin/index-pack.c:1581 #, c-format msgid "Cannot open existing pack file '%s'" msgstr "Съществуващият пакетен файл „%s“ не може да бъде отворен" -#: builtin/index-pack.c:1555 +#: builtin/index-pack.c:1583 #, c-format msgid "Cannot open existing pack idx file for '%s'" msgstr "Съществуващият индекс за пакетния файл „%s“ не може да бъде отворен" -#: builtin/index-pack.c:1603 +#: builtin/index-pack.c:1631 #, c-format msgid "non delta: %d object" msgid_plural "non delta: %d objects" msgstr[0] "%d обект не е разлика" msgstr[1] "%d обекта не са разлика" -#: builtin/index-pack.c:1610 +#: builtin/index-pack.c:1638 #, c-format msgid "chain length = %d: %lu object" msgid_plural "chain length = %d: %lu objects" msgstr[0] "дължината на веригата е %d: %lu обект" msgstr[1] "дължината на веригата е %d: %lu обекта" -#: builtin/index-pack.c:1623 -#, c-format -msgid "packfile name '%s' does not end with '.pack'" -msgstr "името на пакетния файл „%s“ не завършва на „.pack“" +#: builtin/index-pack.c:1675 +msgid "Cannot come back to cwd" +msgstr "Процесът не може да се върне към предишната работна директория" -#: builtin/index-pack.c:1700 builtin/index-pack.c:1703 -#: builtin/index-pack.c:1719 builtin/index-pack.c:1723 +#: builtin/index-pack.c:1724 builtin/index-pack.c:1727 +#: builtin/index-pack.c:1743 builtin/index-pack.c:1747 #, c-format msgid "bad %s" msgstr "неправилна стойност „%s“" -#: builtin/index-pack.c:1739 +#: builtin/index-pack.c:1763 msgid "--fix-thin cannot be used without --stdin" msgstr "опцията „--fix-thin“ изисква „--stdin“" -#: builtin/index-pack.c:1741 +#: builtin/index-pack.c:1765 msgid "--stdin requires a git repository" msgstr "„--stdin“ изисква хранилище на git" -#: builtin/index-pack.c:1749 +#: builtin/index-pack.c:1771 msgid "--verify with no packfile name given" msgstr "опцията „--verify“ изисква име на пакетен файл" @@ -9880,124 +10090,124 @@ msgstr "опцията „--trailer“ е несъвместима с „--name- msgid "no input file given for in-place editing" msgstr "не е зададен входен файл за редактиране на място" -#: builtin/log.c:46 +#: builtin/log.c:48 msgid "git log [] [] [[--] ...]" msgstr "git log [ОПЦИЯ…] [ДИАПАЗОН_НА_ВЕРСИИТЕ] [[--] ПЪТ…]" -#: builtin/log.c:47 +#: builtin/log.c:49 msgid "git show [] ..." msgstr "git show [ОПЦИЯ…] ОБЕКТ…" -#: builtin/log.c:91 +#: builtin/log.c:93 #, c-format msgid "invalid --decorate option: %s" msgstr "неправилна опция „--decorate“: %s" -#: builtin/log.c:151 +#: builtin/log.c:153 msgid "suppress diff output" msgstr "без извеждане на разликите" -#: builtin/log.c:152 +#: builtin/log.c:154 msgid "show source" msgstr "извеждане на изходния код" -#: builtin/log.c:153 +#: builtin/log.c:155 msgid "Use mail map file" msgstr "" "Използване на файл за съответствията на имената и адресите на е-поща („." "mailmap“)" -#: builtin/log.c:155 +#: builtin/log.c:157 msgid "only decorate refs that match " msgstr "специален формат само на указателите напасващи на ШАБЛОНа" -#: builtin/log.c:157 +#: builtin/log.c:159 msgid "do not decorate refs that match " msgstr "без специален формат на указателите напасващи на ШАБЛОНа" -#: builtin/log.c:158 +#: builtin/log.c:160 msgid "decorate options" msgstr "настройки на форма̀та на извежданата информация" -#: builtin/log.c:161 +#: builtin/log.c:163 msgid "Process line range n,m in file, counting from 1" msgstr "" "Обработване само на редовете във файла в диапазона от n до m включително. " "Броенето започва от 1" -#: builtin/log.c:257 +#: builtin/log.c:259 #, c-format msgid "Final output: %d %s\n" msgstr "Резултат: %d %s\n" -#: builtin/log.c:508 +#: builtin/log.c:510 #, c-format msgid "git show %s: bad file" msgstr "git show %s: повреден файл" -#: builtin/log.c:523 builtin/log.c:617 +#: builtin/log.c:525 builtin/log.c:619 #, c-format msgid "Could not read object %s" msgstr "Обектът не може да бъде прочетен: %s" -#: builtin/log.c:641 +#: builtin/log.c:643 #, c-format msgid "Unknown type: %d" msgstr "Неизвестен вид: %d" -#: builtin/log.c:762 +#: builtin/log.c:764 msgid "format.headers without value" msgstr "не е зададена стойност на „format.headers“" -#: builtin/log.c:863 +#: builtin/log.c:865 msgid "name of output directory is too long" msgstr "прекалено дълго име на директорията за изходната информация" -#: builtin/log.c:879 +#: builtin/log.c:881 #, c-format msgid "Cannot open patch file %s" msgstr "Файлът-кръпка „%s“ не може да бъде отворен" -#: builtin/log.c:896 +#: builtin/log.c:898 msgid "Need exactly one range." msgstr "Трябва да зададете точно един диапазон." -#: builtin/log.c:906 +#: builtin/log.c:908 msgid "Not a range." msgstr "Не е диапазон." -#: builtin/log.c:1012 +#: builtin/log.c:1014 msgid "Cover letter needs email format" msgstr "Придружаващото писмо трябва да е форматирано като е-писмо" -#: builtin/log.c:1092 +#: builtin/log.c:1095 #, c-format msgid "insane in-reply-to: %s" msgstr "неправилен формат на заглавната част за отговор „in-reply-to“: %s" -#: builtin/log.c:1119 +#: builtin/log.c:1122 msgid "git format-patch [] [ | ]" msgstr "git format-patch [ОПЦИЯ…] [ОТ | ДИАПАЗОН_НА_ВЕРСИИТЕ]" -#: builtin/log.c:1169 +#: builtin/log.c:1172 msgid "Two output directories?" msgstr "Можете да укажете максимум една директория за изход." -#: builtin/log.c:1276 builtin/log.c:1927 builtin/log.c:1929 builtin/log.c:1941 +#: builtin/log.c:1279 builtin/log.c:1932 builtin/log.c:1934 builtin/log.c:1946 #, c-format msgid "Unknown commit %s" msgstr "Непознато подаване „%s“" -#: builtin/log.c:1286 builtin/notes.c:887 builtin/tag.c:516 +#: builtin/log.c:1289 builtin/notes.c:887 builtin/tag.c:522 #, c-format msgid "Failed to resolve '%s' as a valid ref." msgstr "Не може да се открие към какво сочи „%s“." -#: builtin/log.c:1291 +#: builtin/log.c:1294 msgid "Could not find exact merge base." msgstr "Точната база за сливане не може да се открие." -#: builtin/log.c:1295 +#: builtin/log.c:1298 msgid "" "Failed to get upstream, if you want to record base commit automatically,\n" "please use git branch --set-upstream-to to track a remote branch.\n" @@ -10007,234 +10217,234 @@ msgstr "" "зададете, използвайте „git branch --set-upstream-to“.\n" "Можете ръчно да зададете базово подаване чрез „--base=“." -#: builtin/log.c:1315 +#: builtin/log.c:1318 msgid "Failed to find exact merge base" msgstr "Точната база при сливане не може да бъде открита" -#: builtin/log.c:1326 +#: builtin/log.c:1329 msgid "base commit should be the ancestor of revision list" msgstr "базовото подаване трябва да е предшественикът на списъка с версиите" -#: builtin/log.c:1330 +#: builtin/log.c:1333 msgid "base commit shouldn't be in revision list" msgstr "базовото подаване не може да е в списъка с версиите" -#: builtin/log.c:1379 +#: builtin/log.c:1382 msgid "cannot get patch id" msgstr "идентификаторът на кръпката не може да бъде получен" -#: builtin/log.c:1438 +#: builtin/log.c:1441 msgid "use [PATCH n/m] even with a single patch" msgstr "номерация „[PATCH n/m]“ дори и при единствена кръпка" -#: builtin/log.c:1441 +#: builtin/log.c:1444 msgid "use [PATCH] even with multiple patches" msgstr "номерация „[PATCH]“ дори и при множество кръпки" -#: builtin/log.c:1445 +#: builtin/log.c:1448 msgid "print patches to standard out" msgstr "извеждане на кръпките на стандартния изход" -#: builtin/log.c:1447 +#: builtin/log.c:1450 msgid "generate a cover letter" msgstr "създаване на придружаващо писмо" -#: builtin/log.c:1449 +#: builtin/log.c:1452 msgid "use simple number sequence for output file names" msgstr "проста числова последователност за имената на файловете-кръпки" -#: builtin/log.c:1450 +#: builtin/log.c:1453 msgid "sfx" msgstr "ЗНАЦИ" -#: builtin/log.c:1451 +#: builtin/log.c:1454 msgid "use instead of '.patch'" msgstr "използване на тези ЗНАЦИ за суфикс вместо „.patch“" -#: builtin/log.c:1453 +#: builtin/log.c:1456 msgid "start numbering patches at instead of 1" msgstr "номерирането на кръпките да започва от този БРОЙ, а не с 1" -#: builtin/log.c:1455 +#: builtin/log.c:1458 msgid "mark the series as Nth re-roll" msgstr "отбелязване, че това е N-тата поредна редакция на поредицата от кръпки" -#: builtin/log.c:1457 +#: builtin/log.c:1460 msgid "Use [RFC PATCH] instead of [PATCH]" msgstr "Използване на „[RFC PATCH]“ вместо „[PATCH]“" -#: builtin/log.c:1460 +#: builtin/log.c:1463 msgid "Use [] instead of [PATCH]" msgstr "Използване на този „[ПРЕФИКС]“ вместо „[PATCH]“" -#: builtin/log.c:1463 +#: builtin/log.c:1466 msgid "store resulting files in " msgstr "запазване на изходните файлове в тази ДИРЕКТОРИЯ" -#: builtin/log.c:1466 +#: builtin/log.c:1469 msgid "don't strip/add [PATCH]" msgstr "без добавяне/махане на префикса „[PATCH]“" -#: builtin/log.c:1469 +#: builtin/log.c:1472 msgid "don't output binary diffs" msgstr "без извеждане на разлики между двоични файлове" -#: builtin/log.c:1471 +#: builtin/log.c:1474 msgid "output all-zero hash in From header" msgstr "в заглавната част „From:“ (от) хешът да е само от нули" -#: builtin/log.c:1473 +#: builtin/log.c:1476 msgid "don't include a patch matching a commit upstream" msgstr "да не се включват кръпки, които присъстват в следения клон" -#: builtin/log.c:1475 +#: builtin/log.c:1478 msgid "show patch format instead of default (patch + stat)" msgstr "" "извеждане във формат за кръпки, а на в стандартния (кръпка и статистика)" -#: builtin/log.c:1477 +#: builtin/log.c:1480 msgid "Messaging" msgstr "Опции при изпращане" -#: builtin/log.c:1478 +#: builtin/log.c:1481 msgid "header" msgstr "ЗАГЛАВНА_ЧАСТ" -#: builtin/log.c:1479 +#: builtin/log.c:1482 msgid "add email header" msgstr "добавяне на тази ЗАГЛАВНА_ЧАСТ" -#: builtin/log.c:1480 builtin/log.c:1482 +#: builtin/log.c:1483 builtin/log.c:1485 msgid "email" msgstr "Е-ПОЩА" -#: builtin/log.c:1480 +#: builtin/log.c:1483 msgid "add To: header" msgstr "добавяне на заглавна част „To:“ (до)" -#: builtin/log.c:1482 +#: builtin/log.c:1485 msgid "add Cc: header" msgstr "добавяне на заглавна част „Cc:“ (и до)" -#: builtin/log.c:1484 +#: builtin/log.c:1487 msgid "ident" msgstr "ИДЕНТИЧНОСТ" -#: builtin/log.c:1485 +#: builtin/log.c:1488 msgid "set From address to (or committer ident if absent)" msgstr "" "задаване на адреса в заглавната част „From“ (от) да е тази ИДЕНТИЧНОСТ. Ако " "не е зададена такава, се взима адреса на подаващия" -#: builtin/log.c:1487 +#: builtin/log.c:1490 msgid "message-id" msgstr "ИДЕНТИФИКАТОР_НА_СЪОБЩЕНИЕ" -#: builtin/log.c:1488 +#: builtin/log.c:1491 msgid "make first mail a reply to " msgstr "" "първото съобщение да е в отговор на е-писмото с този " "ИДЕНТИФИКАТОР_НА_СЪОБЩЕНИЕ" -#: builtin/log.c:1489 builtin/log.c:1492 +#: builtin/log.c:1492 builtin/log.c:1495 msgid "boundary" msgstr "граница" -#: builtin/log.c:1490 +#: builtin/log.c:1493 msgid "attach the patch" msgstr "прикрепяне на кръпката" -#: builtin/log.c:1493 +#: builtin/log.c:1496 msgid "inline the patch" msgstr "включване на кръпката в текста на писмата" -#: builtin/log.c:1497 +#: builtin/log.c:1500 msgid "enable message threading, styles: shallow, deep" msgstr "" "използване на нишки за съобщенията. СТИЛът е „shallow“ (плитък) или " "„deep“ (дълбок)" -#: builtin/log.c:1499 +#: builtin/log.c:1502 msgid "signature" msgstr "подпис" -#: builtin/log.c:1500 +#: builtin/log.c:1503 msgid "add a signature" msgstr "добавяне на поле за подпис" -#: builtin/log.c:1501 +#: builtin/log.c:1504 msgid "base-commit" msgstr "БАЗОВО_ПОДАВАНЕ" -#: builtin/log.c:1502 +#: builtin/log.c:1505 msgid "add prerequisite tree info to the patch series" msgstr "добавяне на необходимото БАЗово дърво към серията кръпки" -#: builtin/log.c:1504 +#: builtin/log.c:1507 msgid "add a signature from a file" msgstr "добавяне на подпис от файл" -#: builtin/log.c:1505 +#: builtin/log.c:1508 msgid "don't print the patch filenames" msgstr "без извеждане на имената на кръпките" -#: builtin/log.c:1507 +#: builtin/log.c:1510 msgid "show progress while generating patches" msgstr "извеждане на напредъка във фазата на създаване на кръпките" -#: builtin/log.c:1582 +#: builtin/log.c:1585 #, c-format msgid "invalid ident line: %s" msgstr "грешна идентичност: %s" -#: builtin/log.c:1597 +#: builtin/log.c:1600 msgid "-n and -k are mutually exclusive." msgstr "опциите „-n“ и „-k“ са несъвместими." -#: builtin/log.c:1599 +#: builtin/log.c:1602 msgid "--subject-prefix/--rfc and -k are mutually exclusive." msgstr "опциите „--subject-prefix“/„-rfc“ и „-k“ са несъвместими." -#: builtin/log.c:1607 +#: builtin/log.c:1610 msgid "--name-only does not make sense" msgstr "опцията „--name-only“ е несъвместима с генерирането на кръпки" -#: builtin/log.c:1609 +#: builtin/log.c:1612 msgid "--name-status does not make sense" msgstr "опцията „--name-status“ е несъвместима с генерирането на кръпки" -#: builtin/log.c:1611 +#: builtin/log.c:1614 msgid "--check does not make sense" msgstr "опцията „--check“ е несъвместима с генерирането на кръпки" -#: builtin/log.c:1641 +#: builtin/log.c:1646 msgid "standard output, or directory, which one?" msgstr "" "изходът може да или стандартният, или да е в директория, но не и двете." -#: builtin/log.c:1643 +#: builtin/log.c:1648 #, c-format msgid "Could not create directory '%s'" msgstr "Директорията „%s“ не може да бъде създадена" -#: builtin/log.c:1736 +#: builtin/log.c:1741 #, c-format msgid "unable to read signature file '%s'" msgstr "файлът „%s“ с подпис не може да бъде прочетен" -#: builtin/log.c:1768 +#: builtin/log.c:1773 msgid "Generating patches" msgstr "Създаване на кръпки" -#: builtin/log.c:1812 +#: builtin/log.c:1817 msgid "Failed to create output files" msgstr "Изходните файлове не могат да бъдат създадени" -#: builtin/log.c:1862 +#: builtin/log.c:1867 msgid "git cherry [-v] [ [ []]]" msgstr "git cherry [-v] [ОТДАЛЕЧЕН_КЛОН [ВРЪХ [ПРЕДЕЛ]]]" -#: builtin/log.c:1916 +#: builtin/log.c:1921 #, c-format msgid "" "Could not find a tracked remote branch, please specify manually.\n" @@ -10390,7 +10600,7 @@ msgstr "взимане предвид на „url.БАЗА.insteadOf“" msgid "exit with exit code 2 if no matching refs are found" msgstr "изход с код 2, ако не се открият съвпадащи указатели" -#: builtin/ls-remote.c:66 +#: builtin/ls-remote.c:67 msgid "show underlying ref in addition to the object pointed by it" msgstr "извеждане на указателя заедно с обекта сочен от него" @@ -10437,186 +10647,186 @@ msgstr "" msgid "empty mbox: '%s'" msgstr "празна пощенска кутия mbox: „%s“" -#: builtin/merge.c:48 +#: builtin/merge.c:49 msgid "git merge [] [...]" msgstr "git merge [ОПЦИЯ…] [ПОДАВАНЕ…]" -#: builtin/merge.c:49 +#: builtin/merge.c:50 msgid "git merge --abort" msgstr "git merge --abort" -#: builtin/merge.c:50 +#: builtin/merge.c:51 msgid "git merge --continue" msgstr "git merge --continue" -#: builtin/merge.c:107 +#: builtin/merge.c:108 msgid "switch `m' requires a value" msgstr "опцията „-m“ изисква стойност" -#: builtin/merge.c:144 +#: builtin/merge.c:145 #, c-format msgid "Could not find merge strategy '%s'.\n" msgstr "Няма такава стратегия за сливане: „%s“.\n" -#: builtin/merge.c:145 +#: builtin/merge.c:146 #, c-format msgid "Available strategies are:" msgstr "Наличните стратегии са:" -#: builtin/merge.c:150 +#: builtin/merge.c:151 #, c-format msgid "Available custom strategies are:" msgstr "Допълнителните стратегии са:" -#: builtin/merge.c:200 builtin/pull.c:137 +#: builtin/merge.c:201 builtin/pull.c:137 msgid "do not show a diffstat at the end of the merge" msgstr "без извеждане на статистиката след завършване на сливане" -#: builtin/merge.c:203 builtin/pull.c:140 +#: builtin/merge.c:204 builtin/pull.c:140 msgid "show a diffstat at the end of the merge" msgstr "извеждане на статистиката след завършване на сливане" -#: builtin/merge.c:204 builtin/pull.c:143 +#: builtin/merge.c:205 builtin/pull.c:143 msgid "(synonym to --stat)" msgstr "(синоним на „--stat“)" -#: builtin/merge.c:206 builtin/pull.c:146 +#: builtin/merge.c:207 builtin/pull.c:146 msgid "add (at most ) entries from shortlog to merge commit message" msgstr "" "добавяне (на максимум такъв БРОЙ) записи от съкратения журнал в съобщението " "за подаване" -#: builtin/merge.c:209 builtin/pull.c:152 +#: builtin/merge.c:210 builtin/pull.c:152 msgid "create a single commit instead of doing a merge" msgstr "създаване на едно подаване вместо извършване на сливане" -#: builtin/merge.c:211 builtin/pull.c:155 +#: builtin/merge.c:212 builtin/pull.c:155 msgid "perform a commit if the merge succeeds (default)" msgstr "извършване на подаване при успешно сливане (стандартно действие)" -#: builtin/merge.c:213 builtin/pull.c:158 +#: builtin/merge.c:214 builtin/pull.c:158 msgid "edit message before committing" msgstr "редактиране на съобщението преди подаване" -#: builtin/merge.c:214 +#: builtin/merge.c:215 msgid "allow fast-forward (default)" msgstr "позволяване на превъртане (стандартно действие)" -#: builtin/merge.c:216 builtin/pull.c:164 +#: builtin/merge.c:217 builtin/pull.c:164 msgid "abort if fast-forward is not possible" msgstr "преустановяване, ако превъртането е невъзможно" -#: builtin/merge.c:220 builtin/pull.c:167 +#: builtin/merge.c:221 builtin/pull.c:167 msgid "verify that the named commit has a valid GPG signature" msgstr "проверка, че указаното подаване е с правилен подпис на GPG" -#: builtin/merge.c:221 builtin/notes.c:777 builtin/pull.c:171 +#: builtin/merge.c:222 builtin/notes.c:777 builtin/pull.c:171 #: builtin/revert.c:109 msgid "strategy" msgstr "СТРАТЕГИЯ" -#: builtin/merge.c:222 builtin/pull.c:172 +#: builtin/merge.c:223 builtin/pull.c:172 msgid "merge strategy to use" msgstr "СТРАТЕГИЯ за сливане, която да се ползва" -#: builtin/merge.c:223 builtin/pull.c:175 +#: builtin/merge.c:224 builtin/pull.c:175 msgid "option=value" msgstr "ОПЦИЯ=СТОЙНОСТ" -#: builtin/merge.c:224 builtin/pull.c:176 +#: builtin/merge.c:225 builtin/pull.c:176 msgid "option for selected merge strategy" msgstr "ОПЦИЯ за избраната стратегия за сливане" -#: builtin/merge.c:226 +#: builtin/merge.c:227 msgid "merge commit message (for a non-fast-forward merge)" msgstr "СЪОБЩЕНИЕ при подаването със сливане (при същински сливания)" -#: builtin/merge.c:230 +#: builtin/merge.c:231 msgid "abort the current in-progress merge" msgstr "преустановяване на текущото сливане" -#: builtin/merge.c:232 +#: builtin/merge.c:233 msgid "continue the current in-progress merge" msgstr "продължаване на текущото сливане" -#: builtin/merge.c:234 builtin/pull.c:183 +#: builtin/merge.c:235 builtin/pull.c:183 msgid "allow merging unrelated histories" msgstr "позволяване на сливане на независими истории" -#: builtin/merge.c:240 +#: builtin/merge.c:241 msgid "verify commit-msg hook" msgstr "" "проверка на куката при промяна на съобщението при подаване (commit-msg)" -#: builtin/merge.c:265 +#: builtin/merge.c:266 msgid "could not run stash." msgstr "не може да се извърши скатаване" -#: builtin/merge.c:270 +#: builtin/merge.c:271 msgid "stash failed" msgstr "неуспешно скатаване" -#: builtin/merge.c:275 +#: builtin/merge.c:276 #, c-format msgid "not a valid object: %s" msgstr "неправилен обект: „%s“" -#: builtin/merge.c:297 builtin/merge.c:314 +#: builtin/merge.c:298 builtin/merge.c:315 msgid "read-tree failed" msgstr "неуспешно прочитане на обект-дърво" -#: builtin/merge.c:344 +#: builtin/merge.c:345 msgid " (nothing to squash)" msgstr " (няма какво да се смачка)" -#: builtin/merge.c:355 +#: builtin/merge.c:356 #, c-format msgid "Squash commit -- not updating HEAD\n" msgstr "Подаване със смачкване — указателят „HEAD“ няма да бъде обновен\n" -#: builtin/merge.c:405 +#: builtin/merge.c:406 #, c-format msgid "No merge message -- not updating HEAD\n" msgstr "" "Липсва съобщение при подаване — указателят „HEAD“ няма да бъде обновен\n" -#: builtin/merge.c:455 +#: builtin/merge.c:456 #, c-format msgid "'%s' does not point to a commit" msgstr "„%s“ не сочи към подаване" -#: builtin/merge.c:545 +#: builtin/merge.c:546 #, c-format msgid "Bad branch.%s.mergeoptions string: %s" msgstr "Неправилен низ за настройката „branch.%s.mergeoptions“: „%s“" -#: builtin/merge.c:667 +#: builtin/merge.c:668 msgid "Not handling anything other than two heads merge." msgstr "Поддържа се само сливане на точно две истории." -#: builtin/merge.c:681 +#: builtin/merge.c:682 #, c-format msgid "Unknown option for merge-recursive: -X%s" msgstr "Непозната опция за рекурсивното сливане „merge-recursive“: „-X%s“" -#: builtin/merge.c:696 +#: builtin/merge.c:697 #, c-format msgid "unable to write %s" msgstr "„%s“ не може да бъде записан" -#: builtin/merge.c:748 +#: builtin/merge.c:749 #, c-format msgid "Could not read from '%s'" msgstr "От „%s“ не може да се чете" -#: builtin/merge.c:757 +#: builtin/merge.c:758 #, c-format msgid "Not committing merge; use 'git commit' to complete the merge.\n" msgstr "" "Сливането няма да бъде подадено. За завършването му и подаването му " "използвайте командата „git commit“.\n" -#: builtin/merge.c:763 +#: builtin/merge.c:764 #, c-format msgid "" "Please enter a commit message to explain why this merge is necessary,\n" @@ -10631,72 +10841,72 @@ msgstr "" "Редовете, които започват с „%c“ ще бъдат пропуснати, а празно съобщение\n" "преустановява подаването.\n" -#: builtin/merge.c:799 +#: builtin/merge.c:800 msgid "Empty commit message." msgstr "Празно съобщение при подаване." -#: builtin/merge.c:819 +#: builtin/merge.c:820 #, c-format msgid "Wonderful.\n" msgstr "Първият етап на сливането завърши.\n" -#: builtin/merge.c:872 +#: builtin/merge.c:873 #, c-format msgid "Automatic merge failed; fix conflicts and then commit the result.\n" msgstr "" "Неуспешно автоматично сливане — коригирайте конфликтите и подайте " "резултата.\n" -#: builtin/merge.c:911 +#: builtin/merge.c:912 msgid "No current branch." msgstr "Няма текущ клон." -#: builtin/merge.c:913 +#: builtin/merge.c:914 msgid "No remote for the current branch." msgstr "Текущият клон не следи никой." -#: builtin/merge.c:915 +#: builtin/merge.c:916 msgid "No default upstream defined for the current branch." msgstr "Текущият клон не следи никой клон." -#: builtin/merge.c:920 +#: builtin/merge.c:921 #, c-format msgid "No remote-tracking branch for %s from %s" msgstr "Никой клон не следи клона „%s“ от хранилището „%s“" -#: builtin/merge.c:973 +#: builtin/merge.c:974 #, c-format msgid "Bad value '%s' in environment '%s'" msgstr "Неправилна стойност „%s“ в средата „%s“" -#: builtin/merge.c:1075 +#: builtin/merge.c:1076 #, c-format msgid "not something we can merge in %s: %s" msgstr "не може да се слее в „%s“: %s" -#: builtin/merge.c:1109 +#: builtin/merge.c:1110 msgid "not something we can merge" msgstr "не може да се слее" -#: builtin/merge.c:1174 +#: builtin/merge.c:1212 msgid "--abort expects no arguments" msgstr "опцията „--abort“ не приема аргументи" -#: builtin/merge.c:1178 +#: builtin/merge.c:1216 msgid "There is no merge to abort (MERGE_HEAD missing)." msgstr "" "Не може да преустановите сливане, защото в момента не се извършва такова " "(липсва указател „MERGE_HEAD“)." -#: builtin/merge.c:1190 +#: builtin/merge.c:1228 msgid "--continue expects no arguments" msgstr "опцията „--continue“ не приема аргументи" -#: builtin/merge.c:1194 +#: builtin/merge.c:1232 msgid "There is no merge in progress (MERGE_HEAD missing)." msgstr "В момента не се извършва сливане (липсва указател „MERGE_HEAD“)." -#: builtin/merge.c:1210 +#: builtin/merge.c:1248 msgid "" "You have not concluded your merge (MERGE_HEAD exists).\n" "Please, commit your changes before you merge." @@ -10704,7 +10914,7 @@ msgstr "" "Не сте завършили сливане. (Указателят „MERGE_HEAD“ съществува).\n" "Подайте промените си, преди да започнете ново сливане." -#: builtin/merge.c:1217 +#: builtin/merge.c:1255 msgid "" "You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists).\n" "Please, commit your changes before you merge." @@ -10712,121 +10922,121 @@ msgstr "" "Не сте завършили отбиране на подаване (указателят „CHERRY_PICK_HEAD“\n" "съществува). Подайте промените си, преди да започнете ново сливане." -#: builtin/merge.c:1220 +#: builtin/merge.c:1258 msgid "You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists)." msgstr "" "Не сте завършили отбиране на подаване (указателят „CHERRY_PICK_HEAD“\n" "съществува)." -#: builtin/merge.c:1229 +#: builtin/merge.c:1267 msgid "You cannot combine --squash with --no-ff." msgstr "Опцията „--squash“ е несъвместима с „--no-ff“." -#: builtin/merge.c:1237 +#: builtin/merge.c:1275 msgid "No commit specified and merge.defaultToUpstream not set." msgstr "" "Не е указано подаване и настройката „merge.defaultToUpstream“ не е зададена." -#: builtin/merge.c:1254 +#: builtin/merge.c:1292 msgid "Squash commit into empty head not supported yet" msgstr "Подаване със смачкване във връх без история все още не се поддържа" -#: builtin/merge.c:1256 +#: builtin/merge.c:1294 msgid "Non-fast-forward commit does not make sense into an empty head" msgstr "" "Понеже върхът е без история, всички сливания са превъртания, не може да се " "извърши същинско сливане изисквано от опцията „--no-ff“" -#: builtin/merge.c:1261 +#: builtin/merge.c:1299 #, c-format msgid "%s - not something we can merge" msgstr "„%s“ — не е нещо, което може да се слее" -#: builtin/merge.c:1263 +#: builtin/merge.c:1301 msgid "Can merge only exactly one commit into empty head" msgstr "Можете да слеете точно едно подаване във връх без история" -#: builtin/merge.c:1297 +#: builtin/merge.c:1335 #, c-format msgid "Commit %s has an untrusted GPG signature, allegedly by %s." msgstr "" "Подаването „%s“ е с недоверен подпис от GPG, който твърди, че е на „%s“." -#: builtin/merge.c:1300 +#: builtin/merge.c:1338 #, c-format msgid "Commit %s has a bad GPG signature allegedly by %s." msgstr "" "Подаването „%s“ е с неправилен подпис от GPG, който твърди, че е на „%s“." -#: builtin/merge.c:1303 +#: builtin/merge.c:1341 #, c-format msgid "Commit %s does not have a GPG signature." msgstr "Подаването „%s“ е без подпис от GPG." -#: builtin/merge.c:1306 +#: builtin/merge.c:1344 #, c-format msgid "Commit %s has a good GPG signature by %s\n" msgstr "Подаването „%s“ е с коректен подпис от GPG на „%s“.\n" -#: builtin/merge.c:1368 +#: builtin/merge.c:1403 msgid "refusing to merge unrelated histories" msgstr "независими истории не може да се слеят" -#: builtin/merge.c:1377 +#: builtin/merge.c:1412 msgid "Already up to date." msgstr "Вече е обновено." -#: builtin/merge.c:1387 +#: builtin/merge.c:1422 #, c-format msgid "Updating %s..%s\n" msgstr "Обновяване „%s..%s“\n" -#: builtin/merge.c:1428 +#: builtin/merge.c:1463 #, c-format msgid "Trying really trivial in-index merge...\n" msgstr "Проба със сливане в рамките на индекса…\n" -#: builtin/merge.c:1435 +#: builtin/merge.c:1470 #, c-format msgid "Nope.\n" msgstr "Неуспешно сливане.\n" -#: builtin/merge.c:1460 +#: builtin/merge.c:1495 msgid "Already up to date. Yeeah!" msgstr "Вече е обновено!" -#: builtin/merge.c:1466 +#: builtin/merge.c:1501 msgid "Not possible to fast-forward, aborting." msgstr "Не може да се извърши превъртане, преустановяване на действието." -#: builtin/merge.c:1489 builtin/merge.c:1568 +#: builtin/merge.c:1524 builtin/merge.c:1603 #, c-format msgid "Rewinding the tree to pristine...\n" msgstr "Привеждане на дървото към първоначалното…\n" -#: builtin/merge.c:1493 +#: builtin/merge.c:1528 #, c-format msgid "Trying merge strategy %s...\n" msgstr "Пробване със стратегията за сливане „%s“…\n" -#: builtin/merge.c:1559 +#: builtin/merge.c:1594 #, c-format msgid "No merge strategy handled the merge.\n" msgstr "Никоя стратегия за сливане не може да извърши сливането.\n" -#: builtin/merge.c:1561 +#: builtin/merge.c:1596 #, c-format msgid "Merge with strategy %s failed.\n" msgstr "Неуспешно сливане със стратегия „%s“.\n" -#: builtin/merge.c:1570 +#: builtin/merge.c:1605 #, c-format msgid "Using the %s to prepare resolving by hand.\n" msgstr "" "Ползва се стратегията „%s“, която ще подготви дървото за коригиране на " "ръка.\n" -#: builtin/merge.c:1582 +#: builtin/merge.c:1617 #, c-format msgid "Automatic merge went well; stopped before committing as requested\n" msgstr "" @@ -10985,72 +11195,72 @@ msgstr "„%.*s“ вече е в индекса" msgid "force move/rename even if target exists" msgstr "принудително преместване/преименуване дори целта да съществува" -#: builtin/mv.c:126 +#: builtin/mv.c:127 msgid "skip move/rename errors" msgstr "прескачане на грешките при преместване/преименуване" -#: builtin/mv.c:167 +#: builtin/mv.c:168 #, c-format msgid "destination '%s' is not a directory" msgstr "целта „%s“ съществува и не е директория" -#: builtin/mv.c:178 +#: builtin/mv.c:179 #, c-format msgid "Checking rename of '%s' to '%s'\n" msgstr "Проверка на преименуването на обект от „%s“ на „%s“\n" -#: builtin/mv.c:182 +#: builtin/mv.c:183 msgid "bad source" msgstr "неправилен обект" -#: builtin/mv.c:185 +#: builtin/mv.c:186 msgid "can not move directory into itself" msgstr "директория не може да се премести в себе си" -#: builtin/mv.c:188 +#: builtin/mv.c:189 msgid "cannot move directory over file" msgstr "директория не може да се премести върху файл" -#: builtin/mv.c:197 +#: builtin/mv.c:198 msgid "source directory is empty" msgstr "първоначалната директория е празна" -#: builtin/mv.c:222 +#: builtin/mv.c:223 msgid "not under version control" msgstr "не е под контрола на Git" -#: builtin/mv.c:225 +#: builtin/mv.c:226 msgid "destination exists" msgstr "целта съществува" -#: builtin/mv.c:233 +#: builtin/mv.c:234 #, c-format msgid "overwriting '%s'" msgstr "презаписване на „%s“" -#: builtin/mv.c:236 +#: builtin/mv.c:237 msgid "Cannot overwrite" msgstr "Презаписването е невъзможно" -#: builtin/mv.c:239 +#: builtin/mv.c:240 msgid "multiple sources for the same target" msgstr "множество източници за една цел" -#: builtin/mv.c:241 +#: builtin/mv.c:242 msgid "destination directory does not exist" msgstr "целевата директория не съществува" -#: builtin/mv.c:248 +#: builtin/mv.c:249 #, c-format msgid "%s, source=%s, destination=%s" msgstr "%s, обект: „%s“, цел: „%s“" -#: builtin/mv.c:269 +#: builtin/mv.c:270 #, c-format msgid "Renaming %s to %s\n" msgstr "Преименуване на „%s“ на „%s“\n" -#: builtin/mv.c:275 builtin/remote.c:712 builtin/repack.c:390 +#: builtin/mv.c:276 builtin/remote.c:712 builtin/repack.c:394 #, c-format msgid "renaming '%s' failed" msgstr "неуспешно преименуване на „%s“" @@ -11244,12 +11454,12 @@ msgstr "обектът-бележка не може да бъде записан msgid "the note contents have been left in %s" msgstr "съдържанието на бележката е във файла „%s“" -#: builtin/notes.c:234 builtin/tag.c:500 +#: builtin/notes.c:234 builtin/tag.c:506 #, c-format msgid "cannot read '%s'" msgstr "файлът „%s“ не може да бъде прочетен" -#: builtin/notes.c:236 builtin/tag.c:503 +#: builtin/notes.c:236 builtin/tag.c:509 #, c-format msgid "could not open or read '%s'" msgstr "файлът „%s“ не може да бъде отворен или прочетен" @@ -11503,7 +11713,7 @@ msgstr "опитът за изтриването на несъществуващ msgid "read object names from the standard input" msgstr "изчитане на имената на обектите от стандартния вход" -#: builtin/notes.c:943 builtin/prune.c:105 builtin/worktree.c:158 +#: builtin/notes.c:943 builtin/prune.c:106 builtin/worktree.c:160 msgid "do not remove, show only" msgstr "само извеждане без действително окастряне" @@ -11537,200 +11747,204 @@ msgstr "" "git pack-objects [ОПЦИЯ…] ПРЕФИКС_НА_ИМЕТО [< СПИСЪК_С_УКАЗАТЕЛИ | < " "СПИСЪК_С_ОБЕКТИ]" -#: builtin/pack-objects.c:192 builtin/pack-objects.c:195 +#: builtin/pack-objects.c:195 builtin/pack-objects.c:198 #, c-format msgid "deflate error (%d)" msgstr "грешка при декомпресиране с „deflate“ (%d)" -#: builtin/pack-objects.c:788 +#: builtin/pack-objects.c:791 msgid "disabling bitmap writing, packs are split due to pack.packSizeLimit" msgstr "" "изключване на записването на битовата маска, пакетите са разделени поради " "стойността на „pack.packSizeLimit“" -#: builtin/pack-objects.c:801 +#: builtin/pack-objects.c:804 msgid "Writing objects" msgstr "Записване на обектите" -#: builtin/pack-objects.c:1081 +#: builtin/pack-objects.c:1084 msgid "disabling bitmap writing, as some objects are not being packed" msgstr "" "изключване на записването на битовата маска, защото някои обекти няма да се " "пакетират" -#: builtin/pack-objects.c:2451 +#: builtin/pack-objects.c:2454 msgid "Compressing objects" msgstr "Компресиране на обектите" -#: builtin/pack-objects.c:2599 +#: builtin/pack-objects.c:2625 msgid "invalid value for --missing" msgstr "неправилна стойност за „--missing“" -#: builtin/pack-objects.c:2902 +#: builtin/pack-objects.c:2928 #, c-format msgid "unsupported index version %s" msgstr "неподдържана версия на индекса „%s“" -#: builtin/pack-objects.c:2906 +#: builtin/pack-objects.c:2932 #, c-format msgid "bad index version '%s'" msgstr "неправилна версия на индекса „%s“" -#: builtin/pack-objects.c:2936 +#: builtin/pack-objects.c:2962 msgid "do not show progress meter" msgstr "без извеждане на напредъка" -#: builtin/pack-objects.c:2938 +#: builtin/pack-objects.c:2964 msgid "show progress meter" msgstr "извеждане на напредъка" -#: builtin/pack-objects.c:2940 +#: builtin/pack-objects.c:2966 msgid "show progress meter during object writing phase" msgstr "извеждане на напредъка във фазата на запазване на обектите" -#: builtin/pack-objects.c:2943 +#: builtin/pack-objects.c:2969 msgid "similar to --all-progress when progress meter is shown" msgstr "" "същото действие като опцията „--all-progress“ при извеждането на напредъка" -#: builtin/pack-objects.c:2944 +#: builtin/pack-objects.c:2970 msgid "version[,offset]" msgstr "ВЕРСИЯ[,ОТМЕСТВАНЕ]" -#: builtin/pack-objects.c:2945 +#: builtin/pack-objects.c:2971 msgid "write the pack index file in the specified idx format version" msgstr "" "запазване на индекса на пакетните файлове във форма̀та с указаната версия" -#: builtin/pack-objects.c:2948 +#: builtin/pack-objects.c:2974 msgid "maximum size of each output pack file" msgstr "максимален размер на всеки пакетен файл" -#: builtin/pack-objects.c:2950 +#: builtin/pack-objects.c:2976 msgid "ignore borrowed objects from alternate object store" msgstr "игнориране на обектите заети от други хранилища на обекти" -#: builtin/pack-objects.c:2952 +#: builtin/pack-objects.c:2978 msgid "ignore packed objects" msgstr "игнориране на пакетираните обекти" -#: builtin/pack-objects.c:2954 +#: builtin/pack-objects.c:2980 msgid "limit pack window by objects" msgstr "ограничаване на прозореца за пакетиране по брой обекти" -#: builtin/pack-objects.c:2956 +#: builtin/pack-objects.c:2982 msgid "limit pack window by memory in addition to object limit" msgstr "" "ограничаване на прозореца за пакетиране и по памет освен по брой обекти" -#: builtin/pack-objects.c:2958 +#: builtin/pack-objects.c:2984 msgid "maximum length of delta chain allowed in the resulting pack" msgstr "" "максимална дължина на веригата от разлики, която е позволена в пакетния файл" -#: builtin/pack-objects.c:2960 +#: builtin/pack-objects.c:2986 msgid "reuse existing deltas" msgstr "преизползване на съществуващите разлики" -#: builtin/pack-objects.c:2962 +#: builtin/pack-objects.c:2988 msgid "reuse existing objects" msgstr "преизползване на съществуващите обекти" -#: builtin/pack-objects.c:2964 +#: builtin/pack-objects.c:2990 msgid "use OFS_DELTA objects" msgstr "използване на обекти „OFS_DELTA“" -#: builtin/pack-objects.c:2966 +#: builtin/pack-objects.c:2992 msgid "use threads when searching for best delta matches" msgstr "" "стартиране на нишки за претърсване на най-добрите съвпадения на разликите" -#: builtin/pack-objects.c:2968 +#: builtin/pack-objects.c:2994 msgid "do not create an empty pack output" msgstr "без създаване на празен пакетен файл" -#: builtin/pack-objects.c:2970 +#: builtin/pack-objects.c:2996 msgid "read revision arguments from standard input" msgstr "изчитане на версиите от стандартния вход" -#: builtin/pack-objects.c:2972 +#: builtin/pack-objects.c:2998 msgid "limit the objects to those that are not yet packed" msgstr "ограничаване до все още непакетираните обекти" -#: builtin/pack-objects.c:2975 +#: builtin/pack-objects.c:3001 msgid "include objects reachable from any reference" msgstr "" "включване на всички обекти, които могат да се достигнат от произволен " "указател" -#: builtin/pack-objects.c:2978 +#: builtin/pack-objects.c:3004 msgid "include objects referred by reflog entries" msgstr "включване и на обектите сочени от записите в журнала на указателите" -#: builtin/pack-objects.c:2981 +#: builtin/pack-objects.c:3007 msgid "include objects referred to by the index" msgstr "включване и на обектите сочени от индекса" -#: builtin/pack-objects.c:2984 +#: builtin/pack-objects.c:3010 msgid "output pack to stdout" msgstr "извеждане на пакета на стандартния изход" -#: builtin/pack-objects.c:2986 +#: builtin/pack-objects.c:3012 msgid "include tag objects that refer to objects to be packed" msgstr "" "включване и на обектите-етикети, които сочат към обектите, които ще бъдат " "пакетирани" -#: builtin/pack-objects.c:2988 +#: builtin/pack-objects.c:3014 msgid "keep unreachable objects" msgstr "запазване на недостижимите обекти" -#: builtin/pack-objects.c:2990 +#: builtin/pack-objects.c:3016 msgid "pack loose unreachable objects" msgstr "пакетиране и на недостижимите обекти" -#: builtin/pack-objects.c:2992 +#: builtin/pack-objects.c:3018 msgid "unpack unreachable objects newer than