]> git.ipfire.org Git - thirdparty/git.git/commitdiff
Merge branch 'dk/raise-core-deltabasecachelimit'
authorJunio C Hamano <gitster@pobox.com>
Fri, 6 Jun 2014 18:18:34 +0000 (11:18 -0700)
committerJunio C Hamano <gitster@pobox.com>
Fri, 6 Jun 2014 18:18:34 +0000 (11:18 -0700)
The `core.deltabasecachelimit` used to default to 16 MiB , but this
proved to be too small, and has been bumped to 96 MiB.

* dk/raise-core-deltabasecachelimit:
  Bump core.deltaBaseCacheLimit to 96m

134 files changed:
Documentation/RelNotes/1.9.3.txt [new file with mode: 0644]
Documentation/RelNotes/1.9.4.txt [new file with mode: 0644]
Documentation/RelNotes/2.0.0.txt
Documentation/RelNotes/2.1.0.txt [new file with mode: 0644]
Documentation/config.txt
Documentation/git-grep.txt
Documentation/git-merge.txt
Documentation/git-mergetool.txt
Documentation/git-shell.txt
Documentation/git-update-ref.txt
Documentation/git.txt
Documentation/technical/api-builtin.txt
Documentation/technical/api-hashmap.txt
Documentation/technical/api-strbuf.txt
GIT-VERSION-GEN
Makefile
RelNotes
builtin/apply.c
builtin/blame.c
builtin/checkout.c
builtin/clone.c
builtin/commit.c
builtin/index-pack.c
builtin/merge.c
builtin/notes.c
builtin/rerere.c
builtin/reset.c
builtin/tag.c
builtin/update-ref.c
cache.h
combine-diff.c
compat/mmap.c
compat/poll/poll.c
compat/win32/alloca.h [moved from compat/vcbuild/include/alloca.h with 100% similarity]
config.c
config.mak.uname
configure.ac
contrib/completion/git-prompt.sh
contrib/examples/builtin-fetch--tool.c
contrib/mw-to-git/git-remote-mediawiki.perl
contrib/mw-to-git/t/install-wiki.sh
contrib/mw-to-git/t/t9363-mw-to-git-export-import.sh
contrib/mw-to-git/t/t9365-continuing-queries.sh
contrib/mw-to-git/t/test-gitmw-lib.sh
contrib/remote-helpers/Makefile [deleted file]
contrib/remote-helpers/README [new file with mode: 0644]
contrib/remote-helpers/git-remote-bzr
contrib/remote-helpers/git-remote-hg
contrib/remote-helpers/test-bzr.sh [deleted file]
contrib/remote-helpers/test-hg-bidi.sh [deleted file]
contrib/remote-helpers/test-hg-hg-git.sh [deleted file]
contrib/remote-helpers/test-hg.sh [deleted file]
contrib/subtree/t/t7900-subtree.sh
contrib/thunderbird-patch-inline/appp.sh
diff.c
diff.h
git-compat-util.h
git-gui/git-gui.sh
git-mergetool.sh
git-p4.py
git-pull.sh
git-rebase--merge.sh
git-rebase.sh
git-request-pull.sh
git-send-email.perl
git-sh-setup.sh
git-stash.sh
git-web--browse.sh
git.c
grep.c
imap-send.c
mergetools/gvimdiff3 [new file with mode: 0644]
mergetools/vimdiff
mergetools/vimdiff3 [new file with mode: 0644]
notes-cache.c
notes-utils.c
pager.c
perl/Git/SVN.pm
perl/Git/SVN/Log.pm
po/bg.po
po/fr.po
po/sv.po
pretty.c
read-cache.c
refs.c
refs.h
sequencer.c
strbuf.c
t/lib-credential.sh
t/lib-cvs.sh
t/lib-gpg.sh
t/perf/p5302-pack-index.sh
t/t0001-init.sh
t/t0010-racy-git.sh
t/t0020-crlf.sh
t/t0025-crlf-auto.sh
t/t0026-eol-config.sh
t/t0030-stripspace.sh
t/t0300-credentials.sh
t/t1000-read-tree-m-3way.sh
t/t1001-read-tree-m-2way.sh
t/t1002-read-tree-m-u-2way.sh
t/t1003-read-tree-prefix.sh
t/t1004-read-tree-m-u-wf.sh
t/t1020-subdirectory.sh
t/t1050-large.sh
t/t1300-repo-config.sh
t/t1400-update-ref.sh
t/t3508-cherry-pick-many-commits.sh
t/t3905-stash-include-untracked.sh
t/t3910-mac-os-precompose.sh
t/t4006-diff-mode.sh
t/t4010-diff-pathspec.sh
t/t4012-diff-binary.sh
t/t4013-diff-various.sh
t/t4014-format-patch.sh
t/t4036-format-patch-signer-mime.sh
t/t4038-diff-combined.sh
t/t4057-diff-combined-paths.sh
t/t4107-apply-ignore-whitespace.sh
t/t4116-apply-reverse.sh
t/t4119-apply-config.sh
t/t4204-patch-id.sh
t/t5000-tar-tree.sh
t/t5150-request-pull.sh
t/t5537-fetch-shallow.sh
t/t7004-tag.sh
t/t7500-commit.sh
t/t7501-commit.sh
t/t7502-commit.sh
t/t7800-difftool.sh
t/t9903-bash-prompt.sh
tree-diff.c
wrapper.c

diff --git a/Documentation/RelNotes/1.9.3.txt b/Documentation/RelNotes/1.9.3.txt
new file mode 100644 (file)
index 0000000..17b05ca
--- /dev/null
@@ -0,0 +1,21 @@
+Git v1.9.3 Release Notes
+========================
+
+Fixes since v1.9.2
+------------------
+
+ * "git p4" dealing with changes in binary files were broken by a
+   change in 1.9 release.
+
+ * The shell prompt script (in contrib/), when using the PROMPT_COMMAND
+   interface, used an unsafe construct when showing the branch name in
+   $PS1.
+
+ * "git rebase" used a POSIX shell construct FreeBSD /bin/sh does not
+   work well with.
+
+ * Some more Unicode codepoints defined in Unicode 6.3 as having
+   zero width have been taught to our display column counting logic.
+
+ * Some tests used shell constructs that did not work well on
+   FreeBSD.
diff --git a/Documentation/RelNotes/1.9.4.txt b/Documentation/RelNotes/1.9.4.txt
new file mode 100644 (file)
index 0000000..e1d1835
--- /dev/null
@@ -0,0 +1,16 @@
+Git v1.9.4 Release Notes
+========================
+
+Fixes since v1.9.3
+------------------
+
+ * Commands that take pathspecs on the command line misbehaved when
+   the pathspec is given as an absolute pathname (which is a
+   practice not particularly encouraged) that points at a symbolic
+   link in the working tree.
+
+ * An earlier fix to the shell prompt script (in contrib/) for using
+   the PROMPT_COMMAND interface did not correctly check if the extra
+   code path needs to trigger, causing the branch name not to appear
+   when 'promptvars' option is disabled in bash or PROMPT_SUBST is
+   unset in zsh.
index e6911ac42fc8fd6e81821c1fc173b3a2e979ead7..2617372a0c50391985b02595f43e148ff46df73f 100644 (file)
@@ -44,7 +44,7 @@ with "git diff-files --diff-filter=d").
 The default prefix for "git svn" has changed in Git 2.0.  For a long
 time, "git svn" created its remote-tracking branches directly under
 refs/remotes, but it now places them under refs/remotes/origin/ unless
-it is told otherwise with its --prefix option.
+it is told otherwise with its "--prefix" option.
 
 
 Updates since v1.9 series
@@ -53,7 +53,11 @@ Updates since v1.9 series
 UI, Workflows & Features
 
  * The "multi-mail" post-receive hook (in contrib/) has been updated
-   to a more recent version from the upstream.
+   to a more recent version from upstream.
+
+ * The "remote-hg/bzr" remote-helper interfaces (used to be in
+   contrib/) are no more.  They are now maintained separately as
+   third-party plug-ins in their own repositories.
 
  * "git gc --aggressive" learned "--depth" option and
    "gc.aggressiveDepth" configuration variable to allow use of a less
@@ -63,12 +67,13 @@ UI, Workflows & Features
    single strand-of-pearls is broken in its output.
 
  * The "rev-parse --parseopt" mechanism used by scripted Porcelains to
-   parse command line options and to give help text learned to take
+   parse command-line options and to give help text learned to take
    the argv-help (the placeholder string for an option parameter,
    e.g. "key-id" in "--gpg-sign=<key-id>").
 
  * The pattern to find where the function begins in C/C++ used in
-   "diff" and "grep -p" have been updated to help C++ source better.
+   "diff" and "grep -p" has been updated to improve viewing C++
+   sources.
 
  * "git rebase" learned to interpret a lone "-" as "@{-1}", the
    branch that we were previously on.
@@ -79,7 +84,7 @@ UI, Workflows & Features
    "--sort=version:refname".
 
  * Discard the accumulated "heuristics" to guess from which branch the
-   result wants to be pulled from and make sure what the end user
+   result wants to be pulled from and make sure that what the end user
    specified is not second-guessed by "git request-pull", to avoid
    mistakes.  When you pushed out your 'master' branch to your public
    repository as 'for-linus', use the new "master:for-linus" syntax to
@@ -88,8 +93,8 @@ UI, Workflows & Features
  * "git grep" learned to behave in a way similar to native grep when
    "-h" (no header) and "-c" (count) options are given.
 
- * "git push" via transport-helper interface (e.g. remote-hg) has
-   been updated to allow ref deletion in a way similar to the natively
+ * "git push" via transport-helper interface has been updated to
+   allow forced ref updates in a way similar to the natively
    supported transports.
 
  * The "simple" mode is the default for "git push".
@@ -98,7 +103,7 @@ UI, Workflows & Features
    tree-wide operation even when run inside a subdirectory of a
    working tree.
 
- * "git add <path> is the same as "git add -A <path>" now.
+ * "git add <path>" is the same as "git add -A <path>" now.
 
  * "core.statinfo" configuration variable, which is a
    never-advertised synonym to "core.checkstat", has been removed.
@@ -114,30 +119,30 @@ UI, Workflows & Features
  * The progress indicators from various time-consuming commands have
    been marked for i18n/l10n.
 
- * "git notes -C <blob>" diagnoses an attempt to use an object that
-   is not a blob as an error.
+ * "git notes -C <blob>" diagnoses as an error an attempt to use an
+   object that is not a blob.
 
  * "git config" learned to read from the standard input when "-" is
    given as the value to its "--file" parameter (attempting an
-   operation to update the configuration in the standard input of
-   course is rejected).
+   operation to update the configuration in the standard input is
+   rejected, of course).
 
  * Trailing whitespaces in .gitignore files, unless they are quoted
    for fnmatch(3), e.g. "path\ ", are warned and ignored.  Strictly
-   speaking, this is a backward incompatible change, but very unlikely
+   speaking, this is a backward-incompatible change, but very unlikely
    to bite any sane user and adjusting should be obvious and easy.
 
- * Many commands that create commits, e.g. "pull", "rebase",
-   learned to take the --gpg-sign option on the command line.
+ * Many commands that create commits, e.g. "pull" and "rebase",
+   learned to take the "--gpg-sign" option on the command line.
 
  * "git commit" can be told to always GPG sign the resulting commit
-   by setting "commit.gpgsign" configuration variable to true (the
-   command line option --no-gpg-sign should override it).
+   by setting the "commit.gpgsign" configuration variable to "true"
+   (the command-line option "--no-gpg-sign" should override it).
 
  * "git pull" can be told to only accept fast-forward by setting the
-   new "pull.ff" configuration.
+   new "pull.ff" configuration variable.
 
- * "git reset" learned "-N" option, which does not reset the index
+ * "git reset" learned the "-N" option, which does not reset the index
    fully for paths the index knows about but the tree-ish the command
    resets to does not (these paths are kept as intend-to-add entries).
 
@@ -152,15 +157,15 @@ Performance, Internal Implementation, etc.
 
  * Uses of curl's "multi" interface and "easy" interface do not mix
    well when we attempt to reuse outgoing connections.  Teach the RPC
-   over http code, used in the smart HTTP transport, not to use the
+   over HTTP code, used in the smart HTTP transport, not to use the
    "easy" interface.
 
  * The bitmap-index feature from JGit has been ported, which should
-   significantly improve performance when serving objects form a
+   significantly improve performance when serving objects from a
    repository that uses it.
 
  * The way "git log --cc" shows a combined diff against multiple
-   parents have been optimized.
+   parents has been optimized.
 
  * The prefixcmp() and suffixcmp() functions are gone.  Use
    starts_with() and ends_with(), and also consider if skip_prefix()
@@ -179,27 +184,26 @@ Unless otherwise noted, all the fixes since v1.9 in the maintenance
 track are contained in this release (see the maintenance releases'
 notes for details).
 
+ * "git p4" was broken in 1.9 release to deal with changes in binary
+   files.
+   (merge 749b668 cl/p4-use-diff-tree later to maint).
+
  * The shell prompt script (in contrib/), when using the PROMPT_COMMAND
    interface, used an unsafe construct when showing the branch name in
    $PS1.
-   (merge 8976500 rh/prompt-pcmode-avoid-eval-on-refname later to maint).
-
- * The remote-helper interface to fast-import/fast-export via the
-   transport-helper has been tightened to avoid leaving the import
-   marks file from a failed/crashed run, as such a file that is out of
-   sync with the reality confuses a later invocation of itself.
+   (merge 1e4119c8 rh/prompt-pcmode-avoid-eval-on-refname later to maint).
 
- * "git rebase" used a POSIX shell construct FreeBSD /bin/sh does not
+ * "git rebase" used a POSIX shell construct FreeBSD's /bin/sh does not
    work well with.
    (merge 8cd6596 km/avoid-non-function-return-in-rebase later to maint).
 
  * zsh prompt (in contrib/) leaked unnecessary error messages.
 
- * bash completion (in contrib/) did not complete the refs and remotes
+ * Bash completion (in contrib/) did not complete the refs and remotes
    correctly given "git pu<TAB>" when "pu" is aliased to "push".
 
- * Some more Unicode codepoints defined in Unicode 6.3 as having zero
-   width have been taught to our display column counting logic.
+ * Some more Unicode code points, defined in Unicode 6.3 as having zero
+   width, have been taught to our display column counting logic.
    (merge d813ab9 tb/unicode-6.3-zero-width later to maint).
 
  * Some tests used shell constructs that did not work well on FreeBSD
@@ -213,7 +217,7 @@ notes for details).
  * "git diff --no-index -Mq a b" fell into an infinite loop.
    (merge ad1c3fb jc/fix-diff-no-index-diff-opt-parse later to maint).
 
- * "git fetch --prune", when the right-hand-side of multiple fetch
+ * "git fetch --prune", when the right-hand side of multiple fetch
    refspecs overlap (e.g. storing "refs/heads/*" to
    "refs/remotes/origin/*", while storing "refs/frotz/*" to
    "refs/remotes/origin/fr/*"), aggressively thought that lack of
@@ -268,7 +272,7 @@ notes for details).
    (merge 3c3e6f5 rr/doc-merge-strategies later to maint).
 
  * Serving objects from a shallow repository needs to write a
-   new file to hold the temporary shallow boundaries but it was not
+   new file to hold the temporary shallow boundaries, but it was not
    cleaned when we exit due to die() or a signal.
    (merge 7839632 jk/shallow-update-fix later to maint).
 
@@ -291,19 +295,19 @@ notes for details).
    ".git" tells us where it is.
    (merge fcfec8b da/difftool-git-files later to maint).
 
- * "git push" did not pay attention to branch.*.pushremote if it is
-   defined earlier than remote.pushdefault; the order of these two
+ * "git push" did not pay attention to "branch.*.pushremote" if it is
+   defined earlier than "remote.pushdefault"; the order of these two
    variables in the configuration file should not matter, but it did
    by mistake.
    (merge 98b406f jk/remote-pushremote-config-reading later to maint).
 
- * Codepaths that parse timestamps in commit objects have been
+ * Code paths that parse timestamps in commit objects have been
    tightened.
    (merge f80d1f9 jk/commit-dates-parsing-fix later to maint).
 
  * "git diff --external-diff" incorrectly fed the submodule directory
-   in the working tree to the external diff driver when it knew it is
-   the same as one of the versions being compared.
+   in the working tree to the external diff driver when it knew that it
+   is the same as one of the versions being compared.
    (merge aba4727 tr/diff-submodule-no-reuse-worktree later to maint).
 
  * "git reset" needs to refresh the index when working in a working
@@ -314,7 +318,7 @@ notes for details).
 
  * "git check-attr" when working on a repository with a working tree
    did not work well when the working tree was specified via the
-   --work-tree (and obviously with --git-dir) option.
+   "--work-tree" (and obviously with "--git-dir") option.
    (merge cdbf623 jc/check-attr-honor-working-tree later to maint).
 
  * "merge-recursive" was broken in 1.7.7 era and stopped working in
@@ -322,12 +326,12 @@ notes for details).
    involved.  This has been corrected.
    (merge 6e2068a bk/refresh-missing-ok-in-merge-recursive later to maint.)
 
- * "git rev-parse" was loose in rejecting command line arguments
+ * "git rev-parse" was loose in rejecting command-line arguments
    that do not make sense, e.g. "--default" without the required
    value for that option.
    (merge a43219f ds/rev-parse-required-args later to maint.)
 
- * include.path variable (or any variable that expects a path that
+ * "include.path" variable (or any variable that expects a path that
    can use ~username expansion) in the configuration file is not a
    boolean, but the code failed to check it.
    (merge 67beb60 jk/config-path-include-fix later to maint.)
@@ -336,23 +340,23 @@ notes for details).
    the pathspec is given as an absolute pathname (which is a
    practice not particularly encouraged) that points at a symbolic
    link in the working tree.
-   (merge later 655ee9e mw/symlinks to maint.)
+   (merge 6127ff6 mw/symlinks later to maint.)
 
  * "git diff --quiet -- pathspec1 pathspec2" sometimes did not return
-   correct status value.
+   the correct status value.
    (merge f34b205 nd/diff-quiet-stat-dirty later to maint.)
 
  * Attempting to deepen a shallow repository by fetching over smart
-   HTTP transport failed in the protocol exchange, when no-done
+   HTTP transport failed in the protocol exchange, when the no-done
    extension was used.  The fetching side waited for the list of
-   shallow boundary commits after the sending end stopped talking to
+   shallow boundary commits after the sending side stopped talking to
    it.
    (merge 0232852 nd/http-fetch-shallow-fix later to maint.)
 
  * Allow "git cmd path/", when the 'path' is where a submodule is
    bound to the top-level working tree, to match 'path', despite the
    extra and unnecessary trailing slash (such a slash is often
-   given by command line completion).
+   given by command-line completion).
    (merge 2e70c01 nd/submodule-pathspec-ending-with-slash later to maint.)
 
  * Documentation and in-code comments had many instances of mistaken
diff --git a/Documentation/RelNotes/2.1.0.txt b/Documentation/RelNotes/2.1.0.txt
new file mode 100644 (file)
index 0000000..ad53d0d
--- /dev/null
@@ -0,0 +1,86 @@
+Git v2.1 Release Notes
+======================
+
+Updates since v2.0
+------------------
+
+UI, Workflows & Features
+
+ * "git commit --date=<date>" option learned to read from more
+   timestamp formats, including "--date=now".
+
+ * "git grep" learned grep.fullname configuration variable to force
+   "--full-name" to be default.  This may cause regressions on
+   scripted users that do not expect this new behaviour.
+
+ * "git merge" without argument, even when there is an upstream
+   defined for the current branch, refused to run until
+   merge.defaultToUpstream is set to true.  Flip the default of that
+   configuration variable to true.
+
+ * "git mergetool" learned to drive the vimdiff3 backend.
+
+ * mergetool.prompt used to default to 'true', always asking "do you
+   really want to run the tool on this path?".  Among the two
+   purposes this prompt serves, ignore the use case to confirm that
+   the user wants to view particular path with the named tool, and
+   redefine the meaning of the prompt only to confirm the choice of
+   the tool made by the autodetection (for those who configured the
+   tool explicitly, the prompt shown for the latter purpose is
+   simply annoying).
+
+   Strictly speaking, this is a backward incompatible change and the
+   users need to explicitly set the variable to 'true' if they want
+   to resurrect the now-ignored use case.
+
+ * "git svn" learned to cope with malformed timestamps with only one
+   digit in the hour part, e.g. 2014-01-07T5:01:02.048176Z, emitted
+   by some broken subversion server implementations.
+
+
+Performance, Internal Implementation, etc.
+
+ * "git diff" that compares 3-or-more trees (e.g. parents and the
+   result of a merge) have been optimized.
+
+ * The API to update/delete references are being converted to handle
+   updates to multiple references in a transactional way.  As an
+   example, "update-ref --stdin [-z]" has been updated to use this
+   API.
+
+
+Also contains various documentation updates and code clean-ups.
+
+
+Fixes since v2.0
+----------------
+
+Unless otherwise noted, all the fixes since v2.0 in the maintenance
+track are contained in this release (see the maintenance releases'
+notes for details).
+
+ * "--ignore-space-change" option of "git apply" ignored the spaces
+   at the beginning of line too aggressively, which is inconsistent
+   with the option of the same name "diff" and "git diff" have.
+   (merge 14d3bb4 jc/apply-ignore-whitespace later to maint).
+
+ * "git blame" miscounted number of columns needed to show localized
+   timestamps, resulting in jaggy left-side-edge of the source code
+   lines in its output.
+   (merge dd75553 jx/blame-align-relative-time later to maint).
+
+ * We used to disable threaded "git index-pack" on platforms without
+   thread-safe pread(); use a different workaround for such
+   platforms to allow threaded "git index-pack".
+   (merge 3953949 nd/index-pack-one-fd-per-thread later to maint).
+
+ * "git rerere forget" did not work well when merge.conflictstyle
+   was set to a non-default value.
+   (merge de3d8bb fc/rerere-conflict-style later to maint).
+
+ * "git status", even though it is a read-only operation, tries to
+   update the index with refreshed lstat(2) info to optimize future
+   accesses to the working tree opportunistically, but this could
+   race with a "read-write" operation that modify the index while it
+   is running.  Detect such a race and avoid overwriting the index.
+   (merge 426ddee ym/fix-opportunistic-index-update-race later to maint).
index 21a3c86fa005c3cbe2b92d8c1a29ccc240b1a9c4..a33c087cb4c4487817c51df70b7c03d4bc4d2254 100644 (file)
@@ -558,14 +558,19 @@ core.pager::
        configuration, then `$PAGER`, and then the default chosen at
        compile time (usually 'less').
 +
-When the `LESS` environment variable is unset, Git sets it to `FRSX`
+When the `LESS` environment variable is unset, Git sets it to `FRX`
 (if `LESS` environment variable is set, Git does not change it at
 all).  If you want to selectively override Git's default setting
-for `LESS`, you can set `core.pager` to e.g. `less -+S`.  This will
+for `LESS`, you can set `core.pager` to e.g. `less -S`.  This will
 be passed to the shell by Git, which will translate the final
-command to `LESS=FRSX less -+S`. The environment tells the command
-to set the `S` option to chop long lines but the command line
-resets it to the default to fold long lines.
+command to `LESS=FRX less -S`. The environment does not set the
+`S` option but the command line does, instructing less to truncate
+long lines. Similarly, setting `core.pager` to `less -+F` will
+deactivate the `F` option specified by the environment from the
+command-line, deactivating the "quit if one screen" behavior of
+`less`.  One can specifically activate some flags for particular
+commands: for example, setting `pager.blame` to `less -S` enables
+line truncation only for `git blame`.
 +
 Likewise, when the `LV` environment variable is unset, Git sets it
 to `-c`.  You can override this setting by exporting `LV` with
index f83733490f5a881f6f197b3b62000337c500ef9d..31811f16bdaac49d01d38dcdea82bb191942b1cf 100644 (file)
@@ -53,6 +53,9 @@ grep.extendedRegexp::
        option is ignored when the 'grep.patternType' option is set to a value
        other than 'default'.
 
+grep.fullName::
+       If set to true, enable '--full-name' option by default.
+
 
 OPTIONS
 -------
index a3c1fa332abb8d65051f6f6d5df6a14708fba980..cf2c374b710673e891f8337cb9bcc90d72be460a 100644 (file)
@@ -101,9 +101,8 @@ commit or stash your changes before running 'git merge'.
        Specifying more than one commit will create a merge with
        more than two parents (affectionately called an Octopus merge).
 +
-If no commit is given from the command line, and if `merge.defaultToUpstream`
-configuration variable is set, merge the remote-tracking branches
-that the current branch is configured to use as its upstream.
+If no commit is given from the command line, merge the remote-tracking
+branches that the current branch is configured to use as its upstream.
 See also the configuration section of this manual page.
 
 
index 07137f252b0fd57a671ef69884bea893cdd7767c..e846c2ed7f7f862f5324c0e95a2b17dabcaac58d 100644 (file)
@@ -71,11 +71,13 @@ success of the resolution after the custom tool has exited.
 --no-prompt::
        Don't prompt before each invocation of the merge resolution
        program.
+       This is the default if the merge resolution program is
+       explicitly specified with the `--tool` option or with the
+       `merge.tool` configuration variable.
 
 --prompt::
-       Prompt before each invocation of the merge resolution program.
-       This is the default behaviour; the option is provided to
-       override any configuration settings.
+       Prompt before each invocation of the merge resolution program
+       to give the user a chance to skip the path.
 
 TEMPORARY FILES
 ---------------
index c35051ba58b63cdc489b0ee3f4ffb72631b619e3..e4bdd2235ca4ea9b853e1b568203411da1cc3b84 100644 (file)
@@ -66,7 +66,7 @@ EXAMPLE
 -------
 
 To disable interactive logins, displaying a greeting instead:
-+
+
 ----------------
 $ chsh -s /usr/bin/git-shell
 $ mkdir $HOME/git-shell-commands
index 0a0a5512b3c62eb1179a3d5a9687949c39b2a9ef..c8f5ae5cb362276de94aa867af59818a75b04595 100644 (file)
@@ -68,7 +68,12 @@ performs all modifications together.  Specify commands of the form:
        option SP <opt> LF
 
 Quote fields containing whitespace as if they were strings in C source
-code.  Alternatively, use `-z` to specify commands without quoting:
+code; i.e., surrounded by double-quotes and with backslash escapes.
+Use 40 "0" characters or the empty string to specify a zero value.  To
+specify a missing value, omit the value and its preceding SP entirely.
+
+Alternatively, use `-z` to specify in NUL-terminated format, without
+quoting:
 
        update SP <ref> NUL <newvalue> NUL [<oldvalue>] NUL
        create SP <ref> NUL <newvalue> NUL
@@ -76,8 +81,12 @@ code.  Alternatively, use `-z` to specify commands without quoting:
        verify SP <ref> NUL [<oldvalue>] NUL
        option SP <opt> NUL
 
-Lines of any other format or a repeated <ref> produce an error.
-Command meanings are:
+In this format, use 40 "0" to specify a zero value, and use the empty
+string to specify a missing value.
+
+In either format, values can be specified in any form that Git
+recognizes as an object name.  Commands in any other format or a
+repeated <ref> produce an error.  Command meanings are:
 
 update::
        Set <ref> to <newvalue> after verifying <oldvalue>, if given.
@@ -102,9 +111,6 @@ option::
        The only valid option is `no-deref` to avoid dereferencing
        a symbolic ref.
 
-Use 40 "0" or the empty string to specify a zero value, except that
-with `-z` an empty <oldvalue> is considered missing.
-
 If all <ref>s can be locked with matching <oldvalue>s
 simultaneously, all modifications are performed.  Otherwise, no
 modifications are performed.  Note that while each individual
index 35eb677ce0a193ff670029daa8fd5b9caee0c8f7..b075e0bed55c9cfd84b130ef6e93080ef3207517 100644 (file)
@@ -43,9 +43,16 @@ unreleased) version of Git, that is available from 'master'
 branch of the `git.git` repository.
 Documentation for older releases are available here:
 
-* link:v1.9.2/git.html[documentation for release 1.9.2]
+* link:v2.0.0/git.html[documentation for release 2.0]
 
 * release notes for
+  link:RelNotes/2.0.0.txt[2.0.0].
+
+* link:v1.9.4/git.html[documentation for release 1.9.4]
+
+* release notes for
+  link:RelNotes/1.9.4.txt[1.9.4],
+  link:RelNotes/1.9.3.txt[1.9.3],
   link:RelNotes/1.9.2.txt[1.9.2],
   link:RelNotes/1.9.1.txt[1.9.1],
   link:RelNotes/1.9.0.txt[1.9.0].
index e3d6e7a79a6c2136a796c5409d16feb8058e96d2..22a39b929932b78653d1d0b1a59fe35e5d5e75f5 100644 (file)
@@ -22,11 +22,14 @@ Git:
 where options is the bitwise-or of:
 
 `RUN_SETUP`::
-
-       Make sure there is a Git directory to work on, and if there is a
-       work tree, chdir to the top of it if the command was invoked
-       in a subdirectory.  If there is no work tree, no chdir() is
-       done.
+       If there is not a Git directory to work on, abort.  If there
+       is a work tree, chdir to the top of it if the command was
+       invoked in a subdirectory.  If there is no work tree, no
+       chdir() is done.
+
+`RUN_SETUP_GENTLY`::
+       If there is a Git directory, chdir as per RUN_SETUP, otherwise,
+       don't chdir anywhere.
 
 `USE_PAGER`::
 
index 42ca2347edd2e13c5e3132a077ac96777bbefa11..b977ae8bbb1f46ebb40d1d315e79262fe344f1c2 100644 (file)
@@ -166,7 +166,6 @@ Usage example
 -------------
 
 Here's a simple usage example that maps long keys to double values.
-[source,c]
 ------------
 struct hashmap map;
 
index 3350d97dda2408f92dc44c1e3216facc50257a50..4396be9dda07dfad679f834120b7f1aa2adb16c5 100644 (file)
@@ -121,10 +121,19 @@ Functions
 
 * Related to the contents of the buffer
 
+`strbuf_trim`::
+
+       Strip whitespace from the beginning and end of a string.
+       Equivalent to performing `strbuf_rtrim()` followed by `strbuf_ltrim()`.
+
 `strbuf_rtrim`::
 
        Strip whitespace from the end of a string.
 
+`strbuf_ltrim`::
+
+       Strip whitespace from the beginning of a string.
+
 `strbuf_cmp`::
 
        Compare two buffers. Returns an integer less than, equal to, or greater
index d356425e190f2ffa8401d09f7fe3eb28ff311457..40adbf7bf79ad7d7800b71d2ca79418cdbddd3ed 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 GVF=GIT-VERSION-FILE
-DEF_VER=v2.0.0-rc2
+DEF_VER=v2.0.0.GIT
 
 LF='
 '
index a53f3a8326c2e62dc79bae7169d64137ac3dab20..08fc9ca430d218a8dc279270dc2ec4beaaf01827 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -30,6 +30,8 @@ all::
 # Define LIBPCREDIR=/foo/bar if your libpcre header and library files are in
 # /foo/bar/include and /foo/bar/lib directories.
 #
+# Define HAVE_ALLOCA_H if you have working alloca(3) defined in that header.
+#
 # Define NO_CURL if you do not have libcurl installed.  git-http-fetch and
 # git-http-push are not built, and you cannot use http:// and https://
 # transports (neither smart nor dumb).
@@ -183,9 +185,6 @@ all::
 # Define NO_STRUCT_ITIMERVAL if you don't have struct itimerval
 # This also implies NO_SETITIMER
 #
-# Define NO_THREAD_SAFE_PREAD if your pread() implementation is not
-# thread-safe. (e.g. compat/pread.c or cygwin)
-#
 # Define NO_FAST_WORKING_DIRECTORY if accessing objects in pack files is
 # generally faster on your platform than accessing the working directory.
 #
@@ -1111,6 +1110,10 @@ ifdef USE_LIBPCRE
        EXTLIBS += -lpcre
 endif
 
+ifdef HAVE_ALLOCA_H
+       BASIC_CFLAGS += -DHAVE_ALLOCA_H
+endif
+
 ifdef NO_CURL
        BASIC_CFLAGS += -DNO_CURL
        REMOTE_CURL_PRIMARY =
@@ -1339,10 +1342,6 @@ endif
 ifdef NO_PREAD
        COMPAT_CFLAGS += -DNO_PREAD
        COMPAT_OBJS += compat/pread.o
-       NO_THREAD_SAFE_PREAD = YesPlease
-endif
-ifdef NO_THREAD_SAFE_PREAD
-       BASIC_CFLAGS += -DNO_THREAD_SAFE_PREAD
 endif
 ifdef NO_FAST_WORKING_DIRECTORY
        BASIC_CFLAGS += -DNO_FAST_WORKING_DIRECTORY
index e50885caa1043665dfe2d995e0a2f7a7a7bb51ca..bf760914010786c830233effc8b96ddacfb114fd 120000 (symlink)
--- a/RelNotes
+++ b/RelNotes
@@ -1 +1 @@
-Documentation/RelNotes/2.0.0.txt
\ No newline at end of file
+Documentation/RelNotes/2.1.0.txt
\ No newline at end of file
index 87439fad118a2671989120dd5993a17b4541e2db..9c5724eaccfaee62ff10eb097adc39ace351cade 100644 (file)
@@ -300,11 +300,13 @@ static int fuzzy_matchlines(const char *s1, size_t n1,
        while ((*last2 == '\r') || (*last2 == '\n'))
                last2--;
 
-       /* skip leading whitespace */
-       while (isspace(*s1) && (s1 <= last1))
-               s1++;
-       while (isspace(*s2) && (s2 <= last2))
-               s2++;
+       /* skip leading whitespaces, if both begin with whitespace */
+       if (s1 <= last1 && s2 <= last2 && isspace(*s1) && isspace(*s2)) {
+               while (isspace(*s1) && (s1 <= last1))
+                       s1++;
+               while (isspace(*s2) && (s2 <= last2))
+                       s2++;
+       }
        /* early return if both lines are empty */
        if ((s1 > last1) && (s2 > last2))
                return 1;
index 88cb7997274de6f9ab6f8a5944748334ce605f60..128fc64d64f46af010ffcc1cf83b98705c60dabc 100644 (file)
@@ -1556,22 +1556,29 @@ static void assign_blame(struct scoreboard *sb, int opt)
 static const char *format_time(unsigned long time, const char *tz_str,
                               int show_raw_time)
 {
-       static char time_buf[128];
+       static struct strbuf time_buf = STRBUF_INIT;
 
+       strbuf_reset(&time_buf);
        if (show_raw_time) {
-               snprintf(time_buf, sizeof(time_buf), "%lu %s", time, tz_str);
+               strbuf_addf(&time_buf, "%lu %s", time, tz_str);
        }
        else {
                const char *time_str;
-               int time_len;
+               size_t time_width;
                int tz;
                tz = atoi(tz_str);
                time_str = show_date(time, tz, blame_date_mode);
-               time_len = strlen(time_str);
-               memcpy(time_buf, time_str, time_len);
-               memset(time_buf + time_len, ' ', blame_date_width - time_len);
+               strbuf_addstr(&time_buf, time_str);
+               /*
+                * Add space paddings to time_buf to display a fixed width
+                * string, and use time_width for display width calibration.
+                */
+               for (time_width = utf8_strwidth(time_str);
+                    time_width < blame_date_width;
+                    time_width++)
+                       strbuf_addch(&time_buf, ' ');
        }
-       return time_buf;
+       return time_buf.buf;
 }
 
 #define OUTPUT_ANNOTATE_COMPAT 001
@@ -2331,7 +2338,14 @@ parse_done:
                blame_date_width = sizeof("2006-10-19");
                break;
        case DATE_RELATIVE:
-               /* "normal" is used as the fallback for "relative" */
+               /* TRANSLATORS: This string is used to tell us the maximum
+                  display width for a relative timestamp in "git blame"
+                  output.  For C locale, "4 years, 11 months ago", which
+                  takes 22 places, is the longest among various forms of
+                  relative timestamps, but your language may need more or
+                  fewer display columns. */
+               blame_date_width = utf8_strwidth(_("4 years, 11 months ago")) + 1; /* add the null */
+               break;
        case DATE_LOCAL:
        case DATE_NORMAL:
                blame_date_width = sizeof("Thu Oct 19 16:00:04 2006 -0700");
index 07cf55530918e8de6ae45e1c9b7e16707c32f844..ff4492162d9543598c1cdc8951f8604a4712516d 100644 (file)
@@ -624,7 +624,7 @@ static void update_refs_for_switch(const struct checkout_opts *opts,
                /* Nothing to do. */
        } else if (opts->force_detach || !new->path) {  /* No longer on any branch. */
                update_ref(msg.buf, "HEAD", new->commit->object.sha1, NULL,
-                          REF_NODEREF, DIE_ON_ERR);
+                          REF_NODEREF, UPDATE_REFS_DIE_ON_ERR);
                if (!opts->quiet) {
                        if (old->path && advice_detached_head)
                                detach_advice(new->name);
index 9b3c04d914b3d318f723c2d3ded403fca9503c07..b12989d1caecb48128e8a468014f07b237b1a4cc 100644 (file)
@@ -521,7 +521,7 @@ static void write_followtags(const struct ref *refs, const char *msg)
                if (!has_sha1_file(ref->old_sha1))
                        continue;
                update_ref(msg, ref->name, ref->old_sha1,
-                          NULL, 0, DIE_ON_ERR);
+                          NULL, 0, UPDATE_REFS_DIE_ON_ERR);
        }
 }
 
@@ -589,14 +589,15 @@ static void update_head(const struct ref *our, const struct ref *remote,
                create_symref("HEAD", our->name, NULL);
                if (!option_bare) {
                        const char *head = skip_prefix(our->name, "refs/heads/");
-                       update_ref(msg, "HEAD", our->old_sha1, NULL, 0, DIE_ON_ERR);
+                       update_ref(msg, "HEAD", our->old_sha1, NULL, 0,
+                                  UPDATE_REFS_DIE_ON_ERR);
                        install_branch_config(0, head, option_origin, our->name);
                }
        } else if (our) {
                struct commit *c = lookup_commit_reference(our->old_sha1);
                /* --branch specifies a non-branch (i.e. tags), detach HEAD */
                update_ref(msg, "HEAD", c->object.sha1,
-                          NULL, REF_NODEREF, DIE_ON_ERR);
+                          NULL, REF_NODEREF, UPDATE_REFS_DIE_ON_ERR);
        } else if (remote) {
                /*
                 * We know remote HEAD points to a non-branch, or
@@ -604,7 +605,7 @@ static void update_head(const struct ref *our, const struct ref *remote,
                 * Detach HEAD in all these cases.
                 */
                update_ref(msg, "HEAD", remote->old_sha1,
-                          NULL, REF_NODEREF, DIE_ON_ERR);
+                          NULL, REF_NODEREF, UPDATE_REFS_DIE_ON_ERR);
        }
 }
 
index 9cfef6c6cca61973a4982763e4b834bf1b45cb75..0320efd57d51d3bf78bedd958b895e5a44fca640 100644 (file)
@@ -526,10 +526,29 @@ static int sane_ident_split(struct ident_split *person)
        return 1;
 }
 
+static int parse_force_date(const char *in, char *out, int len)
+{
+       if (len < 1)
+               return -1;
+       *out++ = '@';
+       len--;
+
+       if (parse_date(in, out, len) < 0) {
+               int errors = 0;
+               unsigned long t = approxidate_careful(in, &errors);
+               if (errors)
+                       return -1;
+               snprintf(out, len, "%lu", t);
+       }
+
+       return 0;
+}
+
 static void determine_author_info(struct strbuf *author_ident)
 {
        char *name, *email, *date;
        struct ident_split author;
+       char date_buf[64];
 
        name = getenv("GIT_AUTHOR_NAME");
        email = getenv("GIT_AUTHOR_EMAIL");
@@ -574,8 +593,12 @@ static void determine_author_info(struct strbuf *author_ident)
                email = xstrndup(lb + 2, rb - (lb + 2));
        }
 
-       if (force_date)
-               date = force_date;
+       if (force_date) {
+               if (parse_force_date(force_date, date_buf, sizeof(date_buf)))
+                       die(_("invalid date format: %s"), force_date);
+               date = date_buf;
+       }
+
        strbuf_addstr(author_ident, fmt_ident(name, email, date, IDENT_STRICT));
        if (!split_ident_line(&author, author_ident->buf, author_ident->len) &&
            sane_ident_split(&author)) {
@@ -585,13 +608,16 @@ static void determine_author_info(struct strbuf *author_ident)
        }
 }
 
-static char *cut_ident_timestamp_part(char *string)
+static void split_ident_or_die(struct ident_split *id, const struct strbuf *buf)
+{
+       if (split_ident_line(id, buf->buf, buf->len) ||
+           !sane_ident_split(id))
+               die(_("Malformed ident string: '%s'"), buf->buf);
+}
+
+static int author_date_is_interesting(void)
 {
-       char *ket = strrchr(string, '>');
-       if (!ket || ket[1] != ' ')
-               die(_("Malformed ident string: '%s'"), string);
-       *++ket = '\0';
-       return ket;
+       return author_message || force_date;
 }
 
 static int prepare_to_commit(const char *index_file, const char *prefix,
@@ -650,9 +676,8 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
        } else if (use_message) {
                char *buffer;
                buffer = strstr(use_message_buffer, "\n\n");
-               if (!use_editor && (!buffer || buffer[2] == '\0'))
-                       die(_("commit has empty message"));
-               strbuf_add(&sb, buffer + 2, strlen(buffer + 2));
+               if (buffer)
+                       strbuf_add(&sb, buffer + 2, strlen(buffer + 2));
                hook_arg1 = "commit";
                hook_arg2 = use_message;
        } else if (fixup_message) {
@@ -755,7 +780,8 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
        if (use_editor && include_status) {
                int ident_shown = 0;
                int saved_color_setting;
-               char *ai_tmp, *ci_tmp;
+               struct ident_split ci, ai;
+
                if (whence != FROM_COMMIT) {
                        if (cleanup_mode == CLEANUP_SCISSORS)
                                wt_status_add_cut_line(s->fp);
@@ -795,21 +821,31 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
                        status_printf_ln(s, GIT_COLOR_NORMAL,
                                        "%s", only_include_assumed);
 
-               ai_tmp = cut_ident_timestamp_part(author_ident->buf);
-               ci_tmp = cut_ident_timestamp_part(committer_ident.buf);
-               if (strcmp(author_ident->buf, committer_ident.buf))
+               split_ident_or_die(&ai, author_ident);
+               split_ident_or_die(&ci, &committer_ident);
+
+               if (ident_cmp(&ai, &ci))
                        status_printf_ln(s, GIT_COLOR_NORMAL,
                                _("%s"
-                               "Author:    %s"),
+                               "Author:    %.*s <%.*s>"),
                                ident_shown++ ? "" : "\n",
-                               author_ident->buf);
+                               (int)(ai.name_end - ai.name_begin), ai.name_begin,
+                               (int)(ai.mail_end - ai.mail_begin), ai.mail_begin);
+
+               if (author_date_is_interesting())
+                       status_printf_ln(s, GIT_COLOR_NORMAL,
+                               _("%s"
+                               "Date:      %s"),
+                               ident_shown++ ? "" : "\n",
+                               show_ident_date(&ai, DATE_NORMAL));
 
                if (!committer_ident_sufficiently_given())
                        status_printf_ln(s, GIT_COLOR_NORMAL,
                                _("%s"
-                               "Committer: %s"),
+                               "Committer: %.*s <%.*s>"),
                                ident_shown++ ? "" : "\n",
-                               committer_ident.buf);
+                               (int)(ci.name_end - ci.name_begin), ci.name_begin,
+                               (int)(ci.mail_end - ci.mail_begin), ci.mail_begin);
 
                if (ident_shown)
                        status_printf_ln(s, GIT_COLOR_NORMAL, "");
@@ -818,9 +854,6 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
                s->use_color = 0;
                commitable = run_status(s->fp, index_file, prefix, 1, s);
                s->use_color = saved_color_setting;
-
-               *ai_tmp = ' ';
-               *ci_tmp = ' ';
        } else {
                unsigned char sha1[20];
                const char *parent = "HEAD";
@@ -1356,6 +1389,13 @@ static void print_summary(const char *prefix, const unsigned char *sha1,
                strbuf_addstr(&format, "\n Author: ");
                strbuf_addbuf_percentquote(&format, &author_ident);
        }
+       if (author_date_is_interesting()) {
+               struct strbuf date = STRBUF_INIT;
+               format_commit_message(commit, "%ad", &date, &pctx);
+               strbuf_addstr(&format, "\n Date: ");
+               strbuf_addbuf_percentquote(&format, &date);
+               strbuf_release(&date);
+       }
        if (!committer_ident_sufficiently_given()) {
                strbuf_addstr(&format, "\n Committer: ");
                strbuf_addbuf_percentquote(&format, &committer_ident);
@@ -1672,6 +1712,10 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
                                           ? NULL
                                           : current_head->object.sha1,
                                           0, NULL);
+       if (!ref_lock) {
+               rollback_index_files();
+               die(_("cannot lock HEAD ref"));
+       }
 
        nl = strchr(sb.buf, '\n');
        if (nl)
@@ -1681,10 +1725,6 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
        strbuf_insert(&sb, 0, reflog_msg, strlen(reflog_msg));
        strbuf_insert(&sb, strlen(reflog_msg), ": ", 2);
 
-       if (!ref_lock) {
-               rollback_index_files();
-               die(_("cannot lock HEAD ref"));
-       }
        if (write_ref_sha1(ref_lock, sha1, sb.buf) < 0) {
                rollback_index_files();
                die(_("cannot update HEAD ref"));
index b9f6e12c0e91635eafd8510dc7cf20d6c3e58433..87d8dd81cc4c24ecf7feee932bc8b39a826bb55d 100644 (file)
@@ -40,17 +40,13 @@ struct base_data {
        int ofs_first, ofs_last;
 };
 
-#if !defined(NO_PTHREADS) && defined(NO_THREAD_SAFE_PREAD)
-/* pread() emulation is not thread-safe. Disable threading. */
-#define NO_PTHREADS
-#endif
-
 struct thread_local {
 #ifndef NO_PTHREADS
        pthread_t thread;
 #endif
        struct base_data *base_cache;
        size_t base_cache_used;
+       int pack_fd;
 };
 
 /*
@@ -91,7 +87,8 @@ static off_t consumed_bytes;
 static unsigned deepest_delta;
 static git_SHA_CTX input_ctx;
 static uint32_t input_crc32;
-static int input_fd, output_fd, pack_fd;
+static int input_fd, output_fd;
+static const char *curr_pack;
 
 #ifndef NO_PTHREADS
 
@@ -134,6 +131,7 @@ static inline void unlock_mutex(pthread_mutex_t *mutex)
  */
 static void init_thread(void)
 {
+       int i;
        init_recursive_mutex(&read_mutex);
        pthread_mutex_init(&counter_mutex, NULL);
        pthread_mutex_init(&work_mutex, NULL);
@@ -141,11 +139,18 @@ static void init_thread(void)
                pthread_mutex_init(&deepest_delta_mutex, NULL);
        pthread_key_create(&key, NULL);
        thread_data = xcalloc(nr_threads, sizeof(*thread_data));
+       for (i = 0; i < nr_threads; i++) {
+               thread_data[i].pack_fd = open(curr_pack, O_RDONLY);
+               if (thread_data[i].pack_fd == -1)
+                       die_errno(_("unable to open %s"), curr_pack);
+       }
+
        threads_active = 1;
 }
 
 static void cleanup_thread(void)
 {
+       int i;
        if (!threads_active)
                return;
        threads_active = 0;
@@ -154,6 +159,8 @@ static void cleanup_thread(void)
        pthread_mutex_destroy(&work_mutex);
        if (show_stat)
                pthread_mutex_destroy(&deepest_delta_mutex);
+       for (i = 0; i < nr_threads; i++)
+               close(thread_data[i].pack_fd);
        pthread_key_delete(key);
        free(thread_data);
 }
@@ -288,13 +295,13 @@ static const char *open_pack_file(const char *pack_name)
                        output_fd = open(pack_name, O_CREAT|O_EXCL|O_RDWR, 0600);
                if (output_fd < 0)
                        die_errno(_("unable to create '%s'"), pack_name);
-               pack_fd = output_fd;
+               nothread_data.pack_fd = output_fd;
        } else {
                input_fd = open(pack_name, O_RDONLY);
                if (input_fd < 0)
                        die_errno(_("cannot open packfile '%s'"), pack_name);
                output_fd = -1;
-               pack_fd = input_fd;
+               nothread_data.pack_fd = input_fd;
        }
        git_SHA1_Init(&input_ctx);
        return pack_name;
@@ -542,7 +549,7 @@ static void *unpack_data(struct object_entry *obj,
 
        do {
                ssize_t n = (len < 64*1024) ? len : 64*1024;
-               n = pread(pack_fd, inbuf, n, from);
+               n = xpread(get_thread_data()->pack_fd, inbuf, n, from);
                if (n < 0)
                        die_errno(_("cannot pread pack file"));
                if (!n)
@@ -1490,7 +1497,7 @@ static void show_pack_info(int stat_only)
 int cmd_index_pack(int argc, const char **argv, const char *prefix)
 {
        int i, fix_thin_pack = 0, verify = 0, stat_only = 0;
-       const char *curr_pack, *curr_index;
+       const char *curr_index;
        const char *index_name = NULL, *pack_name = NULL;
        const char *keep_name = NULL, *keep_msg = NULL;
        char *index_name_buf = NULL, *keep_name_buf = NULL;
index 66d8843301b22a6a89d9d765e9d3020942e6f672..428ca247bd17e0f18776b46d40a09282b0b955de 100644 (file)
@@ -63,7 +63,7 @@ static int verbosity;
 static int allow_rerere_auto;
 static int abort_current_merge;
 static int show_progress = -1;
-static int default_to_upstream;
+static int default_to_upstream = 1;
 static const char *sign_commit;
 
 static struct strategy all_strategy[] = {
@@ -398,7 +398,7 @@ static void finish(struct commit *head_commit,
                        const char *argv_gc_auto[] = { "gc", "--auto", NULL };
                        update_ref(reflog_message.buf, "HEAD",
                                new_head, head, 0,
-                               DIE_ON_ERR);
+                               UPDATE_REFS_DIE_ON_ERR);
                        /*
                         * We ignore errors in 'gc --auto', since the
                         * user should see them.
@@ -1222,7 +1222,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
                        die(_("%s - not something we can merge"), argv[0]);
                read_empty(remote_head->object.sha1, 0);
                update_ref("initial pull", "HEAD", remote_head->object.sha1,
-                          NULL, 0, DIE_ON_ERR);
+                          NULL, 0, UPDATE_REFS_DIE_ON_ERR);
                goto done;
        } else {
                struct strbuf merge_names = STRBUF_INIT;
@@ -1339,7 +1339,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
        }
 
        update_ref("updating ORIG_HEAD", "ORIG_HEAD", head_commit->object.sha1,
-                  NULL, 0, DIE_ON_ERR);
+                  NULL, 0, UPDATE_REFS_DIE_ON_ERR);
 
        if (remoteheads && !common)
                ; /* No common ancestors found. We need a real merge. */
index 39c8573cde00bc15e673ae549fcd0f22ea67d29f..820c34135cab439e2168dd08947bd79d7ed7ae71 100644 (file)
@@ -717,7 +717,7 @@ static int merge_commit(struct notes_merge_options *o)
        strbuf_insert(&msg, 0, "notes: ", 7);
        update_ref(msg.buf, o->local_ref, sha1,
                   is_null_sha1(parent_sha1) ? NULL : parent_sha1,
-                  0, DIE_ON_ERR);
+                  0, UPDATE_REFS_DIE_ON_ERR);
 
        free_notes(t);
        strbuf_release(&msg);
@@ -812,11 +812,11 @@ static int merge(int argc, const char **argv, const char *prefix)
        if (result >= 0) /* Merge resulted (trivially) in result_sha1 */
                /* Update default notes ref with new commit */
                update_ref(msg.buf, default_notes_ref(), result_sha1, NULL,
-                          0, DIE_ON_ERR);
+                          0, UPDATE_REFS_DIE_ON_ERR);
        else { /* Merge has unresolved conflicts */
                /* Update .git/NOTES_MERGE_PARTIAL with partial merge result */
                update_ref(msg.buf, "NOTES_MERGE_PARTIAL", result_sha1, NULL,
-                          0, DIE_ON_ERR);
+                          0, UPDATE_REFS_DIE_ON_ERR);
                /* Store ref-to-be-updated into .git/NOTES_MERGE_REF */
                if (create_symref("NOTES_MERGE_REF", default_notes_ref(), NULL))
                        die("Failed to store link to current notes ref (%s)",
index 4e51addb3e135465bdb728bb00c5dc3dd53b7c51..98eb8c5404914e4046fdb886866b611351deeacf 100644 (file)
@@ -60,6 +60,8 @@ int cmd_rerere(int argc, const char **argv, const char *prefix)
 
        argc = parse_options(argc, argv, prefix, options, rerere_usage, 0);
 
+       git_config(git_xmerge_config, NULL);
+
        if (autoupdate == 1)
                flags = RERERE_AUTOUPDATE;
        if (autoupdate == 0)
index f4e087596b6337d2306af4cf45119752b4a049ea..f368266762fae1e6c783d7351e289e423e408b3c 100644 (file)
@@ -252,11 +252,13 @@ static int reset_refs(const char *rev, const unsigned char *sha1)
        if (!get_sha1("HEAD", sha1_orig)) {
                orig = sha1_orig;
                set_reflog_message(&msg, "updating ORIG_HEAD", NULL);
-               update_ref(msg.buf, "ORIG_HEAD", orig, old_orig, 0, MSG_ON_ERR);
+               update_ref(msg.buf, "ORIG_HEAD", orig, old_orig, 0,
+                          UPDATE_REFS_MSG_ON_ERR);
        } else if (old_orig)
                delete_ref("ORIG_HEAD", old_orig, 0);
        set_reflog_message(&msg, "updating HEAD", rev);
-       update_ref_status = update_ref(msg.buf, "HEAD", sha1, orig, 0, MSG_ON_ERR);
+       update_ref_status = update_ref(msg.buf, "HEAD", sha1, orig, 0,
+                                      UPDATE_REFS_MSG_ON_ERR);
        strbuf_release(&msg);
        return update_ref_status;
 }
index 6c7c6bde9de9cbc0ace94aa75df30b7b88b43aca..f3440023abecc672386381749d5e5855f3673ecf 100644 (file)
@@ -80,11 +80,19 @@ static int in_commit_list(const struct commit_list *want, struct commit *c)
        return 0;
 }
 
-static int contains_recurse(struct commit *candidate,
+enum contains_result {
+       CONTAINS_UNKNOWN = -1,
+       CONTAINS_NO = 0,
+       CONTAINS_YES = 1,
+};
+
+/*
+ * Test whether the candidate or one of its parents is contained in the list.
+ * Do not recurse to find out, though, but return -1 if inconclusive.
+ */
+static enum contains_result contains_test(struct commit *candidate,
                            const struct commit_list *want)
 {
-       struct commit_list *p;
-
        /* was it previously marked as containing a want commit? */
        if (candidate->object.flags & TMP_MARK)
                return 1;
@@ -92,26 +100,78 @@ static int contains_recurse(struct commit *candidate,
        if (candidate->object.flags & UNINTERESTING)
                return 0;
        /* or are we it? */
-       if (in_commit_list(want, candidate))
+       if (in_commit_list(want, candidate)) {
+               candidate->object.flags |= TMP_MARK;
                return 1;
+       }
 
        if (parse_commit(candidate) < 0)
                return 0;
 
-       /* Otherwise recurse and mark ourselves for future traversals. */
-       for (p = candidate->parents; p; p = p->next) {
-               if (contains_recurse(p->item, want)) {
-                       candidate->object.flags |= TMP_MARK;
-                       return 1;
-               }
-       }
-       candidate->object.flags |= UNINTERESTING;
-       return 0;
+       return -1;
 }
 
-static int contains(struct commit *candidate, const struct commit_list *want)
+/*
+ * Mimicking the real stack, this stack lives on the heap, avoiding stack
+ * overflows.
+ *
+ * At each recursion step, the stack items points to the commits whose
+ * ancestors are to be inspected.
+ */
+struct stack {
+       int nr, alloc;
+       struct stack_entry {
+               struct commit *commit;
+               struct commit_list *parents;
+       } *stack;
+};
+
+static void push_to_stack(struct commit *candidate, struct stack *stack)
+{
+       int index = stack->nr++;
+       ALLOC_GROW(stack->stack, stack->nr, stack->alloc);
+       stack->stack[index].commit = candidate;
+       stack->stack[index].parents = candidate->parents;
+}
+
+static enum contains_result contains(struct commit *candidate,
+               const struct commit_list *want)
 {
-       return contains_recurse(candidate, want);
+       struct stack stack = { 0, 0, NULL };
+       int result = contains_test(candidate, want);
+
+       if (result != CONTAINS_UNKNOWN)
+               return result;
+
+       push_to_stack(candidate, &stack);
+       while (stack.nr) {
+               struct stack_entry *entry = &stack.stack[stack.nr - 1];
+               struct commit *commit = entry->commit;
+               struct commit_list *parents = entry->parents;
+
+               if (!parents) {
+                       commit->object.flags |= UNINTERESTING;
+                       stack.nr--;
+               }
+               /*
+                * If we just popped the stack, parents->item has been marked,
+                * therefore contains_test will return a meaningful 0 or 1.
+                */
+               else switch (contains_test(parents->item, want)) {
+               case CONTAINS_YES:
+                       commit->object.flags |= TMP_MARK;
+                       stack.nr--;
+                       break;
+               case CONTAINS_NO:
+                       entry->parents = parents->next;
+                       break;
+               case CONTAINS_UNKNOWN:
+                       push_to_stack(parents->item, &stack);
+                       break;
+               }
+       }
+       free(stack.stack);
+       return contains_test(candidate, want);
 }
 
 static void show_tag_lines(const unsigned char *sha1, int lines)
index 5c208bb1fc4f6c467842b37157435e87fe1415cd..405267f6e2776b3b2bf5c91c1102e090f5ac68f0 100644 (file)
@@ -12,238 +12,329 @@ static const char * const git_update_ref_usage[] = {
        NULL
 };
 
-static int updates_alloc;
-static int updates_count;
-static const struct ref_update **updates;
+static struct ref_transaction *transaction;
 
 static char line_termination = '\n';
 static int update_flags;
 
-static struct ref_update *update_alloc(void)
-{
-       struct ref_update *update;
-
-       /* Allocate and zero-init a struct ref_update */
-       update = xcalloc(1, sizeof(*update));
-       ALLOC_GROW(updates, updates_count + 1, updates_alloc);
-       updates[updates_count++] = update;
-
-       /* Store and reset accumulated options */
-       update->flags = update_flags;
-       update_flags = 0;
-
-       return update;
-}
-
-static void update_store_ref_name(struct ref_update *update,
-                                 const char *ref_name)
-{
-       if (check_refname_format(ref_name, REFNAME_ALLOW_ONELEVEL))
-               die("invalid ref format: %s", ref_name);
-       update->ref_name = xstrdup(ref_name);
-}
-
-static void update_store_new_sha1(struct ref_update *update,
-                                 const char *newvalue)
-{
-       if (*newvalue && get_sha1(newvalue, update->new_sha1))
-               die("invalid new value for ref %s: %s",
-                   update->ref_name, newvalue);
-}
-
-static void update_store_old_sha1(struct ref_update *update,
-                                 const char *oldvalue)
-{
-       if (*oldvalue && get_sha1(oldvalue, update->old_sha1))
-               die("invalid old value for ref %s: %s",
-                   update->ref_name, oldvalue);
-
-       /* We have an old value if non-empty, or if empty without -z */
-       update->have_old = *oldvalue || line_termination;
-}
-
+/*
+ * Parse one whitespace- or NUL-terminated, possibly C-quoted argument
+ * and append the result to arg.  Return a pointer to the terminator.
+ * Die if there is an error in how the argument is C-quoted.  This
+ * function is only used if not -z.
+ */
 static const char *parse_arg(const char *next, struct strbuf *arg)
 {
-       /* Parse SP-terminated, possibly C-quoted argument */
-       if (*next != '"')
+       if (*next == '"') {
+               const char *orig = next;
+
+               if (unquote_c_style(arg, next, &next))
+                       die("badly quoted argument: %s", orig);
+               if (*next && !isspace(*next))
+                       die("unexpected character after quoted argument: %s", orig);
+       } else {
                while (*next && !isspace(*next))
                        strbuf_addch(arg, *next++);
-       else if (unquote_c_style(arg, next, &next))
-               die("badly quoted argument: %s", next);
+       }
 
-       /* Return position after the argument */
        return next;
 }
 
-static const char *parse_first_arg(const char *next, struct strbuf *arg)
+/*
+ * Parse the reference name immediately after "command SP".  If not
+ * -z, then handle C-quoting.  Return a pointer to a newly allocated
+ * string containing the name of the reference, or NULL if there was
+ * an error.  Update *next to point at the character that terminates
+ * the argument.  Die if C-quoting is malformed or the reference name
+ * is invalid.
+ */
+static char *parse_refname(struct strbuf *input, const char **next)
 {
-       /* Parse argument immediately after "command SP" */
-       strbuf_reset(arg);
+       struct strbuf ref = STRBUF_INIT;
+
        if (line_termination) {
                /* Without -z, use the next argument */
-               next = parse_arg(next, arg);
+               *next = parse_arg(*next, &ref);
        } else {
-               /* With -z, use rest of first NUL-terminated line */
-               strbuf_addstr(arg, next);
-               next = next + arg->len;
+               /* With -z, use everything up to the next NUL */
+               strbuf_addstr(&ref, *next);
+               *next += ref.len;
        }
-       return next;
+
+       if (!ref.len) {
+               strbuf_release(&ref);
+               return NULL;
+       }
+
+       if (check_refname_format(ref.buf, REFNAME_ALLOW_ONELEVEL))
+               die("invalid ref format: %s", ref.buf);
+
+       return strbuf_detach(&ref, NULL);
 }
 
-static const char *parse_next_arg(const char *next, struct strbuf *arg)
+/*
+ * The value being parsed is <oldvalue> (as opposed to <newvalue>; the
+ * difference affects which error messages are generated):
+ */
+#define PARSE_SHA1_OLD 0x01
+
+/*
+ * For backwards compatibility, accept an empty string for update's
+ * <newvalue> in binary mode to be equivalent to specifying zeros.
+ */
+#define PARSE_SHA1_ALLOW_EMPTY 0x02
+
+/*
+ * Parse an argument separator followed by the next argument, if any.
+ * If there is an argument, convert it to a SHA-1, write it to sha1,
+ * set *next to point at the character terminating the argument, and
+ * return 0.  If there is no argument at all (not even the empty
+ * string), return 1 and leave *next unchanged.  If the value is
+ * provided but cannot be converted to a SHA-1, die.  flags can
+ * include PARSE_SHA1_OLD and/or PARSE_SHA1_ALLOW_EMPTY.
+ */
+static int parse_next_sha1(struct strbuf *input, const char **next,
+                          unsigned char *sha1,
+                          const char *command, const char *refname,
+                          int flags)
 {
-       /* Parse next SP-terminated or NUL-terminated argument, if any */
-       strbuf_reset(arg);
+       struct strbuf arg = STRBUF_INIT;
+       int ret = 0;
+
+       if (*next == input->buf + input->len)
+               goto eof;
+
        if (line_termination) {
                /* Without -z, consume SP and use next argument */
-               if (!*next)
-                       return NULL;
-               if (*next != ' ')
-                       die("expected SP but got: %s", next);
-               next = parse_arg(next + 1, arg);
+               if (!**next || **next == line_termination)
+                       return 1;
+               if (**next != ' ')
+                       die("%s %s: expected SP but got: %s",
+                           command, refname, *next);
+               (*next)++;
+               *next = parse_arg(*next, &arg);
+               if (arg.len) {
+                       if (get_sha1(arg.buf, sha1))
+                               goto invalid;
+               } else {
+                       /* Without -z, an empty value means all zeros: */
+                       hashclr(sha1);
+               }
        } else {
                /* With -z, read the next NUL-terminated line */
-               if (*next)
-                       die("expected NUL but got: %s", next);
-               if (strbuf_getline(arg, stdin, '\0') == EOF)
-                       return NULL;
-               next = arg->buf + arg->len;
+               if (**next)
+                       die("%s %s: expected NUL but got: %s",
+                           command, refname, *next);
+               (*next)++;
+               if (*next == input->buf + input->len)
+                       goto eof;
+               strbuf_addstr(&arg, *next);
+               *next += arg.len;
+
+               if (arg.len) {
+                       if (get_sha1(arg.buf, sha1))
+                               goto invalid;
+               } else if (flags & PARSE_SHA1_ALLOW_EMPTY) {
+                       /* With -z, treat an empty value as all zeros: */
+                       warning("%s %s: missing <newvalue>, treating as zero",
+                               command, refname);
+                       hashclr(sha1);
+               } else {
+                       /*
+                        * With -z, an empty non-required value means
+                        * unspecified:
+                        */
+                       ret = 1;
+               }
        }
-       return next;
+
+       strbuf_release(&arg);
+
+       return ret;
+
+ invalid:
+       die(flags & PARSE_SHA1_OLD ?
+           "%s %s: invalid <oldvalue>: %s" :
+           "%s %s: invalid <newvalue>: %s",
+           command, refname, arg.buf);
+
+ eof:
+       die(flags & PARSE_SHA1_OLD ?
+           "%s %s: unexpected end of input when reading <oldvalue>" :
+           "%s %s: unexpected end of input when reading <newvalue>",
+           command, refname);
 }
 
-static void parse_cmd_update(const char *next)
+
+/*
+ * The following five parse_cmd_*() functions parse the corresponding
+ * command.  In each case, next points at the character following the
+ * command name and the following space.  They each return a pointer
+ * to the character terminating the command, and die with an
+ * explanatory message if there are any parsing problems.  All of
+ * these functions handle either text or binary format input,
+ * depending on how line_termination is set.
+ */
+
+static const char *parse_cmd_update(struct strbuf *input, const char *next)
 {
-       struct strbuf ref = STRBUF_INIT;
-       struct strbuf newvalue = STRBUF_INIT;
-       struct strbuf oldvalue = STRBUF_INIT;
-       struct ref_update *update;
+       char *refname;
+       unsigned char new_sha1[20];
+       unsigned char old_sha1[20];
+       int have_old;
 
-       update = update_alloc();
+       refname = parse_refname(input, &next);
+       if (!refname)
+               die("update: missing <ref>");
 
-       if ((next = parse_first_arg(next, &ref)) != NULL && ref.buf[0])
-               update_store_ref_name(update, ref.buf);
-       else
-               die("update line missing <ref>");
+       if (parse_next_sha1(input, &next, new_sha1, "update", refname,
+                           PARSE_SHA1_ALLOW_EMPTY))
+               die("update %s: missing <newvalue>", refname);
 
-       if ((next = parse_next_arg(next, &newvalue)) != NULL)
-               update_store_new_sha1(update, newvalue.buf);
-       else
-               die("update %s missing <newvalue>", ref.buf);
+       have_old = !parse_next_sha1(input, &next, old_sha1, "update", refname,
+                                   PARSE_SHA1_OLD);
 
-       if ((next = parse_next_arg(next, &oldvalue)) != NULL)
-               update_store_old_sha1(update, oldvalue.buf);
-       else if(!line_termination)
-               die("update %s missing [<oldvalue>] NUL", ref.buf);
+       if (*next != line_termination)
+               die("update %s: extra input: %s", refname, next);
 
-       if (next && *next)
-               die("update %s has extra input: %s", ref.buf, next);
+       ref_transaction_update(transaction, refname, new_sha1, old_sha1,
+                              update_flags, have_old);
+
+       update_flags = 0;
+       free(refname);
+
+       return next;
 }
 
-static void parse_cmd_create(const char *next)
+static const char *parse_cmd_create(struct strbuf *input, const char *next)
 {
-       struct strbuf ref = STRBUF_INIT;
-       struct strbuf newvalue = STRBUF_INIT;
-       struct ref_update *update;
+       char *refname;
+       unsigned char new_sha1[20];
 
-       update = update_alloc();
-       update->have_old = 1;
+       refname = parse_refname(input, &next);
+       if (!refname)
+               die("create: missing <ref>");
 
-       if ((next = parse_first_arg(next, &ref)) != NULL && ref.buf[0])
-               update_store_ref_name(update, ref.buf);
-       else
-               die("create line missing <ref>");
+       if (parse_next_sha1(input, &next, new_sha1, "create", refname, 0))
+               die("create %s: missing <newvalue>", refname);
 
-       if ((next = parse_next_arg(next, &newvalue)) != NULL)
-               update_store_new_sha1(update, newvalue.buf);
-       else
-               die("create %s missing <newvalue>", ref.buf);
-       if (is_null_sha1(update->new_sha1))
-               die("create %s given zero new value", ref.buf);
+       if (is_null_sha1(new_sha1))
+               die("create %s: zero <newvalue>", refname);
+
+       if (*next != line_termination)
+               die("create %s: extra input: %s", refname, next);
 
-       if (next && *next)
-               die("create %s has extra input: %s", ref.buf, next);
+       ref_transaction_create(transaction, refname, new_sha1, update_flags);
+
+       update_flags = 0;
+       free(refname);
+
+       return next;
 }
 
-static void parse_cmd_delete(const char *next)
+static const char *parse_cmd_delete(struct strbuf *input, const char *next)
 {
-       struct strbuf ref = STRBUF_INIT;
-       struct strbuf oldvalue = STRBUF_INIT;
-       struct ref_update *update;
+       char *refname;
+       unsigned char old_sha1[20];
+       int have_old;
 
-       update = update_alloc();
+       refname = parse_refname(input, &next);
+       if (!refname)
+               die("delete: missing <ref>");
 
-       if ((next = parse_first_arg(next, &ref)) != NULL && ref.buf[0])
-               update_store_ref_name(update, ref.buf);
-       else
-               die("delete line missing <ref>");
+       if (parse_next_sha1(input, &next, old_sha1, "delete", refname,
+                           PARSE_SHA1_OLD)) {
+               have_old = 0;
+       } else {
+               if (is_null_sha1(old_sha1))
+                       die("delete %s: zero <oldvalue>", refname);
+               have_old = 1;
+       }
+
+       if (*next != line_termination)
+               die("delete %s: extra input: %s", refname, next);
 
-       if ((next = parse_next_arg(next, &oldvalue)) != NULL)
-               update_store_old_sha1(update, oldvalue.buf);
-       else if(!line_termination)
-               die("delete %s missing [<oldvalue>] NUL", ref.buf);
-       if (update->have_old && is_null_sha1(update->old_sha1))
-               die("delete %s given zero old value", ref.buf);
+       ref_transaction_delete(transaction, refname, old_sha1,
+                              update_flags, have_old);
 
-       if (next && *next)
-               die("delete %s has extra input: %s", ref.buf, next);
+       update_flags = 0;
+       free(refname);
+
+       return next;
 }
 
-static void parse_cmd_verify(const char *next)
+static const char *parse_cmd_verify(struct strbuf *input, const char *next)
 {
-       struct strbuf ref = STRBUF_INIT;
-       struct strbuf value = STRBUF_INIT;
-       struct ref_update *update;
+       char *refname;
+       unsigned char new_sha1[20];
+       unsigned char old_sha1[20];
+       int have_old;
+
+       refname = parse_refname(input, &next);
+       if (!refname)
+               die("verify: missing <ref>");
+
+       if (parse_next_sha1(input, &next, old_sha1, "verify", refname,
+                           PARSE_SHA1_OLD)) {
+               hashclr(new_sha1);
+               have_old = 0;
+       } else {
+               hashcpy(new_sha1, old_sha1);
+               have_old = 1;
+       }
 
-       update = update_alloc();
+       if (*next != line_termination)
+               die("verify %s: extra input: %s", refname, next);
 
-       if ((next = parse_first_arg(next, &ref)) != NULL && ref.buf[0])
-               update_store_ref_name(update, ref.buf);
-       else
-               die("verify line missing <ref>");
+       ref_transaction_update(transaction, refname, new_sha1, old_sha1,
+                              update_flags, have_old);
 
-       if ((next = parse_next_arg(next, &value)) != NULL) {
-               update_store_old_sha1(update, value.buf);
-               update_store_new_sha1(update, value.buf);
-       } else if(!line_termination)
-               die("verify %s missing [<oldvalue>] NUL", ref.buf);
+       update_flags = 0;
+       free(refname);
 
-       if (next && *next)
-               die("verify %s has extra input: %s", ref.buf, next);
+       return next;
 }
 
-static void parse_cmd_option(const char *next)
+static const char *parse_cmd_option(struct strbuf *input, const char *next)
 {
-       if (!strcmp(next, "no-deref"))
+       if (!strncmp(next, "no-deref", 8) && next[8] == line_termination)
                update_flags |= REF_NODEREF;
        else
                die("option unknown: %s", next);
+       return next + 8;
 }
 
 static void update_refs_stdin(void)
 {
-       struct strbuf cmd = STRBUF_INIT;
+       struct strbuf input = STRBUF_INIT;
+       const char *next;
 
+       if (strbuf_read(&input, 0, 1000) < 0)
+               die_errno("could not read from stdin");
+       next = input.buf;
        /* Read each line dispatch its command */
-       while (strbuf_getline(&cmd, stdin, line_termination) != EOF)
-               if (!cmd.buf[0])
+       while (next < input.buf + input.len) {
+               if (*next == line_termination)
                        die("empty command in input");
-               else if (isspace(*cmd.buf))
-                       die("whitespace before command: %s", cmd.buf);
-               else if (starts_with(cmd.buf, "update "))
-                       parse_cmd_update(cmd.buf + 7);
-               else if (starts_with(cmd.buf, "create "))
-                       parse_cmd_create(cmd.buf + 7);
-               else if (starts_with(cmd.buf, "delete "))
-                       parse_cmd_delete(cmd.buf + 7);
-               else if (starts_with(cmd.buf, "verify "))
-                       parse_cmd_verify(cmd.buf + 7);
-               else if (starts_with(cmd.buf, "option "))
-                       parse_cmd_option(cmd.buf + 7);
+               else if (isspace(*next))
+                       die("whitespace before command: %s", next);
+               else if (starts_with(next, "update "))
+                       next = parse_cmd_update(&input, next + 7);
+               else if (starts_with(next, "create "))
+                       next = parse_cmd_create(&input, next + 7);
+               else if (starts_with(next, "delete "))
+                       next = parse_cmd_delete(&input, next + 7);
+               else if (starts_with(next, "verify "))
+                       next = parse_cmd_verify(&input, next + 7);
+               else if (starts_with(next, "option "))
+                       next = parse_cmd_option(&input, next + 7);
                else
-                       die("unknown command: %s", cmd.buf);
+                       die("unknown command: %s", next);
+
+               next++;
+       }
 
-       strbuf_release(&cmd);
+       strbuf_release(&input);
 }
 
 int cmd_update_ref(int argc, const char **argv, const char *prefix)
@@ -268,12 +359,17 @@ int cmd_update_ref(int argc, const char **argv, const char *prefix)
                die("Refusing to perform update with empty message.");
 
        if (read_stdin) {
+               int ret;
+               transaction = ref_transaction_begin();
+
                if (delete || no_deref || argc > 0)
                        usage_with_options(git_update_ref_usage, options);
                if (end_null)
                        line_termination = '\0';
                update_refs_stdin();
-               return update_refs(msg, updates, updates_count, DIE_ON_ERR);
+               ret = ref_transaction_commit(transaction, msg,
+                                            UPDATE_REFS_DIE_ON_ERR);
+               return ret;
        }
 
        if (end_null)
@@ -305,5 +401,5 @@ int cmd_update_ref(int argc, const char **argv, const char *prefix)
                return delete_ref(refname, oldval ? oldsha1 : NULL, flags);
        else
                return update_ref(msg, refname, sha1, oldval ? oldsha1 : NULL,
-                                 flags, DIE_ON_ERR);
+                                 flags, UPDATE_REFS_DIE_ON_ERR);
 }
diff --git a/cache.h b/cache.h
index 107ac61b68f15b1e15532c09fda9e9799f830e44..62a4d39efcfa5f0cbf4257acfbbb9f8fdd5d2859 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -74,6 +74,21 @@ unsigned long git_deflate_bound(git_zstream *, unsigned long);
 #define S_IFGITLINK    0160000
 #define S_ISGITLINK(m) (((m) & S_IFMT) == S_IFGITLINK)
 
+/*
+ * Some mode bits are also used internally for computations.
+ *
+ * They *must* not overlap with any valid modes, and they *must* not be emitted
+ * to outside world - i.e. appear on disk or network. In other words, it's just
+ * temporary fields, which we internally use, but they have to stay in-house.
+ *
+ * ( such approach is valid, as standard S_IF* fits into 16 bits, and in Git
+ *   codebase mode is `unsigned int` which is assumed to be at least 32 bits )
+ */
+
+/* used internally in tree-diff */
+#define S_DIFFTREE_IFXMIN_NEQ  0x80000000
+
+
 /*
  * Intensive research over the course of many years has shown that
  * port 9418 is totally unused by anything else. Or
@@ -279,6 +294,7 @@ struct index_state {
                 initialized : 1;
        struct hashmap name_hash;
        struct hashmap dir_hash;
+       unsigned char sha1[20];
 };
 
 extern struct index_state the_index;
@@ -1045,6 +1061,13 @@ struct ident_split {
  */
 extern int split_ident_line(struct ident_split *, const char *, int);
 
+/*
+ * Like show_date, but pull the timestamp and tz parameters from
+ * the ident_split. It will also sanity-check the values and produce
+ * a well-known sentinel date if they appear bogus.
+ */
+const char *show_ident_date(const struct ident_split *id, enum date_mode mode);
+
 /*
  * Compare split idents for equality or strict ordering. Note that we
  * compare only the ident part of the line, ignoring any timestamp.
@@ -1322,6 +1345,8 @@ extern void fsync_or_die(int fd, const char *);
 
 extern ssize_t read_in_full(int fd, void *buf, size_t count);
 extern ssize_t write_in_full(int fd, const void *buf, size_t count);
+extern ssize_t pread_in_full(int fd, void *buf, size_t count, off_t offset);
+
 static inline ssize_t write_str_in_full(int fd, const char *str)
 {
        return write_in_full(fd, str, strlen(str));
index 24ca7e2334b68e06afd24051ad1aafcc129bcba4..12764fb733f3ca57f12c7fc567eec02d234c889e 100644 (file)
@@ -1301,6 +1301,81 @@ static const char *path_path(void *obj)
        return path->path;
 }
 
+
+/* find set of paths that every parent touches */
+static struct combine_diff_path *find_paths_generic(const unsigned char *sha1,
+       const struct sha1_array *parents, struct diff_options *opt)
+{
+       struct combine_diff_path *paths = NULL;
+       int i, num_parent = parents->nr;
+
+       int output_format = opt->output_format;
+       const char *orderfile = opt->orderfile;
+
+       opt->output_format = DIFF_FORMAT_NO_OUTPUT;
+       /* tell diff_tree to emit paths in sorted (=tree) order */
+       opt->orderfile = NULL;
+
+       /* D(A,P1...Pn) = D(A,P1) ^ ... ^ D(A,Pn)  (wrt paths) */
+       for (i = 0; i < num_parent; i++) {
+               /*
+                * show stat against the first parent even when doing
+                * combined diff.
+                */
+               int stat_opt = (output_format &
+                               (DIFF_FORMAT_NUMSTAT|DIFF_FORMAT_DIFFSTAT));
+               if (i == 0 && stat_opt)
+                       opt->output_format = stat_opt;
+               else
+                       opt->output_format = DIFF_FORMAT_NO_OUTPUT;
+               diff_tree_sha1(parents->sha1[i], sha1, "", opt);
+               diffcore_std(opt);
+               paths = intersect_paths(paths, i, num_parent);
+
+               /* if showing diff, show it in requested order */
+               if (opt->output_format != DIFF_FORMAT_NO_OUTPUT &&
+                   orderfile) {
+                       diffcore_order(orderfile);
+               }
+
+               diff_flush(opt);
+       }
+
+       opt->output_format = output_format;
+       opt->orderfile = orderfile;
+       return paths;
+}
+
+
+/*
+ * find set of paths that everybody touches, assuming diff is run without
+ * rename/copy detection, etc, comparing all trees simultaneously (= faster).
+ */
+static struct combine_diff_path *find_paths_multitree(
+       const unsigned char *sha1, const struct sha1_array *parents,
+       struct diff_options *opt)
+{
+       int i, nparent = parents->nr;
+       const unsigned char **parents_sha1;
+       struct combine_diff_path paths_head;
+       struct strbuf base;
+
+       parents_sha1 = xmalloc(nparent * sizeof(parents_sha1[0]));
+       for (i = 0; i < nparent; i++)
+               parents_sha1[i] = parents->sha1[i];
+
+       /* fake list head, so worker can assume it is non-NULL */
+       paths_head.next = NULL;
+
+       strbuf_init(&base, PATH_MAX);
+       diff_tree_paths(&paths_head, sha1, parents_sha1, nparent, &base, opt);
+
+       strbuf_release(&base);
+       free(parents_sha1);
+       return paths_head.next;
+}
+
+
 void diff_tree_combined(const unsigned char *sha1,
                        const struct sha1_array *parents,
                        int dense,
@@ -1308,49 +1383,82 @@ void diff_tree_combined(const unsigned char *sha1,
 {
        struct diff_options *opt = &rev->diffopt;
        struct diff_options diffopts;
-       struct combine_diff_path *p, *paths = NULL;
+       struct combine_diff_path *p, *paths;
        int i, num_paths, needsep, show_log_first, num_parent = parents->nr;
+       int need_generic_pathscan;
+
+       /* nothing to do, if no parents */
+       if (!num_parent)
+               return;
+
+       show_log_first = !!rev->loginfo && !rev->no_commit_id;
+       needsep = 0;
+       if (show_log_first) {
+               show_log(rev);
+
+               if (rev->verbose_header && opt->output_format)
+                       printf("%s%c", diff_line_prefix(opt),
+                              opt->line_termination);
+       }
 
        diffopts = *opt;
        copy_pathspec(&diffopts.pathspec, &opt->pathspec);
-       diffopts.output_format = DIFF_FORMAT_NO_OUTPUT;
        DIFF_OPT_SET(&diffopts, RECURSIVE);
        DIFF_OPT_CLR(&diffopts, ALLOW_EXTERNAL);
-       /* tell diff_tree to emit paths in sorted (=tree) order */
-       diffopts.orderfile = NULL;
 
-       show_log_first = !!rev->loginfo && !rev->no_commit_id;
-       needsep = 0;
-       /* find set of paths that everybody touches */
-       for (i = 0; i < num_parent; i++) {
-               /* show stat against the first parent even
+       /* find set of paths that everybody touches
+        *
+        * NOTE
+        *
+        * Diffcore transformations are bound to diff_filespec and logic
+        * comparing two entries - i.e. they do not apply directly to combine
+        * diff.
+        *
+        * If some of such transformations is requested - we launch generic
+        * path scanning, which works significantly slower compared to
+        * simultaneous all-trees-in-one-go scan in find_paths_multitree().
+        *
+        * TODO some of the filters could be ported to work on
+        * combine_diff_paths - i.e. all functionality that skips paths, so in
+        * theory, we could end up having only multitree path scanning.
+        *
+        * NOTE please keep this semantically in sync with diffcore_std()
+        */
+       need_generic_pathscan = opt->skip_stat_unmatch  ||
+                       DIFF_OPT_TST(opt, FOLLOW_RENAMES)       ||
+                       opt->break_opt != -1    ||
+                       opt->detect_rename      ||
+                       opt->pickaxe            ||
+                       opt->filter;
+
+
+       if (need_generic_pathscan) {
+               /*
+                * NOTE generic case also handles --stat, as it computes
+                * diff(sha1,parent_i) for all i to do the job, specifically
+                * for parent0.
+                */
+               paths = find_paths_generic(sha1, parents, &diffopts);
+       }
+       else {
+               int stat_opt;
+               paths = find_paths_multitree(sha1, parents, &diffopts);
+
+               /*
+                * show stat against the first parent even
                 * when doing combined diff.
                 */
-               int stat_opt = (opt->output_format &
+               stat_opt = (opt->output_format &
                                (DIFF_FORMAT_NUMSTAT|DIFF_FORMAT_DIFFSTAT));
-               if (i == 0 && stat_opt)
+               if (stat_opt) {
                        diffopts.output_format = stat_opt;
-               else
-                       diffopts.output_format = DIFF_FORMAT_NO_OUTPUT;
-               diff_tree_sha1(parents->sha1[i], sha1, "", &diffopts);
-               diffcore_std(&diffopts);
-               paths = intersect_paths(paths, i, num_parent);
 
-               if (show_log_first && i == 0) {
-                       show_log(rev);
-
-                       if (rev->verbose_header && opt->output_format)
-                               printf("%s%c", diff_line_prefix(opt),
-                                      opt->line_termination);
+                       diff_tree_sha1(parents->sha1[0], sha1, "", &diffopts);
+                       diffcore_std(&diffopts);
+                       if (opt->orderfile)
+                               diffcore_order(opt->orderfile);
+                       diff_flush(&diffopts);
                }
-
-               /* if showing diff, show it in requested order */
-               if (diffopts.output_format != DIFF_FORMAT_NO_OUTPUT &&
-                   opt->orderfile) {
-                       diffcore_order(opt->orderfile);
-               }
-
-               diff_flush(&diffopts);
        }
 
        /* find out number of surviving paths */
index c9d46d174259f42a3e2a2eb073475aba517044be..7f662fef7bcb408045eb1536afed058a607ae97b 100644 (file)
@@ -14,7 +14,7 @@ void *git_mmap(void *start, size_t length, int prot, int flags, int fd, off_t of
        }
 
        while (n < length) {
-               ssize_t count = pread(fd, (char *)start + n, length - n, offset + n);
+               ssize_t count = xpread(fd, (char *)start + n, length - n, offset + n);
 
                if (count == 0) {
                        memset((char *)start+n, 0, length-n);
@@ -22,8 +22,6 @@ void *git_mmap(void *start, size_t length, int prot, int flags, int fd, off_t of
                }
 
                if (count < 0) {
-                       if (errno == EAGAIN || errno == EINTR)
-                               continue;
                        free(start);
                        errno = EACCES;
                        return MAP_FAILED;
index 31163f2ae7b71857889f561dea0b3ffecff61989..a9b41d89f465208b6f0e417672077403bf30898f 100644 (file)
@@ -605,7 +605,7 @@ restart:
 
   if (!rc && timeout == INFTIM)
     {
-      SwitchToThread();
+      SleepEx (1, TRUE);
       goto restart;
     }
 
index a30cb5c07db18a5ac16c1c98b6600c9fe6dc1b73..c227aa85177724354b3c9740ec62ea2ce521ac62 100644 (file)
--- a/config.c
+++ b/config.c
@@ -1636,6 +1636,13 @@ int git_config_set_multivar_in_file(const char *config_filename,
                        MAP_PRIVATE, in_fd, 0);
                close(in_fd);
 
+               if (fchmod(fd, st.st_mode & 07777) < 0) {
+                       error("fchmod on %s failed: %s",
+                               lock->filename, strerror(errno));
+                       ret = CONFIG_NO_WRITE;
+                       goto out_free;
+               }
+
                if (store.seen == 0)
                        store.seen = 1;
 
@@ -1784,6 +1791,7 @@ int git_config_rename_section_in_file(const char *config_filename,
        int out_fd;
        char buf[1024];
        FILE *config_file;
+       struct stat st;
 
        if (new_name && !section_name_is_ok(new_name)) {
                ret = error("invalid section name: %s", new_name);
@@ -1805,6 +1813,14 @@ int git_config_rename_section_in_file(const char *config_filename,
                goto unlock_and_out;
        }
 
+       fstat(fileno(config_file), &st);
+
+       if (fchmod(out_fd, st.st_mode & 07777) < 0) {
+               ret = error("fchmod on %s failed: %s",
+                               lock->filename, strerror(errno));
+               goto out;
+       }
+
        while (fgets(buf, sizeof(buf), config_file)) {
                int i;
                int length;
index 23a880365616c34ea84d8a3194b98163864a2cd1..1ae675b05344912d8798b9856b60b03c282cf908 100644 (file)
@@ -28,6 +28,7 @@ ifeq ($(uname_S),OSF1)
        NO_NSEC = YesPlease
 endif
 ifeq ($(uname_S),Linux)
+       HAVE_ALLOCA_H = YesPlease
        NO_STRLCPY = YesPlease
        NO_MKSTEMPS = YesPlease
        HAVE_PATHS_H = YesPlease
@@ -35,6 +36,7 @@ ifeq ($(uname_S),Linux)
        HAVE_DEV_TTY = YesPlease
 endif
 ifeq ($(uname_S),GNU/kFreeBSD)
+       HAVE_ALLOCA_H = YesPlease
        NO_STRLCPY = YesPlease
        NO_MKSTEMPS = YesPlease
        HAVE_PATHS_H = YesPlease
@@ -103,6 +105,7 @@ ifeq ($(uname_S),SunOS)
        NEEDS_NSL = YesPlease
        SHELL_PATH = /bin/bash
        SANE_TOOL_PATH = /usr/xpg6/bin:/usr/xpg4/bin
+       HAVE_ALLOCA_H = YesPlease
        NO_STRCASESTR = YesPlease
        NO_MEMMEM = YesPlease
        NO_MKDTEMP = YesPlease
@@ -145,7 +148,7 @@ ifeq ($(uname_S),SunOS)
        endif
        INSTALL = /usr/ucb/install
        TAR = gtar
-       BASIC_CFLAGS += -D__EXTENSIONS__ -D__sun__ -DHAVE_ALLOCA_H
+       BASIC_CFLAGS += -D__EXTENSIONS__ -D__sun__
 endif
 ifeq ($(uname_O),Cygwin)
        ifeq ($(shell expr "$(uname_R)" : '1\.[1-6]\.'),4)
@@ -157,7 +160,6 @@ ifeq ($(uname_O),Cygwin)
                NO_SYMLINK_HEAD = YesPlease
                NO_IPV6 = YesPlease
                OLD_ICONV = UnfortunatelyYes
-               NO_THREAD_SAFE_PREAD = YesPlease
                # There are conflicting reports about this.
                # On some boxes NO_MMAP is needed, and not so elsewhere.
                # Try commenting this out if you suspect MMAP is more efficient
@@ -165,6 +167,7 @@ ifeq ($(uname_O),Cygwin)
        else
                NO_REGEX = UnfortunatelyYes
        endif
+       HAVE_ALLOCA_H = YesPlease
        NEEDS_LIBICONV = YesPlease
        NO_FAST_WORKING_DIRECTORY = UnfortunatelyYes
        NO_ST_BLOCKS_IN_STRUCT_STAT = YesPlease
@@ -239,6 +242,7 @@ ifeq ($(uname_S),AIX)
 endif
 ifeq ($(uname_S),GNU)
        # GNU/Hurd
+       HAVE_ALLOCA_H = YesPlease
        NO_STRLCPY = YesPlease
        NO_MKSTEMPS = YesPlease
        HAVE_PATHS_H = YesPlease
@@ -313,6 +317,7 @@ endif
 ifeq ($(uname_S),Windows)
        GIT_VERSION := $(GIT_VERSION).MSVC
        pathsep = ;
+       HAVE_ALLOCA_H = YesPlease
        NO_PREAD = YesPlease
        NEEDS_CRYPTO_WITH_SSL = YesPlease
        NO_LIBGEN_H = YesPlease
@@ -357,17 +362,17 @@ ifeq ($(uname_S),Windows)
        COMPAT_OBJS = compat/msvc.o compat/winansi.o \
                compat/win32/pthread.o compat/win32/syslog.o \
                compat/win32/dirent.o
-       COMPAT_CFLAGS = -D__USE_MINGW_ACCESS -DNOGDI -DHAVE_STRING_H -DHAVE_ALLOCA_H -Icompat -Icompat/regex -Icompat/win32 -DSTRIP_EXTENSION=\".exe\"
-       BASIC_LDFLAGS = -IGNORE:4217 -IGNORE:4049 -NOLOGO -SUBSYSTEM:CONSOLE -NODEFAULTLIB:MSVCRT.lib
+       COMPAT_CFLAGS = -D__USE_MINGW_ACCESS -DNOGDI -DHAVE_STRING_H -Icompat -Icompat/regex -Icompat/win32 -DSTRIP_EXTENSION=\".exe\"
+       BASIC_LDFLAGS = -IGNORE:4217 -IGNORE:4049 -NOLOGO -SUBSYSTEM:CONSOLE
        EXTLIBS = user32.lib advapi32.lib shell32.lib wininet.lib ws2_32.lib invalidcontinue.obj
        PTHREAD_LIBS =
        lib =
 ifndef DEBUG
-       BASIC_CFLAGS += -GL -Os -MT
+       BASIC_CFLAGS += -GL -Os -MD
        BASIC_LDFLAGS += -LTCG
        AR += -LTCG
 else
-       BASIC_CFLAGS += -Zi -MTd
+       BASIC_CFLAGS += -Zi -MDd
 endif
        X = .exe
 endif
@@ -465,6 +470,7 @@ ifeq ($(uname_S),NONSTOP_KERNEL)
 endif
 ifneq (,$(findstring MINGW,$(uname_S)))
        pathsep = ;
+       HAVE_ALLOCA_H = YesPlease
        NO_PREAD = YesPlease
        NEEDS_CRYPTO_WITH_SSL = YesPlease
        NO_LIBGEN_H = YesPlease
index b7112542b4b62fbbf0235c923f75803edc149e5c..4b1ae7c3c9f5ff5080dc026a6eb835d579d29949 100644 (file)
@@ -272,6 +272,14 @@ AS_HELP_STRING([],           [ARG can be also prefix for libpcre library and hea
        GIT_CONF_SUBST([LIBPCREDIR])
     fi)
 #
+# Define HAVE_ALLOCA_H if you have working alloca(3) defined in that header.
+AC_FUNC_ALLOCA
+case $ac_cv_working_alloca_h in
+    yes)    HAVE_ALLOCA_H=YesPlease;;
+    *)      HAVE_ALLOCA_H='';;
+esac
+GIT_CONF_SUBST([HAVE_ALLOCA_H])
+#
 # Define NO_CURL if you do not have curl installed.  git-http-pull and
 # git-http-push are not built, and you cannot use http:// and https://
 # transports.
index 96b8087385ee77dfb7e39fbc91d82af1c2e73714..9d684b10a67ea663410db3ba68482c1a52bbc367 100644 (file)
@@ -209,9 +209,7 @@ __git_ps1_show_upstream ()
                if [[ -n "$count" && -n "$name" ]]; then
                        __git_ps1_upstream_name=$(git rev-parse \
                                --abbrev-ref "$upstream" 2>/dev/null)
-                       if [ $pcmode = yes ]; then
-                               # see the comments around the
-                               # __git_ps1_branch_name variable below
+                       if [ $pcmode = yes ] && [ $ps1_expanded = yes ]; then
                                p="$p \${__git_ps1_upstream_name}"
                        else
                                p="$p ${__git_ps1_upstream_name}"
@@ -270,7 +268,7 @@ __git_ps1_colorize_gitstring ()
        r="$c_clear$r"
 }
 
-eread ()
+__git_eread ()
 {
        f="$1"
        shift
@@ -308,6 +306,43 @@ __git_ps1 ()
                ;;
        esac
 
+       # ps1_expanded:  This variable is set to 'yes' if the shell
+       # subjects the value of PS1 to parameter expansion:
+       #
+       #   * bash does unless the promptvars option is disabled
+       #   * zsh does not unless the PROMPT_SUBST option is set
+       #   * POSIX shells always do
+       #
+       # If the shell would expand the contents of PS1 when drawing
+       # the prompt, a raw ref name must not be included in PS1.
+       # This protects the user from arbitrary code execution via
+       # specially crafted ref names.  For example, a ref named
+       # 'refs/heads/$(IFS=_;cmd=sudo_rm_-rf_/;$cmd)' might cause the
+       # shell to execute 'sudo rm -rf /' when the prompt is drawn.
+       #
+       # Instead, the ref name should be placed in a separate global
+       # variable (in the __git_ps1_* namespace to avoid colliding
+       # with the user's environment) and that variable should be
+       # referenced from PS1.  For example:
+       #
+       #     __git_ps1_foo=$(do_something_to_get_ref_name)
+       #     PS1="...stuff...\${__git_ps1_foo}...stuff..."
+       #
+       # If the shell does not expand the contents of PS1, the raw
+       # ref name must be included in PS1.
+       #
+       # The value of this variable is only relevant when in pcmode.
+       #
+       # Assume that the shell follows the POSIX specification and
+       # expands PS1 unless determined otherwise.  (This is more
+       # likely to be correct if the user has a non-bash, non-zsh
+       # shell and safer than the alternative if the assumption is
+       # incorrect.)
+       #
+       local ps1_expanded=yes
+       [ -z "$ZSH_VERSION" ] || [[ -o PROMPT_SUBST ]] || ps1_expanded=no
+       [ -z "$BASH_VERSION" ] || shopt -q promptvars || ps1_expanded=no
+
        local repo_info rev_parse_exit_code
        repo_info="$(git rev-parse --git-dir --is-inside-git-dir \
                --is-bare-repository --is-inside-work-tree \
@@ -339,9 +374,9 @@ __git_ps1 ()
        local step=""
        local total=""
        if [ -d "$g/rebase-merge" ]; then
-               eread "$g/rebase-merge/head-name" b
-               eread "$g/rebase-merge/msgnum" step
-               eread "$g/rebase-merge/end" total
+               __git_eread "$g/rebase-merge/head-name" b
+               __git_eread "$g/rebase-merge/msgnum" step
+               __git_eread "$g/rebase-merge/end" total
                if [ -f "$g/rebase-merge/interactive" ]; then
                        r="|REBASE-i"
                else
@@ -349,10 +384,10 @@ __git_ps1 ()
                fi
        else
                if [ -d "$g/rebase-apply" ]; then
-                       eread "$g/rebase-apply/next" step
-                       eread "$g/rebase-apply/last" total
+                       __git_eread "$g/rebase-apply/next" step
+                       __git_eread "$g/rebase-apply/last" total
                        if [ -f "$g/rebase-apply/rebasing" ]; then
-                               eread "$g/rebase-apply/head-name" b
+                               __git_eread "$g/rebase-apply/head-name" b
                                r="|REBASE"
                        elif [ -f "$g/rebase-apply/applying" ]; then
                                r="|AM"
@@ -376,7 +411,7 @@ __git_ps1 ()
                        b="$(git symbolic-ref HEAD 2>/dev/null)"
                else
                        local head=""
-                       if ! eread "$g/HEAD" head; then
+                       if ! __git_eread "$g/HEAD" head; then
                                if [ $pcmode = yes ]; then
                                        PS1="$ps1pc_start$ps1pc_end"
                                fi
@@ -457,21 +492,8 @@ __git_ps1 ()
        fi
 
        b=${b##refs/heads/}
-       if [ $pcmode = yes ]; then
-               # In pcmode (and only pcmode) the contents of
-               # $gitstring are subject to expansion by the shell.
-               # Avoid putting the raw ref name in the prompt to
-               # protect the user from arbitrary code execution via
-               # specially crafted ref names (e.g., a ref named
-               # '$(IFS=_;cmd=sudo_rm_-rf_/;$cmd)' would execute
-               # 'sudo rm -rf /' when the prompt is drawn).  Instead,
-               # put the ref name in a new global variable (in the
-               # __git_ps1_* namespace to avoid colliding with the
-               # user's environment) and reference that variable from
-               # PS1.
+       if [ $pcmode = yes ] && [ $ps1_expanded = yes ]; then
                __git_ps1_branch_name=$b
-               # note that the $ is escaped -- the variable will be
-               # expanded later (when it's time to draw the prompt)
                b="\${__git_ps1_branch_name}"
        fi
 
index 8bc8c7533a8678e2a43d3ddd49bc9aa8d670897d..ee1916641e46c1adfaac31e27c78c11b023d6ffa 100644 (file)
@@ -31,7 +31,8 @@ static int update_ref_env(const char *action,
                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, QUIET_ON_ERR);
+       return update_ref(msg, refname, sha1, oldval, 0,
+                         UPDATE_REFS_QUIET_ON_ERR);
 }
 
 static int update_local_ref(const char *name,
index 3f8d993afaca53024aa75b4118da9ee80e6a6313..8dd74a9a406e9cfd685ea1af3947e4bea4c82f90 100755 (executable)
@@ -461,7 +461,12 @@ sub download_mw_mediafile {
 
        my $response = $mediawiki->{ua}->get($download_url);
        if ($response->code == HTTP_CODE_OK) {
-               return $response->decoded_content;
+               # It is tempting to return
+               # $response->decoded_content({charset => "none"}), but
+               # when doing so, utf8::downgrade($content) fails with
+               # "Wide character in subroutine entry".
+               $response->decode();
+               return $response->content();
        } else {
                print {*STDERR} "Error downloading mediafile from :\n";
                print {*STDERR} "URL: ${download_url}\n";
index 70a53f67fd06bd2ce6f2f544655b03b99c6b2ee9..c215213c4bfddb583fb3de0eb624e0cffdb8cc7c 100755 (executable)
@@ -20,6 +20,8 @@ usage () {
        echo "          install | -i :  Install a wiki on your computer."
        echo "          delete | -d : Delete the wiki and all its pages and "
        echo "                  content."
+       echo "          start  | -s : Start the previously configured lighttpd daemon"
+       echo "          stop        : Stop lighttpd daemon."
 }
 
 
@@ -33,6 +35,14 @@ case "$1" in
                wiki_delete
                exit 0
                ;;
+       "start" | "-s")
+               start_lighttpd
+               exit
+               ;;
+       "stop")
+               stop_lighttpd
+               exit
+               ;;
        "--help" | "-h")
                usage
                exit 0
index 5a0373935f1f4b66c4521158e4b3c41508c908ea..3ff3a095670ecdf578dc9f4d51841c102c5a10fd 100755 (executable)
@@ -58,6 +58,25 @@ test_expect_success 'git clone works on previously created wiki with media files
        test_cmp mw_dir_clone/Foo.txt mw_dir/Foo.txt
 '
 
+test_expect_success 'git push can upload media (File:) files containing valid UTF-8' '
+       wiki_reset &&
+       git clone mediawiki::'"$WIKI_URL"' mw_dir &&
+       (
+               cd mw_dir &&
+               "$PERL_PATH" -e "print STDOUT \"UTF-8 content: éèàéê€.\";" >Bar.txt &&
+               git add Bar.txt &&
+               git commit -m "add a text file with UTF-8 content" &&
+               git push
+       )
+'
+
+test_expect_success 'git clone works on previously created wiki with media files containing valid UTF-8' '
+       test_when_finished "rm -rf mw_dir mw_dir_clone" &&
+       git clone -c remote.origin.mediaimport=true \
+               mediawiki::'"$WIKI_URL"' mw_dir_clone &&
+       test_cmp mw_dir_clone/Bar.txt mw_dir/Bar.txt
+'
+
 test_expect_success 'git push & pull work with locally renamed media files' '
        wiki_reset &&
        git clone mediawiki::'"$WIKI_URL"' mw_dir &&
index 27e267f532974914d1b214920bcfb8e2d4e3de6c..016454749f8dfa8539c7af1ca7fe4338414ab661 100755 (executable)
@@ -9,7 +9,7 @@ test_check_precond
 
 test_expect_success 'creating page w/ >500 revisions' '
        wiki_reset &&
-       for i in `test_seq 501`
+       for i in $(test_seq 501)
        do
                echo "creating revision $i" &&
                wiki_editpage foo "revision $i<br/>" true
index 3372b2af346ac23a73a7723ac6d0c81fb8c5e705..6546294f159e940eb8f7adc3e695f16d9395eebc 100755 (executable)
@@ -90,7 +90,7 @@ test_diff_directories () {
 #
 # Check that <dir> contains exactly <N> files
 test_contains_N_files () {
-       if test `ls -- "$1" | wc -l` -ne "$2"; then
+       if test $(ls -- "$1" | wc -l) -ne "$2"; then
                echo "directory $1 should contain $2 files"
                echo "it contains these files:"
                ls "$1"
@@ -289,7 +289,6 @@ start_lighttpd () {
 # Kill daemon lighttpd and removes files and folders associated.
 stop_lighttpd () {
        test -f "$WEB_TMP/pid" && kill $(cat "$WEB_TMP/pid")
-       rm -rf "$WEB"
 }
 
 # Create the SQLite database of the MediaWiki. If the database file already
@@ -341,10 +340,10 @@ wiki_install () {
                        "http://download.wikimedia.org/mediawiki/$MW_VERSION_MAJOR/"\
                        "$MW_FILENAME. "\
                        "Please fix your connection and launch the script again."
-               echo "$MW_FILENAME downloaded in `pwd`. "\
+               echo "$MW_FILENAME downloaded in $(pwd). "\
                        "You can delete it later if you want."
        else
-               echo "Reusing existing $MW_FILENAME downloaded in `pwd`."
+               echo "Reusing existing $MW_FILENAME downloaded in $(pwd)."
        fi
        archive_abs_path=$(pwd)/$MW_FILENAME
        cd "$WIKI_DIR_INST/$WIKI_DIR_NAME/" ||
@@ -415,6 +414,7 @@ wiki_reset () {
 wiki_delete () {
        if test $LIGHTTPD = "true"; then
                stop_lighttpd
+               rm -fr "$WEB"
        else
                # Delete the wiki's directory.
                rm -rf "$WIKI_DIR_INST/$WIKI_DIR_NAME" ||
diff --git a/contrib/remote-helpers/Makefile b/contrib/remote-helpers/Makefile
deleted file mode 100644 (file)
index 239161d..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-TESTS := $(wildcard test*.sh)
-
-export T := $(addprefix $(CURDIR)/,$(TESTS))
-export MAKE := $(MAKE) -e
-export PATH := $(CURDIR):$(PATH)
-export TEST_LINT := test-lint-executable test-lint-shell-syntax
-
-test:
-       $(MAKE) -C ../../t $@
-
-$(TESTS):
-       $(MAKE) -C ../../t $(CURDIR)/$@
-
-.PHONY: $(TESTS)
diff --git a/contrib/remote-helpers/README b/contrib/remote-helpers/README
new file mode 100644 (file)
index 0000000..ac72332
--- /dev/null
@@ -0,0 +1,15 @@
+The remote-helper bridges to access data stored in Mercurial and
+Bazaar are maintained outside the git.git tree in the repositories
+of their primary author:
+
+    https://github.com/felipec/git-remote-hg (for Mercurial)
+    https://github.com/felipec/git-remote-bzr (for Bazaar)
+
+You can pick a directory on your $PATH and download them from these
+repositories, e.g.:
+
+  $ wget -O $HOME/bin/git-remote-hg \
+    https://raw.github.com/felipec/git-remote-hg/master/git-remote-hg
+  $ wget -O $HOME/bin/git-remote-bzr \
+    https://raw.github.com/felipec/git-remote-bzr/master/git-remote-bzr
+  $ chmod +x $HOME/bin/git-remote-hg $HOME/bin/git-remote-bzr
index 9abb58e6ab45077bf9b5e01658438817ea9b7126..712a1377e208f717b61df44f0b5ea0ba99dc72d1 100755 (executable)
 #!/usr/bin/env python
-#
-# Copyright (c) 2012 Felipe Contreras
-#
-
-#
-# Just copy to your ~/bin, or anywhere in your $PATH.
-# Then you can clone with:
-# % git clone bzr::/path/to/bzr/repo/or/url
-#
-# For example:
-# % git clone bzr::$HOME/myrepo
-# or
-# % git clone bzr::lp:myrepo
-#
-# If you want to specify which branches you want to track (per repo):
-# % git config remote.origin.bzr-branches 'trunk, devel, test'
-#
-# Where 'origin' is the name of the repository you want to specify the
-# branches.
-#
-
-import sys
-
-import bzrlib
-if hasattr(bzrlib, "initialize"):
-    bzrlib.initialize()
-
-import bzrlib.plugin
-bzrlib.plugin.load_plugins()
-
-import bzrlib.generate_ids
-import bzrlib.transport
-import bzrlib.errors
-import bzrlib.ui
-import bzrlib.urlutils
-import bzrlib.branch
 
 import sys
-import os
-import json
-import re
-import StringIO
-import atexit, shutil, hashlib, urlparse, subprocess
-
-NAME_RE = re.compile('^([^<>]+)')
-AUTHOR_RE = re.compile('^([^<>]+?)? ?[<>]([^<>]*)(?:$|>)')
-EMAIL_RE = re.compile(r'([^ \t<>]+@[^ \t<>]+)')
-RAW_AUTHOR_RE = re.compile('^(\w+) (.+)? <(.*)> (\d+) ([+-]\d+)')
-
-def die(msg, *args):
-    sys.stderr.write('ERROR: %s\n' % (msg % args))
-    sys.exit(1)
-
-def warn(msg, *args):
-    sys.stderr.write('WARNING: %s\n' % (msg % args))
-
-def gittz(tz):
-    return '%+03d%02d' % (tz / 3600, tz % 3600 / 60)
-
-def get_config(config):
-    cmd = ['git', 'config', '--get', config]
-    process = subprocess.Popen(cmd, stdout=subprocess.PIPE)
-    output, _ = process.communicate()
-    return output
-
-class Marks:
-
-    def __init__(self, path):
-        self.path = path
-        self.tips = {}
-        self.marks = {}
-        self.rev_marks = {}
-        self.last_mark = 0
-        self.load()
-
-    def load(self):
-        if not os.path.exists(self.path):
-            return
-
-        tmp = json.load(open(self.path))
-        self.tips = tmp['tips']
-        self.marks = tmp['marks']
-        self.last_mark = tmp['last-mark']
-
-        for rev, mark in self.marks.iteritems():
-            self.rev_marks[mark] = rev
-
-    def dict(self):
-        return { 'tips': self.tips, 'marks': self.marks, 'last-mark' : self.last_mark }
-
-    def store(self):
-        json.dump(self.dict(), open(self.path, 'w'))
-
-    def __str__(self):
-        return str(self.dict())
-
-    def from_rev(self, rev):
-        return self.marks[rev]
-
-    def to_rev(self, mark):
-        return str(self.rev_marks[mark])
-
-    def next_mark(self):
-        self.last_mark += 1
-        return self.last_mark
-
-    def get_mark(self, rev):
-        self.last_mark += 1
-        self.marks[rev] = self.last_mark
-        return self.last_mark
-
-    def is_marked(self, rev):
-        return rev in self.marks
-
-    def new_mark(self, rev, mark):
-        self.marks[rev] = mark
-        self.rev_marks[mark] = rev
-        self.last_mark = mark
-
-    def get_tip(self, branch):
-        try:
-            return str(self.tips[branch])
-        except KeyError:
-            return None
-
-    def set_tip(self, branch, tip):
-        self.tips[branch] = tip
-
-class Parser:
-
-    def __init__(self, repo):
-        self.repo = repo
-        self.line = self.get_line()
-
-    def get_line(self):
-        return sys.stdin.readline().strip()
-
-    def __getitem__(self, i):
-        return self.line.split()[i]
-
-    def check(self, word):
-        return self.line.startswith(word)
-
-    def each_block(self, separator):
-        while self.line != separator:
-            yield self.line
-            self.line = self.get_line()
-
-    def __iter__(self):
-        return self.each_block('')
-
-    def next(self):
-        self.line = self.get_line()
-        if self.line == 'done':
-            self.line = None
-
-    def get_mark(self):
-        i = self.line.index(':') + 1
-        return int(self.line[i:])
-
-    def get_data(self):
-        if not self.check('data'):
-            return None
-        i = self.line.index(' ') + 1
-        size = int(self.line[i:])
-        return sys.stdin.read(size)
-
-    def get_author(self):
-        m = RAW_AUTHOR_RE.match(self.line)
-        if not m:
-            return None
-        _, name, email, date, tz = m.groups()
-        name = name.decode('utf-8')
-        committer = '%s <%s>' % (name, email)
-        tz = int(tz)
-        tz = ((tz / 100) * 3600) + ((tz % 100) * 60)
-        return (committer, int(date), tz)
-
-def rev_to_mark(rev):
-    return marks.from_rev(rev)
-
-def mark_to_rev(mark):
-    return marks.to_rev(mark)
-
-def fixup_user(user):
-    name = mail = None
-    user = user.replace('"', '')
-    m = AUTHOR_RE.match(user)
-    if m:
-        name = m.group(1)
-        mail = m.group(2).strip()
-    else:
-        m = EMAIL_RE.match(user)
-        if m:
-            mail = m.group(1)
-        else:
-            m = NAME_RE.match(user)
-            if m:
-                name = m.group(1).strip()
-
-    if not name:
-        name = 'unknown'
-    if not mail:
-        mail = 'Unknown'
-
-    return '%s <%s>' % (name, mail)
-
-def get_filechanges(cur, prev):
-    modified = {}
-    removed = {}
-
-    changes = cur.changes_from(prev)
-
-    def u(s):
-        return s.encode('utf-8')
-
-    for path, fid, kind in changes.added:
-        modified[u(path)] = fid
-    for path, fid, kind in changes.removed:
-        removed[u(path)] = None
-    for path, fid, kind, mod, _ in changes.modified:
-        modified[u(path)] = fid
-    for oldpath, newpath, fid, kind, mod, _ in changes.renamed:
-        removed[u(oldpath)] = None
-        if kind == 'directory':
-            lst = cur.list_files(from_dir=newpath, recursive=True)
-            for path, file_class, kind, fid, entry in lst:
-                if kind != 'directory':
-                    modified[u(newpath + '/' + path)] = fid
-        else:
-            modified[u(newpath)] = fid
-
-    return modified, removed
-
-def export_files(tree, files):
-    final = []
-    for path, fid in files.iteritems():
-        kind = tree.kind(fid)
-
-        h = tree.get_file_sha1(fid)
-
-        if kind == 'symlink':
-            d = tree.get_symlink_target(fid)
-            mode = '120000'
-        elif kind == 'file':
-
-            if tree.is_executable(fid):
-                mode = '100755'
-            else:
-                mode = '100644'
-
-            # is the blob already exported?
-            if h in filenodes:
-                mark = filenodes[h]
-                final.append((mode, mark, path))
-                continue
-
-            d = tree.get_file_text(fid)
-        elif kind == 'directory':
-            continue
-        else:
-            die("Unhandled kind '%s' for path '%s'" % (kind, path))
-
-        mark = marks.next_mark()
-        filenodes[h] = mark
-
-        print "blob"
-        print "mark :%u" % mark
-        print "data %d" % len(d)
-        print d
-
-        final.append((mode, mark, path))
-
-    return final
-
-def export_branch(repo, name):
-    ref = '%s/heads/%s' % (prefix, name)
-    tip = marks.get_tip(name)
-
-    branch = get_remote_branch(name)
-    repo = branch.repository
-
-    branch.lock_read()
-    revs = branch.iter_merge_sorted_revisions(None, tip, 'exclude', 'forward')
-    try:
-        tip_revno = branch.revision_id_to_revno(tip)
-        last_revno, _ = branch.last_revision_info()
-        total = last_revno - tip_revno
-    except bzrlib.errors.NoSuchRevision:
-        tip_revno = 0
-        total = 0
-
-    for revid, _, seq, _ in revs:
-
-        if marks.is_marked(revid):
-            continue
-
-        rev = repo.get_revision(revid)
-        revno = seq[0]
-
-        parents = rev.parent_ids
-        time = rev.timestamp
-        tz = rev.timezone
-        committer = rev.committer.encode('utf-8')
-        committer = "%s %u %s" % (fixup_user(committer), time, gittz(tz))
-        authors = rev.get_apparent_authors()
-        if authors:
-            author = authors[0].encode('utf-8')
-            author = "%s %u %s" % (fixup_user(author), time, gittz(tz))
-        else:
-            author = committer
-        msg = rev.message.encode('utf-8')
-
-        msg += '\n'
-
-        if len(parents) == 0:
-            parent = bzrlib.revision.NULL_REVISION
-        else:
-            parent = parents[0]
-
-        cur_tree = repo.revision_tree(revid)
-        prev = repo.revision_tree(parent)
-        modified, removed = get_filechanges(cur_tree, prev)
-
-        modified_final = export_files(cur_tree, modified)
-
-        if len(parents) == 0:
-            print 'reset %s' % ref
-
-        print "commit %s" % ref
-        print "mark :%d" % (marks.get_mark(revid))
-        print "author %s" % (author)
-        print "committer %s" % (committer)
-        print "data %d" % (len(msg))
-        print msg
-
-        for i, p in enumerate(parents):
-            try:
-                m = rev_to_mark(p)
-            except KeyError:
-                # ghost?
-                continue
-            if i == 0:
-                print "from :%s" % m
-            else:
-                print "merge :%s" % m
-
-        for f in removed:
-            print "D %s" % (f,)
-        for f in modified_final:
-            print "M %s :%u %s" % f
-        print
-
-        if len(seq) > 1:
-            # let's skip branch revisions from the progress report
-            continue
-
-        progress = (revno - tip_revno)
-        if (progress % 100 == 0):
-            if total:
-                print "progress revision %d '%s' (%d/%d)" % (revno, name, progress, total)
-            else:
-                print "progress revision %d '%s' (%d)" % (revno, name, progress)
-
-    branch.unlock()
-
-    revid = branch.last_revision()
-
-    # make sure the ref is updated
-    print "reset %s" % ref
-    print "from :%u" % rev_to_mark(revid)
-    print
-
-    marks.set_tip(name, revid)
-
-def export_tag(repo, name):
-    ref = '%s/tags/%s' % (prefix, name)
-    print "reset %s" % ref
-    print "from :%u" % rev_to_mark(tags[name])
-    print
-
-def do_import(parser):
-    repo = parser.repo
-    path = os.path.join(dirname, 'marks-git')
-
-    print "feature done"
-    if os.path.exists(path):
-        print "feature import-marks=%s" % path
-    print "feature export-marks=%s" % path
-    print "feature force"
-    sys.stdout.flush()
-
-    while parser.check('import'):
-        ref = parser[1]
-        if ref.startswith('refs/heads/'):
-            name = ref[len('refs/heads/'):]
-            export_branch(repo, name)
-        if ref.startswith('refs/tags/'):
-            name = ref[len('refs/tags/'):]
-            export_tag(repo, name)
-        parser.next()
-
-    print 'done'
-
-    sys.stdout.flush()
-
-def parse_blob(parser):
-    parser.next()
-    mark = parser.get_mark()
-    parser.next()
-    data = parser.get_data()
-    blob_marks[mark] = data
-    parser.next()
-
-class CustomTree():
-
-    def __init__(self, branch, revid, parents, files):
-        self.updates = {}
-        self.branch = branch
-
-        def copy_tree(revid):
-            files = files_cache[revid] = {}
-            branch.lock_read()
-            tree = branch.repository.revision_tree(revid)
-            try:
-                for path, entry in tree.iter_entries_by_dir():
-                    files[path] = [entry.file_id, None]
-            finally:
-                branch.unlock()
-            return files
-
-        if len(parents) == 0:
-            self.base_id = bzrlib.revision.NULL_REVISION
-            self.base_files = {}
-        else:
-            self.base_id = parents[0]
-            self.base_files = files_cache.get(self.base_id, None)
-            if not self.base_files:
-                self.base_files = copy_tree(self.base_id)
-
-        self.files = files_cache[revid] = self.base_files.copy()
-        self.rev_files = {}
-
-        for path, data in self.files.iteritems():
-            fid, mark = data
-            self.rev_files[fid] = [path, mark]
-
-        for path, f in files.iteritems():
-            fid, mark = self.files.get(path, [None, None])
-            if not fid:
-                fid = bzrlib.generate_ids.gen_file_id(path)
-            f['path'] = path
-            self.rev_files[fid] = [path, mark]
-            self.updates[fid] = f
-
-    def last_revision(self):
-        return self.base_id
-
-    def iter_changes(self):
-        changes = []
-
-        def get_parent(dirname, basename):
-            parent_fid, mark = self.base_files.get(dirname, [None, None])
-            if parent_fid:
-                return parent_fid
-            parent_fid, mark = self.files.get(dirname, [None, None])
-            if parent_fid:
-                return parent_fid
-            if basename == '':
-                return None
-            fid = bzrlib.generate_ids.gen_file_id(path)
-            add_entry(fid, dirname, 'directory')
-            return fid
-
-        def add_entry(fid, path, kind, mode=None):
-            dirname, basename = os.path.split(path)
-            parent_fid = get_parent(dirname, basename)
-
-            executable = False
-            if mode == '100755':
-                executable = True
-            elif mode == '120000':
-                kind = 'symlink'
-
-            change = (fid,
-                    (None, path),
-                    True,
-                    (False, True),
-                    (None, parent_fid),
-                    (None, basename),
-                    (None, kind),
-                    (None, executable))
-            self.files[path] = [change[0], None]
-            changes.append(change)
-
-        def update_entry(fid, path, kind, mode=None):
-            dirname, basename = os.path.split(path)
-            parent_fid = get_parent(dirname, basename)
-
-            executable = False
-            if mode == '100755':
-                executable = True
-            elif mode == '120000':
-                kind = 'symlink'
-
-            change = (fid,
-                    (path, path),
-                    True,
-                    (True, True),
-                    (None, parent_fid),
-                    (None, basename),
-                    (None, kind),
-                    (None, executable))
-            self.files[path] = [change[0], None]
-            changes.append(change)
-
-        def remove_entry(fid, path, kind):
-            dirname, basename = os.path.split(path)
-            parent_fid = get_parent(dirname, basename)
-            change = (fid,
-                    (path, None),
-                    True,
-                    (True, False),
-                    (parent_fid, None),
-                    (None, None),
-                    (None, None),
-                    (None, None))
-            del self.files[path]
-            changes.append(change)
-
-        for fid, f in self.updates.iteritems():
-            path = f['path']
-
-            if 'deleted' in f:
-                remove_entry(fid, path, 'file')
-                continue
-
-            if path in self.base_files:
-                update_entry(fid, path, 'file', f['mode'])
-            else:
-                add_entry(fid, path, 'file', f['mode'])
-
-            self.files[path][1] = f['mark']
-            self.rev_files[fid][1] = f['mark']
-
-        return changes
-
-    def get_content(self, file_id):
-        path, mark = self.rev_files[file_id]
-        if mark:
-            return blob_marks[mark]
-
-        # last resort
-        tree = self.branch.repository.revision_tree(self.base_id)
-        return tree.get_file_text(file_id)
-
-    def get_file_with_stat(self, file_id, path=None):
-        content = self.get_content(file_id)
-        return (StringIO.StringIO(content), None)
-
-    def get_symlink_target(self, file_id):
-        return self.get_content(file_id)
-
-    def id2path(self, file_id):
-        path, mark = self.rev_files[file_id]
-        return path
-
-def c_style_unescape(string):
-    if string[0] == string[-1] == '"':
-        return string.decode('string-escape')[1:-1]
-    return string
-
-def parse_commit(parser):
-    parents = []
-
-    ref = parser[1]
-    parser.next()
-
-    if ref.startswith('refs/heads/'):
-        name = ref[len('refs/heads/'):]
-        branch = get_remote_branch(name)
-    else:
-        die('unknown ref')
-
-    commit_mark = parser.get_mark()
-    parser.next()
-    author = parser.get_author()
-    parser.next()
-    committer = parser.get_author()
-    parser.next()
-    data = parser.get_data()
-    parser.next()
-    if parser.check('from'):
-        parents.append(parser.get_mark())
-        parser.next()
-    while parser.check('merge'):
-        parents.append(parser.get_mark())
-        parser.next()
-
-    # fast-export adds an extra newline
-    if data[-1] == '\n':
-        data = data[:-1]
-
-    files = {}
-
-    for line in parser:
-        if parser.check('M'):
-            t, m, mark_ref, path = line.split(' ', 3)
-            mark = int(mark_ref[1:])
-            f = { 'mode' : m, 'mark' : mark }
-        elif parser.check('D'):
-            t, path = line.split(' ', 1)
-            f = { 'deleted' : True }
-        else:
-            die('Unknown file command: %s' % line)
-        path = c_style_unescape(path).decode('utf-8')
-        files[path] = f
-
-    committer, date, tz = committer
-    author, _, _ = author
-    parents = [mark_to_rev(p) for p in parents]
-    revid = bzrlib.generate_ids.gen_revision_id(committer, date)
-    props = {}
-    props['branch-nick'] = branch.nick
-    props['authors'] = author
-
-    mtree = CustomTree(branch, revid, parents, files)
-    changes = mtree.iter_changes()
-
-    branch.lock_write()
-    try:
-        builder = branch.get_commit_builder(parents, None, date, tz, committer, props, revid)
-        try:
-            list(builder.record_iter_changes(mtree, mtree.last_revision(), changes))
-            builder.finish_inventory()
-            builder.commit(data.decode('utf-8', 'replace'))
-        except Exception, e:
-            builder.abort()
-            raise
-    finally:
-        branch.unlock()
-
-    parsed_refs[ref] = revid
-    marks.new_mark(revid, commit_mark)
-
-def parse_reset(parser):
-    ref = parser[1]
-    parser.next()
-
-    # ugh
-    if parser.check('commit'):
-        parse_commit(parser)
-        return
-    if not parser.check('from'):
-        return
-    from_mark = parser.get_mark()
-    parser.next()
-
-    parsed_refs[ref] = mark_to_rev(from_mark)
-
-def do_export(parser):
-    parser.next()
-
-    for line in parser.each_block('done'):
-        if parser.check('blob'):
-            parse_blob(parser)
-        elif parser.check('commit'):
-            parse_commit(parser)
-        elif parser.check('reset'):
-            parse_reset(parser)
-        elif parser.check('tag'):
-            pass
-        elif parser.check('feature'):
-            pass
-        else:
-            die('unhandled export command: %s' % line)
-
-    for ref, revid in parsed_refs.iteritems():
-        if ref.startswith('refs/heads/'):
-            name = ref[len('refs/heads/'):]
-            branch = get_remote_branch(name)
-            branch.generate_revision_history(revid, marks.get_tip(name))
-
-            if name in peers:
-                peer = bzrlib.branch.Branch.open(peers[name],
-                                                 possible_transports=transports)
-                try:
-                    peer.bzrdir.push_branch(branch, revision_id=revid,
-                                            overwrite=force)
-                except bzrlib.errors.DivergedBranches:
-                    print "error %s non-fast forward" % ref
-                    continue
-
-            try:
-                wt = branch.bzrdir.open_workingtree()
-                wt.update()
-            except bzrlib.errors.NoWorkingTree:
-                pass
-        elif ref.startswith('refs/tags/'):
-            # TODO: implement tag push
-            print "error %s pushing tags not supported" % ref
-            continue
-        else:
-            # transport-helper/fast-export bugs
-            continue
-
-        print "ok %s" % ref
-
-    print
-
-def do_capabilities(parser):
-    print "import"
-    print "export"
-    print "refspec refs/heads/*:%s/heads/*" % prefix
-    print "refspec refs/tags/*:%s/tags/*" % prefix
-
-    path = os.path.join(dirname, 'marks-git')
-
-    if os.path.exists(path):
-        print "*import-marks %s" % path
-    print "*export-marks %s" % path
-
-    print "option"
-    print
-
-class InvalidOptionValue(Exception):
-    pass
-
-def get_bool_option(val):
-    if val == 'true':
-        return True
-    elif val == 'false':
-        return False
-    else:
-        raise InvalidOptionValue()
-
-def do_option(parser):
-    global force
-    opt, val = parser[1:3]
-    try:
-        if opt == 'force':
-            force = get_bool_option(val)
-            print 'ok'
-        else:
-            print 'unsupported'
-    except InvalidOptionValue:
-        print "error '%s' is not a valid value for option '%s'" % (val, opt)
-
-def ref_is_valid(name):
-    return not True in [c in name for c in '~^: \\']
-
-def do_list(parser):
-    master_branch = None
-
-    for name in branches:
-        if not master_branch:
-            master_branch = name
-        print "? refs/heads/%s" % name
-
-    branch = get_remote_branch(master_branch)
-    branch.lock_read()
-    for tag, revid in branch.tags.get_tag_dict().items():
-        try:
-            branch.revision_id_to_dotted_revno(revid)
-        except bzrlib.errors.NoSuchRevision:
-            continue
-        if not ref_is_valid(tag):
-            continue
-        print "? refs/tags/%s" % tag
-        tags[tag] = revid
-    branch.unlock()
-
-    print "@refs/heads/%s HEAD" % master_branch
-    print
-
-def clone(path, remote_branch):
-    try:
-        bdir = bzrlib.bzrdir.BzrDir.create(path, possible_transports=transports)
-    except bzrlib.errors.AlreadyControlDirError:
-        bdir = bzrlib.bzrdir.BzrDir.open(path, possible_transports=transports)
-    repo = bdir.find_repository()
-    repo.fetch(remote_branch.repository)
-    return remote_branch.sprout(bdir, repository=repo)
-
-def get_remote_branch(name):
-    remote_branch = bzrlib.branch.Branch.open(branches[name],
-                                              possible_transports=transports)
-    if isinstance(remote_branch.bzrdir.root_transport, bzrlib.transport.local.LocalTransport):
-        return remote_branch
-
-    branch_path = os.path.join(dirname, 'clone', name)
-
-    try:
-        branch = bzrlib.branch.Branch.open(branch_path,
-                                           possible_transports=transports)
-    except bzrlib.errors.NotBranchError:
-        # clone
-        branch = clone(branch_path, remote_branch)
-    else:
-        # pull
-        try:
-            branch.pull(remote_branch, overwrite=True)
-        except bzrlib.errors.DivergedBranches:
-            # use remote branch for now
-            return remote_branch
-
-    return branch
-
-def find_branches(repo):
-    transport = repo.bzrdir.root_transport
-
-    for fn in transport.iter_files_recursive():
-        if not fn.endswith('.bzr/branch-format'):
-            continue
-
-        name = subdir = fn[:-len('/.bzr/branch-format')]
-        name = name if name != '' else 'master'
-        name = name.replace('/', '+')
-
-        try:
-            cur = transport.clone(subdir)
-            branch = bzrlib.branch.Branch.open_from_transport(cur)
-        except bzrlib.errors.NotBranchError:
-            continue
-        else:
-            yield name, branch.base
-
-def get_repo(url, alias):
-    normal_url = bzrlib.urlutils.normalize_url(url)
-    origin = bzrlib.bzrdir.BzrDir.open(url, possible_transports=transports)
-    is_local = isinstance(origin.transport, bzrlib.transport.local.LocalTransport)
-
-    shared_path = os.path.join(gitdir, 'bzr')
-    try:
-        shared_dir = bzrlib.bzrdir.BzrDir.open(shared_path,
-                                               possible_transports=transports)
-    except bzrlib.errors.NotBranchError:
-        shared_dir = bzrlib.bzrdir.BzrDir.create(shared_path,
-                                                 possible_transports=transports)
-    try:
-        shared_repo = shared_dir.open_repository()
-    except bzrlib.errors.NoRepositoryPresent:
-        shared_repo = shared_dir.create_repository(shared=True)
-
-    if not is_local:
-        clone_path = os.path.join(dirname, 'clone')
-        if not os.path.exists(clone_path):
-            os.mkdir(clone_path)
-        else:
-            # check and remove old organization
-            try:
-                bdir = bzrlib.bzrdir.BzrDir.open(clone_path,
-                                                 possible_transports=transports)
-                bdir.destroy_repository()
-            except bzrlib.errors.NotBranchError:
-                pass
-            except bzrlib.errors.NoRepositoryPresent:
-                pass
-
-    wanted = get_config('remote.%s.bzr-branches' % alias).rstrip().split(', ')
-    # stupid python
-    wanted = [e for e in wanted if e]
-    if not wanted:
-        wanted = get_config('remote-bzr.branches').rstrip().split(', ')
-        # stupid python
-        wanted = [e for e in wanted if e]
-
-    if not wanted:
-        try:
-            repo = origin.open_repository()
-            if not repo.bzrdir.root_transport.listable():
-                # this repository is not usable for us
-                raise bzrlib.errors.NoRepositoryPresent(repo.bzrdir)
-        except bzrlib.errors.NoRepositoryPresent:
-            wanted = ['master']
-
-    if wanted:
-        def list_wanted(url, wanted):
-            for name in wanted:
-                subdir = name if name != 'master' else ''
-                yield name, bzrlib.urlutils.join(url, subdir)
-
-        branch_list = list_wanted(url, wanted)
-    else:
-        branch_list = find_branches(repo)
-
-    for name, url in branch_list:
-        if not is_local:
-            peers[name] = url
-        branches[name] = url
-
-    return origin
-
-def fix_path(alias, orig_url):
-    url = urlparse.urlparse(orig_url, 'file')
-    if url.scheme != 'file' or os.path.isabs(url.path):
-        return
-    abs_url = urlparse.urljoin("%s/" % os.getcwd(), orig_url)
-    cmd = ['git', 'config', 'remote.%s.url' % alias, "bzr::%s" % abs_url]
-    subprocess.call(cmd)
-
-def main(args):
-    global marks, prefix, gitdir, dirname
-    global tags, filenodes
-    global blob_marks
-    global parsed_refs
-    global files_cache
-    global is_tmp
-    global branches, peers
-    global transports
-    global force
-
-    marks = None
-    is_tmp = False
-    gitdir = os.environ.get('GIT_DIR', None)
-
-    if len(args) < 3:
-        die('Not enough arguments.')
-
-    if not gitdir:
-        die('GIT_DIR not set')
-
-    alias = args[1]
-    url = args[2]
-
-    tags = {}
-    filenodes = {}
-    blob_marks = {}
-    parsed_refs = {}
-    files_cache = {}
-    branches = {}
-    peers = {}
-    transports = []
-    force = False
-
-    if alias[5:] == url:
-        is_tmp = True
-        alias = hashlib.sha1(alias).hexdigest()
-
-    prefix = 'refs/bzr/%s' % alias
-    dirname = os.path.join(gitdir, 'bzr', alias)
-
-    if not is_tmp:
-        fix_path(alias, url)
-
-    if not os.path.exists(dirname):
-        os.makedirs(dirname)
-
-    if hasattr(bzrlib.ui.ui_factory, 'be_quiet'):
-        bzrlib.ui.ui_factory.be_quiet(True)
-
-    repo = get_repo(url, alias)
-
-    marks_path = os.path.join(dirname, 'marks-int')
-    marks = Marks(marks_path)
-
-    parser = Parser(repo)
-    for line in parser:
-        if parser.check('capabilities'):
-            do_capabilities(parser)
-        elif parser.check('list'):
-            do_list(parser)
-        elif parser.check('import'):
-            do_import(parser)
-        elif parser.check('export'):
-            do_export(parser)
-        elif parser.check('option'):
-            do_option(parser)
-        else:
-            die('unhandled command: %s' % line)
-        sys.stdout.flush()
 
-def bye():
-    if not marks:
-        return
-    if not is_tmp:
-        marks.store()
-    else:
-        shutil.rmtree(dirname)
+sys.stderr.write('WARNING: git-remote-bzr is now maintained independently.\n')
+sys.stderr.write('WARNING: For more information visit https://github.com/felipec/git-remote-bzr\n')
 
-atexit.register(bye)
-sys.exit(main(sys.argv))
+sys.stderr.write('''WARNING:
+WARNING: You can pick a directory on your $PATH and download it, e.g.:
+WARNING:   $ wget -O $HOME/bin/git-remote-bzr \\
+WARNING:     https://raw.github.com/felipec/git-remote-bzr/master/git-remote-bzr
+WARNING:   $ chmod +x $HOME/bin/git-remote-bzr
+''')
index 34cda027597f30ddacf340466778404f3705361d..4255ad6312ec027b65ffd4dfc456bc0ed5dd533f 100755 (executable)
 #!/usr/bin/env python
-#
-# Copyright (c) 2012 Felipe Contreras
-#
 
-# Inspired by Rocco Rutte's hg-fast-export
-
-# Just copy to your ~/bin, or anywhere in your $PATH.
-# Then you can clone with:
-# git clone hg::/path/to/mercurial/repo/
-#
-# For remote repositories a local clone is stored in
-# "$GIT_DIR/hg/origin/clone/.hg/".
-
-from mercurial import hg, ui, bookmarks, context, encoding, node, error, extensions, discovery, util
-
-import re
 import sys
-import os
-import json
-import shutil
-import subprocess
-import urllib
-import atexit
-import urlparse, hashlib
-import time as ptime
-
-#
-# If you want to see Mercurial revisions as Git commit notes:
-# git config core.notesRef refs/notes/hg
-#
-# If you are not in hg-git-compat mode and want to disable the tracking of
-# named branches:
-# git config --global remote-hg.track-branches false
-#
-# If you want the equivalent of hg's clone/pull--insecure option:
-# git config --global remote-hg.insecure true
-#
-# If you want to switch to hg-git compatibility mode:
-# git config --global remote-hg.hg-git-compat true
-#
-# git:
-# Sensible defaults for git.
-# hg bookmarks are exported as git branches, hg branches are prefixed
-# with 'branches/', HEAD is a special case.
-#
-# hg:
-# Emulate hg-git.
-# Only hg bookmarks are exported as git branches.
-# Commits are modified to preserve hg information and allow bidirectionality.
-#
-
-NAME_RE = re.compile('^([^<>]+)')
-AUTHOR_RE = re.compile('^([^<>]+?)? ?[<>]([^<>]*)(?:$|>)')
-EMAIL_RE = re.compile(r'([^ \t<>]+@[^ \t<>]+)')
-AUTHOR_HG_RE = re.compile('^(.*?) ?<(.*?)(?:>(.+)?)?$')
-RAW_AUTHOR_RE = re.compile('^(\w+) (?:(.+)? )?<(.*)> (\d+) ([+-]\d+)')
-
-VERSION = 2
-
-def die(msg, *args):
-    sys.stderr.write('ERROR: %s\n' % (msg % args))
-    sys.exit(1)
-
-def warn(msg, *args):
-    sys.stderr.write('WARNING: %s\n' % (msg % args))
-
-def gitmode(flags):
-    return 'l' in flags and '120000' or 'x' in flags and '100755' or '100644'
-
-def gittz(tz):
-    return '%+03d%02d' % (-tz / 3600, -tz % 3600 / 60)
-
-def hgmode(mode):
-    m = { '100755': 'x', '120000': 'l' }
-    return m.get(mode, '')
-
-def hghex(n):
-    return node.hex(n)
-
-def hgbin(n):
-    return node.bin(n)
-
-def hgref(ref):
-    return ref.replace('___', ' ')
-
-def gitref(ref):
-    return ref.replace(' ', '___')
-
-def check_version(*check):
-    if not hg_version:
-        return True
-    return hg_version >= check
-
-def get_config(config):
-    cmd = ['git', 'config', '--get', config]
-    process = subprocess.Popen(cmd, stdout=subprocess.PIPE)
-    output, _ = process.communicate()
-    return output
-
-def get_config_bool(config, default=False):
-    value = get_config(config).rstrip('\n')
-    if value == "true":
-        return True
-    elif value == "false":
-        return False
-    else:
-        return default
-
-class Marks:
-
-    def __init__(self, path, repo):
-        self.path = path
-        self.repo = repo
-        self.clear()
-        self.load()
-
-        if self.version < VERSION:
-            if self.version == 1:
-                self.upgrade_one()
-
-            # upgraded?
-            if self.version < VERSION:
-                self.clear()
-                self.version = VERSION
-
-    def clear(self):
-        self.tips = {}
-        self.marks = {}
-        self.rev_marks = {}
-        self.last_mark = 0
-        self.version = 0
-        self.last_note = 0
-
-    def load(self):
-        if not os.path.exists(self.path):
-            return
-
-        tmp = json.load(open(self.path))
-
-        self.tips = tmp['tips']
-        self.marks = tmp['marks']
-        self.last_mark = tmp['last-mark']
-        self.version = tmp.get('version', 1)
-        self.last_note = tmp.get('last-note', 0)
-
-        for rev, mark in self.marks.iteritems():
-            self.rev_marks[mark] = rev
-
-    def upgrade_one(self):
-        def get_id(rev):
-            return hghex(self.repo.changelog.node(int(rev)))
-        self.tips = dict((name, get_id(rev)) for name, rev in self.tips.iteritems())
-        self.marks = dict((get_id(rev), mark) for rev, mark in self.marks.iteritems())
-        self.rev_marks = dict((mark, get_id(rev)) for mark, rev in self.rev_marks.iteritems())
-        self.version = 2
-
-    def dict(self):
-        return { 'tips': self.tips, 'marks': self.marks, 'last-mark' : self.last_mark, 'version' : self.version, 'last-note' : self.last_note }
-
-    def store(self):
-        json.dump(self.dict(), open(self.path, 'w'))
-
-    def __str__(self):
-        return str(self.dict())
-
-    def from_rev(self, rev):
-        return self.marks[rev]
-
-    def to_rev(self, mark):
-        return str(self.rev_marks[mark])
-
-    def next_mark(self):
-        self.last_mark += 1
-        return self.last_mark
-
-    def get_mark(self, rev):
-        self.last_mark += 1
-        self.marks[rev] = self.last_mark
-        return self.last_mark
-
-    def new_mark(self, rev, mark):
-        self.marks[rev] = mark
-        self.rev_marks[mark] = rev
-        self.last_mark = mark
-
-    def is_marked(self, rev):
-        return rev in self.marks
-
-    def get_tip(self, branch):
-        return str(self.tips[branch])
-
-    def set_tip(self, branch, tip):
-        self.tips[branch] = tip
-
-class Parser:
-
-    def __init__(self, repo):
-        self.repo = repo
-        self.line = self.get_line()
-
-    def get_line(self):
-        return sys.stdin.readline().strip()
-
-    def __getitem__(self, i):
-        return self.line.split()[i]
-
-    def check(self, word):
-        return self.line.startswith(word)
-
-    def each_block(self, separator):
-        while self.line != separator:
-            yield self.line
-            self.line = self.get_line()
-
-    def __iter__(self):
-        return self.each_block('')
-
-    def next(self):
-        self.line = self.get_line()
-        if self.line == 'done':
-            self.line = None
-
-    def get_mark(self):
-        i = self.line.index(':') + 1
-        return int(self.line[i:])
-
-    def get_data(self):
-        if not self.check('data'):
-            return None
-        i = self.line.index(' ') + 1
-        size = int(self.line[i:])
-        return sys.stdin.read(size)
-
-    def get_author(self):
-        ex = None
-        m = RAW_AUTHOR_RE.match(self.line)
-        if not m:
-            return None
-        _, name, email, date, tz = m.groups()
-        if name and 'ext:' in name:
-            m = re.match('^(.+?) ext:\((.+)\)$', name)
-            if m:
-                name = m.group(1)
-                ex = urllib.unquote(m.group(2))
-
-        if email != bad_mail:
-            if name:
-                user = '%s <%s>' % (name, email)
-            else:
-                user = '<%s>' % (email)
-        else:
-            user = name
-
-        if ex:
-            user += ex
-
-        tz = int(tz)
-        tz = ((tz / 100) * 3600) + ((tz % 100) * 60)
-        return (user, int(date), -tz)
-
-def fix_file_path(path):
-    path = os.path.normpath(path)
-    if not os.path.isabs(path):
-        return path
-    return os.path.relpath(path, '/')
-
-def export_files(files):
-    final = []
-    for f in files:
-        fid = node.hex(f.filenode())
-
-        if fid in filenodes:
-            mark = filenodes[fid]
-        else:
-            mark = marks.next_mark()
-            filenodes[fid] = mark
-            d = f.data()
-
-            print "blob"
-            print "mark :%u" % mark
-            print "data %d" % len(d)
-            print d
-
-        path = fix_file_path(f.path())
-        final.append((gitmode(f.flags()), mark, path))
-
-    return final
-
-def get_filechanges(repo, ctx, parent):
-    modified = set()
-    added = set()
-    removed = set()
-
-    # load earliest manifest first for caching reasons
-    prev = parent.manifest().copy()
-    cur = ctx.manifest()
-
-    for fn in cur:
-        if fn in prev:
-            if (cur.flags(fn) != prev.flags(fn) or cur[fn] != prev[fn]):
-                modified.add(fn)
-            del prev[fn]
-        else:
-            added.add(fn)
-    removed |= set(prev.keys())
-
-    return added | modified, removed
-
-def fixup_user_git(user):
-    name = mail = None
-    user = user.replace('"', '')
-    m = AUTHOR_RE.match(user)
-    if m:
-        name = m.group(1)
-        mail = m.group(2).strip()
-    else:
-        m = EMAIL_RE.match(user)
-        if m:
-            mail = m.group(1)
-        else:
-            m = NAME_RE.match(user)
-            if m:
-                name = m.group(1).strip()
-    return (name, mail)
-
-def fixup_user_hg(user):
-    def sanitize(name):
-        # stole this from hg-git
-        return re.sub('[<>\n]', '?', name.lstrip('< ').rstrip('> '))
-
-    m = AUTHOR_HG_RE.match(user)
-    if m:
-        name = sanitize(m.group(1))
-        mail = sanitize(m.group(2))
-        ex = m.group(3)
-        if ex:
-            name += ' ext:(' + urllib.quote(ex) + ')'
-    else:
-        name = sanitize(user)
-        if '@' in user:
-            mail = name
-        else:
-            mail = None
-
-    return (name, mail)
-
-def fixup_user(user):
-    if mode == 'git':
-        name, mail = fixup_user_git(user)
-    else:
-        name, mail = fixup_user_hg(user)
-
-    if not name:
-        name = bad_name
-    if not mail:
-        mail = bad_mail
-
-    return '%s <%s>' % (name, mail)
-
-def updatebookmarks(repo, peer):
-    remotemarks = peer.listkeys('bookmarks')
-    localmarks = repo._bookmarks
-
-    if not remotemarks:
-        return
-
-    for k, v in remotemarks.iteritems():
-        localmarks[k] = hgbin(v)
-
-    if hasattr(localmarks, 'write'):
-        localmarks.write()
-    else:
-        bookmarks.write(repo)
-
-def get_repo(url, alias):
-    global peer
-
-    myui = ui.ui()
-    myui.setconfig('ui', 'interactive', 'off')
-    myui.fout = sys.stderr
-
-    if get_config_bool('remote-hg.insecure'):
-        myui.setconfig('web', 'cacerts', '')
-
-    extensions.loadall(myui)
-
-    if hg.islocal(url) and not os.environ.get('GIT_REMOTE_HG_TEST_REMOTE'):
-        repo = hg.repository(myui, url)
-        if not os.path.exists(dirname):
-            os.makedirs(dirname)
-    else:
-        shared_path = os.path.join(gitdir, 'hg')
-
-        # check and upgrade old organization
-        hg_path = os.path.join(shared_path, '.hg')
-        if os.path.exists(shared_path) and not os.path.exists(hg_path):
-            repos = os.listdir(shared_path)
-            for x in repos:
-                local_hg = os.path.join(shared_path, x, 'clone', '.hg')
-                if not os.path.exists(local_hg):
-                    continue
-                if not os.path.exists(hg_path):
-                    shutil.move(local_hg, hg_path)
-                shutil.rmtree(os.path.join(shared_path, x, 'clone'))
-
-        # setup shared repo (if not there)
-        try:
-            hg.peer(myui, {}, shared_path, create=True)
-        except error.RepoError:
-            pass
-
-        if not os.path.exists(dirname):
-            os.makedirs(dirname)
-
-        local_path = os.path.join(dirname, 'clone')
-        if not os.path.exists(local_path):
-            hg.share(myui, shared_path, local_path, update=False)
-        else:
-            # make sure the shared path is always up-to-date
-            util.writefile(os.path.join(local_path, '.hg', 'sharedpath'), hg_path)
-
-        repo = hg.repository(myui, local_path)
-        try:
-            peer = hg.peer(myui, {}, url)
-        except:
-            die('Repository error')
-        repo.pull(peer, heads=None, force=True)
-
-        updatebookmarks(repo, peer)
-
-    return repo
-
-def rev_to_mark(rev):
-    return marks.from_rev(rev.hex())
-
-def mark_to_rev(mark):
-    return marks.to_rev(mark)
-
-def export_ref(repo, name, kind, head):
-    ename = '%s/%s' % (kind, name)
-    try:
-        tip = marks.get_tip(ename)
-        tip = repo[tip].rev()
-    except:
-        tip = 0
-
-    revs = xrange(tip, head.rev() + 1)
-    total = len(revs)
-
-    for rev in revs:
-
-        c = repo[rev]
-        node = c.node()
-
-        if marks.is_marked(c.hex()):
-            continue
-
-        (manifest, user, (time, tz), files, desc, extra) = repo.changelog.read(node)
-        rev_branch = extra['branch']
-
-        author = "%s %d %s" % (fixup_user(user), time, gittz(tz))
-        if 'committer' in extra:
-            user, time, tz = extra['committer'].rsplit(' ', 2)
-            committer = "%s %s %s" % (user, time, gittz(int(tz)))
-        else:
-            committer = author
-
-        parents = [repo[p] for p in repo.changelog.parentrevs(rev) if p >= 0]
-
-        if len(parents) == 0:
-            modified = c.manifest().keys()
-            removed = []
-        else:
-            modified, removed = get_filechanges(repo, c, parents[0])
-
-        desc += '\n'
-
-        if mode == 'hg':
-            extra_msg = ''
-
-            if rev_branch != 'default':
-                extra_msg += 'branch : %s\n' % rev_branch
-
-            renames = []
-            for f in c.files():
-                if f not in c.manifest():
-                    continue
-                rename = c.filectx(f).renamed()
-                if rename:
-                    renames.append((rename[0], f))
-
-            for e in renames:
-                extra_msg += "rename : %s => %s\n" % e
-
-            for key, value in extra.iteritems():
-                if key in ('author', 'committer', 'encoding', 'message', 'branch', 'hg-git'):
-                    continue
-                else:
-                    extra_msg += "extra : %s : %s\n" % (key, urllib.quote(value))
-
-            if extra_msg:
-                desc += '\n--HG--\n' + extra_msg
-
-        if len(parents) == 0 and rev:
-            print 'reset %s/%s' % (prefix, ename)
-
-        modified_final = export_files(c.filectx(f) for f in modified)
-
-        print "commit %s/%s" % (prefix, ename)
-        print "mark :%d" % (marks.get_mark(c.hex()))
-        print "author %s" % (author)
-        print "committer %s" % (committer)
-        print "data %d" % (len(desc))
-        print desc
-
-        if len(parents) > 0:
-            print "from :%s" % (rev_to_mark(parents[0]))
-            if len(parents) > 1:
-                print "merge :%s" % (rev_to_mark(parents[1]))
-
-        for f in removed:
-            print "D %s" % (fix_file_path(f))
-        for f in modified_final:
-            print "M %s :%u %s" % f
-        print
-
-        progress = (rev - tip)
-        if (progress % 100 == 0):
-            print "progress revision %d '%s' (%d/%d)" % (rev, name, progress, total)
-
-    # make sure the ref is updated
-    print "reset %s/%s" % (prefix, ename)
-    print "from :%u" % rev_to_mark(head)
-    print
-
-    pending_revs = set(revs) - notes
-    if pending_revs:
-        note_mark = marks.next_mark()
-        ref = "refs/notes/hg"
-
-        print "commit %s" % ref
-        print "mark :%d" % (note_mark)
-        print "committer remote-hg <> %d %s" % (ptime.time(), gittz(ptime.timezone))
-        desc = "Notes for %s\n" % (name)
-        print "data %d" % (len(desc))
-        print desc
-        if marks.last_note:
-            print "from :%u" % marks.last_note
-
-        for rev in pending_revs:
-            notes.add(rev)
-            c = repo[rev]
-            print "N inline :%u" % rev_to_mark(c)
-            msg = c.hex()
-            print "data %d" % (len(msg))
-            print msg
-        print
-
-        marks.last_note = note_mark
-
-    marks.set_tip(ename, head.hex())
-
-def export_tag(repo, tag):
-    export_ref(repo, tag, 'tags', repo[hgref(tag)])
-
-def export_bookmark(repo, bmark):
-    head = bmarks[hgref(bmark)]
-    export_ref(repo, bmark, 'bookmarks', head)
-
-def export_branch(repo, branch):
-    tip = get_branch_tip(repo, branch)
-    head = repo[tip]
-    export_ref(repo, branch, 'branches', head)
-
-def export_head(repo):
-    export_ref(repo, g_head[0], 'bookmarks', g_head[1])
-
-def do_capabilities(parser):
-    print "import"
-    print "export"
-    print "refspec refs/heads/branches/*:%s/branches/*" % prefix
-    print "refspec refs/heads/*:%s/bookmarks/*" % prefix
-    print "refspec refs/tags/*:%s/tags/*" % prefix
-
-    path = os.path.join(dirname, 'marks-git')
-
-    if os.path.exists(path):
-        print "*import-marks %s" % path
-    print "*export-marks %s" % path
-    print "option"
-
-    print
-
-def branch_tip(branch):
-    return branches[branch][-1]
-
-def get_branch_tip(repo, branch):
-    heads = branches.get(hgref(branch), None)
-    if not heads:
-        return None
-
-    # verify there's only one head
-    if (len(heads) > 1):
-        warn("Branch '%s' has more than one head, consider merging" % branch)
-        return branch_tip(hgref(branch))
-
-    return heads[0]
-
-def list_head(repo, cur):
-    global g_head, fake_bmark
-
-    if 'default' not in branches:
-        # empty repo
-        return
-
-    node = repo[branch_tip('default')]
-    head = 'master' if not 'master' in bmarks else 'default'
-    fake_bmark = head
-    bmarks[head] = node
-
-    head = gitref(head)
-    print "@refs/heads/%s HEAD" % head
-    g_head = (head, node)
-
-def do_list(parser):
-    repo = parser.repo
-    for bmark, node in bookmarks.listbookmarks(repo).iteritems():
-        bmarks[bmark] = repo[node]
-
-    cur = repo.dirstate.branch()
-    orig = peer if peer else repo
-
-    for branch, heads in orig.branchmap().iteritems():
-        # only open heads
-        heads = [h for h in heads if 'close' not in repo.changelog.read(h)[5]]
-        if heads:
-            branches[branch] = heads
-
-    list_head(repo, cur)
-
-    if track_branches:
-        for branch in branches:
-            print "? refs/heads/branches/%s" % gitref(branch)
-
-    for bmark in bmarks:
-        if  bmarks[bmark].hex() == '0000000000000000000000000000000000000000':
-            warn("Ignoring invalid bookmark '%s'", bmark)
-        else:
-            print "? refs/heads/%s" % gitref(bmark)
-
-    for tag, node in repo.tagslist():
-        if tag == 'tip':
-            continue
-        print "? refs/tags/%s" % gitref(tag)
-
-    print
-
-def do_import(parser):
-    repo = parser.repo
-
-    path = os.path.join(dirname, 'marks-git')
-
-    print "feature done"
-    if os.path.exists(path):
-        print "feature import-marks=%s" % path
-    print "feature export-marks=%s" % path
-    print "feature force"
-    sys.stdout.flush()
-
-    tmp = encoding.encoding
-    encoding.encoding = 'utf-8'
-
-    # lets get all the import lines
-    while parser.check('import'):
-        ref = parser[1]
-
-        if (ref == 'HEAD'):
-            export_head(repo)
-        elif ref.startswith('refs/heads/branches/'):
-            branch = ref[len('refs/heads/branches/'):]
-            export_branch(repo, branch)
-        elif ref.startswith('refs/heads/'):
-            bmark = ref[len('refs/heads/'):]
-            export_bookmark(repo, bmark)
-        elif ref.startswith('refs/tags/'):
-            tag = ref[len('refs/tags/'):]
-            export_tag(repo, tag)
-
-        parser.next()
-
-    encoding.encoding = tmp
-
-    print 'done'
-
-def parse_blob(parser):
-    parser.next()
-    mark = parser.get_mark()
-    parser.next()
-    data = parser.get_data()
-    blob_marks[mark] = data
-    parser.next()
-
-def get_merge_files(repo, p1, p2, files):
-    for e in repo[p1].files():
-        if e not in files:
-            if e not in repo[p1].manifest():
-                continue
-            f = { 'ctx' : repo[p1][e] }
-            files[e] = f
-
-def c_style_unescape(string):
-    if string[0] == string[-1] == '"':
-        return string.decode('string-escape')[1:-1]
-    return string
-
-def parse_commit(parser):
-    from_mark = merge_mark = None
-
-    ref = parser[1]
-    parser.next()
-
-    commit_mark = parser.get_mark()
-    parser.next()
-    author = parser.get_author()
-    parser.next()
-    committer = parser.get_author()
-    parser.next()
-    data = parser.get_data()
-    parser.next()
-    if parser.check('from'):
-        from_mark = parser.get_mark()
-        parser.next()
-    if parser.check('merge'):
-        merge_mark = parser.get_mark()
-        parser.next()
-        if parser.check('merge'):
-            die('octopus merges are not supported yet')
-
-    # fast-export adds an extra newline
-    if data[-1] == '\n':
-        data = data[:-1]
-
-    files = {}
-
-    for line in parser:
-        if parser.check('M'):
-            t, m, mark_ref, path = line.split(' ', 3)
-            mark = int(mark_ref[1:])
-            f = { 'mode' : hgmode(m), 'data' : blob_marks[mark] }
-        elif parser.check('D'):
-            t, path = line.split(' ', 1)
-            f = { 'deleted' : True }
-        else:
-            die('Unknown file command: %s' % line)
-        path = c_style_unescape(path)
-        files[path] = f
-
-    # only export the commits if we are on an internal proxy repo
-    if dry_run and not peer:
-        parsed_refs[ref] = None
-        return
-
-    def getfilectx(repo, memctx, f):
-        of = files[f]
-        if 'deleted' in of:
-            raise IOError
-        if 'ctx' in of:
-            return of['ctx']
-        is_exec = of['mode'] == 'x'
-        is_link = of['mode'] == 'l'
-        rename = of.get('rename', None)
-        return context.memfilectx(f, of['data'],
-                is_link, is_exec, rename)
-
-    repo = parser.repo
-
-    user, date, tz = author
-    extra = {}
-
-    if committer != author:
-        extra['committer'] = "%s %u %u" % committer
-
-    if from_mark:
-        p1 = mark_to_rev(from_mark)
-    else:
-        p1 = '0' * 40
-
-    if merge_mark:
-        p2 = mark_to_rev(merge_mark)
-    else:
-        p2 = '0' * 40
-
-    #
-    # If files changed from any of the parents, hg wants to know, but in git if
-    # nothing changed from the first parent, nothing changed.
-    #
-    if merge_mark:
-        get_merge_files(repo, p1, p2, files)
-
-    # Check if the ref is supposed to be a named branch
-    if ref.startswith('refs/heads/branches/'):
-        branch = ref[len('refs/heads/branches/'):]
-        extra['branch'] = hgref(branch)
-
-    if mode == 'hg':
-        i = data.find('\n--HG--\n')
-        if i >= 0:
-            tmp = data[i + len('\n--HG--\n'):].strip()
-            for k, v in [e.split(' : ', 1) for e in tmp.split('\n')]:
-                if k == 'rename':
-                    old, new = v.split(' => ', 1)
-                    files[new]['rename'] = old
-                elif k == 'branch':
-                    extra[k] = v
-                elif k == 'extra':
-                    ek, ev = v.split(' : ', 1)
-                    extra[ek] = urllib.unquote(ev)
-            data = data[:i]
-
-    ctx = context.memctx(repo, (p1, p2), data,
-            files.keys(), getfilectx,
-            user, (date, tz), extra)
-
-    tmp = encoding.encoding
-    encoding.encoding = 'utf-8'
-
-    node = hghex(repo.commitctx(ctx))
-
-    encoding.encoding = tmp
-
-    parsed_refs[ref] = node
-    marks.new_mark(node, commit_mark)
-
-def parse_reset(parser):
-    ref = parser[1]
-    parser.next()
-    # ugh
-    if parser.check('commit'):
-        parse_commit(parser)
-        return
-    if not parser.check('from'):
-        return
-    from_mark = parser.get_mark()
-    parser.next()
-
-    try:
-        rev = mark_to_rev(from_mark)
-    except KeyError:
-        rev = None
-    parsed_refs[ref] = rev
-
-def parse_tag(parser):
-    name = parser[1]
-    parser.next()
-    from_mark = parser.get_mark()
-    parser.next()
-    tagger = parser.get_author()
-    parser.next()
-    data = parser.get_data()
-    parser.next()
-
-    parsed_tags[name] = (tagger, data)
-
-def write_tag(repo, tag, node, msg, author):
-    branch = repo[node].branch()
-    tip = branch_tip(branch)
-    tip = repo[tip]
-
-    def getfilectx(repo, memctx, f):
-        try:
-            fctx = tip.filectx(f)
-            data = fctx.data()
-        except error.ManifestLookupError:
-            data = ""
-        content = data + "%s %s\n" % (node, tag)
-        return context.memfilectx(f, content, False, False, None)
-
-    p1 = tip.hex()
-    p2 = '0' * 40
-    if author:
-        user, date, tz = author
-        date_tz = (date, tz)
-    else:
-        cmd = ['git', 'var', 'GIT_COMMITTER_IDENT']
-        process = subprocess.Popen(cmd, stdout=subprocess.PIPE)
-        output, _ = process.communicate()
-        m = re.match('^.* <.*>', output)
-        if m:
-            user = m.group(0)
-        else:
-            user = repo.ui.username()
-        date_tz = None
-
-    ctx = context.memctx(repo, (p1, p2), msg,
-            ['.hgtags'], getfilectx,
-            user, date_tz, {'branch' : branch})
-
-    tmp = encoding.encoding
-    encoding.encoding = 'utf-8'
-
-    tagnode = repo.commitctx(ctx)
-
-    encoding.encoding = tmp
-
-    return (tagnode, branch)
-
-def checkheads_bmark(repo, ref, ctx):
-    bmark = ref[len('refs/heads/'):]
-    if not bmark in bmarks:
-        # new bmark
-        return True
-
-    ctx_old = bmarks[bmark]
-    ctx_new = ctx
-    if not repo.changelog.descendant(ctx_old.rev(), ctx_new.rev()):
-        if force_push:
-            print "ok %s forced update" % ref
-        else:
-            print "error %s non-fast forward" % ref
-            return False
-
-    return True
-
-def checkheads(repo, remote, p_revs):
-
-    remotemap = remote.branchmap()
-    if not remotemap:
-        # empty repo
-        return True
-
-    new = {}
-    ret = True
-
-    for node, ref in p_revs.iteritems():
-        ctx = repo[node]
-        branch = ctx.branch()
-        if not branch in remotemap:
-            # new branch
-            continue
-        if not ref.startswith('refs/heads/branches'):
-            if ref.startswith('refs/heads/'):
-                if not checkheads_bmark(repo, ref, ctx):
-                    ret = False
-
-            # only check branches
-            continue
-        new.setdefault(branch, []).append(ctx.rev())
-
-    for branch, heads in new.iteritems():
-        old = [repo.changelog.rev(x) for x in remotemap[branch]]
-        for rev in heads:
-            if check_version(2, 3):
-                ancestors = repo.changelog.ancestors([rev], stoprev=min(old))
-            else:
-                ancestors = repo.changelog.ancestors(rev)
-            found = False
-
-            for x in old:
-                if x in ancestors:
-                    found = True
-                    break
-
-            if found:
-                continue
-
-            node = repo.changelog.node(rev)
-            ref = p_revs[node]
-            if force_push:
-                print "ok %s forced update" % ref
-            else:
-                print "error %s non-fast forward" % ref
-                ret = False
-
-    return ret
-
-def push_unsafe(repo, remote, parsed_refs, p_revs):
-
-    force = force_push
-
-    fci = discovery.findcommonincoming
-    commoninc = fci(repo, remote, force=force)
-    common, _, remoteheads = commoninc
-
-    if not checkheads(repo, remote, p_revs):
-        return None
-
-    cg = repo.getbundle('push', heads=list(p_revs), common=common)
-
-    unbundle = remote.capable('unbundle')
-    if unbundle:
-        if force:
-            remoteheads = ['force']
-        return remote.unbundle(cg, remoteheads, 'push')
-    else:
-        return remote.addchangegroup(cg, 'push', repo.url())
-
-def push(repo, remote, parsed_refs, p_revs):
-    if hasattr(remote, 'canpush') and not remote.canpush():
-        print "error cannot push"
-
-    if not p_revs:
-        # nothing to push
-        return
-
-    lock = None
-    unbundle = remote.capable('unbundle')
-    if not unbundle:
-        lock = remote.lock()
-    try:
-        ret = push_unsafe(repo, remote, parsed_refs, p_revs)
-    finally:
-        if lock is not None:
-            lock.release()
-
-    return ret
-
-def check_tip(ref, kind, name, heads):
-    try:
-        ename = '%s/%s' % (kind, name)
-        tip = marks.get_tip(ename)
-    except KeyError:
-        return True
-    else:
-        return tip in heads
-
-def do_export(parser):
-    p_bmarks = []
-    p_revs = {}
-
-    parser.next()
-
-    for line in parser.each_block('done'):
-        if parser.check('blob'):
-            parse_blob(parser)
-        elif parser.check('commit'):
-            parse_commit(parser)
-        elif parser.check('reset'):
-            parse_reset(parser)
-        elif parser.check('tag'):
-            parse_tag(parser)
-        elif parser.check('feature'):
-            pass
-        else:
-            die('unhandled export command: %s' % line)
-
-    need_fetch = False
-
-    for ref, node in parsed_refs.iteritems():
-        bnode = hgbin(node) if node else None
-        if ref.startswith('refs/heads/branches'):
-            branch = ref[len('refs/heads/branches/'):]
-            if branch in branches and bnode in branches[branch]:
-                # up to date
-                continue
-
-            if peer:
-                remotemap = peer.branchmap()
-                if remotemap and branch in remotemap:
-                    heads = [hghex(e) for e in remotemap[branch]]
-                    if not check_tip(ref, 'branches', branch, heads):
-                        print "error %s fetch first" % ref
-                        need_fetch = True
-                        continue
-
-            p_revs[bnode] = ref
-            print "ok %s" % ref
-        elif ref.startswith('refs/heads/'):
-            bmark = ref[len('refs/heads/'):]
-            new = node
-            old = bmarks[bmark].hex() if bmark in bmarks else ''
-
-            if old == new:
-                continue
-
-            print "ok %s" % ref
-            if bmark != fake_bmark and \
-                    not (bmark == 'master' and bmark not in parser.repo._bookmarks):
-                p_bmarks.append((ref, bmark, old, new))
-
-            if peer:
-                remote_old = peer.listkeys('bookmarks').get(bmark)
-                if remote_old:
-                    if not check_tip(ref, 'bookmarks', bmark, remote_old):
-                        print "error %s fetch first" % ref
-                        need_fetch = True
-                        continue
-
-            p_revs[bnode] = ref
-        elif ref.startswith('refs/tags/'):
-            if dry_run:
-                print "ok %s" % ref
-                continue
-            tag = ref[len('refs/tags/'):]
-            tag = hgref(tag)
-            author, msg = parsed_tags.get(tag, (None, None))
-            if mode == 'git':
-                if not msg:
-                    msg = 'Added tag %s for changeset %s' % (tag, node[:12])
-                tagnode, branch = write_tag(parser.repo, tag, node, msg, author)
-                p_revs[tagnode] = 'refs/heads/branches/' + gitref(branch)
-            else:
-                fp = parser.repo.opener('localtags', 'a')
-                fp.write('%s %s\n' % (node, tag))
-                fp.close()
-            p_revs[bnode] = ref
-            print "ok %s" % ref
-        else:
-            # transport-helper/fast-export bugs
-            continue
-
-    if need_fetch:
-        print
-        return
-
-    if dry_run:
-        if peer and not force_push:
-            checkheads(parser.repo, peer, p_revs)
-        print
-        return
-
-    if peer:
-        if not push(parser.repo, peer, parsed_refs, p_revs):
-            # do not update bookmarks
-            print
-            return
-
-        # update remote bookmarks
-        remote_bmarks = peer.listkeys('bookmarks')
-        for ref, bmark, old, new in p_bmarks:
-            if force_push:
-                old = remote_bmarks.get(bmark, '')
-            if not peer.pushkey('bookmarks', bmark, old, new):
-                print "error %s" % ref
-    else:
-        # update local bookmarks
-        for ref, bmark, old, new in p_bmarks:
-            if not bookmarks.pushbookmark(parser.repo, bmark, old, new):
-                print "error %s" % ref
-
-    print
-
-def do_option(parser):
-    global dry_run, force_push
-    _, key, value = parser.line.split(' ')
-    if key == 'dry-run':
-        dry_run = (value == 'true')
-        print 'ok'
-    elif key == 'force':
-        force_push = (value == 'true')
-        print 'ok'
-    else:
-        print 'unsupported'
-
-def fix_path(alias, repo, orig_url):
-    url = urlparse.urlparse(orig_url, 'file')
-    if url.scheme != 'file' or os.path.isabs(os.path.expanduser(url.path)):
-        return
-    abs_url = urlparse.urljoin("%s/" % os.getcwd(), orig_url)
-    cmd = ['git', 'config', 'remote.%s.url' % alias, "hg::%s" % abs_url]
-    subprocess.call(cmd)
-
-def main(args):
-    global prefix, gitdir, dirname, branches, bmarks
-    global marks, blob_marks, parsed_refs
-    global peer, mode, bad_mail, bad_name
-    global track_branches, force_push, is_tmp
-    global parsed_tags
-    global filenodes
-    global fake_bmark, hg_version
-    global dry_run
-    global notes, alias
-
-    marks = None
-    is_tmp = False
-    gitdir = os.environ.get('GIT_DIR', None)
-
-    if len(args) < 3:
-        die('Not enough arguments.')
-
-    if not gitdir:
-        die('GIT_DIR not set')
-
-    alias = args[1]
-    url = args[2]
-    peer = None
-
-    hg_git_compat = get_config_bool('remote-hg.hg-git-compat')
-    track_branches = get_config_bool('remote-hg.track-branches', True)
-    force_push = False
-
-    if hg_git_compat:
-        mode = 'hg'
-        bad_mail = 'none@none'
-        bad_name = ''
-    else:
-        mode = 'git'
-        bad_mail = 'unknown'
-        bad_name = 'Unknown'
-
-    if alias[4:] == url:
-        is_tmp = True
-        alias = hashlib.sha1(alias).hexdigest()
-
-    dirname = os.path.join(gitdir, 'hg', alias)
-    branches = {}
-    bmarks = {}
-    blob_marks = {}
-    parsed_refs = {}
-    parsed_tags = {}
-    filenodes = {}
-    fake_bmark = None
-    try:
-        hg_version = tuple(int(e) for e in util.version().split('.'))
-    except:
-        hg_version = None
-    dry_run = False
-    notes = set()
-
-    repo = get_repo(url, alias)
-    prefix = 'refs/hg/%s' % alias
-
-    if not is_tmp:
-        fix_path(alias, peer or repo, url)
-
-    marks_path = os.path.join(dirname, 'marks-hg')
-    marks = Marks(marks_path, repo)
-
-    if sys.platform == 'win32':
-        import msvcrt
-        msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
-
-    parser = Parser(repo)
-    for line in parser:
-        if parser.check('capabilities'):
-            do_capabilities(parser)
-        elif parser.check('list'):
-            do_list(parser)
-        elif parser.check('import'):
-            do_import(parser)
-        elif parser.check('export'):
-            do_export(parser)
-        elif parser.check('option'):
-            do_option(parser)
-        else:
-            die('unhandled command: %s' % line)
-        sys.stdout.flush()
 
-def bye():
-    if not marks:
-        return
-    if not is_tmp:
-        marks.store()
-    else:
-        shutil.rmtree(dirname)
+sys.stderr.write('WARNING: git-remote-hg is now maintained independently.\n')
+sys.stderr.write('WARNING: For more information visit https://github.com/felipec/git-remote-hg\n')
 
-atexit.register(bye)
-sys.exit(main(sys.argv))
+sys.stderr.write('''WARNING:
+WARNING: You can pick a directory on your $PATH and download it, e.g.:
+WARNING:   $ wget -O $HOME/bin/git-remote-hg \\
+WARNING:     https://raw.github.com/felipec/git-remote-hg/master/git-remote-hg
+WARNING:   $ chmod +x $HOME/bin/git-remote-hg
+''')
diff --git a/contrib/remote-helpers/test-bzr.sh b/contrib/remote-helpers/test-bzr.sh
deleted file mode 100755 (executable)
index a4656ce..0000000
+++ /dev/null
@@ -1,438 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2012 Felipe Contreras
-#
-
-test_description='Test remote-bzr'
-
-test -n "$TEST_DIRECTORY" || TEST_DIRECTORY=${0%/*}/../../t
-. "$TEST_DIRECTORY"/test-lib.sh
-
-if ! test_have_prereq PYTHON
-then
-       skip_all='skipping remote-bzr tests; python not available'
-       test_done
-fi
-
-if ! python -c 'import bzrlib'
-then
-       skip_all='skipping remote-bzr tests; bzr not available'
-       test_done
-fi
-
-check () {
-       echo $3 >expected &&
-       git --git-dir=$1/.git log --format='%s' -1 $2 >actual
-       test_cmp expected actual
-}
-
-bzr whoami "A U Thor <author@example.com>"
-
-test_expect_success 'cloning' '
-       (
-       bzr init bzrrepo &&
-       cd bzrrepo &&
-       echo one >content &&
-       bzr add content &&
-       bzr commit -m one
-       ) &&
-
-       git clone "bzr::bzrrepo" gitrepo &&
-       check gitrepo HEAD one
-'
-
-test_expect_success 'pulling' '
-       (
-       cd bzrrepo &&
-       echo two >content &&
-       bzr commit -m two
-       ) &&
-
-       (cd gitrepo && git pull) &&
-
-       check gitrepo HEAD two
-'
-
-test_expect_success 'pushing' '
-       (
-       cd gitrepo &&
-       echo three >content &&
-       git commit -a -m three &&
-       git push
-       ) &&
-
-       echo three >expected &&
-       cat bzrrepo/content >actual &&
-       test_cmp expected actual
-'
-
-test_expect_success 'forced pushing' '
-       (
-       cd gitrepo &&
-       echo three-new >content &&
-       git commit -a --amend -m three-new &&
-       git push -f
-       ) &&
-
-       (
-       cd bzrrepo &&
-       # the forced update overwrites the bzr branch but not the bzr
-       # working directory (it tries to merge instead)
-       bzr revert
-       ) &&
-
-       echo three-new >expected &&
-       cat bzrrepo/content >actual &&
-       test_cmp expected actual
-'
-
-test_expect_success 'roundtrip' '
-       (
-       cd gitrepo &&
-       git pull &&
-       git log --format="%s" -1 origin/master >actual
-       ) &&
-       echo three-new >expected &&
-       test_cmp expected actual &&
-
-       (cd gitrepo && git push && git pull) &&
-
-       (
-       cd bzrrepo &&
-       echo four >content &&
-       bzr commit -m four
-       ) &&
-
-       (cd gitrepo && git pull && git push) &&
-
-       check gitrepo HEAD four &&
-
-       (
-       cd gitrepo &&
-       echo five >content &&
-       git commit -a -m five &&
-       git push && git pull
-       ) &&
-
-       (cd bzrrepo && bzr revert) &&
-
-       echo five >expected &&
-       cat bzrrepo/content >actual &&
-       test_cmp expected actual
-'
-
-cat >expected <<\EOF
-100644 blob 54f9d6da5c91d556e6b54340b1327573073030af   content
-100755 blob 68769579c3eaadbe555379b9c3538e6628bae1eb   executable
-120000 blob 6b584e8ece562ebffc15d38808cd6b98fc3d97ea   link
-EOF
-
-test_expect_success 'special modes' '
-       (
-       cd bzrrepo &&
-       echo exec >executable
-       chmod +x executable &&
-       bzr add executable
-       bzr commit -m exec &&
-       ln -s content link
-       bzr add link
-       bzr commit -m link &&
-       mkdir dir &&
-       bzr add dir &&
-       bzr commit -m dir
-       ) &&
-
-       (
-       cd gitrepo &&
-       git pull
-       git ls-tree HEAD >../actual
-       ) &&
-
-       test_cmp expected actual &&
-
-       (
-       cd gitrepo &&
-       git cat-file -p HEAD:link >../actual
-       ) &&
-
-       printf content >expected &&
-       test_cmp expected actual
-'
-
-cat >expected <<\EOF
-100644 blob 54f9d6da5c91d556e6b54340b1327573073030af   content
-100755 blob 68769579c3eaadbe555379b9c3538e6628bae1eb   executable
-120000 blob 6b584e8ece562ebffc15d38808cd6b98fc3d97ea   link
-040000 tree 35c0caa46693cef62247ac89a680f0c5ce32b37b   movedir-new
-EOF
-
-test_expect_success 'moving directory' '
-       (
-       cd bzrrepo &&
-       mkdir movedir &&
-       echo one >movedir/one &&
-       echo two >movedir/two &&
-       bzr add movedir &&
-       bzr commit -m movedir &&
-       bzr mv movedir movedir-new &&
-       bzr commit -m movedir-new
-       ) &&
-
-       (
-       cd gitrepo &&
-       git pull &&
-       git ls-tree HEAD >../actual
-       ) &&
-
-       test_cmp expected actual
-'
-
-test_expect_success 'different authors' '
-       (
-       cd bzrrepo &&
-       echo john >>content &&
-       bzr commit -m john \
-         --author "Jane Rey <jrey@example.com>" \
-         --author "John Doe <jdoe@example.com>"
-       ) &&
-
-       (
-       cd gitrepo &&
-       git pull &&
-       git show --format="%an <%ae>, %cn <%ce>" --quiet >../actual
-       ) &&
-
-       echo "Jane Rey <jrey@example.com>, A U Thor <author@example.com>" >expected &&
-       test_cmp expected actual
-'
-
-# cleanup previous stuff
-rm -rf bzrrepo gitrepo
-
-test_expect_success 'fetch utf-8 filenames' '
-       test_when_finished "rm -rf bzrrepo gitrepo && LC_ALL=C" &&
-
-       LC_ALL=en_US.UTF-8
-       export LC_ALL
-
-       (
-       bzr init bzrrepo &&
-       cd bzrrepo &&
-
-       echo test >>"ærø" &&
-       bzr add "ærø" &&
-       echo test >>"ø~?" &&
-       bzr add "ø~?" &&
-       bzr commit -m add-utf-8 &&
-       echo test >>"ærø" &&
-       bzr commit -m test-utf-8 &&
-       bzr rm "ø~?" &&
-       bzr mv "ærø" "ø~?" &&
-       bzr commit -m bzr-mv-utf-8
-       ) &&
-
-       (
-       git clone "bzr::bzrrepo" gitrepo &&
-       cd gitrepo &&
-       git -c core.quotepath=false ls-files >../actual
-       ) &&
-       echo "ø~?" >expected &&
-       test_cmp expected actual
-'
-
-test_expect_success 'push utf-8 filenames' '
-       test_when_finished "rm -rf bzrrepo gitrepo && LC_ALL=C" &&
-
-       mkdir -p tmp && cd tmp &&
-
-       LC_ALL=en_US.UTF-8
-       export LC_ALL
-
-       (
-       bzr init bzrrepo &&
-       cd bzrrepo &&
-
-       echo one >>content &&
-       bzr add content &&
-       bzr commit -m one
-       ) &&
-
-       (
-       git clone "bzr::bzrrepo" gitrepo &&
-       cd gitrepo &&
-
-       echo test >>"ærø" &&
-       git add "ærø" &&
-       git commit -m utf-8 &&
-
-       git push
-       ) &&
-
-       (cd bzrrepo && bzr ls >../actual) &&
-       printf "content\nærø\n" >expected &&
-       test_cmp expected actual
-'
-
-test_expect_success 'pushing a merge' '
-       test_when_finished "rm -rf bzrrepo gitrepo" &&
-
-       (
-       bzr init bzrrepo &&
-       cd bzrrepo &&
-       echo one >content &&
-       bzr add content &&
-       bzr commit -m one
-       ) &&
-
-       git clone "bzr::bzrrepo" gitrepo &&
-
-       (
-       cd bzrrepo &&
-       echo two >content &&
-       bzr commit -m two
-       ) &&
-
-       (
-       cd gitrepo &&
-       echo three >content &&
-       git commit -a -m three &&
-       git fetch &&
-       git merge origin/master || true &&
-       echo three >content &&
-       git commit -a --no-edit &&
-       git push
-       ) &&
-
-       echo three >expected &&
-       cat bzrrepo/content >actual &&
-       test_cmp expected actual
-'
-
-cat >expected <<\EOF
-origin/HEAD
-origin/branch
-origin/trunk
-EOF
-
-test_expect_success 'proper bzr repo' '
-       test_when_finished "rm -rf bzrrepo gitrepo" &&
-
-       bzr init-repo bzrrepo &&
-
-       (
-       bzr init bzrrepo/trunk &&
-       cd bzrrepo/trunk &&
-       echo one >>content &&
-       bzr add content &&
-       bzr commit -m one
-       ) &&
-
-       (
-       bzr branch bzrrepo/trunk bzrrepo/branch &&
-       cd bzrrepo/branch &&
-       echo two >>content &&
-       bzr commit -m one
-       ) &&
-
-       (
-       git clone "bzr::bzrrepo" gitrepo &&
-       cd gitrepo &&
-       git for-each-ref --format "%(refname:short)" refs/remotes/origin >../actual
-       ) &&
-
-       test_cmp expected actual
-'
-
-test_expect_success 'strip' '
-       test_when_finished "rm -rf bzrrepo gitrepo" &&
-
-       (
-       bzr init bzrrepo &&
-       cd bzrrepo &&
-
-       echo one >>content &&
-       bzr add content &&
-       bzr commit -m one &&
-
-       echo two >>content &&
-       bzr commit -m two
-       ) &&
-
-       git clone "bzr::bzrrepo" gitrepo &&
-
-       (
-       cd bzrrepo &&
-       bzr uncommit --force &&
-
-       echo three >>content &&
-       bzr commit -m three &&
-
-       echo four >>content &&
-       bzr commit -m four &&
-       bzr log --line | sed -e "s/^[0-9][0-9]*: //" >../expected
-       ) &&
-
-       (
-       cd gitrepo &&
-       git fetch &&
-       git log --format="%an %ad %s" --date=short origin/master >../actual
-       ) &&
-
-       test_cmp expected actual
-'
-
-test_expect_success 'export utf-8 authors' '
-       test_when_finished "rm -rf bzrrepo gitrepo && LC_ALL=C && GIT_COMMITTER_NAME=\"C O Mitter\""
-
-       LC_ALL=en_US.UTF-8
-       export LC_ALL
-
-       GIT_COMMITTER_NAME="Grégoire"
-       export GIT_COMMITTER_NAME
-
-       bzr init bzrrepo &&
-
-       (
-       git init gitrepo &&
-       cd gitrepo &&
-       echo greg >>content &&
-       git add content &&
-       git commit -m one &&
-       git remote add bzr "bzr::../bzrrepo" &&
-       git push bzr master
-       ) &&
-
-       (
-       cd bzrrepo &&
-       bzr log | grep "^committer: " >../actual
-       ) &&
-
-       echo "committer: Grégoire <committer@example.com>" >expected &&
-       test_cmp expected actual
-'
-
-test_expect_success 'push different author' '
-       test_when_finished "rm -rf bzrrepo gitrepo" &&
-
-       bzr init bzrrepo &&
-
-       (
-       git init gitrepo &&
-       cd gitrepo &&
-       echo john >> content &&
-       git add content &&
-       git commit -m john --author "John Doe <jdoe@example.com>" &&
-       git remote add bzr "bzr::../bzrrepo" &&
-       git push bzr master
-       ) &&
-
-       (
-       cd bzrrepo &&
-       bzr log | grep "^author: " > ../actual
-       ) &&
-
-       echo "author: John Doe <jdoe@example.com>" > expected &&
-       test_cmp expected actual
-'
-
-test_done
diff --git a/contrib/remote-helpers/test-hg-bidi.sh b/contrib/remote-helpers/test-hg-bidi.sh
deleted file mode 100755 (executable)
index d86e147..0000000
+++ /dev/null
@@ -1,243 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2012 Felipe Contreras
-#
-# Base commands from hg-git tests:
-# https://bitbucket.org/durin42/hg-git/src
-#
-
-test_description='Test bidirectionality of remote-hg'
-
-test -n "$TEST_DIRECTORY" || TEST_DIRECTORY=${0%/*}/../../t
-. "$TEST_DIRECTORY"/test-lib.sh
-
-if ! test_have_prereq PYTHON
-then
-       skip_all='skipping remote-hg tests; python not available'
-       test_done
-fi
-
-if ! python -c 'import mercurial'
-then
-       skip_all='skipping remote-hg tests; mercurial not available'
-       test_done
-fi
-
-# clone to a git repo
-git_clone () {
-       git clone -q "hg::$1" $2
-}
-
-# clone to an hg repo
-hg_clone () {
-       (
-       hg init $2 &&
-       cd $1 &&
-       git push -q "hg::../$2" 'refs/tags/*:refs/tags/*' 'refs/heads/*:refs/heads/*'
-       ) &&
-
-       (cd $2 && hg -q update)
-}
-
-# push an hg repo
-hg_push () {
-       (
-       cd $2
-       git checkout -q -b tmp &&
-       git fetch -q "hg::../$1" 'refs/tags/*:refs/tags/*' 'refs/heads/*:refs/heads/*' &&
-       git checkout -q @{-1} &&
-       git branch -q -D tmp 2>/dev/null || true
-       )
-}
-
-hg_log () {
-       hg -R $1 log --graph --debug
-}
-
-setup () {
-       (
-       echo "[ui]"
-       echo "username = A U Thor <author@example.com>"
-       echo "[defaults]"
-       echo "backout = -d \"0 0\""
-       echo "commit = -d \"0 0\""
-       echo "debugrawcommit = -d \"0 0\""
-       echo "tag = -d \"0 0\""
-       echo "[extensions]"
-       echo "graphlog ="
-       ) >>"$HOME"/.hgrc &&
-       git config --global remote-hg.hg-git-compat true
-       git config --global remote-hg.track-branches true
-
-       HGEDITOR=/usr/bin/true
-       GIT_AUTHOR_DATE="2007-01-01 00:00:00 +0230"
-       GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
-       export HGEDITOR GIT_AUTHOR_DATE GIT_COMMITTER_DATE
-}
-
-setup
-
-test_expect_success 'encoding' '
-       test_when_finished "rm -rf gitrepo* hgrepo*" &&
-
-       (
-       git init -q gitrepo &&
-       cd gitrepo &&
-
-       echo alpha >alpha &&
-       git add alpha &&
-       git commit -m "add älphà" &&
-
-       GIT_AUTHOR_NAME="tést èncödîng" &&
-       export GIT_AUTHOR_NAME &&
-       echo beta >beta &&
-       git add beta &&
-       git commit -m "add beta" &&
-
-       echo gamma >gamma &&
-       git add gamma &&
-       git commit -m "add gämmâ" &&
-
-       : TODO git config i18n.commitencoding latin-1 &&
-       echo delta >delta &&
-       git add delta &&
-       git commit -m "add déltà"
-       ) &&
-
-       hg_clone gitrepo hgrepo &&
-       git_clone hgrepo gitrepo2 &&
-       hg_clone gitrepo2 hgrepo2 &&
-
-       HGENCODING=utf-8 hg_log hgrepo >expected &&
-       HGENCODING=utf-8 hg_log hgrepo2 >actual &&
-
-       test_cmp expected actual
-'
-
-test_expect_success 'file removal' '
-       test_when_finished "rm -rf gitrepo* hgrepo*" &&
-
-       (
-       git init -q gitrepo &&
-       cd gitrepo &&
-       echo alpha >alpha &&
-       git add alpha &&
-       git commit -m "add alpha" &&
-       echo beta >beta &&
-       git add beta &&
-       git commit -m "add beta"
-       mkdir foo &&
-       echo blah >foo/bar &&
-       git add foo &&
-       git commit -m "add foo" &&
-       git rm alpha &&
-       git commit -m "remove alpha" &&
-       git rm foo/bar &&
-       git commit -m "remove foo/bar"
-       ) &&
-
-       hg_clone gitrepo hgrepo &&
-       git_clone hgrepo gitrepo2 &&
-       hg_clone gitrepo2 hgrepo2 &&
-
-       hg_log hgrepo >expected &&
-       hg_log hgrepo2 >actual &&
-
-       test_cmp expected actual
-'
-
-test_expect_success 'git tags' '
-       test_when_finished "rm -rf gitrepo* hgrepo*" &&
-
-       (
-       git init -q gitrepo &&
-       cd gitrepo &&
-       git config receive.denyCurrentBranch ignore &&
-       echo alpha >alpha &&
-       git add alpha &&
-       git commit -m "add alpha" &&
-       git tag alpha &&
-
-       echo beta >beta &&
-       git add beta &&
-       git commit -m "add beta" &&
-       git tag -a -m "added tag beta" beta
-       ) &&
-
-       hg_clone gitrepo hgrepo &&
-       git_clone hgrepo gitrepo2 &&
-       hg_clone gitrepo2 hgrepo2 &&
-
-       hg_log hgrepo >expected &&
-       hg_log hgrepo2 >actual &&
-
-       test_cmp expected actual
-'
-
-test_expect_success 'hg branch' '
-       test_when_finished "rm -rf gitrepo* hgrepo*" &&
-
-       (
-       git init -q gitrepo &&
-       cd gitrepo &&
-
-       echo alpha >alpha &&
-       git add alpha &&
-       git commit -q -m "add alpha" &&
-       git checkout -q -b not-master
-       ) &&
-
-       (
-       hg_clone gitrepo hgrepo &&
-
-       cd hgrepo &&
-       hg -q co default &&
-       hg mv alpha beta &&
-       hg -q commit -m "rename alpha to beta" &&
-       hg branch gamma | grep -v "permanent and global" &&
-       hg -q commit -m "started branch gamma"
-       ) &&
-
-       hg_push hgrepo gitrepo &&
-       hg_clone gitrepo hgrepo2 &&
-
-       : Back to the common revision &&
-       (cd hgrepo && hg checkout default) &&
-
-       hg_log hgrepo >expected &&
-       hg_log hgrepo2 >actual &&
-
-       test_cmp expected actual
-'
-
-test_expect_success 'hg tags' '
-       test_when_finished "rm -rf gitrepo* hgrepo*" &&
-
-       (
-       git init -q gitrepo &&
-       cd gitrepo &&
-
-       echo alpha >alpha &&
-       git add alpha &&
-       git commit -m "add alpha" &&
-       git checkout -q -b not-master
-       ) &&
-
-       (
-       hg_clone gitrepo hgrepo &&
-
-       cd hgrepo &&
-       hg co default &&
-       hg tag alpha
-       ) &&
-
-       hg_push hgrepo gitrepo &&
-       hg_clone gitrepo hgrepo2 &&
-
-       hg_log hgrepo >expected &&
-       hg_log hgrepo2 >actual &&
-
-       test_cmp expected actual
-'
-
-test_done
diff --git a/contrib/remote-helpers/test-hg-hg-git.sh b/contrib/remote-helpers/test-hg-hg-git.sh
deleted file mode 100755 (executable)
index b23909a..0000000
+++ /dev/null
@@ -1,542 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2012 Felipe Contreras
-#
-# Base commands from hg-git tests:
-# https://bitbucket.org/durin42/hg-git/src
-#
-
-test_description='Test remote-hg output compared to hg-git'
-
-test -n "$TEST_DIRECTORY" || TEST_DIRECTORY=${0%/*}/../../t
-. "$TEST_DIRECTORY"/test-lib.sh
-
-if ! test_have_prereq PYTHON
-then
-       skip_all='skipping remote-hg tests; python not available'
-       test_done
-fi
-
-if ! python -c 'import mercurial'
-then
-       skip_all='skipping remote-hg tests; mercurial not available'
-       test_done
-fi
-
-if ! python -c 'import hggit'
-then
-       skip_all='skipping remote-hg tests; hg-git not available'
-       test_done
-fi
-
-# clone to a git repo with git
-git_clone_git () {
-       git clone -q "hg::$1" $2 &&
-       (cd $2 && git checkout master && git branch -D default)
-}
-
-# clone to an hg repo with git
-hg_clone_git () {
-       (
-       hg init $2 &&
-       hg -R $2 bookmark -i master &&
-       cd $1 &&
-       git push -q "hg::../$2" 'refs/tags/*:refs/tags/*' 'refs/heads/*:refs/heads/*'
-       ) &&
-
-       (cd $2 && hg -q update)
-}
-
-# clone to a git repo with hg
-git_clone_hg () {
-       (
-       git init -q $2 &&
-       cd $1 &&
-       hg bookmark -i -f -r tip master &&
-       hg -q push -r master ../$2 || true
-       )
-}
-
-# clone to an hg repo with hg
-hg_clone_hg () {
-       hg -q clone $1 $2
-}
-
-# push an hg repo with git
-hg_push_git () {
-       (
-       cd $2
-       git checkout -q -b tmp &&
-       git fetch -q "hg::../$1" 'refs/tags/*:refs/tags/*' 'refs/heads/*:refs/heads/*' &&
-       git branch -D default &&
-       git checkout -q @{-1} &&
-       git branch -q -D tmp 2>/dev/null || true
-       )
-}
-
-# push an hg git repo with hg
-hg_push_hg () {
-       (
-       cd $1 &&
-       hg -q push ../$2 || true
-       )
-}
-
-hg_log () {
-       hg -R $1 log --graph --debug >log &&
-       grep -v 'tag: *default/' log
-}
-
-git_log () {
-       git --git-dir=$1/.git fast-export --branches
-}
-
-setup () {
-       (
-       echo "[ui]"
-       echo "username = A U Thor <author@example.com>"
-       echo "[defaults]"
-       echo "backout = -d \"0 0\""
-       echo "commit = -d \"0 0\""
-       echo "debugrawcommit = -d \"0 0\""
-       echo "tag = -d \"0 0\""
-       echo "[extensions]"
-       echo "hgext.bookmarks ="
-       echo "hggit ="
-       echo "graphlog ="
-       ) >>"$HOME"/.hgrc &&
-       git config --global receive.denycurrentbranch warn
-       git config --global remote-hg.hg-git-compat true
-       git config --global remote-hg.track-branches false
-
-       HGEDITOR=true
-       HGMERGE=true
-
-       GIT_AUTHOR_DATE="2007-01-01 00:00:00 +0230"
-       GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
-       export HGEDITOR HGMERGE GIT_AUTHOR_DATE GIT_COMMITTER_DATE
-}
-
-setup
-
-test_expect_success 'executable bit' '
-       test_when_finished "rm -rf gitrepo* hgrepo*" &&
-
-       (
-       git init -q gitrepo &&
-       cd gitrepo &&
-       echo alpha >alpha &&
-       chmod 0644 alpha &&
-       git add alpha &&
-       git commit -m "add alpha" &&
-       chmod 0755 alpha &&
-       git add alpha &&
-       git commit -m "set executable bit" &&
-       chmod 0644 alpha &&
-       git add alpha &&
-       git commit -m "clear executable bit"
-       ) &&
-
-       for x in hg git
-       do
-               (
-               hg_clone_$x gitrepo hgrepo-$x &&
-               cd hgrepo-$x &&
-               hg_log . &&
-               hg manifest -r 1 -v &&
-               hg manifest -v
-               ) >"output-$x" &&
-
-               git_clone_$x hgrepo-$x gitrepo2-$x &&
-               git_log gitrepo2-$x >"log-$x"
-       done &&
-
-       test_cmp output-hg output-git &&
-       test_cmp log-hg log-git
-'
-
-test_expect_success 'symlink' '
-       test_when_finished "rm -rf gitrepo* hgrepo*" &&
-
-       (
-       git init -q gitrepo &&
-       cd gitrepo &&
-       echo alpha >alpha &&
-       git add alpha &&
-       git commit -m "add alpha" &&
-       ln -s alpha beta &&
-       git add beta &&
-       git commit -m "add beta"
-       ) &&
-
-       for x in hg git
-       do
-               (
-               hg_clone_$x gitrepo hgrepo-$x &&
-               cd hgrepo-$x &&
-               hg_log . &&
-               hg manifest -v
-               ) >"output-$x" &&
-
-               git_clone_$x hgrepo-$x gitrepo2-$x &&
-               git_log gitrepo2-$x >"log-$x"
-       done &&
-
-       test_cmp output-hg output-git &&
-       test_cmp log-hg log-git
-'
-
-test_expect_success 'merge conflict 1' '
-       test_when_finished "rm -rf gitrepo* hgrepo*" &&
-
-       (
-       hg init hgrepo1 &&
-       cd hgrepo1 &&
-       echo A >afile &&
-       hg add afile &&
-       hg ci -m "origin" &&
-
-       echo B >afile &&
-       hg ci -m "A->B" &&
-
-       hg up -r0 &&
-       echo C >afile &&
-       hg ci -m "A->C" &&
-
-       hg merge -r1 &&
-       echo C >afile &&
-       hg resolve -m afile &&
-       hg ci -m "merge to C"
-       ) &&
-
-       for x in hg git
-       do
-               git_clone_$x hgrepo1 gitrepo-$x &&
-               hg_clone_$x gitrepo-$x hgrepo2-$x &&
-               hg_log hgrepo2-$x >"hg-log-$x" &&
-               git_log gitrepo-$x >"git-log-$x"
-       done &&
-
-       test_cmp hg-log-hg hg-log-git &&
-       test_cmp git-log-hg git-log-git
-'
-
-test_expect_success 'merge conflict 2' '
-       test_when_finished "rm -rf gitrepo* hgrepo*" &&
-
-       (
-       hg init hgrepo1 &&
-       cd hgrepo1 &&
-       echo A >afile &&
-       hg add afile &&
-       hg ci -m "origin" &&
-
-       echo B >afile &&
-       hg ci -m "A->B" &&
-
-       hg up -r0 &&
-       echo C >afile &&
-       hg ci -m "A->C" &&
-
-       hg merge -r1 || true &&
-       echo B >afile &&
-       hg resolve -m afile &&
-       hg ci -m "merge to B"
-       ) &&
-
-       for x in hg git
-       do
-               git_clone_$x hgrepo1 gitrepo-$x &&
-               hg_clone_$x gitrepo-$x hgrepo2-$x &&
-               hg_log hgrepo2-$x >"hg-log-$x" &&
-               git_log gitrepo-$x >"git-log-$x"
-       done &&
-
-       test_cmp hg-log-hg hg-log-git &&
-       test_cmp git-log-hg git-log-git
-'
-
-test_expect_success 'converged merge' '
-       test_when_finished "rm -rf gitrepo* hgrepo*" &&
-
-       (
-       hg init hgrepo1 &&
-       cd hgrepo1 &&
-       echo A >afile &&
-       hg add afile &&
-       hg ci -m "origin" &&
-
-       echo B >afile &&
-       hg ci -m "A->B" &&
-
-       echo C >afile &&
-       hg ci -m "B->C" &&
-
-       hg up -r0 &&
-       echo C >afile &&
-       hg ci -m "A->C" &&
-
-       hg merge -r2 || true &&
-       hg ci -m "merge"
-       ) &&
-
-       for x in hg git
-       do
-               git_clone_$x hgrepo1 gitrepo-$x &&
-               hg_clone_$x gitrepo-$x hgrepo2-$x &&
-               hg_log hgrepo2-$x >"hg-log-$x" &&
-               git_log gitrepo-$x >"git-log-$x"
-       done &&
-
-       test_cmp hg-log-hg hg-log-git &&
-       test_cmp git-log-hg git-log-git
-'
-
-test_expect_success 'encoding' '
-       test_when_finished "rm -rf gitrepo* hgrepo*" &&
-
-       (
-       git init -q gitrepo &&
-       cd gitrepo &&
-
-       echo alpha >alpha &&
-       git add alpha &&
-       git commit -m "add älphà" &&
-
-       GIT_AUTHOR_NAME="tést èncödîng" &&
-       export GIT_AUTHOR_NAME &&
-       echo beta >beta &&
-       git add beta &&
-       git commit -m "add beta" &&
-
-       echo gamma >gamma &&
-       git add gamma &&
-       git commit -m "add gämmâ" &&
-
-       : TODO git config i18n.commitencoding latin-1 &&
-       echo delta >delta &&
-       git add delta &&
-       git commit -m "add déltà"
-       ) &&
-
-       for x in hg git
-       do
-               hg_clone_$x gitrepo hgrepo-$x &&
-               git_clone_$x hgrepo-$x gitrepo2-$x &&
-
-               HGENCODING=utf-8 hg_log hgrepo-$x >"hg-log-$x" &&
-               git_log gitrepo2-$x >"git-log-$x"
-       done &&
-
-       test_cmp hg-log-hg hg-log-git &&
-       test_cmp git-log-hg git-log-git
-'
-
-test_expect_success 'file removal' '
-       test_when_finished "rm -rf gitrepo* hgrepo*" &&
-
-       (
-       git init -q gitrepo &&
-       cd gitrepo &&
-       echo alpha >alpha &&
-       git add alpha &&
-       git commit -m "add alpha" &&
-       echo beta >beta &&
-       git add beta &&
-       git commit -m "add beta"
-       mkdir foo &&
-       echo blah >foo/bar &&
-       git add foo &&
-       git commit -m "add foo" &&
-       git rm alpha &&
-       git commit -m "remove alpha" &&
-       git rm foo/bar &&
-       git commit -m "remove foo/bar"
-       ) &&
-
-       for x in hg git
-       do
-               (
-               hg_clone_$x gitrepo hgrepo-$x &&
-               cd hgrepo-$x &&
-               hg_log . &&
-               hg manifest -r 3 &&
-               hg manifest
-               ) >"output-$x" &&
-
-               git_clone_$x hgrepo-$x gitrepo2-$x &&
-               git_log gitrepo2-$x >"log-$x"
-       done &&
-
-       test_cmp output-hg output-git &&
-       test_cmp log-hg log-git
-'
-
-test_expect_success 'git tags' '
-       test_when_finished "rm -rf gitrepo* hgrepo*" &&
-
-       (
-       git init -q gitrepo &&
-       cd gitrepo &&
-       git config receive.denyCurrentBranch ignore &&
-       echo alpha >alpha &&
-       git add alpha &&
-       git commit -m "add alpha" &&
-       git tag alpha &&
-
-       echo beta >beta &&
-       git add beta &&
-       git commit -m "add beta" &&
-       git tag -a -m "added tag beta" beta
-       ) &&
-
-       for x in hg git
-       do
-               hg_clone_$x gitrepo hgrepo-$x &&
-               hg_log hgrepo-$x >"log-$x"
-       done &&
-
-       test_cmp log-hg log-git
-'
-
-test_expect_success 'hg author' '
-       test_when_finished "rm -rf gitrepo* hgrepo*" &&
-
-       for x in hg git
-       do
-               (
-               git init -q gitrepo-$x &&
-               cd gitrepo-$x &&
-
-               echo alpha >alpha &&
-               git add alpha &&
-               git commit -m "add alpha" &&
-               git checkout -q -b not-master
-               ) &&
-
-               (
-               hg_clone_$x gitrepo-$x hgrepo-$x &&
-               cd hgrepo-$x &&
-
-               hg co master &&
-               echo beta >beta &&
-               hg add beta &&
-               hg commit -u "test" -m "add beta" &&
-
-               echo gamma >>beta &&
-               hg commit -u "test <test@example.com> (comment)" -m "modify beta" &&
-
-               echo gamma >gamma &&
-               hg add gamma &&
-               hg commit -u "<test@example.com>" -m "add gamma" &&
-
-               echo delta >delta &&
-               hg add delta &&
-               hg commit -u "name<test@example.com>" -m "add delta" &&
-
-               echo epsilon >epsilon &&
-               hg add epsilon &&
-               hg commit -u "name <test@example.com" -m "add epsilon" &&
-
-               echo zeta >zeta &&
-               hg add zeta &&
-               hg commit -u " test " -m "add zeta" &&
-
-               echo eta >eta &&
-               hg add eta &&
-               hg commit -u "test < test@example.com >" -m "add eta" &&
-
-               echo theta >theta &&
-               hg add theta &&
-               hg commit -u "test >test@example.com>" -m "add theta" &&
-
-               echo iota >iota &&
-               hg add iota &&
-               hg commit -u "test <test <at> example <dot> com>" -m "add iota"
-               ) &&
-
-               hg_push_$x hgrepo-$x gitrepo-$x &&
-               hg_clone_$x gitrepo-$x hgrepo2-$x &&
-
-               hg_log hgrepo2-$x >"hg-log-$x" &&
-               git_log gitrepo-$x >"git-log-$x"
-       done &&
-
-       test_cmp hg-log-hg hg-log-git &&
-       test_cmp git-log-hg git-log-git
-'
-
-test_expect_success 'hg branch' '
-       test_when_finished "rm -rf gitrepo* hgrepo*" &&
-
-       for x in hg git
-       do
-               (
-               git init -q gitrepo-$x &&
-               cd gitrepo-$x &&
-
-               echo alpha >alpha &&
-               git add alpha &&
-               git commit -q -m "add alpha" &&
-               git checkout -q -b not-master
-               ) &&
-
-               (
-               hg_clone_$x gitrepo-$x hgrepo-$x &&
-
-               cd hgrepo-$x &&
-               hg -q co master &&
-               hg mv alpha beta &&
-               hg -q commit -m "rename alpha to beta" &&
-               hg branch gamma | grep -v "permanent and global" &&
-               hg -q commit -m "started branch gamma"
-               ) &&
-
-               hg_push_$x hgrepo-$x gitrepo-$x &&
-               hg_clone_$x gitrepo-$x hgrepo2-$x &&
-
-               hg_log hgrepo2-$x >"hg-log-$x" &&
-               git_log gitrepo-$x >"git-log-$x"
-       done &&
-
-       test_cmp hg-log-hg hg-log-git &&
-       test_cmp git-log-hg git-log-git
-'
-
-test_expect_success 'hg tags' '
-       test_when_finished "rm -rf gitrepo* hgrepo*" &&
-
-       for x in hg git
-       do
-               (
-               git init -q gitrepo-$x &&
-               cd gitrepo-$x &&
-
-               echo alpha >alpha &&
-               git add alpha &&
-               git commit -m "add alpha" &&
-               git checkout -q -b not-master
-               ) &&
-
-               (
-               hg_clone_$x gitrepo-$x hgrepo-$x &&
-
-               cd hgrepo-$x &&
-               hg co master &&
-               hg tag alpha
-               ) &&
-
-               hg_push_$x hgrepo-$x gitrepo-$x &&
-               hg_clone_$x gitrepo-$x hgrepo2-$x &&
-
-               (
-               git --git-dir=gitrepo-$x/.git tag -l &&
-               hg_log hgrepo2-$x &&
-               cat hgrepo2-$x/.hgtags
-               ) >"output-$x"
-       done &&
-
-       test_cmp output-hg output-git
-'
-
-test_done
diff --git a/contrib/remote-helpers/test-hg.sh b/contrib/remote-helpers/test-hg.sh
deleted file mode 100755 (executable)
index 7d90056..0000000
+++ /dev/null
@@ -1,848 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2012 Felipe Contreras
-#
-# Base commands from hg-git tests:
-# https://bitbucket.org/durin42/hg-git/src
-#
-
-test_description='Test remote-hg'
-
-test -n "$TEST_DIRECTORY" || TEST_DIRECTORY=${0%/*}/../../t
-. "$TEST_DIRECTORY"/test-lib.sh
-
-if ! test_have_prereq PYTHON
-then
-       skip_all='skipping remote-hg tests; python not available'
-       test_done
-fi
-
-if ! python -c 'import mercurial'
-then
-       skip_all='skipping remote-hg tests; mercurial not available'
-       test_done
-fi
-
-check () {
-       echo $3 >expected &&
-       git --git-dir=$1/.git log --format='%s' -1 $2 >actual
-       test_cmp expected actual
-}
-
-check_branch () {
-       if test -n "$3"
-       then
-               echo $3 >expected &&
-               hg -R $1 log -r $2 --template '{desc}\n' >actual &&
-               test_cmp expected actual
-       else
-               hg -R $1 branches >out &&
-               ! grep $2 out
-       fi
-}
-
-check_bookmark () {
-       if test -n "$3"
-       then
-               echo $3 >expected &&
-               hg -R $1 log -r "bookmark('$2')" --template '{desc}\n' >actual &&
-               test_cmp expected actual
-       else
-               hg -R $1 bookmarks >out &&
-               ! grep $2 out
-       fi
-}
-
-check_push () {
-       expected_ret=$1 ret=0 ref_ret=0
-
-       shift
-       git push origin "$@" 2>error
-       ret=$?
-       cat error
-
-       while IFS=':' read branch kind
-       do
-               case "$kind" in
-               'new')
-                       grep "^ \* \[new branch\] *${branch} -> ${branch}$" error || ref_ret=1
-                       ;;
-               'non-fast-forward')
-                       grep "^ ! \[rejected\] *${branch} -> ${branch} (non-fast-forward)$" error || ref_ret=1
-                       ;;
-               'fetch-first')
-                       grep "^ ! \[rejected\] *${branch} -> ${branch} (fetch first)$" error || ref_ret=1
-                       ;;
-               'forced-update')
-                       grep "^ + [a-f0-9]*\.\.\.[a-f0-9]* *${branch} -> ${branch} (forced update)$" error || ref_ret=1
-                       ;;
-               '')
-                       grep "^   [a-f0-9]*\.\.[a-f0-9]* *${branch} -> ${branch}$" error || ref_ret=1
-                       ;;
-               esac
-               test $ref_ret -ne 0 && echo "match for '$branch' failed" && break
-       done
-
-       if test $expected_ret -ne $ret || test $ref_ret -ne 0
-       then
-               return 1
-       fi
-
-       return 0
-}
-
-setup () {
-       (
-       echo "[ui]"
-       echo "username = H G Wells <wells@example.com>"
-       echo "[extensions]"
-       echo "mq ="
-       ) >>"$HOME"/.hgrc &&
-
-       GIT_AUTHOR_DATE="2007-01-01 00:00:00 +0230" &&
-       GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE" &&
-       export GIT_COMMITTER_DATE GIT_AUTHOR_DATE
-}
-
-setup
-
-test_expect_success 'cloning' '
-       test_when_finished "rm -rf gitrepo*" &&
-
-       (
-       hg init hgrepo &&
-       cd hgrepo &&
-       echo zero >content &&
-       hg add content &&
-       hg commit -m zero
-       ) &&
-
-       git clone "hg::hgrepo" gitrepo &&
-       check gitrepo HEAD zero
-'
-
-test_expect_success 'cloning with branches' '
-       test_when_finished "rm -rf gitrepo*" &&
-
-       (
-       cd hgrepo &&
-       hg branch next &&
-       echo next >content &&
-       hg commit -m next
-       ) &&
-
-       git clone "hg::hgrepo" gitrepo &&
-       check gitrepo origin/branches/next next
-'
-
-test_expect_success 'cloning with bookmarks' '
-       test_when_finished "rm -rf gitrepo*" &&
-
-       (
-       cd hgrepo &&
-       hg checkout default &&
-       hg bookmark feature-a &&
-       echo feature-a >content &&
-       hg commit -m feature-a
-       ) &&
-
-       git clone "hg::hgrepo" gitrepo &&
-       check gitrepo origin/feature-a feature-a
-'
-
-test_expect_success 'update bookmark' '
-       test_when_finished "rm -rf gitrepo*" &&
-
-       (
-       cd hgrepo &&
-       hg bookmark devel
-       ) &&
-
-       (
-       git clone "hg::hgrepo" gitrepo &&
-       cd gitrepo &&
-       git checkout --quiet devel &&
-       echo devel >content &&
-       git commit -a -m devel &&
-       git push --quiet
-       ) &&
-
-       check_bookmark hgrepo devel devel
-'
-
-test_expect_success 'new bookmark' '
-       test_when_finished "rm -rf gitrepo*" &&
-
-       (
-       git clone "hg::hgrepo" gitrepo &&
-       cd gitrepo &&
-       git checkout --quiet -b feature-b &&
-       echo feature-b >content &&
-       git commit -a -m feature-b &&
-       git push --quiet origin feature-b
-       ) &&
-
-       check_bookmark hgrepo feature-b feature-b
-'
-
-# cleanup previous stuff
-rm -rf hgrepo
-
-author_test () {
-       echo $1 >>content &&
-       hg commit -u "$2" -m "add $1" &&
-       echo "$3" >>../expected
-}
-
-test_expect_success 'authors' '
-       test_when_finished "rm -rf hgrepo gitrepo" &&
-
-       (
-       hg init hgrepo &&
-       cd hgrepo &&
-
-       touch content &&
-       hg add content &&
-
-       >../expected &&
-       author_test alpha "" "H G Wells <wells@example.com>" &&
-       author_test beta "beta" "beta <unknown>" &&
-       author_test gamma "gamma <test@example.com> (comment)" "gamma <test@example.com>" &&
-       author_test delta "<delta@example.com>" "Unknown <delta@example.com>" &&
-       author_test epsilon "epsilon<test@example.com>" "epsilon <test@example.com>" &&
-       author_test zeta "zeta <test@example.com" "zeta <test@example.com>" &&
-       author_test eta " eta " "eta <unknown>" &&
-       author_test theta "theta < test@example.com >" "theta <test@example.com>" &&
-       author_test iota "iota >test@example.com>" "iota <test@example.com>" &&
-       author_test kappa "kappa < test <at> example <dot> com>" "kappa <unknown>" &&
-       author_test lambda "lambda@example.com" "Unknown <lambda@example.com>" &&
-       author_test mu "mu.mu@example.com" "Unknown <mu.mu@example.com>"
-       ) &&
-
-       git clone "hg::hgrepo" gitrepo &&
-       git --git-dir=gitrepo/.git log --reverse --format="%an <%ae>" >actual &&
-
-       test_cmp expected actual
-'
-
-test_expect_success 'strip' '
-       test_when_finished "rm -rf hgrepo gitrepo" &&
-
-       (
-       hg init hgrepo &&
-       cd hgrepo &&
-
-       echo one >>content &&
-       hg add content &&
-       hg commit -m one &&
-
-       echo two >>content &&
-       hg commit -m two
-       ) &&
-
-       git clone "hg::hgrepo" gitrepo &&
-
-       (
-       cd hgrepo &&
-       hg strip 1 &&
-
-       echo three >>content &&
-       hg commit -m three &&
-
-       echo four >>content &&
-       hg commit -m four
-       ) &&
-
-       (
-       cd gitrepo &&
-       git fetch &&
-       git log --format="%s" origin/master >../actual
-       ) &&
-
-       hg -R hgrepo log --template "{desc}\n" >expected &&
-       test_cmp actual expected
-'
-
-test_expect_success 'remote push with master bookmark' '
-       test_when_finished "rm -rf hgrepo gitrepo*" &&
-
-       (
-       hg init hgrepo &&
-       cd hgrepo &&
-       echo zero >content &&
-       hg add content &&
-       hg commit -m zero &&
-       hg bookmark master &&
-       echo one >content &&
-       hg commit -m one
-       ) &&
-
-       (
-       git clone "hg::hgrepo" gitrepo &&
-       cd gitrepo &&
-       echo two >content &&
-       git commit -a -m two &&
-       git push
-       ) &&
-
-       check_branch hgrepo default two
-'
-
-cat >expected <<\EOF
-changeset:   0:6e2126489d3d
-tag:         tip
-user:        A U Thor <author@example.com>
-date:        Mon Jan 01 00:00:00 2007 +0230
-summary:     one
-
-EOF
-
-test_expect_success 'remote push from master branch' '
-       test_when_finished "rm -rf hgrepo gitrepo*" &&
-
-       hg init hgrepo &&
-
-       (
-       git init gitrepo &&
-       cd gitrepo &&
-       git remote add origin "hg::../hgrepo" &&
-       echo one >content &&
-       git add content &&
-       git commit -a -m one &&
-       git push origin master
-       ) &&
-
-       hg -R hgrepo log >actual &&
-       cat actual &&
-       test_cmp expected actual &&
-
-       check_branch hgrepo default one
-'
-
-GIT_REMOTE_HG_TEST_REMOTE=1
-export GIT_REMOTE_HG_TEST_REMOTE
-
-test_expect_success 'remote cloning' '
-       test_when_finished "rm -rf gitrepo*" &&
-
-       (
-       hg init hgrepo &&
-       cd hgrepo &&
-       echo zero >content &&
-       hg add content &&
-       hg commit -m zero
-       ) &&
-
-       git clone "hg::hgrepo" gitrepo &&
-       check gitrepo HEAD zero
-'
-
-test_expect_success 'moving remote clone' '
-       test_when_finished "rm -rf gitrepo*" &&
-
-       (
-       git clone "hg::hgrepo" gitrepo &&
-       mv gitrepo gitrepo2 &&
-       cd gitrepo2 &&
-       git fetch
-       )
-'
-
-test_expect_success 'remote update bookmark' '
-       test_when_finished "rm -rf gitrepo*" &&
-
-       (
-       cd hgrepo &&
-       hg bookmark devel
-       ) &&
-
-       (
-       git clone "hg::hgrepo" gitrepo &&
-       cd gitrepo &&
-       git checkout --quiet devel &&
-       echo devel >content &&
-       git commit -a -m devel &&
-       git push --quiet
-       ) &&
-
-       check_bookmark hgrepo devel devel
-'
-
-test_expect_success 'remote new bookmark' '
-       test_when_finished "rm -rf gitrepo*" &&
-
-       (
-       git clone "hg::hgrepo" gitrepo &&
-       cd gitrepo &&
-       git checkout --quiet -b feature-b &&
-       echo feature-b >content &&
-       git commit -a -m feature-b &&
-       git push --quiet origin feature-b
-       ) &&
-
-       check_bookmark hgrepo feature-b feature-b
-'
-
-test_expect_success 'remote push diverged' '
-       test_when_finished "rm -rf gitrepo*" &&
-
-       git clone "hg::hgrepo" gitrepo &&
-
-       (
-       cd hgrepo &&
-       hg checkout default &&
-       echo bump >content &&
-       hg commit -m bump
-       ) &&
-
-       (
-       cd gitrepo &&
-       echo diverge >content &&
-       git commit -a -m diverged &&
-       check_push 1 <<-\EOF
-       master:non-fast-forward
-       EOF
-       ) &&
-
-       check_branch hgrepo default bump
-'
-
-test_expect_success 'remote update bookmark diverge' '
-       test_when_finished "rm -rf gitrepo*" &&
-
-       (
-       cd hgrepo &&
-       hg checkout tip^ &&
-       hg bookmark diverge
-       ) &&
-
-       git clone "hg::hgrepo" gitrepo &&
-
-       (
-       cd hgrepo &&
-       echo "bump bookmark" >content &&
-       hg commit -m "bump bookmark"
-       ) &&
-
-       (
-       cd gitrepo &&
-       git checkout --quiet diverge &&
-       echo diverge >content &&
-       git commit -a -m diverge &&
-       check_push 1 <<-\EOF
-       diverge:fetch-first
-       EOF
-       ) &&
-
-       check_bookmark hgrepo diverge "bump bookmark"
-'
-
-test_expect_success 'remote new bookmark multiple branch head' '
-       test_when_finished "rm -rf gitrepo*" &&
-
-       (
-       git clone "hg::hgrepo" gitrepo &&
-       cd gitrepo &&
-       git checkout --quiet -b feature-c HEAD^ &&
-       echo feature-c >content &&
-       git commit -a -m feature-c &&
-       git push --quiet origin feature-c
-       ) &&
-
-       check_bookmark hgrepo feature-c feature-c
-'
-
-# cleanup previous stuff
-rm -rf hgrepo
-
-test_expect_success 'fetch special filenames' '
-       test_when_finished "rm -rf hgrepo gitrepo && LC_ALL=C" &&
-
-       LC_ALL=en_US.UTF-8
-       export LC_ALL
-
-       (
-       hg init hgrepo &&
-       cd hgrepo &&
-
-       echo test >> "æ rø" &&
-       hg add "æ rø" &&
-       echo test >> "ø~?" &&
-       hg add "ø~?" &&
-       hg commit -m add-utf-8 &&
-       echo test >> "æ rø" &&
-       hg commit -m test-utf-8 &&
-       hg rm "ø~?" &&
-       hg mv "æ rø" "ø~?" &&
-       hg commit -m hg-mv-utf-8
-       ) &&
-
-       (
-       git clone "hg::hgrepo" gitrepo &&
-       cd gitrepo &&
-       git -c core.quotepath=false ls-files > ../actual
-       ) &&
-       echo "ø~?" > expected &&
-       test_cmp expected actual
-'
-
-test_expect_success 'push special filenames' '
-       test_when_finished "rm -rf hgrepo gitrepo && LC_ALL=C" &&
-
-       mkdir -p tmp && cd tmp &&
-
-       LC_ALL=en_US.UTF-8
-       export LC_ALL
-
-       (
-       hg init hgrepo &&
-       cd hgrepo &&
-
-       echo one >> content &&
-       hg add content &&
-       hg commit -m one
-       ) &&
-
-       (
-       git clone "hg::hgrepo" gitrepo &&
-       cd gitrepo &&
-
-       echo test >> "æ rø" &&
-       git add "æ rø" &&
-       git commit -m utf-8 &&
-
-       git push
-       ) &&
-
-       (cd hgrepo &&
-       hg update &&
-       hg manifest > ../actual
-       ) &&
-
-       printf "content\næ rø\n" > expected &&
-       test_cmp expected actual
-'
-
-setup_big_push () {
-       (
-       hg init hgrepo &&
-       cd hgrepo &&
-       echo zero >content &&
-       hg add content &&
-       hg commit -m zero &&
-       hg bookmark bad_bmark1 &&
-       echo one >content &&
-       hg commit -m one &&
-       hg bookmark bad_bmark2 &&
-       hg bookmark good_bmark &&
-       hg bookmark -i good_bmark &&
-       hg -q branch good_branch &&
-       echo "good branch" >content &&
-       hg commit -m "good branch" &&
-       hg -q branch bad_branch &&
-       echo "bad branch" >content &&
-       hg commit -m "bad branch"
-       ) &&
-
-       git clone "hg::hgrepo" gitrepo &&
-
-       (
-       cd gitrepo &&
-       echo two >content &&
-       git commit -q -a -m two &&
-
-       git checkout -q good_bmark &&
-       echo three >content &&
-       git commit -q -a -m three &&
-
-       git checkout -q bad_bmark1 &&
-       git reset --hard HEAD^ &&
-       echo four >content &&
-       git commit -q -a -m four &&
-
-       git checkout -q bad_bmark2 &&
-       git reset --hard HEAD^ &&
-       echo five >content &&
-       git commit -q -a -m five &&
-
-       git checkout -q -b new_bmark master &&
-       echo six >content &&
-       git commit -q -a -m six &&
-
-       git checkout -q branches/good_branch &&
-       echo seven >content &&
-       git commit -q -a -m seven &&
-       echo eight >content &&
-       git commit -q -a -m eight &&
-
-       git checkout -q branches/bad_branch &&
-       git reset --hard HEAD^ &&
-       echo nine >content &&
-       git commit -q -a -m nine &&
-
-       git checkout -q -b branches/new_branch master &&
-       echo ten >content &&
-       git commit -q -a -m ten
-       )
-}
-
-test_expect_success 'remote big push' '
-       test_when_finished "rm -rf hgrepo gitrepo*" &&
-
-       setup_big_push
-
-       (
-       cd gitrepo &&
-
-       check_push 1 --all <<-\EOF
-       master
-       good_bmark
-       branches/good_branch
-       new_bmark:new
-       branches/new_branch:new
-       bad_bmark1:non-fast-forward
-       bad_bmark2:non-fast-forward
-       branches/bad_branch:non-fast-forward
-       EOF
-       ) &&
-
-       check_branch hgrepo default one &&
-       check_branch hgrepo good_branch "good branch" &&
-       check_branch hgrepo bad_branch "bad branch" &&
-       check_branch hgrepo new_branch '' &&
-       check_bookmark hgrepo good_bmark one &&
-       check_bookmark hgrepo bad_bmark1 one &&
-       check_bookmark hgrepo bad_bmark2 one &&
-       check_bookmark hgrepo new_bmark ''
-'
-
-test_expect_success 'remote big push fetch first' '
-       test_when_finished "rm -rf hgrepo gitrepo*" &&
-
-       (
-       hg init hgrepo &&
-       cd hgrepo &&
-       echo zero >content &&
-       hg add content &&
-       hg commit -m zero &&
-       hg bookmark bad_bmark &&
-       hg bookmark good_bmark &&
-       hg bookmark -i good_bmark &&
-       hg -q branch good_branch &&
-       echo "good branch" >content &&
-       hg commit -m "good branch" &&
-       hg -q branch bad_branch &&
-       echo "bad branch" >content &&
-       hg commit -m "bad branch"
-       ) &&
-
-       git clone "hg::hgrepo" gitrepo &&
-
-       (
-       cd hgrepo &&
-       hg bookmark -f bad_bmark &&
-       echo update_bmark >content &&
-       hg commit -m "update bmark"
-       ) &&
-
-       (
-       cd gitrepo &&
-       echo two >content &&
-       git commit -q -a -m two &&
-
-       git checkout -q good_bmark &&
-       echo three >content &&
-       git commit -q -a -m three &&
-
-       git checkout -q bad_bmark &&
-       echo four >content &&
-       git commit -q -a -m four &&
-
-       git checkout -q branches/bad_branch &&
-       echo five >content &&
-       git commit -q -a -m five &&
-
-       check_push 1 --all <<-\EOF &&
-       master
-       good_bmark
-       bad_bmark:fetch-first
-       branches/bad_branch:festch-first
-       EOF
-
-       git fetch &&
-
-       check_push 1 --all <<-\EOF
-       master
-       good_bmark
-       bad_bmark:non-fast-forward
-       branches/bad_branch:non-fast-forward
-       EOF
-       )
-'
-
-test_expect_success 'remote big push force' '
-       test_when_finished "rm -rf hgrepo gitrepo*" &&
-
-       setup_big_push
-
-       (
-       cd gitrepo &&
-
-       check_push 0 --force --all <<-\EOF
-       master
-       good_bmark
-       branches/good_branch
-       new_bmark:new
-       branches/new_branch:new
-       bad_bmark1:forced-update
-       bad_bmark2:forced-update
-       branches/bad_branch:forced-update
-       EOF
-       ) &&
-
-       check_branch hgrepo default six &&
-       check_branch hgrepo good_branch eight &&
-       check_branch hgrepo bad_branch nine &&
-       check_branch hgrepo new_branch ten &&
-       check_bookmark hgrepo good_bmark three &&
-       check_bookmark hgrepo bad_bmark1 four &&
-       check_bookmark hgrepo bad_bmark2 five &&
-       check_bookmark hgrepo new_bmark six
-'
-
-test_expect_success 'remote big push dry-run' '
-       test_when_finished "rm -rf hgrepo gitrepo*" &&
-
-       setup_big_push
-
-       (
-       cd gitrepo &&
-
-       check_push 1 --dry-run --all <<-\EOF &&
-       master
-       good_bmark
-       branches/good_branch
-       new_bmark:new
-       branches/new_branch:new
-       bad_bmark1:non-fast-forward
-       bad_bmark2:non-fast-forward
-       branches/bad_branch:non-fast-forward
-       EOF
-
-       check_push 0 --dry-run master good_bmark new_bmark branches/good_branch branches/new_branch <<-\EOF
-       master
-       good_bmark
-       branches/good_branch
-       new_bmark:new
-       branches/new_branch:new
-       EOF
-       ) &&
-
-       check_branch hgrepo default one &&
-       check_branch hgrepo good_branch "good branch" &&
-       check_branch hgrepo bad_branch "bad branch" &&
-       check_branch hgrepo new_branch '' &&
-       check_bookmark hgrepo good_bmark one &&
-       check_bookmark hgrepo bad_bmark1 one &&
-       check_bookmark hgrepo bad_bmark2 one &&
-       check_bookmark hgrepo new_bmark ''
-'
-
-test_expect_success 'remote double failed push' '
-       test_when_finished "rm -rf hgrepo gitrepo*" &&
-
-       (
-       hg init hgrepo &&
-       cd hgrepo &&
-       echo zero >content &&
-       hg add content &&
-       hg commit -m zero &&
-       echo one >content &&
-       hg commit -m one
-       ) &&
-
-       (
-       git clone "hg::hgrepo" gitrepo &&
-       cd gitrepo &&
-       git reset --hard HEAD^ &&
-       echo two >content &&
-       git commit -a -m two &&
-       test_expect_code 1 git push &&
-       test_expect_code 1 git push
-       )
-'
-
-test_expect_success 'clone remote with master null bookmark, then push to the bookmark' '
-       test_when_finished "rm -rf gitrepo* hgrepo*" &&
-
-       hg init hgrepo &&
-       (
-               cd hgrepo &&
-               echo a >a &&
-               hg add a &&
-               hg commit -m a &&
-               hg bookmark -r null master
-       ) &&
-
-       git clone "hg::hgrepo" gitrepo &&
-       check gitrepo HEAD a &&
-       (
-               cd gitrepo &&
-               git checkout --quiet -b master &&
-               echo b >b &&
-               git add b &&
-               git commit -m b &&
-               git push origin master
-       )
-'
-
-test_expect_success 'clone remote with default null bookmark, then push to the bookmark' '
-       test_when_finished "rm -rf gitrepo* hgrepo*" &&
-
-       hg init hgrepo &&
-       (
-               cd hgrepo &&
-               echo a >a &&
-               hg add a &&
-               hg commit -m a &&
-               hg bookmark -r null -f default
-       ) &&
-
-       git clone "hg::hgrepo" gitrepo &&
-       check gitrepo HEAD a &&
-       (
-               cd gitrepo &&
-               git checkout --quiet -b default &&
-               echo b >b &&
-               git add b &&
-               git commit -m b &&
-               git push origin default
-       )
-'
-
-test_expect_success 'clone remote with generic null bookmark, then push to the bookmark' '
-       test_when_finished "rm -rf gitrepo* hgrepo*" &&
-
-       hg init hgrepo &&
-       (
-               cd hgrepo &&
-               echo a >a &&
-               hg add a &&
-               hg commit -m a &&
-               hg bookmark -r null bmark
-       ) &&
-
-       git clone "hg::hgrepo" gitrepo &&
-       check gitrepo HEAD a &&
-       (
-               cd gitrepo &&
-               git checkout --quiet -b bmark &&
-               git remote -v &&
-               echo b >b &&
-               git add b &&
-               git commit -m b &&
-               git push origin bmark
-       )
-'
-
-test_done
index 66ce4b07c2dc2d2d56dc260883f86d8672d2ac69..b22b710c262ed6c55e97859aac8a2fd1c5adb219 100755 (executable)
@@ -76,7 +76,7 @@ test_expect_success 'add sub1' '
 
 # Save this hash for testing later.
 
-subdir_hash=`git rev-parse HEAD`
+subdir_hash=$(git rev-parse HEAD)
 
 test_expect_success 'add sub2' '
         create sub2 &&
index 5eb4a5164397e3a34be10690025a9cd472261db9..8dc73ece15a075bb60971da577d2da272c8f7c14 100755 (executable)
@@ -10,7 +10,7 @@ CONFFILE=~/.appprc
 
 SEP="-=-=-=-=-=-=-=-=-=# Don't remove this line #=-=-=-=-=-=-=-=-=-"
 if [ -e "$CONFFILE" ] ; then
-       LAST_DIR=`grep -m 1 "^LAST_DIR=" "${CONFFILE}"|sed -e 's/^LAST_DIR=//'`
+       LAST_DIR=$(grep -m 1 "^LAST_DIR=" "${CONFFILE}"|sed -e 's/^LAST_DIR=//')
        cd "${LAST_DIR}"
 else
        cd > /dev/null
@@ -25,11 +25,11 @@ fi
 
 cd - > /dev/null
 
-SUBJECT=`sed -n -e '/^Subject: /p' "${PATCH}"`
-HEADERS=`sed -e '/^'"${SEP}"'$/,$d' $1`
-BODY=`sed -e "1,/${SEP}/d" $1`
-CMT_MSG=`sed -e '1,/^$/d' -e '/^---$/,$d' "${PATCH}"`
-DIFF=`sed -e '1,/^---$/d' "${PATCH}"`
+SUBJECT=$(sed -n -e '/^Subject: /p' "${PATCH}")
+HEADERS=$(sed -e '/^'"${SEP}"'$/,$d' $1)
+BODY=$(sed -e "1,/${SEP}/d" $1)
+CMT_MSG=$(sed -e '1,/^$/d' -e '/^---$/,$d' "${PATCH}")
+DIFF=$(sed -e '1,/^---$/d' "${PATCH}")
 
 CCS=`echo -e "$CMT_MSG\n$HEADERS" | sed -n -e 's/^Cc: \(.*\)$/\1,/gp' \
        -e 's/^Signed-off-by: \(.*\)/\1,/gp'`
@@ -48,7 +48,7 @@ if [ "x${BODY}x" != "xx" ] ; then
 fi
 echo "$DIFF" >> $1
 
-LAST_DIR=`dirname "${PATCH}"`
+LAST_DIR=$(dirname "${PATCH}")
 
 grep -v "^LAST_DIR=" "${CONFFILE}" > "${CONFFILE}_"
 echo "LAST_DIR=${LAST_DIR}" >> "${CONFFILE}_"
diff --git a/diff.c b/diff.c
index f72769a1c492dfcac501032c54c3fb2ac0a4343e..f66716fab4b477c58434126b4aaa4b4372ce163a 100644 (file)
--- a/diff.c
+++ b/diff.c
@@ -2880,6 +2880,16 @@ static struct diff_tempfile *prepare_temp_file(const char *name,
        return temp;
 }
 
+static void add_external_diff_name(struct argv_array *argv,
+                                  const char *name,
+                                  struct diff_filespec *df)
+{
+       struct diff_tempfile *temp = prepare_temp_file(name, df);
+       argv_array_push(argv, temp->name);
+       argv_array_push(argv, temp->hex);
+       argv_array_push(argv, temp->mode);
+}
+
 /* An external diff command takes:
  *
  * diff-cmd name infile1 infile1-sha1 infile1-mode \
@@ -2896,48 +2906,32 @@ static void run_external_diff(const char *pgm,
                              struct diff_options *o)
 {
        struct argv_array argv = ARGV_ARRAY_INIT;
-       int retval;
+       struct argv_array env = ARGV_ARRAY_INIT;
        struct diff_queue_struct *q = &diff_queued_diff;
-       const char *env[3] = { NULL };
-       char env_counter[50];
-       char env_total[50];
+
+       argv_array_push(&argv, pgm);
+       argv_array_push(&argv, name);
 
        if (one && two) {
-               struct diff_tempfile *temp_one, *temp_two;
-               const char *othername = (other ? other : name);
-               temp_one = prepare_temp_file(name, one);
-               temp_two = prepare_temp_file(othername, two);
-               argv_array_push(&argv, pgm);
-               argv_array_push(&argv, name);
-               argv_array_push(&argv, temp_one->name);
-               argv_array_push(&argv, temp_one->hex);
-               argv_array_push(&argv, temp_one->mode);
-               argv_array_push(&argv, temp_two->name);
-               argv_array_push(&argv, temp_two->hex);
-               argv_array_push(&argv, temp_two->mode);
-               if (other) {
+               add_external_diff_name(&argv, name, one);
+               if (!other)
+                       add_external_diff_name(&argv, name, two);
+               else {
+                       add_external_diff_name(&argv, other, two);
                        argv_array_push(&argv, other);
                        argv_array_push(&argv, xfrm_msg);
                }
-       } else {
-               argv_array_push(&argv, pgm);
-               argv_array_push(&argv, name);
        }
-       fflush(NULL);
 
-       env[0] = env_counter;
-       snprintf(env_counter, sizeof(env_counter), "GIT_DIFF_PATH_COUNTER=%d",
-                ++o->diff_path_counter);
-       env[1] = env_total;
-       snprintf(env_total, sizeof(env_total), "GIT_DIFF_PATH_TOTAL=%d", q->nr);
+       argv_array_pushf(&env, "GIT_DIFF_PATH_COUNTER=%d", ++o->diff_path_counter);
+       argv_array_pushf(&env, "GIT_DIFF_PATH_TOTAL=%d", q->nr);
+
+       if (run_command_v_opt_cd_env(argv.argv, RUN_USING_SHELL, NULL, env.argv))
+               die(_("external diff died, stopping at %s"), name);
 
-       retval = run_command_v_opt_cd_env(argv.argv, RUN_USING_SHELL, NULL, env);
        remove_tempfile();
        argv_array_clear(&argv);
-       if (retval) {
-               fprintf(stderr, "external diff died, stopping at %s.\n", name);
-               exit(1);
-       }
+       argv_array_clear(&env);
 }
 
 static int similarity_index(struct diff_filepair *p)
@@ -3205,6 +3199,7 @@ void diff_setup(struct diff_options *options)
        options->context = diff_context_default;
        DIFF_OPT_SET(options, RENAME_EMPTY);
 
+       /* pathchange left =NULL by default */
        options->change = diff_change;
        options->add_remove = diff_addremove;
        options->use_color = diff_use_color_default;
@@ -4749,6 +4744,7 @@ void diffcore_fix_diff_index(struct diff_options *options)
 
 void diffcore_std(struct diff_options *options)
 {
+       /* NOTE please keep the following in sync with diff_tree_combined() */
        if (options->skip_stat_unmatch)
                diffcore_skip_stat_unmatch(options);
        if (!options->found_follow) {
diff --git a/diff.h b/diff.h
index a24a767db78d8e864175cf342f03fc48e159e06e..b4a624d235748bf13be44e7479f086880dcf574f 100644 (file)
--- a/diff.h
+++ b/diff.h
@@ -15,6 +15,10 @@ struct diff_filespec;
 struct userdiff_driver;
 struct sha1_array;
 struct commit;
+struct combine_diff_path;
+
+typedef int (*pathchange_fn_t)(struct diff_options *options,
+                struct combine_diff_path *path);
 
 typedef void (*change_fn_t)(struct diff_options *options,
                 unsigned old_mode, unsigned new_mode,
@@ -157,6 +161,7 @@ struct diff_options {
        int close_file;
 
        struct pathspec pathspec;
+       pathchange_fn_t pathchange;
        change_fn_t change;
        add_remove_fn_t add_remove;
        diff_format_fn_t format_callback;
@@ -189,8 +194,10 @@ const char *diff_line_prefix(struct diff_options *);
 
 extern const char mime_boundary_leader[];
 
-extern int diff_tree(struct tree_desc *t1, struct tree_desc *t2,
-                    const char *base, struct diff_options *opt);
+extern struct combine_diff_path *diff_tree_paths(
+       struct combine_diff_path *p, const unsigned char *sha1,
+       const unsigned char **parent_sha1, int nparent,
+       struct strbuf *base, struct diff_options *opt);
 extern int diff_tree_sha1(const unsigned char *old, const unsigned char *new,
                          const char *base, struct diff_options *opt);
 extern int diff_root_tree_sha1(const unsigned char *new, const char *base,
index f6d3a46622d1de2497b56274a255d7bca46117dd..76910e6cd16f128be9430ac86f35a8e06d390e0f 100644 (file)
@@ -521,6 +521,14 @@ extern void release_pack_memory(size_t);
 typedef void (*try_to_free_t)(size_t);
 extern try_to_free_t set_try_to_free_routine(try_to_free_t);
 
+#ifdef HAVE_ALLOCA_H
+# include <alloca.h>
+# define xalloca(size)      (alloca(size))
+# define xalloca_free(p)    do {} while (0)
+#else
+# define xalloca(size)      (xmalloc(size))
+# define xalloca_free(p)    (free(p))
+#endif
 extern char *xstrdup(const char *str);
 extern void *xmalloc(size_t size);
 extern void *xmallocz(size_t size);
@@ -531,6 +539,7 @@ extern void *xcalloc(size_t nmemb, size_t size);
 extern void *xmmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);
 extern ssize_t xread(int fd, void *buf, size_t len);
 extern ssize_t xwrite(int fd, const void *buf, size_t len);
+extern ssize_t xpread(int fd, void *buf, size_t len, off_t offset);
 extern int xdup(int fd);
 extern FILE *xfdopen(int fd, const char *mode);
 extern int xmkstemp(char *template);
index cf2209b4f201b990cffab6d454599b9fa6932fc0..6a8907e7b327d066c616f8f77c2bc2096d618e06 100755 (executable)
@@ -1283,7 +1283,7 @@ load_config 0
 apply_config
 
 # v1.7.0 introduced --show-toplevel to return the canonical work-tree
-if {[package vsatisfies $_git_version 1.7.0]} {
+if {[package vsatisfies $_git_version 1.7.0-]} {
        if { [is_Cygwin] } {
                catch {set _gitworktree [exec cygpath --windows [git rev-parse --show-toplevel]]}
        } else {
@@ -1539,7 +1539,7 @@ proc rescan_stage2 {fd after} {
                close $fd
        }
 
-       if {[package vsatisfies $::_git_version 1.6.3]} {
+       if {[package vsatisfies $::_git_version 1.6.3-]} {
                set ls_others [list --exclude-standard]
        } else {
                set ls_others [list --exclude-per-directory=.gitignore]
index 332528ff4556116f9ff22c257e49825954a183fb..d08dc92589b366746965a0eab0727ce2befc579d 100755 (executable)
@@ -277,7 +277,7 @@ merge_file () {
        echo "Normal merge conflict for '$MERGED':"
        describe_file "$local_mode" "local" "$LOCAL"
        describe_file "$remote_mode" "remote" "$REMOTE"
-       if "$prompt" = true
+       if test "$guessed_merge_tool" = true || test "$prompt" = true
        then
                printf "Hit return to start merge resolution tool (%s): " "$merge_tool"
                read ans || return 1
@@ -315,7 +315,8 @@ merge_file () {
        return 0
 }
 
-prompt=$(git config --bool mergetool.prompt || echo true)
+prompt=$(git config --bool mergetool.prompt)
+guessed_merge_tool=false
 
 while test $# != 0
 do
@@ -373,7 +374,14 @@ prompt_after_failed_merge () {
 
 if test -z "$merge_tool"
 then
-       merge_tool=$(get_merge_tool "$merge_tool") || exit
+       # Check if a merge tool has been configured
+       merge_tool=$(get_configured_merge_tool)
+       # Try to guess an appropriate merge tool if no tool has been set.
+       if test -z "$merge_tool"
+       then
+               merge_tool=$(guess_merge_tool) || exit
+               guessed_merge_tool=true
+       fi
 fi
 merge_keep_backup="$(git config --bool mergetool.keepBackup || echo true)"
 merge_keep_temporaries="$(git config --bool mergetool.keepTemporaries || echo false)"
index 8d11b25ae37761a9cfea263bd9a5591c0495fc1c..773cafcd89b6cd89d413e3d51056c4aaf53c1f2c 100755 (executable)
--- a/git-p4.py
+++ b/git-p4.py
@@ -1311,7 +1311,7 @@ class P4Submit(Command, P4UserMap):
             else:
                 die("unknown modifier %s for %s" % (modifier, path))
 
-        diffcmd = "git diff-tree -p \"%s\"" % (id)
+        diffcmd = "git diff-tree --full-index -p \"%s\"" % (id)
         patchcmd = diffcmd + " | git apply "
         tryPatchCmd = patchcmd + "--check -"
         applyPatchCmd = patchcmd + "--check --apply -"
index 6cd8ebc534c174dfe613f62047424dc7491d75fa..cfc589dc15061c8ed1797c2d91ec420b1d6f33fe 100755 (executable)
@@ -108,7 +108,7 @@ do
        -s|--s|--st|--str|--stra|--strat|--strate|--strateg|--strategy)
                case "$#,$1" in
                *,*=*)
-                       strategy=`expr "z$1" : 'z-[^=]*=\(.*\)'` ;;
+                       strategy=$(expr "z$1" : 'z-[^=]*=\(.*\)') ;;
                1,*)
                        usage ;;
                *)
index 71429fd74373f3f804fc841b5dd60faca2baaec6..6d77b3ca9118e6fdd36615757a24c109cf0530ee 100644 (file)
@@ -24,7 +24,7 @@ continue_merge () {
                die "$resolvemsg"
        fi
 
-       cmt=`cat "$state_dir/current"`
+       cmt=$(cat "$state_dir/current")
        if ! git diff-index --quiet --ignore-submodules HEAD --
        then
                if ! git commit ${gpg_sign_opt:+"$gpg_sign_opt"} --no-verify -C "$cmt"
@@ -143,7 +143,7 @@ echo "$onto_name" > "$state_dir/onto_name"
 write_basic_state
 
 msgnum=0
-for cmt in `git rev-list --reverse --no-merges "$revisions"`
+for cmt in $(git rev-list --reverse --no-merges "$revisions")
 do
        msgnum=$(($msgnum + 1))
        echo "$cmt" > "$state_dir/cmt.$msgnum"
index 4543815ffd6b0d49466edc3059f6d085b79ebf8a..5c7a0a1a583552de49ee2e094e80f80ee18fd68c 100755 (executable)
@@ -457,8 +457,8 @@ then
 else
        if test -z "$onto"
        then
-               empty_tree=`git hash-object -t tree /dev/null`
-               onto=`git commit-tree $empty_tree </dev/null`
+               empty_tree=$(git hash-object -t tree /dev/null)
+               onto=$(git commit-tree $empty_tree </dev/null)
                squash_onto="$onto"
        fi
        unset upstream_name
@@ -516,10 +516,10 @@ case "$#" in
        ;;
 0)
        # Do not need to switch branches, we are already on it.
-       if branch_name=`git symbolic-ref -q HEAD`
+       if branch_name=$(git symbolic-ref -q HEAD)
        then
                head_name=$branch_name
-               branch_name=`expr "z$branch_name" : 'zrefs/heads/\(.*\)'`
+               branch_name=$(expr "z$branch_name" : 'zrefs/heads/\(.*\)')
        else
                head_name="detached HEAD"
                branch_name=HEAD ;# detached
index 5c1599752314696ef1f317095d1786493fbfc935..d5500fde4658410db477008617730cb5799f310e 100755 (executable)
@@ -119,6 +119,12 @@ then
        status=1
 fi
 
+# Special case: turn "for_linus" to "tags/for_linus" when it is correct
+if test "$ref" = "refs/tags/$pretty_remote"
+then
+       pretty_remote=tags/$pretty_remote
+fi
+
 url=$(git ls-remote --get-url "$url")
 
 git show -s --format='The following changes since commit %H:
index fdb0029b597898559376b1b28d692450794251f3..abd62b484cdaef8e6ab5ba366551c03959c08beb 100755 (executable)
@@ -1113,6 +1113,18 @@ sub ssl_verify_params {
        }
 }
 
+sub file_name_is_absolute {
+       my ($path) = @_;
+
+       # msys does not grok DOS drive-prefixes
+       if ($^O eq 'msys') {
+               return ($path =~ m#^/# || $path =~ m#^[a-zA-Z]\:#)
+       }
+
+       require File::Spec::Functions;
+       return File::Spec::Functions::file_name_is_absolute($path);
+}
+
 # Returns 1 if the message was sent, and 0 otherwise.
 # In actuality, the whole program dies when there
 # is an error sending a message.
@@ -1197,7 +1209,7 @@ X-Mailer: git-send-email $gitversion
 
        if ($dry_run) {
                # We don't want to send the email.
-       } elsif ($smtp_server =~ m#^/#) {
+       } elsif (file_name_is_absolute($smtp_server)) {
                my $pid = open my $sm, '|-';
                defined $pid or die $!;
                if (!$pid) {
@@ -1271,7 +1283,7 @@ X-Mailer: git-send-email $gitversion
                printf (($dry_run ? "Dry-" : "")."Sent %s\n", $subject);
        } else {
                print (($dry_run ? "Dry-" : "")."OK. Log says:\n");
-               if ($smtp_server !~ m#^/#) {
+               if (!file_name_is_absolute($smtp_server)) {
                        print "Server: $smtp_server\n";
                        print "MAIL FROM:<$raw_from>\n";
                        foreach my $entry (@recipients) {
index 5f28b32dc7ff75830bde919b2f4776f7a9b017e2..9447980330ce7892757f9b11fa45cfeb3e6fcb34 100644 (file)
@@ -160,7 +160,7 @@ git_pager() {
        else
                GIT_PAGER=cat
        fi
-       : ${LESS=-FRSX}
+       : ${LESS=-FRX}
        : ${LV=-c}
        export LESS LV
 
index 4798bcf0e51b705005215e9a6339310defe16d03..af549c731779db02db29fef446014a58bc9a3996 100755 (executable)
@@ -13,7 +13,7 @@ USAGE="list [<options>]
 
 SUBDIRECTORY_OK=Yes
 OPTIONS_SPEC=
-START_DIR=`pwd`
+START_DIR=$(pwd)
 . git-sh-setup
 . git-sh-i18n
 require_work_tree
index ebdfba6c94db947f66add0c1b4840319c12252ea..ae152534f5026d50fa32b568d1bdd591629bc59d 100755 (executable)
@@ -59,7 +59,7 @@ do
        -b|--browser*|-t|--tool*)
                case "$#,$1" in
                *,*=*)
-                       browser=`expr "z$1" : 'z-[^=]*=\(.*\)'`
+                       browser=$(expr "z$1" : 'z-[^=]*=\(.*\)')
                        ;;
                1,*)
                        usage ;;
@@ -71,7 +71,7 @@ do
        -c|--config*)
                case "$#,$1" in
                *,*=*)
-                       conf=`expr "z$1" : 'z-[^=]*=\(.*\)'`
+                       conf=$(expr "z$1" : 'z-[^=]*=\(.*\)')
                        ;;
                1,*)
                        usage ;;
@@ -100,7 +100,7 @@ then
        for opt in "$conf" "web.browser"
        do
                test -z "$opt" && continue
-               browser="`git config $opt`"
+               browser="$(git config $opt)"
                test -z "$browser" || break
        done
        if test -n "$browser" && ! valid_tool "$browser"; then
diff --git a/git.c b/git.c
index 9efd1a3ec1f2af63fe575f9c755dff685d9b1e51..778057294892d68b3dee58869cf22265223cab83 100644 (file)
--- a/git.c
+++ b/git.c
@@ -290,7 +290,7 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv)
        if (!help) {
                if (p->option & RUN_SETUP)
                        prefix = setup_git_directory();
-               if (p->option & RUN_SETUP_GENTLY) {
+               else if (p->option & RUN_SETUP_GENTLY) {
                        int nongit_ok;
                        prefix = setup_git_directory_gently(&nongit_ok);
                }
diff --git a/grep.c b/grep.c
index 4aef0a69d084deee61486e43bc62ae2da6b6b440..99217dc04f5d04c761f094069f1053cb090baaf1 100644 (file)
--- a/grep.c
+++ b/grep.c
@@ -86,6 +86,11 @@ int grep_config(const char *var, const char *value, void *cb)
                return 0;
        }
 
+       if (!strcmp(var, "grep.fullname")) {
+               opt->relative = !git_config_bool(var, value);
+               return 0;
+       }
+
        if (!strcmp(var, "color.grep"))
                opt->color = git_config_colorbool(var, value);
        else if (!strcmp(var, "color.grep.context"))
index 0bc6f7fae151ea364e9d141b30b8e68d544a4448..5c4f336330e416379a15cee75b593f0aea451025 100644 (file)
@@ -23,9 +23,9 @@
  */
 
 #include "cache.h"
+#include "credential.h"
 #include "exec_cmd.h"
 #include "run-command.h"
-#include "prompt.h"
 #ifdef NO_OPENSSL
 typedef void *SSL;
 #endif
@@ -946,6 +946,7 @@ static int auth_cram_md5(struct imap_store *ctx, struct imap_cmd *cmd, const cha
 
 static struct imap_store *imap_open_store(struct imap_server_conf *srvc)
 {
+       struct credential cred = CREDENTIAL_INIT;
        struct imap_store *ctx;
        struct imap *imap;
        char *arg, *rsp;
@@ -1096,25 +1097,23 @@ static struct imap_store *imap_open_store(struct imap_server_conf *srvc)
                }
 #endif
                imap_info("Logging in...\n");
-               if (!srvc->user) {
-                       fprintf(stderr, "Skipping server %s, no user\n", srvc->host);
-                       goto bail;
-               }
-               if (!srvc->pass) {
-                       struct strbuf prompt = STRBUF_INIT;
-                       strbuf_addf(&prompt, "Password (%s@%s): ", srvc->user, srvc->host);
-                       arg = git_getpass(prompt.buf);
-                       strbuf_release(&prompt);
-                       if (!*arg) {
-                               fprintf(stderr, "Skipping account %s@%s, no password\n", srvc->user, srvc->host);
-                               goto bail;
-                       }
-                       /*
-                        * getpass() returns a pointer to a static buffer.  make a copy
-                        * for long term storage.
-                        */
-                       srvc->pass = xstrdup(arg);
+               if (!srvc->user || !srvc->pass) {
+                       cred.protocol = xstrdup(srvc->use_ssl ? "imaps" : "imap");
+                       cred.host = xstrdup(srvc->host);
+
+                       if (srvc->user)
+                               cred.username = xstrdup(srvc->user);
+                       if (srvc->pass)
+                               cred.password = xstrdup(srvc->pass);
+
+                       credential_fill(&cred);
+
+                       if (!srvc->user)
+                               srvc->user = xstrdup(cred.username);
+                       if (!srvc->pass)
+                               srvc->pass = xstrdup(cred.password);
                }
+
                if (CAP(NOLOGIN)) {
                        fprintf(stderr, "Skipping account %s@%s, server forbids LOGIN\n", srvc->user, srvc->host);
                        goto bail;
@@ -1153,10 +1152,18 @@ static struct imap_store *imap_open_store(struct imap_server_conf *srvc)
                }
        } /* !preauth */
 
+       if (cred.username)
+               credential_approve(&cred);
+       credential_clear(&cred);
+
        ctx->prefix = "";
        return ctx;
 
 bail:
+       if (cred.username)
+               credential_reject(&cred);
+       credential_clear(&cred);
+
        imap_close_store(ctx);
        return NULL;
 }
diff --git a/mergetools/gvimdiff3 b/mergetools/gvimdiff3
new file mode 100644 (file)
index 0000000..04a5bb0
--- /dev/null
@@ -0,0 +1 @@
+. "$MERGE_TOOLS_DIR/vimdiff"
index 39d032771b8525253d3828fd68b2c7f6d6df8478..1ddfbfcd782d3b8d0e479cb0c5e29abce86e63c9 100644 (file)
@@ -20,16 +20,26 @@ merge_cmd () {
                "$merge_tool_path" -f -d -c 'wincmd l' \
                        "$LOCAL" "$MERGED" "$REMOTE"
                ;;
+       gvimdiff3|vimdiff3)
+               if $base_present
+               then
+                       "$merge_tool_path" -f -d -c 'hid | hid | hid' \
+                               "$LOCAL" "$REMOTE" "$BASE" "$MERGED"
+               else
+                       "$merge_tool_path" -f -d -c 'hid | hid' \
+                               "$LOCAL" "$REMOTE" "$MERGED"
+               fi
+               ;;
        esac
        check_unchanged
 }
 
 translate_merge_tool_path() {
        case "$1" in
-       gvimdiff|gvimdiff2)
+       gvimdiff|gvimdiff2|gvimdiff3)
                echo gvim
                ;;
-       vimdiff|vimdiff2)
+       vimdiff|vimdiff2|vimdiff3)
                echo vim
                ;;
        esac
diff --git a/mergetools/vimdiff3 b/mergetools/vimdiff3
new file mode 100644 (file)
index 0000000..04a5bb0
--- /dev/null
@@ -0,0 +1 @@
+. "$MERGE_TOOLS_DIR/vimdiff"
index eabe4a0d9bf44050dba43cbd821642cdfd3fb40b..97dfd63c9bf564ac052addc4a3f62a325bbc1303 100644 (file)
@@ -62,7 +62,7 @@ int notes_cache_write(struct notes_cache *c)
        if (commit_tree(&msg, tree_sha1, NULL, commit_sha1, NULL, NULL) < 0)
                return -1;
        if (update_ref("update notes cache", c->tree.ref, commit_sha1, NULL,
-                      0, QUIET_ON_ERR) < 0)
+                      0, UPDATE_REFS_QUIET_ON_ERR) < 0)
                return -1;
 
        return 0;
index 4aa7023903374aa3ccea23d5fc9ae82c9c67bca7..a0b1d7be98253368921a6e95653ceb36dbda28b2 100644 (file)
@@ -48,7 +48,8 @@ void commit_notes(struct notes_tree *t, const char *msg)
 
        create_notes_commit(t, NULL, &buf, commit_sha1);
        strbuf_insert(&buf, 0, "notes: ", 7); /* commit message starts at index 7 */
-       update_ref(buf.buf, t->ref, commit_sha1, NULL, 0, DIE_ON_ERR);
+       update_ref(buf.buf, t->ref, commit_sha1, NULL, 0,
+                  UPDATE_REFS_DIE_ON_ERR);
 
        strbuf_release(&buf);
 }
diff --git a/pager.c b/pager.c
index 0cc75a8eee32a0195a74c6819a04745f341e45e3..8b5cbc56e4fd57a1b9d2cad3e668df4c508a7b17 100644 (file)
--- a/pager.c
+++ b/pager.c
@@ -64,7 +64,7 @@ void setup_pager(void)
 {
        const char *pager = git_pager(isatty(1));
 
-       if (!pager || pager_in_use())
+       if (!pager)
                return;
 
        /*
@@ -85,7 +85,7 @@ void setup_pager(void)
                int i = 0;
 
                if (!getenv("LESS"))
-                       env[i++] = "LESS=FRSX";
+                       env[i++] = "LESS=FRX";
                if (!getenv("LV"))
                        env[i++] = "LV=-c";
                env[i] = NULL;
index a59564fb34fbedd4915da2afd7d4b8f1fd40bb49..09cff135efd98a486ff767485602d9383e7c3c23 100644 (file)
@@ -1321,7 +1321,7 @@ sub get_untracked {
 sub parse_svn_date {
        my $date = shift || return '+0000 1970-01-01 00:00:00';
        my ($Y,$m,$d,$H,$M,$S) = ($date =~ /^(\d{4})\-(\d\d)\-(\d\d)T
-                                           (\d\d)\:(\d\d)\:(\d\d)\.\d*Z$/x) or
+                                           (\d\d?)\:(\d\d)\:(\d\d)\.\d*Z$/x) or
                                         croak "Unable to parse date: $date\n";
        my $parsed_date;    # Set next.
 
index 34f2869ab5995e3f9143af8cc2c46a4717ae8be8..664105357c0031e869b3348a09d91777a42c1cdf 100644 (file)
@@ -116,7 +116,7 @@ sub run_pager {
                return;
        }
        open STDIN, '<&', $rfd or fatal "Can't redirect stdin: $!";
-       $ENV{LESS} ||= 'FRSX';
+       $ENV{LESS} ||= 'FRX';
        $ENV{LV} ||= '-c';
        exec $pager or fatal "Can't run pager: $! ($pager)";
 }
index fb450b241498bdddb3e60b096aa0fd9c1ef3521a..e862e106047d9e646e21efeb8dcb39465bb10928 100644 (file)
--- a/po/bg.po
+++ b/po/bg.po
 # rebase пребазирам
 # force (push) принудително изтласквам
 # stash/index индекс
+# squash commits смачкване на подавания
+# root commit начално подаване
+# fixup вкарвам подаване в предното без следа
+# remote-tracking branch следящ клон
+# git bundle архив на git
+# bisect двоично търсене
+# am прилагам поредица от кръпки
+# working directory/tree — винаги работно дърво, git следи цялото дърво, а не директории
+# switch to branch прехвърлям се/преминавам към клон
+# sparse entry частично изтеглена директория/път
+# revision range диапазон на версиите
+# cover letter придружаващо писмо
+# reference repository еталонно хранилище
+# grafted repository хранилище с присаждане
+# thin pack съкратен пакет
+# stat (a file) получавам информация чрез „stat“ (за файл)
+# mixed reset смесено зануляване (индекса и указателя „HEAD“, без работното дърво)
+# soft reset меко зануляване (само указателя „HEAD“, без индекса и работното дърво)
+# hard reset пълно зануляване (указателя „HEAD“, индекса и работното дърво)
+# merge reset слято зануляване (целия индекс и отчасти работното дърво — без файловете с промени между работното дърво и индекса)
+# keep reset запазващо зануляване (отчасти индекса и работното дърво — файловете с промени от подаването и „HEAD“)
+# commit-ish указател към подаване
+# sequence последователност/поредица
+# whitespace symbol знаци за интервали
+# shortlog съкратения журнал
+# ----
+# FAILED to parse неуспешен анализ на... -> неразпозната стойност на
+#
+# ========================
+# „“…—
 # ========================
 # RECHECK
 # ------------------------
 # grep ^#: bg.po | cut -c4- |tr ' ' '\n'| sed -e 's/:[0-9][0-9]*//'  -e 's%.*/%%' -e 's/[.][^.]*$//' > OUT
 # sort -u OUT > UNIQUE
 # for i in `cat UNIQUE`; do echo   `grep "^$i$" OUT | wc -l` $i ; done | sort -nr > STATS
+#
 # ========================
-# DONE strings
-# ------------------------
-# 222
-# ========================
-# REMAINING strings
+# FIND NON FULLY TRANSLATED
 # ------------------------
-# 1988
+# msgattrib  --untranslated bg.po > untranslated.po
+# msgattrib  --only-fuzzy bg.po > fuzzy.po
+# msgcat.exe untranslated.po fuzzy.po > new.po
+# grep ^#: new.po | cut -c4- |tr ' ' '\n'| sed -e 's/:[0-9][0-9]*//'  -e 's%.*/%%' -e 's/[.][^.]*$//' | sort -u
+#
 # ========================
-# DONE alphabetical ordering
+# STRINGS statistics
 # ------------------------
-#
-# advice, fsck, gc, help, parse-options, reflog, remote, rm, run-command
+# 1307t,0f,921u
 #
 # ========================
-# REMAINING alphabetical ordering
+# MOST IMPORTANT name asc ordering
 # ------------------------
-#
-# add, apply, archive, attr, bisect--helper, blame, branch, bundle, cat-file, check-attr, check-ignore, check-mailmap,
-# checkout, checkout-index, clean, clone, column, commit, common-cmds, config, connected, count-objects, date, describe,
-# diff, diffcore-order, fast-export, fetch, fmt-merge-msg, for-each-ref, git, git-am, git-bisect, git-pull, git-rebase,
-# git-stash, git-submodule, gpg-interface, grep, hash-object, index-pack, init-db, log, ls-files, ls-tree, merge,
-# merge-base, merge-file, merge-recursive, mktree, mv, name-rev, notes, notes-utils, object, obstack, pack-objects,
-# pack-refs, pathspec, precompose_utf8, prune, prune-packed, push, read-tree, repack, replace, rerere, reset, revert,
-# rev-parse, sequencer, sha1_name, shortlog, show-branch, show-ref, submodule, symbolic-ref, tag, update-index,
-# update-ref, update-server-info, urlmatch, verify-pack, verify-tag, wrapper, write-tree, wt-status
-#
+# add, blame, branch, checkout, clone, commit, common-cmds, config, diff, fetch, fsck, gc, git-rebase, git-stash, grep, log, mv, parse-options, push, reflog, remote, reset, revert, rm, wt-status
 #
 # ========================
-# MOST IMPORTANT strings ordering
+# IMPORTANT strings desc, name asc ordering
 # ------------------------
-# 144 [remote]    68 fetch       28 blame         16 [parse-options]
-# 137 commit      64 grep        27 git-rebase    12 [gc]
-# 115 branch      46 push        24 revert        12 [fsck]
-# 102 wt-status   38 add         21 common-cmds   3 reflog
-#  78 checkout    34 config      21 [rm]
-#  77 log         33 reset       21 mv
-#  69 clone       29 git-stash   13 diff
+# 111 apply            54 git-submodule  30 git-am      13 check-ignore  10 merge-file 
+#  97 merge            39 init-db        30 describe    12 pathspec      10 merge-base 
+#  64 tag              35 archive        29 git-bisect  12 name-rev      10 ls-tree    
+#  55 merge-recursive  32 clean          14 show-ref    11 date          10 hash-object
 #
 # ========================
-# WHOLE STATISTICS strings ordering
+# WHOLE STATISTICS strings desc, name asc ordering
 # ------------------------
-# 144 remote           54 git-submodule  27 ls-files        12 pathspec         8 replace         3 prune-packed
-# 137 commit           48 push           27 git-rebase      12 name-rev         8 git-pull        3 pack-refs
-# 115 branch           41 help           24 revert          12 gc               8 fmt-merge-msg   3 count-objects
-# 111 apply            40 pack-objects   24 mv              12 fsck             7 symbolic-ref    3 connected
-# 102 wt-status        39 init-db        21 rm              12 checkout-index   6 gpg-interface   3 bisect--helper
-# 100 notes            38 add            21 common-cmds     11 date             6 check-attr      2 verify-tag
-#  97 merge            35 archive        19 show-branch     11 column           5 write-tree      2 update-server-info
-#  78 checkout         34 config         19 read-tree       10 urlmatch         5 sha1_name       2 run-command
-#  77 log              33 reset          19 bundle          10 shortlog         5 rev-parse       2 rerere
-#  69 clone            32 clean          17 repack          10 merge-file       5 prune           2 obstack
-#  68 index-pack       30 git-am         16 parse-options   10 merge-base       4 wrapper         2 advice
-#  68 fetch            30 describe       14 submodule       10 ls-tree          4 notes-utils     1 precompose_utf8
-#  64 grep             29 git-stash      14 show-ref        10 hash-object      4 mktree          1 object
-#  58 tag              29 git-bisect     14 fast-export     10 for-each-ref     4 check-mailmap   1 git
-#  56 sequencer        28 update-index   13 diff            10 cat-file         3 verify-pack     1 diffcore-order
-#  55 merge-recursive  28 blame          13 check-ignore     9 update-ref       3 reflog          1 attr
+# 144 [remote]           47 [push]          26 [revert]         12 checkout-index    6 [prune]          2 [verify-tag]
+# 137 [commit]           46 pack-objects    24 [mv]             11 date              6 [gpg-interface]  2 [update-server-info]
+# 114 [branch]           41 [help]          23 repack           11 column            6 [check-attr]     2 [run-command]
+# 111 apply              39 init-db         21 [rm]             10 urlmatch          5 [write-tree]     2 [rerere]
+# 101 notes              36 [add]           21 [common-cmds]    10 shortlog          5 [sha1_name]      2 [read-cache]
+# 100 [wt-status]        35 [reset]         19 [show-branch]    10 merge-file        5 [rev-parse]      2 [obstack]
+#  97 merge              35 archive         19 read-tree        10 merge-base        4 [wrapper]        2 [advice]
+#  78 [checkout]         34 [config]        19 bundle           10 ls-tree           4 [prune-packed]   1 [unpack-trees]
+#  77 [log]              32 clean           16 [parse-options]  10 hash-object       4 [notes-utils]    1 [unpack-objects]
+#  69 [clone]            30 git-am          15 [fsck]           10 for-each-ref      4 [mktree]         1 [progress]
+#  68 index-pack         30 describe        14 show-ref         10 cat-file          4 [check-mailmap]  1 [precompose_utf8]
+#  68 [fetch]            29 [git-stash]     14 [gc]              9 [update-ref]      3 [verify-pack]    1 [object]
+#  64 tag                29 git-bisect      14 fast-export       9 [submodule]       3 [reflog]         1 [git]
+#  64 [grep]             28 update-index    13 [diff]            8 [replace]         3 [pack-refs]      1 [diffcore-rename]
+#  56 sequencer          28 [blame]         13 check-ignore      8 [git-pull]        3 [count-objects]  1 [diffcore-order]
+#  55 merge-recursive    27 ls-files        12 pathspec          8 [fmt-merge-msg]   3 [connected]      1 [attr]
+#  54 git-submodule      27 [git-rebase]    12 name-rev          7 [symbolic-ref]    3 [bisect--helper]
+#
 msgid ""
 msgstr ""
 "Project-Id-Version: git master\n"
 "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2014-01-18 07:42+0800\n"
-"PO-Revision-Date: 2014-01-28 19:05+0200\n"
+"POT-Creation-Date: 2014-04-19 12:50+0800\n"
+"PO-Revision-Date: 2014-05-11 17:06+0300\n"
 "Last-Translator: Alexander Shopov <ash@kambanaria.org>\n"
 "Language-Team: Bulgarian <dict@fsa-bg.org>\n"
 "Language: bg\n"
@@ -97,16 +117,12 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
-#: advice.c:57
+#: advice.c:55
 #, c-format
 msgid "hint: %.*s\n"
 msgstr "Подсказка: %.*s\n"
 
-#.
-#. * Message used both when 'git commit' fails and when
-#. * other commands doing a merge do.
-#.
-#: advice.c:87
+#: advice.c:85
 msgid ""
 "Fix them up in the work tree,\n"
 "and then use 'git add/rm <file>' as\n"
@@ -135,76 +151,76 @@ msgstr ""
 msgid "git archive --remote <repo> [--exec <cmd>] --list"
 msgstr ""
 
-#: archive.c:242 builtin/add.c:240 builtin/add.c:559 builtin/rm.c:328
+#: archive.c:243 builtin/add.c:136 builtin/add.c:428 builtin/rm.c:328
 #, c-format
 msgid "pathspec '%s' did not match any files"
 msgstr "пътят „%s“ не съвпада с никой файл"
 
-#: archive.c:327
+#: archive.c:328
 msgid "fmt"
 msgstr ""
 
-#: archive.c:327
+#: archive.c:328
 msgid "archive format"
 msgstr ""
 
-#: archive.c:328 builtin/log.c:1193
+#: archive.c:329 builtin/log.c:1193
 msgid "prefix"
-msgstr ""
+msgstr "префикс"
 
-#: archive.c:329
+#: archive.c:330
 msgid "prepend prefix to each pathname in the archive"
 msgstr ""
 
-#: archive.c:330 builtin/archive.c:88 builtin/blame.c:2265
-#: builtin/blame.c:2266 builtin/config.c:58 builtin/fast-export.c:680
-#: builtin/fast-export.c:682 builtin/grep.c:716 builtin/hash-object.c:77
-#: builtin/ls-files.c:486 builtin/ls-files.c:489 builtin/notes.c:408
-#: builtin/notes.c:565 builtin/read-tree.c:108 parse-options.h:154
+#: archive.c:331 builtin/archive.c:88 builtin/blame.c:2258
+#: builtin/blame.c:2259 builtin/config.c:57 builtin/fast-export.c:680
+#: builtin/fast-export.c:682 builtin/grep.c:714 builtin/hash-object.c:77
+#: builtin/ls-files.c:489 builtin/ls-files.c:492 builtin/notes.c:412
+#: builtin/notes.c:569 builtin/read-tree.c:108 parse-options.h:151
 msgid "file"
 msgstr "файл"
 
-#: archive.c:331 builtin/archive.c:89
+#: archive.c:332 builtin/archive.c:89
 msgid "write the archive to this file"
 msgstr ""
 
-#: archive.c:333
+#: archive.c:334
 msgid "read .gitattributes in working directory"
 msgstr ""
 
-#: archive.c:334
+#: archive.c:335
 msgid "report archived files on stderr"
 msgstr ""
 
-#: archive.c:335
+#: archive.c:336
 msgid "store only"
 msgstr ""
 
-#: archive.c:336
+#: archive.c:337
 msgid "compress faster"
 msgstr ""
 
-#: archive.c:344
+#: archive.c:345
 msgid "compress better"
 msgstr ""
 
-#: archive.c:347
+#: archive.c:348
 msgid "list supported archive formats"
 msgstr ""
 
-#: archive.c:349 builtin/archive.c:90 builtin/clone.c:84
+#: archive.c:350 builtin/archive.c:90 builtin/clone.c:84
 msgid "repo"
-msgstr ""
+msgstr "хранилище"
 
-#: archive.c:350 builtin/archive.c:91
+#: archive.c:351 builtin/archive.c:91
 msgid "retrieve the archive from remote repository <repo>"
 msgstr ""
 
-#: archive.c:351 builtin/archive.c:92 builtin/notes.c:487
+#: archive.c:352 builtin/archive.c:92 builtin/notes.c:491
 msgid "command"
 msgstr ""
 
-#: archive.c:352 builtin/archive.c:93
+#: archive.c:353 builtin/archive.c:93
 msgid "path to the remote git-upload-archive command"
 msgstr ""
 
@@ -213,87 +229,88 @@ msgid ""
 "Negative patterns are ignored in git attributes\n"
 "Use '\\!' for literal leading exclamation."
 msgstr ""
+"Отрицателните шаблони се игнорират в атрибутите на git.\n"
+"Ако ви трябва начална удивителна, ползвайте „\\!“."
 
 #: branch.c:60
 #, c-format
 msgid "Not setting branch %s as its own upstream."
 msgstr ""
+"Клонът „%s“ не може да служи като източник за собствената си синхронизация."
 
-#: branch.c:82
+#: branch.c:83
 #, c-format
 msgid "Branch %s set up to track remote branch %s from %s by rebasing."
 msgstr ""
+"Клонът „%s“ ще следи клона „%s“ от отдалеченото хранилище „%s“ чрез "
+"пребазиране."
 
-#: branch.c:83
+#: branch.c:84
 #, c-format
 msgid "Branch %s set up to track remote branch %s from %s."
-msgstr ""
+msgstr "Клонът „%s“ ще следи клона „%s“ от отдалеченото хранилище „%s“."
 
-#: branch.c:87
+#: branch.c:88
 #, c-format
 msgid "Branch %s set up to track local branch %s by rebasing."
 msgstr ""
+"Клонът „%s“ ще следи клона „%s“ от локалното хранилище чрез пребазиране."
 
-#: branch.c:88
+#: branch.c:89
 #, c-format
 msgid "Branch %s set up to track local branch %s."
-msgstr ""
+msgstr "Клонът „%s“ ще следи клона „%s“ от локалното хранилище."
 
-#: branch.c:92
+#: branch.c:94
 #, c-format
 msgid "Branch %s set up to track remote ref %s by rebasing."
-msgstr ""
+msgstr "Клонът „%s“ ще следи отдалечения указател „%s“ чрез пребазиране."
 
-#: branch.c:93
+#: branch.c:95
 #, c-format
 msgid "Branch %s set up to track remote ref %s."
-msgstr ""
+msgstr "Клонът „%s“ ще следи отдалечения указател „%s“."
 
-#: branch.c:97
+#: branch.c:99
 #, c-format
 msgid "Branch %s set up to track local ref %s by rebasing."
-msgstr ""
+msgstr "Клонът „%s“ ще следи локалния указател „%s“ чрез пребазиране."
 
-#: branch.c:98
+#: branch.c:100
 #, c-format
 msgid "Branch %s set up to track local ref %s."
-msgstr ""
-
-#: branch.c:118
-#, c-format
-msgid "Tracking not set up: name too long: %s"
-msgstr ""
+msgstr "Клонът „%s“ ще следи локалния указател „%s“."
 
-#: branch.c:137
+#: branch.c:133
 #, c-format
 msgid "Not tracking: ambiguous information for ref %s"
-msgstr ""
+msgstr "Няма следене: двусмислена информация за указателя „%s“"
 
-#: branch.c:182
+#: branch.c:178
 #, c-format
 msgid "'%s' is not a valid branch name."
-msgstr ""
+msgstr "„%s“ не е позволено име за клон."
 
-#: branch.c:187
+#: branch.c:183
 #, c-format
 msgid "A branch named '%s' already exists."
-msgstr ""
+msgstr "Вече съществува клон с име „%s“."
 
-#: branch.c:195
+#: branch.c:191
 msgid "Cannot force update the current branch."
-msgstr ""
+msgstr "Текущият клон не може да бъде принудително обновен."
 
-#: branch.c:215
+#: branch.c:211
 #, c-format
 msgid "Cannot setup tracking information; starting point '%s' is not a branch."
-msgstr ""
+msgstr "Зададените настройки за следенето са грешни — началото „%s“ не е клон."
 
-#: branch.c:217
+#: branch.c:213
 #, c-format
 msgid "the requested upstream branch '%s' does not exist"
-msgstr ""
+msgstr "заявеният отдалечен клон „%s“ не съществува"
 
-#: branch.c:219
+#: branch.c:215
 msgid ""
 "\n"
 "If you are planning on basing your work on an upstream\n"
@@ -304,135 +321,142 @@ msgid ""
 "will track its remote counterpart, you may want to use\n"
 "\"git push -u\" to set the upstream config as you push."
 msgstr ""
+"\n"
+"Ако искате да базирате работата си на клон от отдалечено хранилище, може \n"
+"да се наложи да изпълните „git fetch“, за да получите информацията за него.\n"
+"\n"
+"Ако искате да изтласкате нов, локален клон, който да следи отдалечен клон,\n"
+"може да използвате „git push -u“, за да настроите към кой клон да се "
+"изтласква."
 
-#: branch.c:264
+#: branch.c:260
 #, c-format
 msgid "Not a valid object name: '%s'."
-msgstr ""
+msgstr "Неправилно име на обект: „%s“"
 
-#: branch.c:284
+#: branch.c:280
 #, c-format
 msgid "Ambiguous object name: '%s'."
-msgstr ""
+msgstr "Двусмислено име на обект: „%s“"
 
-#: branch.c:289
+#: branch.c:285
 #, c-format
 msgid "Not a valid branch point: '%s'."
-msgstr ""
+msgstr "Неправилно място за начало на клон: „%s“"
 
-#: branch.c:295
+#: branch.c:291
 msgid "Failed to lock ref for update"
-msgstr ""
+msgstr "Указателят не може да бъде заключен, за да бъде обновен"
 
-#: branch.c:313
+#: branch.c:309
 msgid "Failed to write ref"
-msgstr ""
+msgstr "Указателят не може да бъде записан"
 
-#: bundle.c:37
+#: bundle.c:33
 #, c-format
 msgid "'%s' does not look like a v2 bundle file"
-msgstr ""
+msgstr "Файлът „%s“ не изглежда да е архив на git версия 2"
 
-#: bundle.c:64
+#: bundle.c:60
 #, c-format
 msgid "unrecognized header: %s%s (%d)"
 msgstr ""
 
-#: bundle.c:90 builtin/commit.c:706
+#: bundle.c:86 builtin/commit.c:706
 #, c-format
 msgid "could not open '%s'"
-msgstr ""
+msgstr "„%s“ не може да се отвори"
 
-#: bundle.c:141
+#: bundle.c:138
 msgid "Repository lacks these prerequisite commits:"
 msgstr ""
 
-#: bundle.c:165 sequencer.c:662 sequencer.c:1112 builtin/log.c:332
+#: bundle.c:162 sequencer.c:669 sequencer.c:1123 builtin/log.c:332
 #: builtin/log.c:821 builtin/log.c:1418 builtin/log.c:1644 builtin/merge.c:357
 #: builtin/shortlog.c:158
 msgid "revision walk setup failed"
-msgstr ""
+msgstr "неуспешно настройване на обхождането на версиите"
 
-#: bundle.c:187
+#: bundle.c:184
 #, c-format
 msgid "The bundle contains this ref:"
 msgid_plural "The bundle contains these %d refs:"
 msgstr[0] ""
 msgstr[1] ""
 
-#: bundle.c:194
+#: bundle.c:191
 msgid "The bundle records a complete history."
 msgstr ""
 
-#: bundle.c:196
+#: bundle.c:193
 #, c-format
 msgid "The bundle requires this ref:"
 msgid_plural "The bundle requires these %d refs:"
 msgstr[0] ""
 msgstr[1] ""
 
-#: bundle.c:296
+#: bundle.c:293
 msgid "rev-list died"
 msgstr ""
 
-#: bundle.c:302 builtin/log.c:1329 builtin/shortlog.c:261
+#: bundle.c:299 builtin/log.c:1329 builtin/shortlog.c:261
 #, c-format
 msgid "unrecognized argument: %s"
-msgstr ""
+msgstr "непознат аргумент: %s"
 
-#: bundle.c:337
+#: bundle.c:334
 #, c-format
 msgid "ref '%s' is excluded by the rev-list options"
 msgstr ""
 
-#: bundle.c:382
+#: bundle.c:379
 msgid "Refusing to create empty bundle."
 msgstr ""
 
-#: bundle.c:398
+#: bundle.c:395
 msgid "Could not spawn pack-objects"
 msgstr ""
 
-#: bundle.c:416
+#: bundle.c:413
 msgid "pack-objects died"
 msgstr ""
 
-#: bundle.c:419
+#: bundle.c:416
 #, c-format
 msgid "cannot create '%s'"
 msgstr ""
 
-#: bundle.c:441
+#: bundle.c:438
 msgid "index-pack died"
 msgstr ""
 
-#: commit.c:53
+#: commit.c:54
 #, c-format
 msgid "could not parse %s"
-msgstr ""
+msgstr "„%s“ не може да се анализира"
 
-#: commit.c:55
+#: commit.c:56
 #, c-format
 msgid "%s %s is not a commit!"
-msgstr ""
+msgstr "%s %s не е подаване!"
 
 #: compat/obstack.c:406 compat/obstack.c:408
 msgid "memory exhausted"
-msgstr ""
+msgstr "паметта свърши"
 
 #: connected.c:70
 msgid "Could not run 'git rev-list'"
-msgstr ""
+msgstr "Командата „git rev-list“ не може да бъде изпълнена."
 
 #: connected.c:90
 #, c-format
 msgid "failed write to rev-list: %s"
-msgstr ""
+msgstr "неуспешен запис в списъка с версиите: %s"
 
 #: connected.c:98
 #, c-format
 msgid "failed to close rev-list's stdin: %s"
-msgstr ""
+msgstr "стандартният вход на списъка с версиите не може да бъде затворен: %s"
 
 #: date.c:95
 msgid "in the future"
@@ -487,6 +511,7 @@ msgid_plural "%lu years"
 msgstr[0] ""
 msgstr[1] ""
 
+#. TRANSLATORS: "%s" is "<n> years"
 #: date.c:149
 #, c-format
 msgid "%s, %lu month ago"
@@ -504,22 +529,28 @@ msgstr[1] ""
 #: diffcore-order.c:24
 #, c-format
 msgid "failed to read orderfile '%s'"
-msgstr ""
+msgstr "файлът с подредбата на съответствията „%s“ не може да бъде прочетен"
+
+#: diffcore-rename.c:517
+msgid "Performing inexact rename detection"
+msgstr "Търсене на преименувания на обекти съчетани с промени"
 
 #: diff.c:113
 #, c-format
 msgid "  Failed to parse dirstat cut-off percentage '%s'\n"
 msgstr ""
+"  Неуспешно разпознаване на „%s“ като процент-праг за статистиката по "
+"директории\n"
 
 #: diff.c:118
 #, c-format
 msgid "  Unknown dirstat parameter '%s'\n"
-msgstr ""
+msgstr "  Непознат параметър „%s“ за статистиката по директории'\n"
 
 #: diff.c:213
 #, c-format
 msgid "Unknown value for 'diff.submodule' config variable: '%s'"
-msgstr ""
+msgstr "Непозната стойност „%s“ за настройката „diff.submodule“"
 
 #: diff.c:263
 #, c-format
@@ -527,70 +558,74 @@ msgid ""
 "Found errors in 'diff.dirstat' config variable:\n"
 "%s"
 msgstr ""
+"Грешки в настройката „diff.dirstat“:\n"
+"%s"
 
-#: diff.c:3509
+#: diff.c:3495
 #, c-format
 msgid ""
 "Failed to parse --dirstat/-X option parameter:\n"
 "%s"
 msgstr ""
+"Неразпознат параметър към опцията „--dirstat/-X“:\n"
+"%s"
 
-#: diff.c:3523
+#: diff.c:3509
 #, c-format
 msgid "Failed to parse --submodule option parameter: '%s'"
-msgstr ""
+msgstr "Неразпознат параметър към опцията „--submodule“: „%s“"
 
 #: gpg-interface.c:59 gpg-interface.c:131
 msgid "could not run gpg."
-msgstr ""
+msgstr "Програмата „gpg“ не може да бъде стартирана."
 
 #: gpg-interface.c:71
 msgid "gpg did not accept the data"
-msgstr ""
+msgstr "Програмата „gpg“ не прие подадените данни."
 
 #: gpg-interface.c:82
 msgid "gpg failed to sign the data"
-msgstr ""
+msgstr "Програмата „gpg“ не подписа данните."
 
 #: gpg-interface.c:115
 #, c-format
 msgid "could not create temporary file '%s': %s"
-msgstr ""
+msgstr "Програмата „gpg“ не успя да създаде временния файл „%s“: %s"
 
 #: gpg-interface.c:118
 #, c-format
 msgid "failed writing detached signature to '%s': %s"
-msgstr ""
+msgstr "Програмата „gpg“ не успя да запише самостоятелния подпис към „%s“: %s"
 
-#: grep.c:1695
+#: grep.c:1698
 #, c-format
 msgid "'%s': unable to read %s"
-msgstr ""
+msgstr "„%s“: файлът сочен от „%s“ не може да бъде прочетен"
 
-#: grep.c:1712
+#: grep.c:1715
 #, c-format
 msgid "'%s': %s"
-msgstr ""
+msgstr "„%s“: „%s“"
 
-#: grep.c:1723
+#: grep.c:1726
 #, c-format
 msgid "'%s': short read %s"
-msgstr ""
+msgstr "„%s“: изчитането на „%s“ върна по-малко байтове от заявените"
 
-#: help.c:210
+#: help.c:209
 #, c-format
 msgid "available git commands in '%s'"
 msgstr "налични команди на git от „%s“"
 
-#: help.c:217
+#: help.c:216
 msgid "git commands available from elsewhere on your $PATH"
 msgstr "команди на git от други директории от пътя „$PATH“"
 
-#: help.c:233
+#: help.c:232
 msgid "The most commonly used git commands are:"
 msgstr "Най-често употребяваните команди на git са:"
 
-#: help.c:290
+#: help.c:289
 #, c-format
 msgid ""
 "'%s' appears to be a git command, but we were not\n"
@@ -599,11 +634,12 @@ msgstr ""
 "Изглежда, че „%s“ е команда на git, но тя не може да\n"
 "бъде изпълнена. Вероятно пакетът „git-%s“ е повреден."
 
-#: help.c:347
+# FIXME bad message
+#: help.c:346
 msgid "Uh oh. Your system reports no Git commands at all."
 msgstr "Странно, изглежда, че на системата ви няма нито една команда на git."
 
-#: help.c:369
+#: help.c:368
 #, c-format
 msgid ""
 "WARNING: You called a Git command named '%s', which does not exist.\n"
@@ -614,17 +650,17 @@ msgstr ""
 "съществува. Изпълнението автоматично продължава, като се счита, че имате "
 "предвид „%s“"
 
-#: help.c:374
+#: help.c:373
 #, c-format
 msgid "in %0.1f seconds automatically..."
 msgstr "след %0.1f секунди…"
 
-#: help.c:381
+#: help.c:380
 #, c-format
 msgid "git: '%s' is not a git command. See 'git --help'."
 msgstr "git: „%s“ не е команда на git. Вижте изхода от „git --help“."
 
-#: help.c:385 help.c:444
+#: help.c:384 help.c:443
 msgid ""
 "\n"
 "Did you mean this?"
@@ -638,7 +674,7 @@ msgstr[1] ""
 "\n"
 "Команди с подобно име са:"
 
-#: help.c:440
+#: help.c:439
 #, c-format
 msgid "%s: %s - %s"
 msgstr "%s: %s — %s"
@@ -647,305 +683,305 @@ msgstr "%s: %s — %s"
 msgid "failed to read the cache"
 msgstr ""
 
-#: merge.c:110 builtin/checkout.c:358 builtin/checkout.c:559
+#: merge.c:110 builtin/checkout.c:357 builtin/checkout.c:558
 #: builtin/clone.c:661
 msgid "unable to write new index file"
-msgstr ""
+msgstr "неуспешно записване на новия индекс"
 
 #: merge-recursive.c:190
 #, c-format
 msgid "(bad commit)\n"
 msgstr ""
 
-#: merge-recursive.c:206
+#: merge-recursive.c:208
 #, c-format
 msgid "addinfo_cache failed for path '%s'"
 msgstr ""
 
-#: merge-recursive.c:269
+#: merge-recursive.c:271
 msgid "error building trees"
 msgstr ""
 
-#: merge-recursive.c:673
+#: merge-recursive.c:675
 #, c-format
 msgid "failed to create path '%s'%s"
 msgstr ""
 
-#: merge-recursive.c:684
+#: merge-recursive.c:686
 #, c-format
 msgid "Removing %s to make room for subdirectory\n"
 msgstr ""
 
-#. something else exists
-#. .. but not some other error (who really cares what?)
-#: merge-recursive.c:698 merge-recursive.c:719
+#: merge-recursive.c:700 merge-recursive.c:721
 msgid ": perhaps a D/F conflict?"
 msgstr ""
 
-#: merge-recursive.c:709
+#: merge-recursive.c:711
 #, c-format
 msgid "refusing to lose untracked file at '%s'"
 msgstr ""
 
-#: merge-recursive.c:749
+#: merge-recursive.c:751
 #, c-format
 msgid "cannot read object %s '%s'"
 msgstr ""
 
-#: merge-recursive.c:751
+#: merge-recursive.c:753
 #, c-format
 msgid "blob expected for %s '%s'"
 msgstr ""
 
-#: merge-recursive.c:774 builtin/clone.c:317
+#: merge-recursive.c:776 builtin/clone.c:317
 #, c-format
 msgid "failed to open '%s'"
-msgstr ""
+msgstr "директорията „%s“ не може да бъде отворена"
 
-#: merge-recursive.c:782
+#: merge-recursive.c:784
 #, c-format
 msgid "failed to symlink '%s'"
 msgstr ""
 
-#: merge-recursive.c:785
+#: merge-recursive.c:787
 #, c-format
 msgid "do not know what to do with %06o %s '%s'"
 msgstr ""
 
-#: merge-recursive.c:923
+#: merge-recursive.c:925
 msgid "Failed to execute internal merge"
 msgstr ""
 
-#: merge-recursive.c:927
+#: merge-recursive.c:929
 #, c-format
 msgid "Unable to add %s to database"
 msgstr ""
 
-#: merge-recursive.c:943
+#: merge-recursive.c:945
 msgid "unsupported object type in the tree"
 msgstr ""
 
-#: merge-recursive.c:1022 merge-recursive.c:1036
+#: merge-recursive.c:1024 merge-recursive.c:1038
 #, c-format
 msgid ""
 "CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left "
 "in tree."
 msgstr ""
 
-#: merge-recursive.c:1028 merge-recursive.c:1041
+#: merge-recursive.c:1030 merge-recursive.c:1043
 #, c-format
 msgid ""
 "CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left "
 "in tree at %s."
 msgstr ""
 
-#: merge-recursive.c:1082
+#: merge-recursive.c:1084
 msgid "rename"
 msgstr ""
 
-#: merge-recursive.c:1082 wt-status.c:283
+#: merge-recursive.c:1084
 msgid "renamed"
-msgstr ""
+msgstr "преименуван"
 
-#: merge-recursive.c:1138
+#: merge-recursive.c:1140
 #, c-format
 msgid "%s is a directory in %s adding as %s instead"
 msgstr ""
 
-#: merge-recursive.c:1160
+#: merge-recursive.c:1162
 #, c-format
 msgid ""
 "CONFLICT (rename/rename): Rename \"%s\"->\"%s\" in branch \"%s\" rename \"%s"
 "\"->\"%s\" in \"%s\"%s"
 msgstr ""
 
-#: merge-recursive.c:1165
+#: merge-recursive.c:1167
 msgid " (left unresolved)"
 msgstr ""
 
-#: merge-recursive.c:1219
+#: merge-recursive.c:1221
 #, c-format
 msgid "CONFLICT (rename/rename): Rename %s->%s in %s. Rename %s->%s in %s"
 msgstr ""
 
-#: merge-recursive.c:1249
+#: merge-recursive.c:1251
 #, c-format
 msgid "Renaming %s to %s and %s to %s instead"
 msgstr ""
 
-#: merge-recursive.c:1448
+#: merge-recursive.c:1450
 #, c-format
 msgid "CONFLICT (rename/add): Rename %s->%s in %s. %s added in %s"
 msgstr ""
 
-#: merge-recursive.c:1458
+#: merge-recursive.c:1460
 #, c-format
 msgid "Adding merged %s"
 msgstr ""
 
-#: merge-recursive.c:1463 merge-recursive.c:1661
+#: merge-recursive.c:1465 merge-recursive.c:1663
 #, c-format
 msgid "Adding as %s instead"
 msgstr ""
 
-#: merge-recursive.c:1514
+#: merge-recursive.c:1516
 #, c-format
 msgid "cannot read object %s"
 msgstr ""
 
-#: merge-recursive.c:1517
+#: merge-recursive.c:1519
 #, c-format
 msgid "object %s is not a blob"
 msgstr ""
 
-#: merge-recursive.c:1565
+#: merge-recursive.c:1567
 msgid "modify"
 msgstr ""
 
-#: merge-recursive.c:1565 wt-status.c:281
+#: merge-recursive.c:1567
 msgid "modified"
-msgstr ""
+msgstr "променен"
 
-#: merge-recursive.c:1575
+#: merge-recursive.c:1577
 msgid "content"
 msgstr ""
 
-#: merge-recursive.c:1582
+#: merge-recursive.c:1584
 msgid "add/add"
 msgstr ""
 
-#: merge-recursive.c:1616
+#: merge-recursive.c:1618
 #, c-format
 msgid "Skipped %s (merged same as existing)"
 msgstr ""
 
-#: merge-recursive.c:1630
+#: merge-recursive.c:1632
 #, c-format
 msgid "Auto-merging %s"
 msgstr ""
 
-#: merge-recursive.c:1634 git-submodule.sh:1148
+#: merge-recursive.c:1636 git-submodule.sh:1149
 msgid "submodule"
-msgstr ""
+msgstr "ПОДМОДУЛ"
 
-#: merge-recursive.c:1635
+#: merge-recursive.c:1637
 #, c-format
 msgid "CONFLICT (%s): Merge conflict in %s"
 msgstr ""
 
-#: merge-recursive.c:1725
+#: merge-recursive.c:1727
 #, c-format
 msgid "Removing %s"
-msgstr ""
+msgstr "Изтриване на „%s“"
 
-#: merge-recursive.c:1750
+#: merge-recursive.c:1752
 msgid "file/directory"
 msgstr ""
 
-#: merge-recursive.c:1756
+#: merge-recursive.c:1758
 msgid "directory/file"
 msgstr ""
 
-#: merge-recursive.c:1761
+#: merge-recursive.c:1763
 #, c-format
 msgid "CONFLICT (%s): There is a directory with name %s in %s. Adding %s as %s"
 msgstr ""
 
-#: merge-recursive.c:1771
+#: merge-recursive.c:1773
 #, c-format
 msgid "Adding %s"
 msgstr ""
 
-#: merge-recursive.c:1788
+#: merge-recursive.c:1790
 msgid "Fatal merge failure, shouldn't happen."
 msgstr ""
 
-#: merge-recursive.c:1807
+#: merge-recursive.c:1809
 msgid "Already up-to-date!"
 msgstr ""
 
-#: merge-recursive.c:1816
+#: merge-recursive.c:1818
 #, c-format
 msgid "merging of trees %s and %s failed"
 msgstr ""
 
-#: merge-recursive.c:1846
+#: merge-recursive.c:1848
 #, c-format
 msgid "Unprocessed path??? %s"
 msgstr ""
 
-#: merge-recursive.c:1891
+#: merge-recursive.c:1893
 msgid "Merging:"
 msgstr ""
 
-#: merge-recursive.c:1904
+#: merge-recursive.c:1906
 #, c-format
 msgid "found %u common ancestor:"
 msgid_plural "found %u common ancestors:"
 msgstr[0] ""
 msgstr[1] ""
 
-#: merge-recursive.c:1941
+#: merge-recursive.c:1943
 msgid "merge returned no commit"
 msgstr ""
 
-#: merge-recursive.c:1998
+#: merge-recursive.c:2000
 #, c-format
 msgid "Could not parse object '%s'"
 msgstr ""
 
-#: merge-recursive.c:2010 builtin/merge.c:665
+#: merge-recursive.c:2012 builtin/merge.c:668
 msgid "Unable to write index."
 msgstr ""
 
 #: notes-utils.c:40
 msgid "Cannot commit uninitialized/unreferenced notes tree"
 msgstr ""
+"Неинициализирано или нереферирано дърво за бележки не може да бъде подадено"
 
 #: notes-utils.c:81
 #, c-format
 msgid "Bad notes.rewriteMode value: '%s'"
-msgstr ""
+msgstr "Лоша стойност за „notes.rewriteMode“: „%s“"
 
 #: notes-utils.c:91
 #, c-format
 msgid "Refusing to rewrite notes in %s (outside of refs/notes/)"
 msgstr ""
+"Бележките в „%s“ няма да бъдат презаписани, защото са извън „refs/notes/“."
 
 #. TRANSLATORS: The first %s is the name of the
 #. environment variable, the second %s is its value
 #: notes-utils.c:118
 #, c-format
 msgid "Bad %s value: '%s'"
-msgstr ""
+msgstr "Зададена е лоша стойност на променливата „%s“: „%s“"
 
-#: object.c:202
+#: object.c:229
 #, c-format
 msgid "unable to parse object: %s"
-msgstr ""
+msgstr "обектът „%s“ не може да бъде анализиран"
 
-#: parse-options.c:537
+#: parse-options.c:532
 msgid "..."
 msgstr "…"
 
-#: parse-options.c:555
+#: parse-options.c:550
 #, c-format
 msgid "usage: %s"
 msgstr "употреба: %s"
 
 #. TRANSLATORS: the colon here should align with the
 #. one in "usage: %s" translation
-#: parse-options.c:559
+#: parse-options.c:554
 #, c-format
 msgid "   or: %s"
 msgstr "     или: %s"
 
-#: parse-options.c:562
+#: parse-options.c:557
 #, c-format
 msgid "    %s"
 msgstr "    %s"
 
-#: parse-options.c:596
+#: parse-options.c:591
 msgid "-NUM"
 msgstr "-ЧИСЛО"
 
@@ -993,11 +1029,6 @@ msgstr ""
 msgid "Pathspec '%s' is in submodule '%.*s'"
 msgstr ""
 
-#.
-#. * We may want to substitute "this command" with a command
-#. * name. E.g. when add--interactive dies when running
-#. * "checkout -p"
-#.
 #: pathspec.c:353
 #, c-format
 msgid "%s: pathspec magic not supported by this command: %s"
@@ -1014,56 +1045,74 @@ msgid ""
 "Perhaps you forgot to add either ':/' or '.' ?"
 msgstr ""
 
-#: remote.c:753
+#: progress.c:224
+msgid "done"
+msgstr "действието завърши"
+
+#: read-cache.c:1238
+#, c-format
+msgid ""
+"index.version set, but the value is invalid.\n"
+"Using version %i"
+msgstr ""
+"Зададена е неправилна стойност на настройката „index.version“.\n"
+"Ще се ползва версия %i"
+
+#: read-cache.c:1248
+#, c-format
+msgid ""
+"GIT_INDEX_VERSION set, but the value is invalid.\n"
+"Using version %i"
+msgstr ""
+"Зададена е неправилна стойност на променливата на средата "
+"„GIT_INDEX_VERSION“.\n"
+"Ще се ползва версия %i"
+
+#: remote.c:758
 #, c-format
 msgid "Cannot fetch both %s and %s to %s"
 msgstr "Невъзможно е да се доставят едновременно и „%s“, и „%s“ към „%s“"
 
-#: remote.c:757
+#: remote.c:762
 #, c-format
 msgid "%s usually tracks %s, not %s"
 msgstr "„%s“ обикновено следи „%s“, а не „%s“"
 
-#: remote.c:761
+#: remote.c:766
 #, c-format
 msgid "%s tracks both %s and %s"
 msgstr "„%s“ следи както „%s“, така и „%s“"
 
-#.
-#. * This last possibility doesn't occur because
-#. * FETCH_HEAD_IGNORE entries always appear at
-#. * the end of the list.
-#.
-#: remote.c:769
+#: remote.c:774
 msgid "Internal error"
 msgstr "Вътрешна грешка"
 
-#: remote.c:1871
+#: remote.c:1948
 #, c-format
 msgid "Your branch is based on '%s', but the upstream is gone.\n"
 msgstr "Този клон следи „%s“, но следеният клон е изтрит.\n"
 
-#: remote.c:1875
+#: remote.c:1952
 msgid "  (use \"git branch --unset-upstream\" to fixup)\n"
-msgstr "  (за да коригирате това използвайте „git branch --unset-upstream“)\n"
+msgstr "  (за да коригирате това, използвайте „git branch --unset-upstream“)\n"
 
-#: remote.c:1878
+#: remote.c:1955
 #, c-format
 msgid "Your branch is up-to-date with '%s'.\n"
 msgstr "Клонът е актуализиран както „%s“.\n"
 
-#: remote.c:1882
+#: remote.c:1959
 #, 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:1888
+#: remote.c:1965
 msgid "  (use \"git push\" to publish your local commits)\n"
 msgstr "  (публикувайте локалните си промени чрез „git push“)\n"
 
-#: remote.c:1891
+#: remote.c:1968
 #, c-format
 msgid "Your branch is behind '%s' by %d commit, and can be fast-forwarded.\n"
 msgid_plural ""
@@ -1073,11 +1122,11 @@ msgstr[0] ""
 msgstr[1] ""
 "Клонът ви е с %2$d подавания след „%1$s“ и може да бъде тривиално слят.\n"
 
-#: remote.c:1899
+#: remote.c:1976
 msgid "  (use \"git pull\" to update your local branch)\n"
 msgstr "  (обновете локалния си клон чрез „git pull“)\n"
 
-#: remote.c:1902
+#: remote.c:1979
 #, c-format
 msgid ""
 "Your branch and '%s' have diverged,\n"
@@ -1092,7 +1141,7 @@ msgstr[1] ""
 "Текущият клон се е отделил от „%s“,\n"
 "двата имат съответно по %d и %d несъвпадащи подавания.\n"
 
-#: remote.c:1912
+#: remote.c:1989
 msgid "  (use \"git pull\" to merge the remote branch into yours)\n"
 msgstr "  (слейте отдалечения клон в локалния чрез „git pull“)\n"
 
@@ -1105,14 +1154,14 @@ msgstr "неуспешно отваряне на „/dev/null“"
 msgid "dup2(%d,%d) failed"
 msgstr "неуспешно изпълнение на dup2(%d,%d)"
 
-#: sequencer.c:206 builtin/merge.c:783 builtin/merge.c:896
-#: builtin/merge.c:1006 builtin/merge.c:1016
+#: sequencer.c:206 builtin/merge.c:786 builtin/merge.c:899
+#: builtin/merge.c:1009 builtin/merge.c:1019
 #, c-format
 msgid "Could not open '%s' for writing"
 msgstr ""
 
-#: sequencer.c:208 builtin/merge.c:343 builtin/merge.c:786
-#: builtin/merge.c:1008 builtin/merge.c:1021
+#: sequencer.c:208 builtin/merge.c:343 builtin/merge.c:789
+#: builtin/merge.c:1011 builtin/merge.c:1024
 #, c-format
 msgid "Could not write to '%s'"
 msgstr ""
@@ -1130,7 +1179,7 @@ msgid ""
 "and commit the result with 'git commit'"
 msgstr ""
 
-#: sequencer.c:245 sequencer.c:870 sequencer.c:953
+#: sequencer.c:245 sequencer.c:879 sequencer.c:962
 #, c-format
 msgid "Could not write to %s"
 msgstr ""
@@ -1156,7 +1205,7 @@ msgstr ""
 #: sequencer.c:325
 #, c-format
 msgid "%s: Unable to write new index file"
-msgstr ""
+msgstr "%s: новият индекс не може да бъде запазен"
 
 #: sequencer.c:356
 msgid "Could not resolve HEAD commit\n"
@@ -1166,184 +1215,184 @@ msgstr ""
 msgid "Unable to update cache tree\n"
 msgstr ""
 
-#: sequencer.c:423
+#: sequencer.c:430
 #, c-format
 msgid "Could not parse commit %s\n"
 msgstr ""
 
-#: sequencer.c:428
+#: sequencer.c:435
 #, c-format
 msgid "Could not parse parent commit %s\n"
 msgstr ""
 
-#: sequencer.c:494
+#: sequencer.c:501
 msgid "Your index file is unmerged."
-msgstr ""
+msgstr "Индексът не е слят."
 
-#: sequencer.c:513
+#: sequencer.c:520
 #, c-format
 msgid "Commit %s is a merge but no -m option was given."
 msgstr ""
 
-#: sequencer.c:521
+#: sequencer.c:528
 #, c-format
 msgid "Commit %s does not have parent %d"
 msgstr ""
 
-#: sequencer.c:525
+#: sequencer.c:532
 #, c-format
 msgid "Mainline was specified but commit %s is not a merge."
 msgstr ""
 
 #. TRANSLATORS: The first %s will be "revert" or
 #. "cherry-pick", the second %s a SHA1
-#: sequencer.c:538
+#: sequencer.c:545
 #, c-format
 msgid "%s: cannot parse parent commit %s"
 msgstr ""
 
-#: sequencer.c:542
+#: sequencer.c:549
 #, c-format
 msgid "Cannot get commit message for %s"
 msgstr ""
 
-#: sequencer.c:628
+#: sequencer.c:635
 #, c-format
 msgid "could not revert %s... %s"
 msgstr ""
 
-#: sequencer.c:629
+#: sequencer.c:636
 #, c-format
 msgid "could not apply %s... %s"
 msgstr ""
 
-#: sequencer.c:665
+#: sequencer.c:672
 msgid "empty commit set passed"
 msgstr ""
 
-#: sequencer.c:673
+#: sequencer.c:680
 #, c-format
 msgid "git %s: failed to read the index"
 msgstr ""
 
-#: sequencer.c:678
+#: sequencer.c:685
 #, c-format
 msgid "git %s: failed to refresh the index"
 msgstr ""
 
-#: sequencer.c:736
+#: sequencer.c:743
 #, c-format
 msgid "Cannot %s during a %s"
 msgstr ""
 
-#: sequencer.c:758
+#: sequencer.c:765
 #, c-format
 msgid "Could not parse line %d."
 msgstr ""
 
-#: sequencer.c:763
+#: sequencer.c:770
 msgid "No commits parsed."
 msgstr ""
 
-#: sequencer.c:776
+#: sequencer.c:783
 #, c-format
 msgid "Could not open %s"
 msgstr ""
 
-#: sequencer.c:780
+#: sequencer.c:787
 #, c-format
 msgid "Could not read %s."
 msgstr ""
 
-#: sequencer.c:787
+#: sequencer.c:794
 #, c-format
 msgid "Unusable instruction sheet: %s"
 msgstr ""
 
-#: sequencer.c:815
+#: sequencer.c:824
 #, c-format
 msgid "Invalid key: %s"
 msgstr ""
 
-#: sequencer.c:818
+#: sequencer.c:827
 #, c-format
 msgid "Invalid value for %s: %s"
 msgstr ""
 
-#: sequencer.c:830
+#: sequencer.c:839
 #, c-format
 msgid "Malformed options sheet: %s"
 msgstr ""
 
-#: sequencer.c:851
+#: sequencer.c:860
 msgid "a cherry-pick or revert is already in progress"
 msgstr ""
 
-#: sequencer.c:852
+#: sequencer.c:861
 msgid "try \"git cherry-pick (--continue | --quit | --abort)\""
 msgstr ""
 
-#: sequencer.c:856
+#: sequencer.c:865
 #, c-format
 msgid "Could not create sequencer directory %s"
 msgstr ""
 
-#: sequencer.c:872 sequencer.c:957
+#: sequencer.c:881 sequencer.c:966
 #, c-format
 msgid "Error wrapping up %s."
 msgstr ""
 
-#: sequencer.c:891 sequencer.c:1025
+#: sequencer.c:900 sequencer.c:1036
 msgid "no cherry-pick or revert in progress"
 msgstr ""
 
-#: sequencer.c:893
+#: sequencer.c:902
 msgid "cannot resolve HEAD"
 msgstr ""
 
-#: sequencer.c:895
+#: sequencer.c:904
 msgid "cannot abort from a branch yet to be born"
 msgstr ""
 
-#: sequencer.c:917 builtin/apply.c:4061
+#: sequencer.c:926 builtin/apply.c:4061
 #, c-format
 msgid "cannot open %s: %s"
 msgstr ""
 
-#: sequencer.c:920
+#: sequencer.c:929
 #, c-format
 msgid "cannot read %s: %s"
 msgstr ""
 
-#: sequencer.c:921
+#: sequencer.c:930
 msgid "unexpected end of file"
 msgstr ""
 
-#: sequencer.c:927
+#: sequencer.c:936
 #, c-format
 msgid "stored pre-cherry-pick HEAD file '%s' is corrupt"
 msgstr ""
 
-#: sequencer.c:950
+#: sequencer.c:959
 #, c-format
 msgid "Could not format %s."
 msgstr ""
 
-#: sequencer.c:1093
+#: sequencer.c:1104
 #, c-format
 msgid "%s: can't cherry-pick a %s"
 msgstr ""
 
-#: sequencer.c:1096
+#: sequencer.c:1107
 #, c-format
 msgid "%s: bad revision"
 msgstr ""
 
-#: sequencer.c:1130
+#: sequencer.c:1141
 msgid "Can't revert as initial commit"
 msgstr ""
 
-#: sequencer.c:1131
+#: sequencer.c:1142
 msgid "Can't cherry-pick into empty head"
 msgstr ""
 
@@ -1359,80 +1408,76 @@ msgid ""
 "examine these refs and maybe delete them. Turn this message off by\n"
 "running \"git config advice.objectNameWarning false\""
 msgstr ""
+"При нормална работа git никога не създава указатели, които завършват с 40\n"
+"шестнасетични знаци, защото те ще бъдат прескачани, когато указвате \n"
+"шестнайсетични знаци. Една възможност е такива указатели да са създадени\n"
+"по погрешка. Например:\n"
+"\n"
+"  git checkout -b $BRANCH $(git rev-parse…)\n"
+"\n"
+"където стойността на променливата на средата BRANCH е празна, при което се\n"
+"създава подобен указател. Прегледайте тези указатели и ги изтрийте. Можете "
+"да\n"
+"спрете това съобщение като изпълнете „git config advice.objectNameWarning "
+"false“"
 
-#: sha1_name.c:1109
+#: sha1_name.c:1072
 msgid "HEAD does not point to a branch"
-msgstr ""
+msgstr "Указателят „HEAD“ не сочи към клон"
 
-#: sha1_name.c:1112
+#: sha1_name.c:1075
 #, c-format
 msgid "No such branch: '%s'"
-msgstr ""
+msgstr "Не съществува клон на име „%s“"
 
-#: sha1_name.c:1114
+#: sha1_name.c:1077
 #, c-format
 msgid "No upstream configured for branch '%s'"
-msgstr ""
+msgstr "Не е зададен клон-източник за клона „%s“"
 
-#: sha1_name.c:1118
+#: sha1_name.c:1081
 #, c-format
 msgid "Upstream branch '%s' not stored as a remote-tracking branch"
-msgstr ""
+msgstr "Клонът-източник „%s“ не е съхранен като следящ клон"
 
 #: submodule.c:64 submodule.c:98
 msgid "Cannot change unmerged .gitmodules, resolve merge conflicts first"
 msgstr ""
+"Неслетите файлове „.gitmodules“ не могат да бъдат променяни. Първо "
+"коригирайте конфликтите"
 
 #: submodule.c:68 submodule.c:102
 #, c-format
 msgid "Could not find section in .gitmodules where path=%s"
-msgstr ""
+msgstr "Във файла „.gitmodules“ липсва раздел за директория „path=%s“"
 
-#. Maybe the user already did that, don't error out here
 #: submodule.c:76
 #, c-format
 msgid "Could not update .gitmodules entry %s"
-msgstr ""
+msgstr "Записът „%s“ във файла „.gitmodules“ не може да бъде променен"
 
-#. Maybe the user already did that, don't error out here
 #: submodule.c:109
 #, c-format
 msgid "Could not remove .gitmodules entry for %s"
-msgstr ""
-
-#: submodule.c:127
-msgid "could not find .gitmodules in index"
-msgstr ""
-
-#: submodule.c:133
-msgid "reading updated .gitmodules failed"
-msgstr ""
-
-#: submodule.c:135
-msgid "unable to stat updated .gitmodules"
-msgstr ""
+msgstr "Записът „%s“ във файла „.gitmodules“ не може да бъде изтрит"
 
-#: submodule.c:139
-msgid "unable to remove .gitmodules from index"
-msgstr ""
-
-#: submodule.c:141
-msgid "adding updated .gitmodules failed"
-msgstr ""
-
-#: submodule.c:143
+#: submodule.c:120
 msgid "staging updated .gitmodules failed"
-msgstr ""
+msgstr "неуспешно добавяне в индекса на променения файл „.gitmodules“"
 
-#: submodule.c:1144 builtin/init-db.c:363
+#: submodule.c:1121 builtin/init-db.c:363
 #, c-format
 msgid "Could not create git link %s"
-msgstr ""
+msgstr "Връзката в Git „%s“ не може да бъде създадена"
 
-#: submodule.c:1155
+#: submodule.c:1132
 #, c-format
 msgid "Could not set core.worktree in %s"
-msgstr ""
+msgstr "В „%s“ не може да се зададе настройката „core.worktree“"
+
+#: unpack-trees.c:206
+msgid "Checking out files"
+msgstr "Изтегляне на файлове"
 
 #: urlmatch.c:120
 msgid "invalid URL scheme name or missing '://' suffix"
@@ -1466,623 +1511,623 @@ msgstr ""
 #: wrapper.c:422
 #, c-format
 msgid "unable to access '%s': %s"
-msgstr ""
+msgstr "няма достъп до „%s“: %s"
 
 #: wrapper.c:443
 #, c-format
 msgid "unable to access '%s'"
-msgstr ""
+msgstr "няма достъп до „%s“"
 
 #: wrapper.c:454
 #, c-format
 msgid "unable to look up current user in the passwd file: %s"
-msgstr ""
+msgstr "текущият потребител не може да бъде открит във файла „/etc/passwd“: %s"
 
 #: wrapper.c:455
 msgid "no such user"
-msgstr ""
+msgstr "такъв потребител не съществува"
 
 #: wt-status.c:150
 msgid "Unmerged paths:"
-msgstr ""
+msgstr "Неслети пътища:"
 
 #: wt-status.c:177 wt-status.c:204
 #, c-format
 msgid "  (use \"git reset %s <file>...\" to unstage)"
-msgstr ""
+msgstr "  (използвайте „git reset %s ФАЙЛ…“, за да извадите ФАЙЛа от индекса)"
 
 #: wt-status.c:179 wt-status.c:206
 msgid "  (use \"git rm --cached <file>...\" to unstage)"
 msgstr ""
+"  (използвайте „git rm --cached %s ФАЙЛ…“, за да извадите ФАЙЛа от индекса)"
 
 #: wt-status.c:183
 msgid "  (use \"git add <file>...\" to mark resolution)"
 msgstr ""
+"  (използвайте „git add ФАЙЛ…“, за да укажете разрешаването на конфликта)"
 
 #: wt-status.c:185 wt-status.c:189
 msgid "  (use \"git add/rm <file>...\" as appropriate to mark resolution)"
 msgstr ""
+"  (използвайте „git add/rm ФАЙЛ…“, според решението, което избирате за "
+"конфликта)"
 
 #: wt-status.c:187
 msgid "  (use \"git rm <file>...\" to mark resolution)"
 msgstr ""
+"  (използвайте „git rm ФАЙЛ…“, за да укажете разрешаването на конфликта)"
 
 #: wt-status.c:198
 msgid "Changes to be committed:"
-msgstr ""
+msgstr "Промени, които ще бъдат подадени:"
 
 #: wt-status.c:216
 msgid "Changes not staged for commit:"
-msgstr ""
+msgstr "Промени, които не са в индекса за подаване:"
 
 #: wt-status.c:220
 msgid "  (use \"git add <file>...\" to update what will be committed)"
 msgstr ""
+"  (използвайте „git add ФАЙЛ…“, за да обновите съдържанието за подаване)"
 
 #: wt-status.c:222
 msgid "  (use \"git add/rm <file>...\" to update what will be committed)"
 msgstr ""
+"  (използвайте „git add/rm ФАЙЛ…“, за да обновите съдържанието за подаване)"
 
 #: wt-status.c:223
 msgid ""
 "  (use \"git checkout -- <file>...\" to discard changes in working directory)"
 msgstr ""
+"  (използвайте „git checkout -- ФАЙЛ…“, за да отхвърлите промените в "
+"работното дърво)"
 
 #: wt-status.c:225
 msgid "  (commit or discard the untracked or modified content in submodules)"
 msgstr ""
+"  (подайте или отхвърлете неследеното или промененото съдържание в "
+"подмодулите)"
 
 #: wt-status.c:237
 #, c-format
 msgid "  (use \"git %s <file>...\" to include in what will be committed)"
 msgstr ""
+"  (използвайте „git %s ФАЙЛ…“, за да определите какво включвате в подаването)"
 
-#: wt-status.c:254
-msgid "bug"
-msgstr ""
-
-#: wt-status.c:259
+#: wt-status.c:252
 msgid "both deleted:"
-msgstr ""
+msgstr "изтрити в двата случая:"
 
-#: wt-status.c:260
+#: wt-status.c:254
 msgid "added by us:"
-msgstr ""
+msgstr "добавени от вас:"
 
-#: wt-status.c:261
+#: wt-status.c:256
 msgid "deleted by them:"
-msgstr ""
+msgstr "изтрити от тях:"
 
-#: wt-status.c:262
+#: wt-status.c:258
 msgid "added by them:"
-msgstr ""
+msgstr "добавени от тях:"
 
-#: wt-status.c:263
+#: wt-status.c:260
 msgid "deleted by us:"
-msgstr ""
+msgstr "изтрити от нас:"
 
-#: wt-status.c:264
+#: wt-status.c:262
 msgid "both added:"
-msgstr ""
+msgstr "добавени и в двата случая:"
 
-#: wt-status.c:265
+#: wt-status.c:264
 msgid "both modified:"
-msgstr ""
+msgstr "променени и в двата случая:"
 
-#: wt-status.c:275
-msgid "new file"
-msgstr ""
+#: wt-status.c:266
+#, c-format
+msgid "bug: unhandled unmerged status %x"
+msgstr "грешка: състоянието на промяната „%x“ не може да бъде обработено"
 
-#: wt-status.c:277
-msgid "copied"
-msgstr ""
+#: wt-status.c:274
+msgid "new file:"
+msgstr "нов файл:"
 
-#: wt-status.c:279
-msgid "deleted"
-msgstr ""
+#: wt-status.c:276
+msgid "copied:"
+msgstr "копиран:"
 
-#: wt-status.c:285
-msgid "typechange"
-msgstr ""
+#: wt-status.c:278
+msgid "deleted:"
+msgstr "изтрит:"
 
-#: wt-status.c:287
-msgid "unknown"
-msgstr ""
+#: wt-status.c:280
+msgid "modified:"
+msgstr "променен:"
 
-#: wt-status.c:289
-msgid "unmerged"
-msgstr ""
+#: wt-status.c:282
+msgid "renamed:"
+msgstr "преименуван:"
 
-#: wt-status.c:336
+#: wt-status.c:284
+msgid "typechange:"
+msgstr "смяна на вида:"
+
+#: wt-status.c:286
+msgid "unknown:"
+msgstr "непозната промяна:"
+
+#: wt-status.c:288
+msgid "unmerged:"
+msgstr "неслят:"
+
+#: wt-status.c:370
 msgid "new commits, "
-msgstr ""
+msgstr "нови подавания, "
 
-#: wt-status.c:338
+#: wt-status.c:372
 msgid "modified content, "
-msgstr ""
+msgstr "променено съдържание, "
 
-#: wt-status.c:340
+#: wt-status.c:374
 msgid "untracked content, "
-msgstr ""
+msgstr "неследено съдържание, "
 
-#: wt-status.c:357
+#: wt-status.c:391
 #, c-format
 msgid "bug: unhandled diff status %c"
-msgstr ""
+msgstr "грешка: състоянието на промяната „%c“ не може да бъде обработено"
 
-#: wt-status.c:732
+#: wt-status.c:765
 msgid "Submodules changed but not updated:"
-msgstr ""
+msgstr "Подмодулите са променени, но не са обновени:"
 
-#: wt-status.c:734
+#: wt-status.c:767
 msgid "Submodule changes to be committed:"
-msgstr ""
+msgstr "Промени в подмодулите за подаване:"
 
-#: wt-status.c:836
+#: wt-status.c:846
 msgid ""
 "Do not touch the line above.\n"
 "Everything below will be removed."
 msgstr ""
+"Не променяйте горния ред.\n"
+"Всичко отдолу ще бъде изтрито."
 
-#: wt-status.c:899
+#: wt-status.c:937
 msgid "You have unmerged paths."
-msgstr ""
+msgstr "Някои пътища не са слети."
 
-#: wt-status.c:902
+#: wt-status.c:940
 msgid "  (fix conflicts and run \"git commit\")"
-msgstr ""
+msgstr "  (коригирайте конфликтите и изпълнете „git commit“)"
 
-#: wt-status.c:905
+#: wt-status.c:943
 msgid "All conflicts fixed but you are still merging."
-msgstr ""
+msgstr "Всички конфликти са решени, но продължавате сливането."
 
-#: wt-status.c:908
+#: wt-status.c:946
 msgid "  (use \"git commit\" to conclude merge)"
-msgstr ""
+msgstr "  (използвайте „git commit“, за да завършите сливането)"
 
-#: wt-status.c:918
+#: wt-status.c:956
 msgid "You are in the middle of an am session."
-msgstr ""
+msgstr "В момента прилагате поредица от кръпки чрез „git am“."
 
-#: wt-status.c:921
+#: wt-status.c:959
 msgid "The current patch is empty."
-msgstr ""
+msgstr "Текущата кръпка е празна."
 
-#: wt-status.c:925
+#: wt-status.c:963
 msgid "  (fix conflicts and then run \"git am --continue\")"
-msgstr ""
+msgstr "  (коригирайте конфликтите и изпълнете „git am --continue“)"
 
-#: wt-status.c:927
+#: wt-status.c:965
 msgid "  (use \"git am --skip\" to skip this patch)"
-msgstr ""
+msgstr "  (използвайте „git am --skip“, за да пропуснете тази кръпка)"
 
-#: wt-status.c:929
+#: wt-status.c:967
 msgid "  (use \"git am --abort\" to restore the original branch)"
 msgstr ""
+"  (използвайте „git am --abort“, за да възстановите първоначалния клон)"
 
-#: wt-status.c:989 wt-status.c:1006
+#: wt-status.c:1027 wt-status.c:1044
 #, c-format
 msgid "You are currently rebasing branch '%s' on '%s'."
-msgstr ""
+msgstr "В момента пребазирате клона „%s“ върху „%s“."
 
-#: wt-status.c:994 wt-status.c:1011
+#: wt-status.c:1032 wt-status.c:1049
 msgid "You are currently rebasing."
-msgstr ""
+msgstr "В момента пребазирате."
 
-#: wt-status.c:997
+#: wt-status.c:1035
 msgid "  (fix conflicts and then run \"git rebase --continue\")"
-msgstr ""
+msgstr "  (коригирайте конфликтите и използвайте „git rebase --continue“)"
 
-#: wt-status.c:999
+#: wt-status.c:1037
 msgid "  (use \"git rebase --skip\" to skip this patch)"
-msgstr ""
+msgstr "  (използвайте „git rebase --skip“, за да пропуснете тази кръпка)"
 
-#: wt-status.c:1001
+#: wt-status.c:1039
 msgid "  (use \"git rebase --abort\" to check out the original branch)"
 msgstr ""
+"  (използвайте „git rebase --abort“, за да възстановите първоначалния клон)"
 
-#: wt-status.c:1014
+#: wt-status.c:1052
 msgid "  (all conflicts fixed: run \"git rebase --continue\")"
-msgstr ""
+msgstr "  (всички конфликти са коригирани: изпълнете „git rebase --continue“)"
 
-#: wt-status.c:1018
+#: wt-status.c:1056
 #, c-format
 msgid ""
 "You are currently splitting a commit while rebasing branch '%s' on '%s'."
-msgstr ""
+msgstr "В момента разделяте подаване докато пребазирате клона „%s“ върху „%s“."
 
-#: wt-status.c:1023
+#: wt-status.c:1061
 msgid "You are currently splitting a commit during a rebase."
-msgstr ""
+msgstr "В момента разделяте подаване докато пребазирате."
 
-#: wt-status.c:1026
+#: wt-status.c:1064
 msgid "  (Once your working directory is clean, run \"git rebase --continue\")"
 msgstr ""
+"  (След като работното ви дърво стане чисто, използвайте „git rebase --"
+"continue“)"
 
-#: wt-status.c:1030
+#: wt-status.c:1068
 #, c-format
 msgid "You are currently editing a commit while rebasing branch '%s' on '%s'."
 msgstr ""
+"В момента редактирате подаване докато пребазирате клона „%s“ върху „%s“."
 
-#: wt-status.c:1035
+#: wt-status.c:1073
 msgid "You are currently editing a commit during a rebase."
-msgstr ""
+msgstr "В момента редактирате подаване докато пребазирате."
 
-#: wt-status.c:1038
+#: wt-status.c:1076
 msgid "  (use \"git commit --amend\" to amend the current commit)"
 msgstr ""
+"  (използвайте „git commit --amend“, за да редактирате текущото подаване)"
 
-#: wt-status.c:1040
+#: wt-status.c:1078
 msgid ""
 "  (use \"git rebase --continue\" once you are satisfied with your changes)"
 msgstr ""
+"  (използвайте „git rebase --continue“, след като завършите промените си)"
 
-#: wt-status.c:1050
+#: wt-status.c:1088
 #, c-format
 msgid "You are currently cherry-picking commit %s."
-msgstr ""
+msgstr "В момента отбирате подаването „%s“."
 
-#: wt-status.c:1055
+#: wt-status.c:1093
 msgid "  (fix conflicts and run \"git cherry-pick --continue\")"
-msgstr ""
+msgstr "  (коригирайте конфликтите и изпълнете „git cherry-pick --continue“)"
 
-#: wt-status.c:1058
+#: wt-status.c:1096
 msgid "  (all conflicts fixed: run \"git cherry-pick --continue\")"
 msgstr ""
+"  (всички конфликти са коригирани, изпълнете „git cherry-pick --continue“)"
 
-#: wt-status.c:1060
+#: wt-status.c:1098
 msgid "  (use \"git cherry-pick --abort\" to cancel the cherry-pick operation)"
 msgstr ""
+"  (използвайте „git cherry-pick --abort“, за да отмените всички действия с "
+"отбиране)"
 
-#: wt-status.c:1069
+#: wt-status.c:1107
 #, c-format
 msgid "You are currently reverting commit %s."
-msgstr ""
+msgstr "В момента отменяте подаване „%s“."
 
-#: wt-status.c:1074
+#: wt-status.c:1112
 msgid "  (fix conflicts and run \"git revert --continue\")"
-msgstr ""
+msgstr "  (коригирайте конфликтите и изпълнете „git revert --continue“)"
 
-#: wt-status.c:1077
+#: wt-status.c:1115
 msgid "  (all conflicts fixed: run \"git revert --continue\")"
-msgstr ""
+msgstr "  (всички конфликти са коригирани, изпълнете „git revert --continue“)"
 
-#: wt-status.c:1079
+#: wt-status.c:1117
 msgid "  (use \"git revert --abort\" to cancel the revert operation)"
 msgstr ""
+"  (използвайте „git revert --abort“, за да преустановите отмяната на "
+"подаване)"
 
-#: wt-status.c:1090
+#: wt-status.c:1128
 #, c-format
 msgid "You are currently bisecting, started from branch '%s'."
-msgstr ""
+msgstr "В момента търсите двоично, като сте стартирали от клон „%s“."
 
-#: wt-status.c:1094
+#: wt-status.c:1132
 msgid "You are currently bisecting."
-msgstr ""
+msgstr "В момента търсите двоично."
 
-#: wt-status.c:1097
+#: wt-status.c:1135
 msgid "  (use \"git bisect reset\" to get back to the original branch)"
 msgstr ""
+"  (използвайте „git bisect reset“, за да се върнете към първоначалното "
+"състояние и клон)"
 
-#: wt-status.c:1272
+#: wt-status.c:1310
 msgid "On branch "
-msgstr ""
+msgstr "На клон "
 
-#: wt-status.c:1279
+#: wt-status.c:1317
 msgid "rebase in progress; onto "
-msgstr ""
+msgstr "извършвате пребазиране върху "
 
-#: wt-status.c:1286
+#: wt-status.c:1324
 msgid "HEAD detached at "
-msgstr ""
+msgstr "Указателят „HEAD“ не е свързан и е на подаване "
 
-#: wt-status.c:1288
+#: wt-status.c:1326
 msgid "HEAD detached from "
-msgstr ""
+msgstr "Указателят „HEAD“ не е свързан и е отделѐн от "
 
-#: wt-status.c:1291
+#: wt-status.c:1329
 msgid "Not currently on any branch."
-msgstr ""
+msgstr "Извън всички клони"
 
-#: wt-status.c:1308
+#: wt-status.c:1346
 msgid "Initial commit"
-msgstr ""
+msgstr "Първоначално подаване"
 
-#: wt-status.c:1322
+#: wt-status.c:1360
 msgid "Untracked files"
-msgstr ""
+msgstr "Неследени файлове"
 
-#: wt-status.c:1324
+#: wt-status.c:1362
 msgid "Ignored files"
-msgstr ""
+msgstr "Игнорирани файлове"
 
-#: wt-status.c:1328
+#: wt-status.c:1366
 #, c-format
 msgid ""
 "It took %.2f seconds to enumerate untracked files. 'status -uno'\n"
 "may speed it up, but you have to be careful not to forget to add\n"
 "new files yourself (see 'git help status')."
 msgstr ""
+"Бяха необходими %.2f секунди за изброяването на неследените файлове.\n"
+"Добавянето на опцията „-uno“ към командата „git status“, ще ускори\n"
+"нещата, но не трябва да забравяте ръчно да добавяте новите файлове.\n"
+"За повече подробности погледнете „git status help“."
 
-#: wt-status.c:1334
+#: wt-status.c:1372
 #, c-format
 msgid "Untracked files not listed%s"
-msgstr ""
+msgstr "Неследените файлове не са изведени%s"
 
-#: wt-status.c:1336
+#: wt-status.c:1374
 msgid " (use -u option to show untracked files)"
-msgstr ""
+msgstr " (използвайте опцията „-u“, за да изведете неследените файлове)"
 
-#: wt-status.c:1342
+#: wt-status.c:1380
 msgid "No changes"
-msgstr ""
+msgstr "Няма промени"
 
-#: wt-status.c:1347
+#: wt-status.c:1385
 #, 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:1350
+#: wt-status.c:1388
 #, c-format
 msgid "no changes added to commit\n"
-msgstr ""
+msgstr "към индекса за подаване не са добавени промени\n"
 
-#: wt-status.c:1353
+#: wt-status.c:1391
 #, c-format
 msgid ""
 "nothing added to commit but untracked files present (use \"git add\" to "
 "track)\n"
 msgstr ""
+"към индекса за подаване не са добавени промени, но има нови файлове "
+"(използвайте „git add“, за да започне тяхното следене)\n"
 
-#: wt-status.c:1356
+#: wt-status.c:1394
 #, c-format
 msgid "nothing added to commit but untracked files present\n"
-msgstr ""
+msgstr "към индекса за подаване не са добавени промени, но има нови файлове\n"
 
-#: wt-status.c:1359
+#: wt-status.c:1397
 #, c-format
 msgid "nothing to commit (create/copy files and use \"git add\" to track)\n"
 msgstr ""
+"липсват каквито и да е промени (създайте или копирайте файлове и използвайте "
+"„git add“, за да започне тяхното следене)\n"
 
-#: wt-status.c:1362 wt-status.c:1367
+#: wt-status.c:1400 wt-status.c:1405
 #, c-format
 msgid "nothing to commit\n"
-msgstr ""
+msgstr "липсват каквито и да е промени\n"
 
-#: wt-status.c:1365
+#: wt-status.c:1403
 #, c-format
 msgid "nothing to commit (use -u to show untracked files)\n"
 msgstr ""
+"липсват каквито и да е промени (използвайте опцията „-u“, за да се изведат и "
+"неследените файлове)\n"
 
-#: wt-status.c:1369
+#: wt-status.c:1407
 #, c-format
 msgid "nothing to commit, working directory clean\n"
-msgstr ""
+msgstr "липсват каквито и да е промени, работното дърво е чисто\n"
 
-#: wt-status.c:1478
+#: wt-status.c:1516
 msgid "HEAD (no branch)"
-msgstr ""
+msgstr "HEAD (извън клон)"
 
-#: wt-status.c:1484
+#: wt-status.c:1522
 msgid "Initial commit on "
-msgstr ""
+msgstr "Първоначално подаване на "
 
-#: wt-status.c:1514
+#: wt-status.c:1554
 msgid "gone"
-msgstr ""
+msgstr "изтрит"
 
-#: wt-status.c:1516
+#: wt-status.c:1556 wt-status.c:1564
 msgid "behind "
-msgstr ""
-
-#: wt-status.c:1519 wt-status.c:1522
-msgid "ahead "
-msgstr ""
-
-#: wt-status.c:1524
-msgid ", behind "
-msgstr ""
+msgstr "назад с "
 
 #: compat/precompose_utf8.c:55 builtin/clone.c:356
 #, c-format
 msgid "failed to unlink '%s'"
-msgstr ""
+msgstr "неуспешно изтриване на „%s“"
 
-#: builtin/add.c:20
+#: builtin/add.c:21
 msgid "git add [options] [--] <pathspec>..."
-msgstr ""
-
-#.
-#. * To be consistent with "git add -p" and most Git
-#. * commands, we should default to being tree-wide, but
-#. * this is not the original behavior and can't be
-#. * changed until users trained themselves not to type
-#. * "git add -u" or "git add -A". For now, we warn and
-#. * keep the old behavior. Later, the behavior can be changed
-#. * to tree-wide, keeping the warning for a while, and
-#. * eventually we can drop the warning.
-#.
-#: builtin/add.c:58
-#, c-format
-msgid ""
-"The behavior of 'git add %s (or %s)' with no path argument from a\n"
-"subdirectory of the tree will change in Git 2.0 and should not be used "
-"anymore.\n"
-"To add content for the whole tree, run:\n"
-"\n"
-"  git add %s :/\n"
-"  (or git add %s :/)\n"
-"\n"
-"To restrict the command to the current directory, run:\n"
-"\n"
-"  git add %s .\n"
-"  (or git add %s .)\n"
-"\n"
-"With the current Git version, the command is restricted to the current "
-"directory.\n"
-msgstr ""
-
-#: builtin/add.c:100
-#, c-format
-msgid ""
-"You ran 'git add' with neither '-A (--all)' or '--ignore-removal',\n"
-"whose behaviour will change in Git 2.0 with respect to paths you removed.\n"
-"Paths like '%s' that are\n"
-"removed from your working tree are ignored with this version of Git.\n"
-"\n"
-"* 'git add --ignore-removal <pathspec>', which is the current default,\n"
-"  ignores paths you removed from your working tree.\n"
-"\n"
-"* 'git add --all <pathspec>' will let you also record the removals.\n"
-"\n"
-"Run 'git status' to check the paths you removed from your working tree.\n"
-msgstr ""
+msgstr "git add [ОПЦИИ] [--] ПЪТ…"
 
-#: builtin/add.c:144
+#: builtin/add.c:64
 #, c-format
 msgid "unexpected diff status %c"
-msgstr ""
+msgstr "неочакван изходен код при генериране на разлика: %c"
 
-#: builtin/add.c:149 builtin/commit.c:260
+#: builtin/add.c:69 builtin/commit.c:261
 msgid "updating files failed"
-msgstr ""
+msgstr "неуспешно обновяване на файловете"
 
-#: builtin/add.c:163
+#: builtin/add.c:79
 #, c-format
 msgid "remove '%s'\n"
-msgstr ""
+msgstr "изтриване на „%s“\n"
 
-#: builtin/add.c:237
+#: builtin/add.c:133
 msgid "Unstaged changes after refreshing the index:"
-msgstr ""
+msgstr "Промени, които и след обновяването на индекса не са добавени към него:"
 
-#: builtin/add.c:299
+#: builtin/add.c:193
 msgid "Could not read the index"
-msgstr ""
+msgstr "Индексът не може да бъде прочетен"
 
-#: builtin/add.c:310
+#: builtin/add.c:204
 #, c-format
 msgid "Could not open '%s' for writing."
-msgstr ""
+msgstr "Файлът „%s“ не може да бъде отворен за запис."
 
-#: builtin/add.c:314
+#: builtin/add.c:208
 msgid "Could not write patch"
-msgstr ""
+msgstr "Кръпката не може да бъде записана"
 
-#: builtin/add.c:319
+#: builtin/add.c:213
 #, c-format
 msgid "Could not stat '%s'"
-msgstr ""
+msgstr "Не може да се получи информация чрез „stat“ за файла „%s“"
 
-#: builtin/add.c:321
+#: builtin/add.c:215
 msgid "Empty patch. Aborted."
-msgstr ""
+msgstr "Празна кръпка, преустановяване на действието."
 
-#: builtin/add.c:327
+#: builtin/add.c:221
 #, c-format
 msgid "Could not apply '%s'"
-msgstr ""
+msgstr "Кръпката „%s“ не може да бъде приложена"
 
-#: builtin/add.c:337
+#: builtin/add.c:231
 msgid "The following paths are ignored by one of your .gitignore files:\n"
 msgstr ""
+"Следните пътища ще бъдат игнорирани според някой от файловете „.gitignore“:\n"
 
-#: builtin/add.c:354 builtin/clean.c:875 builtin/fetch.c:93 builtin/mv.c:70
-#: builtin/prune-packed.c:77 builtin/push.c:506 builtin/remote.c:1344
+#: builtin/add.c:248 builtin/clean.c:876 builtin/fetch.c:93 builtin/mv.c:70
+#: builtin/prune-packed.c:77 builtin/push.c:489 builtin/remote.c:1344
 #: builtin/rm.c:269
 msgid "dry run"
 msgstr "пробно изпълнeние"
 
-#: builtin/add.c:355 builtin/apply.c:4410 builtin/check-ignore.c:19
-#: builtin/commit.c:1249 builtin/count-objects.c:95 builtin/fsck.c:612
+#: builtin/add.c:249 builtin/apply.c:4410 builtin/check-ignore.c:19
+#: builtin/commit.c:1256 builtin/count-objects.c:95 builtin/fsck.c:612
 #: builtin/log.c:1592 builtin/mv.c:69 builtin/read-tree.c:113
 msgid "be verbose"
 msgstr "повече подробности"
 
-#: builtin/add.c:357
+#: builtin/add.c:251
 msgid "interactive picking"
-msgstr ""
+msgstr "интерактивно отбиране на промени"
 
-#: builtin/add.c:358 builtin/checkout.c:1109 builtin/reset.c:272
+#: builtin/add.c:252 builtin/checkout.c:1108 builtin/reset.c:283
 msgid "select hunks interactively"
-msgstr ""
+msgstr "интерактивен избор на парчета код"
 
-#: builtin/add.c:359
+#: builtin/add.c:253
 msgid "edit current diff and apply"
-msgstr ""
+msgstr "редактиране на текущата разлика и прилагане"
 
-#: builtin/add.c:360
+#: builtin/add.c:254
 msgid "allow adding otherwise ignored files"
-msgstr ""
+msgstr "добавяне и на иначе игнорираните файлове"
 
-#: builtin/add.c:361
+#: builtin/add.c:255
 msgid "update tracked files"
-msgstr ""
+msgstr "обновяване на следените файлове"
 
-#: builtin/add.c:362
+#: builtin/add.c:256
 msgid "record only the fact that the path will be added later"
-msgstr ""
+msgstr "отбелязване само на факта, че пътят ще бъде добавен по-късно"
 
-#: builtin/add.c:363
+#: builtin/add.c:257
 msgid "add changes from all tracked and untracked files"
-msgstr ""
+msgstr "добавяне на всички промени в следените и неследените файлове"
 
-#. takes no arguments
-#: builtin/add.c:366
+#: builtin/add.c:260
 msgid "ignore paths removed in the working tree (same as --no-all)"
 msgstr ""
+"игнориране на пътищата, които са изтрити от работното дърво (същото като „--"
+"no-all“)"
 
-#: builtin/add.c:368
+#: builtin/add.c:262
 msgid "don't add, only refresh the index"
-msgstr ""
+msgstr "без добавяне на нови файлове, само обновяване на индекса"
 
-#: builtin/add.c:369
+#: builtin/add.c:263
 msgid "just skip files which cannot be added because of errors"
 msgstr ""
+"прескачане на файловете, които не могат да бъдат добавени поради грешки"
 
-#: builtin/add.c:370
+#: builtin/add.c:264
 msgid "check if - even missing - files are ignored in dry run"
 msgstr ""
+"проверка, че при пробно изпълнение всички файлове, дори и изтритите, се "
+"игнорират"
 
-#: builtin/add.c:392
+#: builtin/add.c:286
 #, c-format
 msgid "Use -f if you really want to add them.\n"
-msgstr ""
+msgstr "Използвайте опцията „-f“, ако наистина искате да ги добавите.\n"
 
-#: builtin/add.c:393
+#: builtin/add.c:287
 msgid "no files added"
-msgstr ""
+msgstr "не са добавени файлове"
 
-#: builtin/add.c:399
+#: builtin/add.c:293
 msgid "adding files failed"
-msgstr ""
+msgstr "неуспешно добавяне на файлове"
 
-#: builtin/add.c:438
+#: builtin/add.c:330
 msgid "-A and -u are mutually incompatible"
-msgstr ""
+msgstr "опциите „-A“ и „-u“ са несъвместими"
 
-#: builtin/add.c:456
+#: builtin/add.c:337
 msgid "Option --ignore-missing can only be used together with --dry-run"
-msgstr ""
+msgstr "Опцията „--ignore-missing“ е съвместима само с „--dry-run“"
 
-#: builtin/add.c:486
+#: builtin/add.c:358
 #, c-format
 msgid "Nothing specified, nothing added.\n"
-msgstr ""
+msgstr "Нищо не е зададено и нищо не е добавено.\n"
 
-#: builtin/add.c:487
+#: builtin/add.c:359
 #, c-format
 msgid "Maybe you wanted to say 'git add .'?\n"
-msgstr ""
+msgstr "Вероятно искахте да използвате „git add .“?\n"
 
-#: builtin/add.c:492 builtin/check-ignore.c:172 builtin/clean.c:919
-#: builtin/commit.c:320 builtin/mv.c:90 builtin/reset.c:224 builtin/rm.c:299
+#: builtin/add.c:364 builtin/check-ignore.c:172 builtin/clean.c:920
+#: builtin/commit.c:320 builtin/mv.c:90 builtin/reset.c:234 builtin/rm.c:299
 msgid "index file corrupt"
 msgstr "файлът с индекса е повреден"
 
-#: builtin/add.c:592 builtin/apply.c:4506 builtin/mv.c:270 builtin/rm.c:432
+#: builtin/add.c:448 builtin/apply.c:4506 builtin/mv.c:280 builtin/rm.c:432
 msgid "Unable to write new index file"
-msgstr "Новият файл с индекса не може да бъде записан"
+msgstr "Новият индекс не може да бъде записан"
 
 #: builtin/apply.c:57
 msgid "git apply [options] [<patch>...]"
@@ -2177,17 +2222,17 @@ msgstr ""
 msgid "deleted file %s still has contents"
 msgstr ""
 
+# FIXME - double **??
 #: builtin/apply.c:1725
 #, c-format
 msgid "** warning: file %s becomes empty but is not deleted"
-msgstr ""
+msgstr "●● предупреждение: файлът „%s“ вече е празен, но не е изтрит"
 
 #: builtin/apply.c:1871
 #, c-format
 msgid "corrupt binary patch at line %d: %.*s"
 msgstr ""
 
-#. there has to be one hunk (forward hunk)
 #: builtin/apply.c:1900
 #, c-format
 msgid "unrecognized binary patch at line %d"
@@ -2326,10 +2371,10 @@ msgstr ""
 msgid "Checking patch %s..."
 msgstr ""
 
-#: builtin/apply.c:3680 builtin/checkout.c:213 builtin/reset.c:127
+#: builtin/apply.c:3680 builtin/checkout.c:213 builtin/reset.c:134
 #, c-format
 msgid "make_cache_entry failed for path '%s'"
-msgstr ""
+msgstr "неуспешно създаване на запис в кеша чрез „make_cache_entry“ за „%s“"
 
 #: builtin/apply.c:3823
 #, c-format
@@ -2375,7 +2420,6 @@ msgstr ""
 msgid "internal error"
 msgstr ""
 
-#. Say this even without --verbose
 #: builtin/apply.c:4043
 #, c-format
 msgid "Applying patch %%s with %d reject..."
@@ -2404,12 +2448,12 @@ msgstr ""
 
 #: builtin/apply.c:4238
 msgid "unable to read index file"
-msgstr ""
+msgstr "индексът не може да бъде записан"
 
 #: builtin/apply.c:4357 builtin/apply.c:4360 builtin/clone.c:90
 #: builtin/fetch.c:78
 msgid "path"
-msgstr ""
+msgstr "път"
 
 #: builtin/apply.c:4358
 msgid "don't apply changes matching the given path"
@@ -2467,14 +2511,13 @@ msgstr ""
 msgid "build a temporary index based on embedded index information"
 msgstr ""
 
-#: builtin/apply.c:4389 builtin/checkout-index.c:197 builtin/ls-files.c:452
+#: builtin/apply.c:4389 builtin/checkout-index.c:197 builtin/ls-files.c:455
 msgid "paths are separated with NUL character"
-msgstr ""
+msgstr "разделяне на пътищата с нулевия знак „NUL“"
 
 #: builtin/apply.c:4392
-#, fuzzy
 msgid "ensure at least <n> lines of context match"
-msgstr "<брой>"
+msgstr "да се осигури контекст от поне такъв БРОЙ съвпадащи редове"
 
 #: builtin/apply.c:4393
 msgid "action"
@@ -2588,132 +2631,150 @@ msgstr ""
 
 #: builtin/bisect--helper.c:7
 msgid "git bisect--helper --next-all [--no-checkout]"
-msgstr ""
+msgstr "git bisect--helper --next-all [--no-checkout]"
 
 #: builtin/bisect--helper.c:17
 msgid "perform 'git bisect next'"
-msgstr ""
+msgstr "извършване на „git bisect next“"
 
 #: builtin/bisect--helper.c:19
 msgid "update BISECT_HEAD instead of checking out the current commit"
 msgstr ""
+"обновяване на указателя „BISECT_HEAD“ вместо да се използва текущото подаване"
 
 #: builtin/blame.c:27
 msgid "git blame [options] [rev-opts] [rev] [--] file"
-msgstr ""
+msgstr "git blame [ОПЦИИ] [ОПЦИИ_ЗА_ВЕРСИЯТА] [ВЕРСИЯ] [--] ФАЙЛ"
 
 #: builtin/blame.c:32
 msgid "[rev-opts] are documented in git-rev-list(1)"
-msgstr ""
+msgstr "ОПЦИИте_ЗА_ВЕРСИЯТА са документирани в ръководството git-rev-list(1)"
 
-#: builtin/blame.c:2249
+#: builtin/blame.c:2242
 msgid "Show blame entries as we find them, incrementally"
-msgstr ""
+msgstr "Извеждане на анотациите с намирането им, последователно"
 
-# FIXME
-#: builtin/blame.c:2250
+# FIXME SHA-1 -> SHA1
+#: builtin/blame.c:2243
 msgid "Show blank SHA-1 for boundary commits (Default: off)"
 msgstr ""
+"Извеждане на празни суми по SHA1 за граничните подавания (стандартно опцията "
+"е изключена)"
 
-#: builtin/blame.c:2251
+#: builtin/blame.c:2244
 msgid "Do not treat root commits as boundaries (Default: off)"
 msgstr ""
+"Началните подавания да не се считат за гранични (стандартно опцията е "
+"изключена)"
 
-#: builtin/blame.c:2252
+#: builtin/blame.c:2245
 msgid "Show work cost statistics"
-msgstr ""
+msgstr "Извеждане на статистика за извършените действия"
 
-#: builtin/blame.c:2253
+#: builtin/blame.c:2246
 msgid "Show output score for blame entries"
-msgstr ""
+msgstr "Извеждане на допълнителна информация за определянето на анотациите"
 
-#: builtin/blame.c:2254
+#: builtin/blame.c:2247
 msgid "Show original filename (Default: auto)"
 msgstr ""
+"Извеждане на първоначалното име на файл (стандартно това е автоматично)"
 
-#: builtin/blame.c:2255
+#: builtin/blame.c:2248
 msgid "Show original linenumber (Default: off)"
 msgstr ""
+"Извеждане на първоначалният номер на ред (стандартно опцията е изключена)"
 
-#: builtin/blame.c:2256
+#: builtin/blame.c:2249
 msgid "Show in a format designed for machine consumption"
-msgstr ""
+msgstr "Извеждане във формат за по-нататъшна обработка"
 
-#: builtin/blame.c:2257
+#: builtin/blame.c:2250
 msgid "Show porcelain format with per-line commit information"
 msgstr ""
+"Извеждане във формат за по-нататъшна обработка с информация на всеки ред"
 
-#: builtin/blame.c:2258
+#: builtin/blame.c:2251
 msgid "Use the same output mode as git-annotate (Default: off)"
 msgstr ""
+"Използване на същия формат като „git-annotate“ (стандартно опцията е "
+"изключена)"
 
-#: builtin/blame.c:2259
+#: builtin/blame.c:2252
 msgid "Show raw timestamp (Default: off)"
-msgstr ""
+msgstr "Извеждане на неформатирани времена (стандартно опцията е изключена)"
 
-#: builtin/blame.c:2260
+#: builtin/blame.c:2253
 msgid "Show long commit SHA1 (Default: off)"
-msgstr ""
+msgstr "Извеждане на пълните суми по SHA1 (стандартно опцията е изключена)"
 
-#: builtin/blame.c:2261
+#: builtin/blame.c:2254
 msgid "Suppress author name and timestamp (Default: off)"
-msgstr ""
+msgstr "Без име на автор и време на промяна(стандартно опцията е изключена)"
 
-#: builtin/blame.c:2262
+#: builtin/blame.c:2255
 msgid "Show author email instead of name (Default: off)"
 msgstr ""
+"Извеждане на е-пощата на автора, а не името му (стандартно опцията е "
+"изключена)"
 
-#: builtin/blame.c:2263
+#: builtin/blame.c:2256
 msgid "Ignore whitespace differences"
-msgstr ""
+msgstr "Без разлики в знаците за интервали"
 
-#: builtin/blame.c:2264
+#: builtin/blame.c:2257
 msgid "Spend extra cycles to find better match"
-msgstr ""
+msgstr "Допълнителни изчисления за по-добри резултати"
 
-#: builtin/blame.c:2265
+#: builtin/blame.c:2258
 msgid "Use revisions from <file> instead of calling git-rev-list"
-msgstr ""
+msgstr "Изчитане на версиите от ФАЙЛ, а не чрез изпълнение на „git-rev-list“"
 
-#: builtin/blame.c:2266
+#: builtin/blame.c:2259
 msgid "Use <file>'s contents as the final image"
-msgstr ""
+msgstr "Използване на съдържанието на ФАЙЛа като крайно положение"
 
-#: builtin/blame.c:2267 builtin/blame.c:2268
+#: builtin/blame.c:2260 builtin/blame.c:2261
 msgid "score"
-msgstr ""
+msgstr "напасване на редовете"
 
-#: builtin/blame.c:2267
+#: builtin/blame.c:2260
 msgid "Find line copies within and across files"
 msgstr ""
+"Търсене на копирани редове както в рамките на един файл, така и от един файл "
+"към друг"
 
-#: builtin/blame.c:2268
+#: builtin/blame.c:2261
 msgid "Find line movements within and across files"
 msgstr ""
+"Търсене на преместени редове както в рамките на един файл, така и от един "
+"файл към друг"
 
-#: builtin/blame.c:2269
+#: builtin/blame.c:2262
 msgid "n,m"
-msgstr ""
+msgstr "n,m"
 
-#: builtin/blame.c:2269
+#: builtin/blame.c:2262
 msgid "Process only line range n,m, counting from 1"
 msgstr ""
+"Информация само за редовете в интервала от n до m включително. Броенето "
+"започва от 1"
 
 #: builtin/branch.c:24
 msgid "git branch [options] [-r | -a] [--merged | --no-merged]"
-msgstr ""
+msgstr "git branch [ОПЦИИ] [-r | -a] [--merged | --no-merged]"
 
 #: builtin/branch.c:25
 msgid "git branch [options] [-l] [-f] <branchname> [<start-point>]"
-msgstr ""
+msgstr "git branch [ОПЦИИ] [-l] [-f] ИМЕ_НА_КЛОН [НАЧАЛО]"
 
 #: builtin/branch.c:26
 msgid "git branch [options] [-r] (-d | -D) <branchname>..."
-msgstr ""
+msgstr "git branch [ОПЦИИ] [-r] (-d | -D) ИМЕ_НА_КЛОН…"
 
 #: builtin/branch.c:27
 msgid "git branch [options] (-m | -M) [<oldbranch>] <newbranch>"
-msgstr ""
+msgstr "git branch [ОПЦИИ] (-m | -M) [СТАР_КЛОН] НОВ_КЛОН"
 
 #: builtin/branch.c:150
 #, c-format
@@ -2721,6 +2782,8 @@ msgid ""
 "deleting branch '%s' that has been merged to\n"
 "         '%s', but not yet merged to HEAD."
 msgstr ""
+"изтриване на клона „%s“, който е слят към „%s“,\n"
+"         но още не е слят към върха „HEAD“."
 
 #: builtin/branch.c:154
 #, c-format
@@ -2728,11 +2791,13 @@ msgid ""
 "not deleting branch '%s' that is not yet merged to\n"
 "         '%s', even though it is merged to HEAD."
 msgstr ""
+"отказване на изтриване на клона „%s“, който не е слят към\n"
+"         „%s“, но е слят към върха „HEAD“."
 
 #: builtin/branch.c:168
 #, c-format
 msgid "Couldn't look up commit object for '%s'"
-msgstr ""
+msgstr "Обектът-подаване за „%s“ не може да бъде открит"
 
 #: builtin/branch.c:172
 #, c-format
@@ -2740,336 +2805,346 @@ msgid ""
 "The branch '%s' is not fully merged.\n"
 "If you are sure you want to delete it, run 'git branch -D %s'."
 msgstr ""
+"Клонът „%s“ не е слят напълно. Ако сте сигурни, че искате\n"
+"да го изтриете, изпълнете „git branch -D %s“."
 
 #: builtin/branch.c:185
 msgid "Update of config-file failed"
-msgstr ""
+msgstr "Неуспешно обновяване на конфигурационния файл"
 
 #: builtin/branch.c:213
 msgid "cannot use -a with -d"
-msgstr ""
+msgstr "Опцията „-a“ е несъвместима с опцията „-d“"
 
 #: builtin/branch.c:219
 msgid "Couldn't look up commit object for HEAD"
-msgstr ""
+msgstr "Обектът-подаване, сочен от указателя „HEAD“, не може да бъде открит"
 
 #: builtin/branch.c:227
 #, c-format
 msgid "Cannot delete the branch '%s' which you are currently on."
-msgstr ""
+msgstr "Не можете да изтриете клона „%s“, защото в момента е текущ."
 
 #: builtin/branch.c:240
 #, c-format
 msgid "remote branch '%s' not found."
-msgstr ""
+msgstr "отдалеченият клон „%s“ не може да бъде открит."
 
 #: builtin/branch.c:241
 #, c-format
 msgid "branch '%s' not found."
-msgstr ""
+msgstr "клонът „%s“ не може да бъде открит."
 
 #: builtin/branch.c:255
 #, c-format
 msgid "Error deleting remote branch '%s'"
-msgstr ""
+msgstr "Грешка при изтриването на отдалечения клон „%s“"
 
 #: builtin/branch.c:256
 #, c-format
 msgid "Error deleting branch '%s'"
-msgstr ""
+msgstr "Грешка при изтриването на клона „%s“"
 
 #: builtin/branch.c:263
 #, c-format
 msgid "Deleted remote branch %s (was %s).\n"
-msgstr ""
+msgstr "Изтрит отдалечен клон „%s“ (той сочеше към „%s“).\n"
 
 #: builtin/branch.c:264
 #, c-format
 msgid "Deleted branch %s (was %s).\n"
-msgstr ""
+msgstr "Изтрит клон „%s“ (той сочеше към „%s“).\n"
 
 #: builtin/branch.c:366
 #, c-format
 msgid "branch '%s' does not point at a commit"
-msgstr ""
+msgstr "клонът „%s“ не сочи към подаване"
 
 #: builtin/branch.c:454
 #, c-format
 msgid "[%s: gone]"
-msgstr ""
+msgstr "[%s: изтрит]"
 
 #: builtin/branch.c:459
 #, c-format
 msgid "[%s]"
-msgstr ""
+msgstr "[%s]"
 
 #: builtin/branch.c:464
 #, c-format
 msgid "[%s: behind %d]"
-msgstr ""
+msgstr "[%s: назад с %d]"
 
 #: builtin/branch.c:466
 #, c-format
 msgid "[behind %d]"
-msgstr ""
+msgstr "[назад с %d]"
 
 #: builtin/branch.c:470
 #, c-format
 msgid "[%s: ahead %d]"
-msgstr ""
+msgstr "[%s: напред с %d]"
 
 #: builtin/branch.c:472
 #, c-format
 msgid "[ahead %d]"
-msgstr ""
+msgstr "[напред с %d]"
 
 #: builtin/branch.c:475
 #, c-format
 msgid "[%s: ahead %d, behind %d]"
-msgstr ""
+msgstr "[%s: напред с %d, назад с %d]"
 
 #: builtin/branch.c:478
 #, c-format
 msgid "[ahead %d, behind %d]"
-msgstr ""
+msgstr "[напред с %d, назад с %d]"
 
+# FIXME ** how many??
 #: builtin/branch.c:502
 msgid " **** invalid ref ****"
-msgstr ""
+msgstr " ●●●● неправилен указател ●●●●"
 
 #: builtin/branch.c:594
 #, c-format
 msgid "(no branch, rebasing %s)"
-msgstr ""
+msgstr "(извън клон, пребазиране на „%s“)"
 
 #: builtin/branch.c:597
 #, c-format
 msgid "(no branch, bisect started on %s)"
-msgstr ""
+msgstr "(извън клон, двоично търсене от „%s“)"
 
 #: builtin/branch.c:600
 #, c-format
 msgid "(detached from %s)"
-msgstr ""
+msgstr "(състояние, несвързано към „%s“)"
 
 #: builtin/branch.c:603
 msgid "(no branch)"
-msgstr ""
+msgstr "(извън клон)"
 
 #: builtin/branch.c:649
 #, c-format
 msgid "object '%s' does not point to a commit"
-msgstr ""
+msgstr "обектът „%s“ не сочи към подаване"
 
 #: builtin/branch.c:681
 msgid "some refs could not be read"
-msgstr ""
+msgstr "някои указатели не могат да бъдат прочетени"
 
 #: builtin/branch.c:694
 msgid "cannot rename the current branch while not on any."
 msgstr ""
+"не можете да преименувате текущия клон, защото сте извън който и да е клон"
 
 #: builtin/branch.c:704
 #, c-format
 msgid "Invalid branch name: '%s'"
-msgstr ""
+msgstr "Неправилно име на клон: „%s“"
 
 #: builtin/branch.c:719
 msgid "Branch rename failed"
-msgstr ""
+msgstr "Неуспешно преименуване на клон"
 
 #: builtin/branch.c:723
 #, c-format
 msgid "Renamed a misnamed branch '%s' away"
-msgstr ""
+msgstr "На клона с неправилно име „%s“ е дадено служебно име"
 
 #: builtin/branch.c:727
 #, c-format
 msgid "Branch renamed to %s, but HEAD is not updated!"
-msgstr ""
+msgstr "Клонът е преименуван на „%s“, но указателят „HEAD“ не е преименуван"
 
 #: builtin/branch.c:734
 msgid "Branch is renamed, but update of config-file failed"
-msgstr ""
+msgstr "Клонът е преименуван, но конфигурационният файл не бе обновен"
 
 #: builtin/branch.c:749
 #, c-format
 msgid "malformed object name %s"
-msgstr ""
+msgstr "неправилно име на обект „%s“"
 
 #: builtin/branch.c:773
 #, c-format
 msgid "could not write branch description template: %s"
-msgstr ""
+msgstr "шаблонът за описание на клон не бе записан: „%s“"
 
 #: builtin/branch.c:803
 msgid "Generic options"
-msgstr ""
+msgstr "Общи настройки"
 
 #: builtin/branch.c:805
 msgid "show hash and subject, give twice for upstream branch"
 msgstr ""
+"извеждане на хеша и темата. Повтарянето на опцията прибавя отдалечените клони"
 
 #: builtin/branch.c:806
 msgid "suppress informational messages"
-msgstr ""
+msgstr "без информационни съобщения"
 
 #: builtin/branch.c:807
 msgid "set up tracking mode (see git-pull(1))"
-msgstr ""
+msgstr "задаване на режима на следене (виж git-pull(1))"
 
 #: builtin/branch.c:809
 msgid "change upstream info"
-msgstr ""
+msgstr "смяна на следения клон"
 
 #: builtin/branch.c:813
 msgid "use colored output"
-msgstr ""
+msgstr "цветен изход"
 
 #: builtin/branch.c:814
 msgid "act on remote-tracking branches"
-msgstr ""
+msgstr "действие върху следящите клони"
 
 #: builtin/branch.c:817 builtin/branch.c:823 builtin/branch.c:844
-#: builtin/branch.c:850 builtin/commit.c:1460 builtin/commit.c:1461
-#: builtin/commit.c:1462 builtin/commit.c:1463 builtin/tag.c:468
+#: builtin/branch.c:850 builtin/commit.c:1494 builtin/commit.c:1495
+#: builtin/commit.c:1496 builtin/commit.c:1497 builtin/tag.c:527
+#: builtin/tag.c:533
 msgid "commit"
-msgstr ""
+msgstr "подаване"
 
 #: builtin/branch.c:818 builtin/branch.c:824
 msgid "print only branches that contain the commit"
-msgstr ""
+msgstr "извеждане само на клоните, които съдържат това подаване"
 
 #: builtin/branch.c:830
 msgid "Specific git-branch actions:"
-msgstr ""
+msgstr "Специални действия на „git-branch“:"
 
 #: builtin/branch.c:831
 msgid "list both remote-tracking and local branches"
-msgstr ""
+msgstr "извеждане както на следящите, така и на локалните клони"
 
 #: builtin/branch.c:833
 msgid "delete fully merged branch"
-msgstr ""
+msgstr "изтриване на клони, които са напълно слети"
 
 #: builtin/branch.c:834
 msgid "delete branch (even if not merged)"
-msgstr ""
+msgstr "изтриване и на клони, които не са напълно слети"
 
 #: builtin/branch.c:835
 msgid "move/rename a branch and its reflog"
 msgstr ""
+"преместване/преименуване на клон и принадлежащият му журнал на указателите"
 
 #: builtin/branch.c:836
 msgid "move/rename a branch, even if target exists"
-msgstr ""
+msgstr "преместване/преименуване на клон, дори ако има вече клон с такова име"
 
 #: builtin/branch.c:837
 msgid "list branch names"
-msgstr ""
+msgstr "извеждане на имената на клоните"
 
 #: builtin/branch.c:838
 msgid "create the branch's reflog"
-msgstr ""
+msgstr "създаване на журнала на указателите на клона"
 
 #: builtin/branch.c:840
 msgid "edit the description for the branch"
-msgstr ""
+msgstr "редактиране на описанието на клона"
 
 #: builtin/branch.c:841
 msgid "force creation (when already exists)"
-msgstr ""
+msgstr "принудително създаване, дори ако съществува клон с такова име"
 
 #: builtin/branch.c:844
 msgid "print only not merged branches"
-msgstr ""
+msgstr "извеждане само на неслетите клони"
 
 #: builtin/branch.c:850
 msgid "print only merged branches"
-msgstr ""
+msgstr "извеждане само на слетите клони"
 
 #: builtin/branch.c:854
 msgid "list branches in columns"
-msgstr ""
+msgstr "извеждане по колони"
 
 #: builtin/branch.c:867
 msgid "Failed to resolve HEAD as a valid ref."
-msgstr ""
+msgstr "Не може да се открие към какво сочи указателят „HEAD“"
 
 #: builtin/branch.c:872 builtin/clone.c:635
 msgid "HEAD not found below refs/heads!"
-msgstr ""
+msgstr "В директорията „refs/heads“ липсва файл „HEAD“"
 
 #: builtin/branch.c:896
 msgid "--column and --verbose are incompatible"
-msgstr ""
+msgstr "Опциите „--column“ и „--verbose“ са несъвместими"
 
 #: builtin/branch.c:902 builtin/branch.c:941
 msgid "branch name required"
-msgstr ""
+msgstr "Необходимо е име на клон"
 
 #: builtin/branch.c:917
 msgid "Cannot give description to detached HEAD"
-msgstr ""
+msgstr "Не може да зададете описание на „HEAD“ извън клон"
 
 #: builtin/branch.c:922
 msgid "cannot edit description of more than one branch"
-msgstr ""
+msgstr "Не може да редактирате описанието на повече от един клон едновременно"
 
 #: builtin/branch.c:929
 #, c-format
 msgid "No commit on branch '%s' yet."
-msgstr ""
+msgstr "В клона „%s“ все още няма подавания."
 
 #: builtin/branch.c:932
 #, c-format
 msgid "No branch named '%s'."
-msgstr ""
+msgstr "Липсва клон на име „%s“."
 
 #: builtin/branch.c:947
 msgid "too many branches for a rename operation"
-msgstr ""
+msgstr "Прекалено много клони за преименуване"
 
 #: builtin/branch.c:952
 msgid "too many branches to set new upstream"
-msgstr ""
+msgstr "Прекалено много клони за задаване на следене"
 
 #: builtin/branch.c:956
 #, c-format
 msgid ""
 "could not set upstream of HEAD to %s when it does not point to any branch."
 msgstr ""
+"Следеното от „HEAD“ не може да се зададе да е „%s“, защото то не сочи към "
+"никой клон."
 
 #: builtin/branch.c:959 builtin/branch.c:981 builtin/branch.c:1002
 #, c-format
 msgid "no such branch '%s'"
-msgstr ""
+msgstr "Няма клон на име „%s“."
 
 #: builtin/branch.c:963
 #, c-format
 msgid "branch '%s' does not exist"
-msgstr ""
+msgstr "Не съществува клон на име „%s“."
 
 #: builtin/branch.c:975
 msgid "too many branches to unset upstream"
-msgstr ""
+msgstr "Прекалено много клони за махане на следене"
 
 #: builtin/branch.c:979
 msgid "could not unset upstream of HEAD when it does not point to any branch."
 msgstr ""
+"Следеното от „HEAD“ не може да махне, защото то не сочи към никой клон."
 
 #: builtin/branch.c:985
 #, c-format
 msgid "Branch '%s' has no upstream information"
-msgstr ""
+msgstr "Няма информация клонът „%s“ да следи някой друг"
 
 #: builtin/branch.c:999
 msgid "it does not make sense to create 'HEAD' manually"
-msgstr ""
+msgstr "Няма никакъв смисъл ръчно да създавате „HEAD“."
 
 #: builtin/branch.c:1005
 msgid "-a and -r options to 'git branch' do not make sense with a branch name"
-msgstr ""
+msgstr "Опциите „-a“ и „-r“ на „git branch“ са несъвместими с име на клон"
 
 #: builtin/branch.c:1008
 #, c-format
@@ -3077,6 +3152,8 @@ msgid ""
 "The --set-upstream flag is deprecated and will be removed. Consider using --"
 "track or --set-upstream-to\n"
 msgstr ""
+"Опцията „--set-upstream“ вече е остаряла и предстои да бъде махната. "
+"Използвайте „--track“ или „--set-upstream-to“\n"
 
 #: builtin/branch.c:1025
 #, c-format
@@ -3085,16 +3162,19 @@ msgid ""
 "If you wanted to make '%s' track '%s', do this:\n"
 "\n"
 msgstr ""
+"\n"
+"За да накарате „%s“ да следи „%s“, изпълнете следната команда:\n"
+"\n"
 
 #: builtin/branch.c:1026
 #, c-format
 msgid "    git branch -d %s\n"
-msgstr ""
+msgstr "    git branch -d %s\n"
 
 #: builtin/branch.c:1027
 #, c-format
 msgid "    git branch --set-upstream-to %s\n"
-msgstr ""
+msgstr "    git branch --set-upstream-to %s\n"
 
 #: builtin/bundle.c:47
 #, c-format
@@ -3109,71 +3189,71 @@ msgstr ""
 msgid "Need a repository to unbundle."
 msgstr ""
 
-#: builtin/cat-file.c:328
+#: builtin/cat-file.c:331
 msgid "git cat-file (-t|-s|-e|-p|<type>|--textconv) <object>"
 msgstr ""
 
-#: builtin/cat-file.c:329
+#: builtin/cat-file.c:332
 msgid "git cat-file (--batch|--batch-check) < <list_of_objects>"
 msgstr ""
 
-#: builtin/cat-file.c:366
+#: builtin/cat-file.c:369
 msgid "<type> can be one of: blob, tree, commit, tag"
 msgstr ""
 
-#: builtin/cat-file.c:367
+#: builtin/cat-file.c:370
 msgid "show object type"
 msgstr ""
 
-#: builtin/cat-file.c:368
+#: builtin/cat-file.c:371
 msgid "show object size"
 msgstr ""
 
-#: builtin/cat-file.c:370
+#: builtin/cat-file.c:373
 msgid "exit with zero when there's no error"
 msgstr ""
 
-#: builtin/cat-file.c:371
+#: builtin/cat-file.c:374
 msgid "pretty-print object's content"
 msgstr ""
 
-#: builtin/cat-file.c:373
+#: builtin/cat-file.c:376
 msgid "for blob objects, run textconv on object's content"
 msgstr ""
 
-#: builtin/cat-file.c:375
+#: builtin/cat-file.c:378
 msgid "show info and content of objects fed from the standard input"
 msgstr ""
 
-#: builtin/cat-file.c:378
+#: builtin/cat-file.c:381
 msgid "show info about objects fed from the standard input"
 msgstr ""
 
 #: builtin/check-attr.c:11
 msgid "git check-attr [-a | --all | attr...] [--] pathname..."
-msgstr ""
+msgstr "git check-attr [-a | --all | АТРИБУТ…] [--] ПЪТ…"
 
 #: builtin/check-attr.c:12
 msgid "git check-attr --stdin [-z] [-a | --all | attr...] < <list-of-paths>"
-msgstr ""
+msgstr "git check-attr --stdin [-z] [-a | --all | АТРИБУТ…] < СПИСЪК_С_ПЪТИЩА"
 
 #: builtin/check-attr.c:19
 msgid "report all attributes set on file"
-msgstr ""
+msgstr "извеждане на всички атрибути, зададени върху файл"
 
 #: builtin/check-attr.c:20
 msgid "use .gitattributes only from the index"
-msgstr ""
+msgstr "използване на файла „.gitattributes“ само от индекса"
 
 #: builtin/check-attr.c:21 builtin/check-ignore.c:22 builtin/hash-object.c:75
 msgid "read file names from stdin"
-msgstr ""
+msgstr "изчитане на имената на файловете от стандартния вход"
 
 #: builtin/check-attr.c:23 builtin/check-ignore.c:24
 msgid "terminate input and output records by a NUL character"
-msgstr ""
+msgstr "разделяне на входните и изходните записи с нулевия знак „NUL“"
 
-#: builtin/check-ignore.c:18 builtin/checkout.c:1090 builtin/gc.c:260
+#: builtin/check-ignore.c:18 builtin/checkout.c:1089 builtin/gc.c:271
 msgid "suppress progress reporting"
 msgstr "без показване на напредъка"
 
@@ -3211,20 +3291,20 @@ msgstr ""
 
 #: builtin/check-mailmap.c:8
 msgid "git check-mailmap [options] <contact>..."
-msgstr ""
+msgstr "git check-mailmap [ОПЦИИ] КОНТАКТ…"
 
 #: builtin/check-mailmap.c:13
 msgid "also read contacts from stdin"
-msgstr ""
+msgstr "четене на контакти и от стандартния вход"
 
 #: builtin/check-mailmap.c:24
 #, c-format
 msgid "unable to parse contact: %s"
-msgstr ""
+msgstr "контактът не може да бъде анализиран: %s"
 
 #: builtin/check-mailmap.c:47
 msgid "no contacts specified"
-msgstr ""
+msgstr "не са указани контакти"
 
 #: builtin/checkout-index.c:126
 msgid "git checkout-index [options] [--] [<file>...]"
@@ -3248,7 +3328,7 @@ msgstr ""
 
 #: builtin/checkout-index.c:194
 msgid "update stat information in the index file"
-msgstr ""
+msgstr "обновяване на информацията получена чрез „stat“ за файловете в индекса"
 
 #: builtin/checkout-index.c:200
 msgid "read list of paths from the standard input"
@@ -3272,112 +3352,115 @@ msgstr ""
 
 #: builtin/checkout.c:25
 msgid "git checkout [options] <branch>"
-msgstr ""
+msgstr "git checkout [ОПЦИИ] КЛОН"
 
 #: builtin/checkout.c:26
 msgid "git checkout [options] [<branch>] -- <file>..."
-msgstr ""
+msgstr "git checkout [ОПЦИИ] [КЛОН] -- ФАЙЛ…"
 
 #: builtin/checkout.c:114 builtin/checkout.c:147
 #, c-format
 msgid "path '%s' does not have our version"
-msgstr ""
+msgstr "вашата версия липсва в пътя „%s“"
 
 #: builtin/checkout.c:116 builtin/checkout.c:149
 #, c-format
 msgid "path '%s' does not have their version"
-msgstr ""
+msgstr "чуждата версия липсва в пътя „%s“"
 
+# FIXME SAME AS [1]
 #: builtin/checkout.c:132
 #, c-format
 msgid "path '%s' does not have all necessary versions"
-msgstr ""
+msgstr "някоя от необходимите версии липсва в пътя „%s“"
 
+# FIXME SAME AS [1]
 #: builtin/checkout.c:176
 #, c-format
 msgid "path '%s' does not have necessary versions"
-msgstr ""
+msgstr "някоя от необходимите версии липсва в пътя „%s“"
 
 #: builtin/checkout.c:193
 #, c-format
 msgid "path '%s': cannot merge"
-msgstr ""
+msgstr "пътят „%s“ не може да бъде слян"
 
 #: builtin/checkout.c:210
 #, c-format
 msgid "Unable to add merge result for '%s'"
-msgstr ""
+msgstr "Резултатът за „%s“ не може да бъде слян"
 
 #: builtin/checkout.c:232 builtin/checkout.c:235 builtin/checkout.c:238
 #: builtin/checkout.c:241
 #, c-format
 msgid "'%s' cannot be used with updating paths"
-msgstr ""
+msgstr "Опцията „%s“ е несъвместима с обновяването на пътища"
 
 #: builtin/checkout.c:244 builtin/checkout.c:247
 #, c-format
 msgid "'%s' cannot be used with %s"
-msgstr ""
+msgstr "Опцията „%s“ е несъвместима с „%s“"
 
 #: builtin/checkout.c:250
 #, c-format
 msgid "Cannot update paths and switch to branch '%s' at the same time."
 msgstr ""
+"Невъзможно е едновременно да обновявате пътища и да се прехвърлите към клона "
+"„%s“."
 
-#: builtin/checkout.c:261 builtin/checkout.c:451
+#: builtin/checkout.c:261 builtin/checkout.c:450
 msgid "corrupt index file"
-msgstr ""
+msgstr "повреден файл на индекса"
 
-#: builtin/checkout.c:322 builtin/checkout.c:329
+#: builtin/checkout.c:321 builtin/checkout.c:328
 #, c-format
 msgid "path '%s' is unmerged"
-msgstr ""
+msgstr "пътят „%s“ не е слят"
 
-#: builtin/checkout.c:473
+#: builtin/checkout.c:472
 msgid "you need to resolve your current index first"
-msgstr ""
+msgstr "първо трябва да коригирате индекса си"
 
-#: builtin/checkout.c:594
+#: builtin/checkout.c:593
 #, c-format
 msgid "Can not do reflog for '%s'\n"
-msgstr ""
+msgstr "Журналът на указателите за „%s“ не може да бъде създаден\n"
 
-#: builtin/checkout.c:632
+#: builtin/checkout.c:631
 msgid "HEAD is now at"
-msgstr ""
+msgstr "Указателят „HEAD“ в момента сочи към"
 
-#: builtin/checkout.c:639
+#: builtin/checkout.c:638
 #, c-format
 msgid "Reset branch '%s'\n"
-msgstr ""
+msgstr "Зануляване на клона „%s“\n"
 
-#: builtin/checkout.c:642
+#: builtin/checkout.c:641
 #, c-format
 msgid "Already on '%s'\n"
-msgstr ""
+msgstr "Вече сте на „%s“\n"
 
-#: builtin/checkout.c:646
+#: builtin/checkout.c:645
 #, c-format
 msgid "Switched to and reset branch '%s'\n"
-msgstr ""
+msgstr "Преминаване към клона „%s“ и зануляване на промените\n"
 
-#: builtin/checkout.c:648 builtin/checkout.c:1033
+#: builtin/checkout.c:647 builtin/checkout.c:1032
 #, c-format
 msgid "Switched to a new branch '%s'\n"
-msgstr ""
+msgstr "Преминахте към новия клон „%s“\n"
 
-#: builtin/checkout.c:650
+#: builtin/checkout.c:649
 #, c-format
 msgid "Switched to branch '%s'\n"
-msgstr ""
+msgstr "Преминахте към клона „%s“\n"
 
-#: builtin/checkout.c:706
+#: builtin/checkout.c:705
 #, c-format
 msgid " ... and %d more.\n"
-msgstr ""
+msgstr "… и още %d.\n"
 
-#. The singular version
-#: builtin/checkout.c:712
+#: builtin/checkout.c:711
 #, c-format
 msgid ""
 "Warning: you are leaving %d commit behind, not connected to\n"
@@ -3390,9 +3473,16 @@ msgid_plural ""
 "\n"
 "%s\n"
 msgstr[0] ""
+"ПРЕДУПРЕЖДЕНИЕ: изоставяте %d подаване, което не е свързано към никой клон:\n"
+"\n"
+"%s\n"
 msgstr[1] ""
+"ПРЕДУПРЕЖДЕНИЕ: изоставяте %d подавания, които не са свързани към никой "
+"клон:\n"
+"\n"
+"%s\n"
 
-#: builtin/checkout.c:730
+#: builtin/checkout.c:729
 #, c-format
 msgid ""
 "If you want to keep them by creating a new branch, this may be a good time\n"
@@ -3401,157 +3491,171 @@ msgid ""
 " git branch new_branch_name %s\n"
 "\n"
 msgstr ""
+"Ако все пак искате да ги запазите, сега вероятно е най-подходящият момент "
+"да\n"
+"създадете нов клон с тях чрез командата:\n"
+"\n"
+" git branch ИМЕ_НА_НОВИЯ_КЛОН %s\n"
+"\n"
 
-#: builtin/checkout.c:760
+#: builtin/checkout.c:759
 msgid "internal error in revision walk"
-msgstr ""
+msgstr "вътрешна грешка при обхождането на версиите"
 
-#: builtin/checkout.c:764
+#: builtin/checkout.c:763
 msgid "Previous HEAD position was"
-msgstr ""
+msgstr "Преди това „HEAD“ сочеше към"
 
-#: builtin/checkout.c:791 builtin/checkout.c:1028
+#: builtin/checkout.c:790 builtin/checkout.c:1027
 msgid "You are on a branch yet to be born"
-msgstr ""
+msgstr "В момента сте на клон, който предстои да бъде създаден"
 
-#: builtin/checkout.c:935
+#: builtin/checkout.c:934
 #, c-format
 msgid "only one reference expected, %d given."
-msgstr ""
+msgstr "очакваше се един указател, а сте подали %d."
 
-#: builtin/checkout.c:974
+#: builtin/checkout.c:973
 #, c-format
 msgid "invalid reference: %s"
-msgstr ""
+msgstr "неправилен указател: %s"
 
-#. case (1): want a tree
-#: builtin/checkout.c:1003
+#: builtin/checkout.c:1002
 #, c-format
 msgid "reference is not a tree: %s"
-msgstr ""
+msgstr "указателят не сочи към обект-дърво: %s"
 
-#: builtin/checkout.c:1042
+#: builtin/checkout.c:1041
 msgid "paths cannot be used with switching branches"
-msgstr ""
+msgstr "задаването на път е несъвместимо с преминаването от един клон към друг"
 
-#: builtin/checkout.c:1045 builtin/checkout.c:1049
+#: builtin/checkout.c:1044 builtin/checkout.c:1048
 #, c-format
 msgid "'%s' cannot be used with switching branches"
-msgstr ""
+msgstr "опцията „%s“ е несъвместима с преминаването от един клон към друг"
 
-#: builtin/checkout.c:1053 builtin/checkout.c:1056 builtin/checkout.c:1061
-#: builtin/checkout.c:1064
+#: builtin/checkout.c:1052 builtin/checkout.c:1055 builtin/checkout.c:1060
+#: builtin/checkout.c:1063
 #, c-format
 msgid "'%s' cannot be used with '%s'"
-msgstr ""
+msgstr "опцията „%s“ е несъвместима с „%s“"
 
-#: builtin/checkout.c:1069
+#: builtin/checkout.c:1068
 #, c-format
 msgid "Cannot switch branch to a non-commit '%s'"
 msgstr ""
+"За да преминете към клон, подайте указател, който сочи към подаване. „%s“ не "
+"е такъв"
 
-#: builtin/checkout.c:1091 builtin/checkout.c:1093 builtin/clone.c:88
+#: builtin/checkout.c:1090 builtin/checkout.c:1092 builtin/clone.c:88
 #: builtin/remote.c:159 builtin/remote.c:161
 msgid "branch"
 msgstr "клон"
 
-#: builtin/checkout.c:1092
+#: builtin/checkout.c:1091
 msgid "create and checkout a new branch"
-msgstr ""
+msgstr "създаване и преминаване към нов клон"
 
-#: builtin/checkout.c:1094
+#: builtin/checkout.c:1093
 msgid "create/reset and checkout a branch"
-msgstr ""
+msgstr "създаване/зануляване на клон и преминаване към него"
 
-#: builtin/checkout.c:1095
+#: builtin/checkout.c:1094
 msgid "create reflog for new branch"
-msgstr ""
+msgstr "създаване на журнал на указателите за нов клон"
 
-#: builtin/checkout.c:1096
+#: builtin/checkout.c:1095
 msgid "detach the HEAD at named commit"
-msgstr ""
+msgstr "отделяне на указателя „HEAD“ към указаното подаване"
 
-#: builtin/checkout.c:1097
+#: builtin/checkout.c:1096
 msgid "set upstream info for new branch"
-msgstr ""
+msgstr "задаване на кой клон бива следен при създаването на новия клон"
 
-#: builtin/checkout.c:1099
-msgid "new branch"
-msgstr ""
+#: builtin/checkout.c:1098
+msgid "new-branch"
+msgstr "НОВ_КЛОН"
 
-#: builtin/checkout.c:1099
+#: builtin/checkout.c:1098
 msgid "new unparented branch"
-msgstr ""
+msgstr "нов клон без родител"
 
-#: builtin/checkout.c:1100
+#: builtin/checkout.c:1099
 msgid "checkout our version for unmerged files"
-msgstr ""
+msgstr "изтегляне на вашата версия на неслетите файлове"
 
-#: builtin/checkout.c:1102
+#: builtin/checkout.c:1101
 msgid "checkout their version for unmerged files"
-msgstr ""
+msgstr "изтегляне на чуждата версия на неслетите файлове"
 
-#: builtin/checkout.c:1104
+#: builtin/checkout.c:1103
 msgid "force checkout (throw away local modifications)"
-msgstr ""
+msgstr "принудително изтегляне (вашите промени ще бъдат занулени)"
 
-#: builtin/checkout.c:1105
+#: builtin/checkout.c:1104
 msgid "perform a 3-way merge with the new branch"
-msgstr ""
+msgstr "извършване на тройно сливане с новия клон"
 
-#: builtin/checkout.c:1106 builtin/merge.c:225
+#: builtin/checkout.c:1105 builtin/merge.c:225
 msgid "update ignored files (default)"
-msgstr ""
+msgstr "обновяване на игнорираните файлове (стандартно)"
 
-#: builtin/checkout.c:1107 builtin/log.c:1228 parse-options.h:248
+#: builtin/checkout.c:1106 builtin/log.c:1228 parse-options.h:245
 msgid "style"
 msgstr "стил"
 
-#: builtin/checkout.c:1108
+#: builtin/checkout.c:1107
 msgid "conflict style (merge or diff3)"
-msgstr ""
+msgstr "действие при конфликт (сливане или тройна разлика)"
 
-#: builtin/checkout.c:1111
+#: builtin/checkout.c:1110
 msgid "do not limit pathspecs to sparse entries only"
-msgstr ""
+msgstr "без ограничаване на изброените пътища само до частично изтеглените"
 
-#: builtin/checkout.c:1113
+#: builtin/checkout.c:1112
 msgid "second guess 'git checkout no-such-branch'"
 msgstr ""
+"последващ опит за отгатване след неуспешен опит с „git checkout no-such-"
+"branch“"
 
-#: builtin/checkout.c:1136
+#: builtin/checkout.c:1135
 msgid "-b, -B and --orphan are mutually exclusive"
-msgstr ""
+msgstr "Опциите „-b“, „-B“ и „--orphan“ са несъвместими една с друга"
 
-#: builtin/checkout.c:1153
+#: builtin/checkout.c:1152
 msgid "--track needs a branch name"
-msgstr ""
+msgstr "опцията „--track“ изисква име на клон"
 
-#: builtin/checkout.c:1160
+#: builtin/checkout.c:1159
 msgid "Missing branch name; try -b"
-msgstr ""
+msgstr "Липсва име на клон, използвайте опцията „-b“"
 
-#: builtin/checkout.c:1197
+#: builtin/checkout.c:1196
 msgid "invalid path specification"
-msgstr ""
+msgstr "указан е неправилен път"
 
-#: builtin/checkout.c:1204
+#: builtin/checkout.c:1203
 #, c-format
 msgid ""
 "Cannot update paths and switch to branch '%s' at the same time.\n"
 "Did you intend to checkout '%s' which can not be resolved as commit?"
 msgstr ""
+"Не можете едновременно да обновявате пътища и да преминете към клона „%s“.\n"
+"Дали не искате да изтеглите „%s“, който не сочи към подаване?"
 
-#: builtin/checkout.c:1209
+#: builtin/checkout.c:1208
 #, c-format
 msgid "git checkout: --detach does not take a path argument '%s'"
-msgstr ""
+msgstr "git checkout: опцията „--detach“ не приема аргумент-път „%s“"
 
-#: builtin/checkout.c:1213
+#: builtin/checkout.c:1212
 msgid ""
 "git checkout: --ours/--theirs, --force and --merge are incompatible when\n"
 "checking out of the index."
 msgstr ""
+"git checkout: опциите „--ours“/„--theirs“, „--force“ и „--merge“ са "
+"несъвместими\n"
+"с изтегляне от индекса."
 
 #: builtin/clean.c:26
 msgid ""
@@ -3583,7 +3687,7 @@ msgstr ""
 msgid "failed to remove %s"
 msgstr ""
 
-#: builtin/clean.c:294
+#: builtin/clean.c:295
 msgid ""
 "Prompt help:\n"
 "1          - select a numbered item\n"
@@ -3591,7 +3695,7 @@ msgid ""
 "           - (empty) select nothing"
 msgstr ""
 
-#: builtin/clean.c:298
+#: builtin/clean.c:299
 msgid ""
 "Prompt help:\n"
 "1          - select a single item\n"
@@ -3603,35 +3707,35 @@ msgid ""
 "           - (empty) finish selecting"
 msgstr ""
 
-#: builtin/clean.c:516
+#: builtin/clean.c:517
 #, c-format
 msgid "Huh (%s)?"
 msgstr ""
 
-#: builtin/clean.c:659
+#: builtin/clean.c:660
 #, c-format
 msgid "Input ignore patterns>> "
 msgstr ""
 
-#: builtin/clean.c:696
+#: builtin/clean.c:697
 #, c-format
 msgid "WARNING: Cannot find items matched by: %s"
 msgstr ""
 
-#: builtin/clean.c:717
+#: builtin/clean.c:718
 msgid "Select items to delete"
 msgstr ""
 
-#: builtin/clean.c:757
+#: builtin/clean.c:758
 #, c-format
 msgid "remove %s? "
 msgstr ""
 
-#: builtin/clean.c:782
+#: builtin/clean.c:783
 msgid "Bye."
 msgstr ""
 
-#: builtin/clean.c:790
+#: builtin/clean.c:791
 msgid ""
 "clean               - start cleaning\n"
 "filter by pattern   - exclude items from deletion\n"
@@ -3642,215 +3746,218 @@ msgid ""
 "?                   - help for prompt selection"
 msgstr ""
 
-#: builtin/clean.c:817
+# FIXME how many ***
+#: builtin/clean.c:818
 msgid "*** Commands ***"
-msgstr ""
+msgstr "●●● Команди ●●●"
 
-#: builtin/clean.c:818
+#: builtin/clean.c:819
 msgid "What now"
 msgstr ""
 
-#: builtin/clean.c:826
+#: builtin/clean.c:827
 msgid "Would remove the following item:"
 msgid_plural "Would remove the following items:"
 msgstr[0] ""
 msgstr[1] ""
 
-#: builtin/clean.c:843
+#: builtin/clean.c:844
 msgid "No more files to clean, exiting."
 msgstr ""
 
-#: builtin/clean.c:874
+#: builtin/clean.c:875
 msgid "do not print names of files removed"
 msgstr ""
 
-#: builtin/clean.c:876
+#: builtin/clean.c:877
 msgid "force"
 msgstr ""
 
-#: builtin/clean.c:877
+#: builtin/clean.c:878
 msgid "interactive cleaning"
 msgstr ""
 
-#: builtin/clean.c:879
+#: builtin/clean.c:880
 msgid "remove whole directories"
 msgstr ""
 
-#: builtin/clean.c:880 builtin/describe.c:420 builtin/grep.c:718
-#: builtin/ls-files.c:483 builtin/name-rev.c:314 builtin/show-ref.c:185
+#: builtin/clean.c:881 builtin/describe.c:415 builtin/grep.c:716
+#: builtin/ls-files.c:486 builtin/name-rev.c:314 builtin/show-ref.c:185
 msgid "pattern"
-msgstr ""
+msgstr "шаблон"
 
-#: builtin/clean.c:881
+#: builtin/clean.c:882
 msgid "add <pattern> to ignore rules"
 msgstr ""
 
-#: builtin/clean.c:882
+#: builtin/clean.c:883
 msgid "remove ignored files, too"
 msgstr ""
 
-#: builtin/clean.c:884
+#: builtin/clean.c:885
 msgid "remove only ignored files"
 msgstr ""
 
-#: builtin/clean.c:902
+#: builtin/clean.c:903
 msgid "-x and -X cannot be used together"
 msgstr ""
 
-#: builtin/clean.c:906
+#: builtin/clean.c:907
 msgid ""
-"clean.requireForce set to true and neither -i, -n nor -f given; refusing to "
+"clean.requireForce set to true and neither -i, -n, nor -f given; refusing to "
 "clean"
 msgstr ""
 
-#: builtin/clean.c:909
+#: builtin/clean.c:910
 msgid ""
-"clean.requireForce defaults to true and neither -i, -n nor -f given; "
+"clean.requireForce defaults to true and neither -i, -n, nor -f given; "
 "refusing to clean"
 msgstr ""
 
 #: builtin/clone.c:36
 msgid "git clone [options] [--] <repo> [<dir>]"
-msgstr ""
+msgstr "git clone [ОПЦИИ] [--] ХРАНИЛИЩЕ [ДИРЕКТОРИЯ]"
 
 #: builtin/clone.c:64 builtin/fetch.c:97 builtin/merge.c:222
-#: builtin/push.c:521
+#: builtin/push.c:504
 msgid "force progress reporting"
-msgstr ""
+msgstr "извеждане на напредъка"
 
 #: builtin/clone.c:66
 msgid "don't create a checkout"
-msgstr ""
+msgstr "без създаване на работно дърво"
 
-#: builtin/clone.c:67 builtin/clone.c:69 builtin/init-db.c:488
+#: builtin/clone.c:67 builtin/clone.c:69 builtin/init-db.c:486
 msgid "create a bare repository"
-msgstr ""
+msgstr "създаване на голо хранилище"
 
 #: builtin/clone.c:71
 msgid "create a mirror repository (implies bare)"
-msgstr ""
+msgstr "създаване на хранилище-огледало (това включва хранилището да е голо)"
 
 #: builtin/clone.c:73
 msgid "to clone from a local repository"
-msgstr ""
+msgstr "клониране от локално хранилище"
 
 #: builtin/clone.c:75
 msgid "don't use local hardlinks, always copy"
-msgstr ""
+msgstr "без твърди връзки, файловете винаги да се копират"
 
 #: builtin/clone.c:77
 msgid "setup as shared repository"
-msgstr ""
+msgstr "настройване за споделено хранилище"
 
 #: builtin/clone.c:79 builtin/clone.c:81
 msgid "initialize submodules in the clone"
-msgstr ""
+msgstr "инициализиране на подмодулите при това клониране"
 
-#: builtin/clone.c:82 builtin/init-db.c:485
+#: builtin/clone.c:82 builtin/init-db.c:483
 msgid "template-directory"
-msgstr ""
+msgstr "директория с шаблони"
 
-#: builtin/clone.c:83 builtin/init-db.c:486
+#: builtin/clone.c:83 builtin/init-db.c:484
 msgid "directory from which templates will be used"
-msgstr ""
+msgstr "директория, която съдържа шаблоните, които да се ползват"
 
 #: builtin/clone.c:85
 msgid "reference repository"
-msgstr ""
+msgstr "еталонно хранилище"
 
 #: builtin/clone.c:86 builtin/column.c:26 builtin/merge-file.c:44
 msgid "name"
-msgstr ""
+msgstr "ИМЕ"
 
 #: builtin/clone.c:87
 msgid "use <name> instead of 'origin' to track upstream"
-msgstr ""
+msgstr "използване на това ИМЕ вместо „origin“ при проследяване на клони"
 
 #: builtin/clone.c:89
 msgid "checkout <branch> instead of the remote's HEAD"
-msgstr ""
+msgstr "изтегляне на този КЛОН, а не соченият от отдалечения указател „HEAD“"
 
 #: builtin/clone.c:91
 msgid "path to git-upload-pack on the remote"
-msgstr ""
+msgstr "път към командата „git-upload-pack“ на отдалеченото хранилище"
 
-#: builtin/clone.c:92 builtin/fetch.c:98 builtin/grep.c:663
+#: builtin/clone.c:92 builtin/fetch.c:98 builtin/grep.c:661
 msgid "depth"
-msgstr ""
+msgstr "ДЪЛБОЧИНА"
 
 #: builtin/clone.c:93
 msgid "create a shallow clone of that depth"
-msgstr ""
+msgstr "плитко клониране до тази ДЪЛБОЧИНА"
 
 #: builtin/clone.c:95
 msgid "clone only one branch, HEAD or --branch"
 msgstr ""
+"клониране само на един клон — или сочения от отдалечения „HEAD“, или изрично "
+"зададения с „--branch“"
 
-#: builtin/clone.c:96 builtin/init-db.c:494
+#: builtin/clone.c:96 builtin/init-db.c:492
 msgid "gitdir"
-msgstr ""
+msgstr "СЛУЖЕБНА_ДИРЕКТОРИЯ"
 
-#: builtin/clone.c:97 builtin/init-db.c:495
+#: builtin/clone.c:97 builtin/init-db.c:493
 msgid "separate git dir from working tree"
-msgstr ""
+msgstr "отделна СЛУЖЕБНА_ДИРЕКТОРИЯ за git извън работното дърво"
 
 #: builtin/clone.c:98
 msgid "key=value"
-msgstr ""
+msgstr "КЛЮЧ=СТОЙНОСТ"
 
 #: builtin/clone.c:99
 msgid "set config inside the new repository"
-msgstr ""
+msgstr "задаване на настройките на новото хранилище"
 
 #: builtin/clone.c:252
 #, c-format
 msgid "reference repository '%s' is not a local repository."
-msgstr ""
+msgstr "еталонното хранилище „%s“ не е локално"
 
 #: builtin/clone.c:256
 #, c-format
 msgid "reference repository '%s' is shallow"
-msgstr ""
+msgstr "еталонното хранилище „%s“ е плитко"
 
 #: builtin/clone.c:259
 #, c-format
 msgid "reference repository '%s' is grafted"
-msgstr ""
+msgstr "еталонното хранилище „%s“ е с присаждане"
 
 #: builtin/clone.c:321
 #, c-format
 msgid "failed to create directory '%s'"
-msgstr ""
+msgstr "директорията „%s“ не може да бъде създадена"
 
 #: builtin/clone.c:323 builtin/diff.c:83
 #, c-format
 msgid "failed to stat '%s'"
-msgstr ""
+msgstr "не може да бъде получена информация чрез „stat“ за „%s“"
 
 #: builtin/clone.c:325
 #, c-format
 msgid "%s exists and is not a directory"
-msgstr ""
+msgstr "„%s“ съществува и не е директория"
 
 #: builtin/clone.c:339
 #, c-format
 msgid "failed to stat %s\n"
-msgstr ""
+msgstr "не може да бъде получена информация чрез „stat“ за „%s“\n"
 
 #: builtin/clone.c:361
 #, c-format
 msgid "failed to create link '%s'"
-msgstr ""
+msgstr "връзката „%s“ не може да бъде създадена"
 
 #: builtin/clone.c:365
 #, c-format
 msgid "failed to copy file to '%s'"
-msgstr ""
+msgstr "файлът не можа да бъде копиран като „%s“"
 
 #: builtin/clone.c:388 builtin/clone.c:565
 #, c-format
 msgid "done.\n"
-msgstr ""
+msgstr "действието завърши.\n"
 
 #: builtin/clone.c:401
 msgid ""
@@ -3858,111 +3965,121 @@ msgid ""
 "You can inspect what was checked out with 'git status'\n"
 "and retry the checkout with 'git checkout -f HEAD'\n"
 msgstr ""
+"Клонирането бе успешно за разлика от подготовката на работното дърво\n"
+"за определен клон. Все пак можете да проверите кои файлове и от кой\n"
+"клон в момента са изтеглени с командата „git status“. Можете да\n"
+"завършите изтеглянето на клона с командата „git checkout -f HEAD“.\n"
 
 #: builtin/clone.c:480
 #, c-format
 msgid "Could not find remote branch %s to clone."
 msgstr ""
+"Клонът „%s“ от отдалеченото хранилище което клонирате,\n"
+"който следва да бъде изтеглен, не съществува."
 
 #: builtin/clone.c:560
 #, c-format
 msgid "Checking connectivity... "
-msgstr ""
+msgstr "Проверка на връзката…"
 
 #: builtin/clone.c:563
 msgid "remote did not send all necessary objects"
-msgstr ""
+msgstr "отдалеченото хранилище не изпрати всички необходими обекти."
 
 #: builtin/clone.c:626
 msgid "remote HEAD refers to nonexistent ref, unable to checkout.\n"
 msgstr ""
+"указателят „HEAD“ от отдалеченото хранилище сочи към нещо,\n"
+"което не съществува. Не може да се изтегли определен клон.\n"
 
 #: builtin/clone.c:657
 msgid "unable to checkout working tree"
-msgstr ""
+msgstr "работното дърво не може да бъде подготвено"
 
 #: builtin/clone.c:765
 msgid "Too many arguments."
-msgstr ""
+msgstr "Прекалено много аргументи."
 
 #: builtin/clone.c:769
 msgid "You must specify a repository to clone."
-msgstr ""
+msgstr "Трябва да укажете кое хранилище искате да клонирате."
 
 #: builtin/clone.c:780
 #, c-format
 msgid "--bare and --origin %s options are incompatible."
-msgstr ""
+msgstr "опциите „--bare“ и „--origin %s“ са несъвместими."
 
 #: builtin/clone.c:783
 msgid "--bare and --separate-git-dir are incompatible."
-msgstr ""
+msgstr "опциите „--bare“ и „--separate-git-dir“ са несъвместими."
 
 #: builtin/clone.c:796
 #, c-format
 msgid "repository '%s' does not exist"
-msgstr ""
+msgstr "не съществува хранилище „%s“"
 
 #: builtin/clone.c:802
 msgid "--depth is ignored in local clones; use file:// instead."
 msgstr ""
+"При локално клониране опцията „--depth“ се игнорира. Ползвайте схемата "
+"„file://“."
 
 #: builtin/clone.c:805
 msgid "source repository is shallow, ignoring --local"
-msgstr ""
+msgstr "клонираното хранилище е плитко, затова опцията „--local“ се игнорира"
 
 #: builtin/clone.c:810
 msgid "--local is ignored"
-msgstr ""
+msgstr "опцията „--local“ се игнорира"
 
 #: builtin/clone.c:814 builtin/fetch.c:1119
 #, c-format
 msgid "depth %s is not a positive number"
-msgstr ""
+msgstr "дълбочината трябва да е положително цяло число, а не „%s“"
 
 #: builtin/clone.c:824
 #, c-format
 msgid "destination path '%s' already exists and is not an empty directory."
-msgstr ""
+msgstr "целевият път „%s“ съществува и не е празна директория."
 
 #: builtin/clone.c:834
 #, c-format
 msgid "working tree '%s' already exists."
-msgstr ""
+msgstr "в „%s“ вече съществува работно дърво."
 
 #: builtin/clone.c:847 builtin/clone.c:859
 #, c-format
 msgid "could not create leading directories of '%s'"
-msgstr ""
+msgstr "родителските директории на „%s“ не могат да бъдат създадени"
 
 #: builtin/clone.c:850
 #, c-format
 msgid "could not create work tree dir '%s'."
-msgstr ""
+msgstr "работното дърво в „%s“ не може да бъде създадено."
 
 #: builtin/clone.c:869
 #, c-format
 msgid "Cloning into bare repository '%s'...\n"
-msgstr ""
+msgstr "Клониране и създаване на голо хранилище в „%s“…\n"
 
 #: builtin/clone.c:871
 #, c-format
 msgid "Cloning into '%s'...\n"
-msgstr ""
+msgstr "Клониране и създаване на хранилище в „%s“…\n"
 
 #: builtin/clone.c:906
 #, c-format
 msgid "Don't know how to clone %s"
-msgstr ""
+msgstr "Не се поддържа клониране на връзки от вида „%s“ "
 
 #: builtin/clone.c:957 builtin/clone.c:965
 #, c-format
 msgid "Remote branch %s not found in upstream %s"
-msgstr ""
+msgstr "Отдалеченият клон „%s“ липсва в клонираното хранилище „%s“"
 
 #: builtin/clone.c:968
 msgid "You appear to have cloned an empty repository."
-msgstr ""
+msgstr "Изглежда клонирахте празно хранилище."
 
 #: builtin/column.c:9
 msgid "git column [options]"
@@ -3998,11 +4115,11 @@ msgstr ""
 
 #: builtin/commit.c:36
 msgid "git commit [options] [--] <pathspec>..."
-msgstr ""
+msgstr "git commit [ОПЦИИ] [--] ПЪТ…"
 
 #: builtin/commit.c:41
 msgid "git status [options] [--] <pathspec>..."
-msgstr ""
+msgstr "git status [ОПЦИИ] [--] ПЪТ…"
 
 #: builtin/commit.c:46
 msgid ""
@@ -4017,6 +4134,17 @@ msgid ""
 "\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:58
 msgid ""
@@ -4024,6 +4152,11 @@ msgid ""
 "it empty. You can repeat your command with --allow-empty, or you can\n"
 "remove the commit entirely with \"git reset HEAD^\".\n"
 msgstr ""
+"Поискахте да поправите последното си подаване. Това действие ще превърне\n"
+"подаването в празно. Можете или да го повторите като разрешите такива "
+"подавания\n"
+"с опцията „--allow-empty“, или да го изтриете от историята с командата:\n"
+"„git reset HEAD^“.\n"
 
 #: builtin/commit.c:63
 msgid ""
@@ -4033,10 +4166,16 @@ msgid ""
 "    git commit --allow-empty\n"
 "\n"
 msgstr ""
+"Предишното отбрано подаване вече е празно, като най-вероятната причина е\n"
+"корекция на конфликт. Ако все пак искате да го ползвате, използвайте "
+"командата:\n"
+"\n"
+"    git commit --allow-empty\n"
+"\n"
 
 #: builtin/commit.c:70
 msgid "Otherwise, please use 'git reset'\n"
-msgstr ""
+msgstr "В противен случай използвайте командата „git reset“\n"
 
 #: builtin/commit.c:73
 msgid ""
@@ -4047,95 +4186,101 @@ msgid ""
 "Then \"git cherry-pick --continue\" will resume cherry-picking\n"
 "the remaining commits.\n"
 msgstr ""
+"Ако искате да прескочите това подаване, използвайте командата:\n"
+"\n"
+"    git reset\n"
+"\n"
+"Чрез командата „git cherry-pick --continue“ ще продължите отбирането на\n"
+"останалите подавания.\n"
 
-#: builtin/commit.c:287
+#: builtin/commit.c:288
 msgid "failed to unpack HEAD tree object"
-msgstr ""
+msgstr "неуспешно изваждана на върховото дърво (HEAD tree object) от пакет"
 
-#: builtin/commit.c:329
+#: builtin/commit.c:330
 msgid "unable to create temporary index"
-msgstr ""
+msgstr "неуспешно създаване на временен индекс"
 
-#: builtin/commit.c:335
+#: builtin/commit.c:336
 msgid "interactive add failed"
-msgstr ""
+msgstr "неуспешно интерактивно добавяне"
 
-#: builtin/commit.c:368 builtin/commit.c:389 builtin/commit.c:439
+#: builtin/commit.c:369 builtin/commit.c:390 builtin/commit.c:440
 msgid "unable to write new_index file"
-msgstr ""
+msgstr "неуспешен запис на новия индекс"
 
-#: builtin/commit.c:420
+#: builtin/commit.c:421
 msgid "cannot do a partial commit during a merge."
-msgstr ""
+msgstr "по време на сливане не може да се извърши частично подаване."
 
-#: builtin/commit.c:422
+#: builtin/commit.c:423
 msgid "cannot do a partial commit during a cherry-pick."
-msgstr ""
+msgstr "по време на отбиране не може да се извърши частично подаване."
 
-#: builtin/commit.c:432
+#: builtin/commit.c:433
 msgid "cannot read the index"
-msgstr ""
+msgstr "индексът не може да бъде прочетен"
 
-#: builtin/commit.c:452
+#: builtin/commit.c:453
 msgid "unable to write temporary index file"
-msgstr ""
+msgstr "временният индекс не може да бъде записан"
 
-#: builtin/commit.c:543 builtin/commit.c:549
+#: builtin/commit.c:544 builtin/commit.c:550
 #, c-format
 msgid "invalid commit: %s"
-msgstr ""
+msgstr "неправилно подаване: %s"
 
-#: builtin/commit.c:571
+#: builtin/commit.c:572
 msgid "malformed --author parameter"
-msgstr ""
+msgstr "неправилен параметър към опцията „--author“"
 
-#: builtin/commit.c:591
+#: builtin/commit.c:592
 #, c-format
 msgid "Malformed ident string: '%s'"
-msgstr ""
+msgstr "Неправилен низ за идентичност: „%s“"
 
-#: builtin/commit.c:630 builtin/commit.c:663 builtin/commit.c:1007
+#: builtin/commit.c:629 builtin/commit.c:663 builtin/commit.c:1014
 #, c-format
 msgid "could not lookup commit %s"
-msgstr ""
+msgstr "следното подаване не може да бъде открито: %s"
 
-#: builtin/commit.c:642 builtin/shortlog.c:273
+#: builtin/commit.c:641 builtin/shortlog.c:273
 #, c-format
 msgid "(reading log message from standard input)\n"
-msgstr ""
+msgstr "(изчитане на съобщението за подаване от стандартния вход)\n"
 
-#: builtin/commit.c:644
+#: builtin/commit.c:643
 msgid "could not read log from standard input"
-msgstr ""
+msgstr "съобщението за подаване не бе прочетено стандартния вход"
 
-#: builtin/commit.c:648
+#: builtin/commit.c:647
 #, c-format
 msgid "could not read log file '%s'"
-msgstr ""
+msgstr "файлът със съобщението за подаване „%s“ не може да бъде прочетен"
 
 #: builtin/commit.c:654
 msgid "commit has empty message"
-msgstr ""
+msgstr "подаване с празно съобщение"
 
 #: builtin/commit.c:670
 msgid "could not read MERGE_MSG"
-msgstr ""
+msgstr "съобщението за сливане MERGE_MSG не може да бъде прочетено"
 
 #: builtin/commit.c:674
 msgid "could not read SQUASH_MSG"
-msgstr ""
+msgstr "съобщението за смачкване SQUASH_MSG не може да бъде прочетено"
 
 #: builtin/commit.c:678
 #, c-format
 msgid "could not read '%s'"
-msgstr ""
+msgstr "файлът „%s“ не може да бъде прочетен"
 
 #: builtin/commit.c:749
 msgid "could not write commit template"
-msgstr ""
+msgstr "шаблонът за подаване не може да бъде запазен"
 
 # FIXME
-#: builtin/commit.c:760
+#: builtin/commit.c:764
 #, c-format
 msgid ""
 "\n"
@@ -4144,9 +4289,14 @@ msgid ""
 "\t%s\n"
 "and try again.\n"
 msgstr ""
+"\n"
+"Изглежда, че подавате сливане. Ако това не е така, изтрийте файла:\n"
+"\n"
+"  %s\n"
+"и опитайте отново.\n"
 
 # FIXME
-#: builtin/commit.c:765
+#: builtin/commit.c:769
 #, c-format
 msgid ""
 "\n"
@@ -4155,681 +4305,724 @@ msgid ""
 "\t%s\n"
 "and try again.\n"
 msgstr ""
+"\n"
+"Изглежда, че извършвате отбрано подаване. Ако това не е така, изтрийте "
+"файла:\n"
+"\n"
+"  %s\n"
+"и опитайте отново.\n"
 
-#: builtin/commit.c:777
+#: builtin/commit.c:782
 #, c-format
 msgid ""
 "Please enter the commit message for your changes. Lines starting\n"
 "with '%c' will be ignored, and an empty message aborts the commit.\n"
 msgstr ""
+"Въведете съобщението за подаване на промените. Редовете, които започват\n"
+"с „%c“ ще бъдат филтрирани, а празно съобщение отменя подаването.\n"
 
-#: builtin/commit.c:782
+#: builtin/commit.c:789
 #, c-format
 msgid ""
 "Please enter the commit message for your changes. Lines starting\n"
 "with '%c' will be kept; you may remove them yourself if you want to.\n"
 "An empty message aborts the commit.\n"
 msgstr ""
+"Въведете съобщението за подаване на промените. Редовете, които започват\n"
+"с „%c“ НЯМА да бъдат филтрирани, може да ги изтриете вие. Празно \n"
+"съобщение отменя подаването.\n"
 
-#: builtin/commit.c:795
+#: builtin/commit.c:802
 #, c-format
 msgid "%sAuthor:    %s"
-msgstr ""
+msgstr "%sАвтор:    %s"
 
-#: builtin/commit.c:802
+#: builtin/commit.c:809
 #, c-format
 msgid "%sCommitter: %s"
-msgstr ""
+msgstr "%sПодаващ: %s"
 
-#: builtin/commit.c:822
+#: builtin/commit.c:829
 msgid "Cannot read index"
-msgstr ""
+msgstr "Индексът не може да бъде прочетен"
 
-#: builtin/commit.c:865
+#: builtin/commit.c:872
 msgid "Error building trees"
-msgstr ""
+msgstr "Грешка при изграждане на дърветата"
 
-#: builtin/commit.c:880 builtin/tag.c:359
+#: builtin/commit.c:887 builtin/tag.c:391
 #, c-format
 msgid "Please supply the message using either -m or -F option.\n"
-msgstr ""
+msgstr "Подайте съобщението с някоя от опциите „-m“ или „-F“.\n"
 
-#: builtin/commit.c:982
+#: builtin/commit.c:989
 #, c-format
 msgid "No existing author found with '%s'"
-msgstr ""
+msgstr "Не е открит автор с име „%s“."
 
-#: builtin/commit.c:997 builtin/commit.c:1237
+#: builtin/commit.c:1004 builtin/commit.c:1244
 #, c-format
 msgid "Invalid untracked files mode '%s'"
-msgstr ""
+msgstr "Неправилна стойност за неследените файлове: „%s“"
 
-#: builtin/commit.c:1034
+#: builtin/commit.c:1041
 msgid "--long and -z are incompatible"
-msgstr ""
+msgstr "Опциите „--long“ и „-z“ са несъвместими."
 
-#: builtin/commit.c:1064
+#: builtin/commit.c:1071
 msgid "Using both --reset-author and --author does not make sense"
-msgstr ""
+msgstr "Опциите „--reset-author“ и „--author“ са несъвместими."
 
-#: builtin/commit.c:1075
+#: builtin/commit.c:1080
 msgid "You have nothing to amend."
-msgstr ""
+msgstr "Няма какво да бъде поправено."
 
-#: builtin/commit.c:1078
+#: builtin/commit.c:1083
 msgid "You are in the middle of a merge -- cannot amend."
-msgstr ""
+msgstr "В момента се извършва сливане, не можете да поправяте."
 
-#: builtin/commit.c:1080
+#: builtin/commit.c:1085
 msgid "You are in the middle of a cherry-pick -- cannot amend."
-msgstr ""
+msgstr "В момента се извършва отбиране на подаване, не можете да поправяте."
 
-#: builtin/commit.c:1083
+#: builtin/commit.c:1088
 msgid "Options --squash and --fixup cannot be used together"
-msgstr ""
+msgstr "Опциите „--squash“ и „--fixup“ са несъвместими."
 
-#: builtin/commit.c:1093
+#: builtin/commit.c:1098
 msgid "Only one of -c/-C/-F/--fixup can be used."
 msgstr ""
+"Можете да използвате само една от опциите „-c“, „-C“, „-F“ и „--fixup“."
 
-#: builtin/commit.c:1095
+#: builtin/commit.c:1100
 msgid "Option -m cannot be combined with -c/-C/-F/--fixup."
-msgstr ""
+msgstr "Опцията „-m“ е несъвместима с „-c“, „-C“, „-F“ и „--fixup“."
 
-#: builtin/commit.c:1103
+#: builtin/commit.c:1108
 msgid "--reset-author can be used only with -C, -c or --amend."
 msgstr ""
+"Опцията „--reset-author“ може да се използва само заедно с „-C“, „-c“ или\n"
+"„--amend“."
 
-#: builtin/commit.c:1120
+#: builtin/commit.c:1125
 msgid "Only one of --include/--only/--all/--interactive/--patch can be used."
 msgstr ""
+"Опциите „--include“, „--only“, „--all“, „--interactive“ и „--patch“ са\n"
+"несъвместими."
 
-#: builtin/commit.c:1122
+#: builtin/commit.c:1127
 msgid "No paths with --include/--only does not make sense."
-msgstr ""
+msgstr "Опциите „--include“ и „--only“ изискват аргументи."
 
-#: builtin/commit.c:1124
+# FIXME bad message
+#: builtin/commit.c:1129
 msgid "Clever... amending the last one with dirty index."
 msgstr ""
+"Поправяте последното подаване докато индекса има проблеми. Това е лоша идея."
 
-#: builtin/commit.c:1126
-msgid "Explicit paths specified without -i nor -o; assuming --only paths..."
+#: builtin/commit.c:1131
+msgid "Explicit paths specified without -i or -o; assuming --only paths..."
 msgstr ""
+"Зададени са изрични пътища без опциите „-i“ или „-o“. Приема се, че все едно "
+"сте\n"
+"ползвали опцията „--only“ с ПЪТища…"
 
-#: builtin/commit.c:1136 builtin/tag.c:572
+#: builtin/commit.c:1143 builtin/tag.c:639
 #, c-format
 msgid "Invalid cleanup mode %s"
-msgstr ""
+msgstr "Несъществуващ режим на изчистване „%s“"
 
-#: builtin/commit.c:1141
+#: builtin/commit.c:1148
 msgid "Paths with -a does not make sense."
-msgstr ""
+msgstr "Използването на пътища е несъвместимо със задаването на опцията „-a“."
 
-#: builtin/commit.c:1251 builtin/commit.c:1482
+#: builtin/commit.c:1258 builtin/commit.c:1516
 msgid "show status concisely"
-msgstr ""
+msgstr "кратка информация за състоянието"
 
-#: builtin/commit.c:1253 builtin/commit.c:1484
+#: builtin/commit.c:1260 builtin/commit.c:1518
 msgid "show branch information"
-msgstr ""
+msgstr "информация за клоните"
 
-#: builtin/commit.c:1255 builtin/commit.c:1486 builtin/push.c:507
+#: builtin/commit.c:1262 builtin/commit.c:1520 builtin/push.c:490
 msgid "machine-readable output"
-msgstr ""
+msgstr "формат на изхода за четене от програма"
 
-#: builtin/commit.c:1258 builtin/commit.c:1488
+#: builtin/commit.c:1265 builtin/commit.c:1522
 msgid "show status in long format (default)"
-msgstr ""
+msgstr "подробна информация за състоянието (стандартно)"
 
-#: builtin/commit.c:1261 builtin/commit.c:1491
+#: builtin/commit.c:1268 builtin/commit.c:1525
 msgid "terminate entries with NUL"
-msgstr ""
+msgstr "разделяне на елементите с нулевия знак „NUL“"
 
-#: builtin/commit.c:1263 builtin/commit.c:1494 builtin/fast-export.c:674
-#: builtin/fast-export.c:677 builtin/tag.c:459
+#: builtin/commit.c:1270 builtin/commit.c:1528 builtin/fast-export.c:674
+#: builtin/fast-export.c:677 builtin/tag.c:514
 msgid "mode"
-msgstr ""
+msgstr "режим"
 
-#: builtin/commit.c:1264 builtin/commit.c:1494
+#: builtin/commit.c:1271 builtin/commit.c:1528
 msgid "show untracked files, optional modes: all, normal, no. (Default: all)"
 msgstr ""
+"извеждане на неследените файлове. Възможните режими са „all“ (подробна\n"
+"информация), „normal“ (кратка информация), „no“ (без неследените файлове).\n"
+"Стандартният режим е: „all“."
 
-#: builtin/commit.c:1267
+#: builtin/commit.c:1274
 msgid "show ignored files"
-msgstr ""
+msgstr "извеждане на игнорираните файлове"
 
-#: builtin/commit.c:1268 parse-options.h:156
+#: builtin/commit.c:1275 parse-options.h:153
 msgid "when"
 msgstr "кога"
 
-#: builtin/commit.c:1269
+#: builtin/commit.c:1276
 msgid ""
 "ignore changes to submodules, optional when: all, dirty, untracked. "
 "(Default: all)"
 msgstr ""
+"игнориране на промените в подмодулите. Опция с незадължителна стойност — "
+"една от\n"
+"„all“ (всички), „dirty“ (тези с неподадени промени), „untracked“ (неследени)"
 
-#: builtin/commit.c:1271
+#: builtin/commit.c:1278
 msgid "list untracked files in columns"
-msgstr ""
+msgstr "извеждане на неследените файлове в колони"
 
-#: builtin/commit.c:1340
+#: builtin/commit.c:1347
 msgid "couldn't look up newly created commit"
-msgstr ""
+msgstr "току що създаденото подаване не може да бъде открито"
 
-#: builtin/commit.c:1342
+#: builtin/commit.c:1349
 msgid "could not parse newly created commit"
-msgstr ""
+msgstr "току що създаденото подаване не може да бъде анализирано"
 
-#: builtin/commit.c:1383
+#: builtin/commit.c:1390
 msgid "detached HEAD"
-msgstr ""
+msgstr "несвързан връх HEAD"
 
-#: builtin/commit.c:1385
+#: builtin/commit.c:1392
 msgid " (root-commit)"
-msgstr ""
+msgstr " (начално подаване)"
 
-#: builtin/commit.c:1452
+#: builtin/commit.c:1486
 msgid "suppress summary after successful commit"
-msgstr ""
+msgstr "без информация след успешно подаване"
 
-#: builtin/commit.c:1453
+#: builtin/commit.c:1487
 msgid "show diff in commit message template"
-msgstr ""
+msgstr "добавяне на разликата към шаблона за съобщението при подаване"
 
-#: builtin/commit.c:1455
+#: builtin/commit.c:1489
 msgid "Commit message options"
-msgstr ""
+msgstr "Опции за съобщението при подаване"
 
-#: builtin/commit.c:1456 builtin/tag.c:457
+#: builtin/commit.c:1490 builtin/tag.c:512
 msgid "read message from file"
-msgstr ""
+msgstr "взимане та съобщението от файл"
 
-#: builtin/commit.c:1457
+#: builtin/commit.c:1491
 msgid "author"
-msgstr ""
+msgstr "автор"
 
-#: builtin/commit.c:1457
+#: builtin/commit.c:1491
 msgid "override author for commit"
-msgstr ""
+msgstr "задаване на автор за подаването"
 
-#: builtin/commit.c:1458 builtin/gc.c:261
+#: builtin/commit.c:1492 builtin/gc.c:272
 msgid "date"
 msgstr "дата"
 
-#: builtin/commit.c:1458
+#: builtin/commit.c:1492
 msgid "override date for commit"
-msgstr ""
+msgstr "задаване на дата за подаването"
 
-#: builtin/commit.c:1459 builtin/merge.c:216 builtin/notes.c:405
-#: builtin/notes.c:562 builtin/tag.c:455
+#: builtin/commit.c:1493 builtin/merge.c:216 builtin/notes.c:409
+#: builtin/notes.c:566 builtin/tag.c:510
 msgid "message"
-msgstr ""
+msgstr "съобщение"
 
-#: builtin/commit.c:1459
+#: builtin/commit.c:1493
 msgid "commit message"
-msgstr ""
+msgstr "съобщение при подаване"
 
-#: builtin/commit.c:1460
+#: builtin/commit.c:1494
 msgid "reuse and edit message from specified commit"
-msgstr ""
+msgstr "преизползване и редактиране на съобщението от указаното подаване"
 
-#: builtin/commit.c:1461
+#: builtin/commit.c:1495
 msgid "reuse message from specified commit"
-msgstr ""
+msgstr "преизползване на съобщението от указаното подаване"
 
-#: builtin/commit.c:1462
+#: builtin/commit.c:1496
 msgid "use autosquash formatted message to fixup specified commit"
 msgstr ""
+"използване на автоматичното съобщение при смачкване за вкарване на "
+"указаното\n"
+"подаване в предното без следа"
 
-#: builtin/commit.c:1463
+#: builtin/commit.c:1497
 msgid "use autosquash formatted message to squash specified commit"
 msgstr ""
+"използване на автоматичното съобщение при смачкване за смачкване на "
+"указаното\n"
+"подаване в предното"
 
-#: builtin/commit.c:1464
+#: builtin/commit.c:1498
 msgid "the commit is authored by me now (used with -C/-c/--amend)"
 msgstr ""
+"смяна на автора да съвпада с подаващия (използва се с „-C“/„-c“/„--amend“)"
 
-#: builtin/commit.c:1465 builtin/log.c:1180 builtin/revert.c:86
+#: builtin/commit.c:1499 builtin/log.c:1180 builtin/revert.c:86
 msgid "add Signed-off-by:"
-msgstr ""
+msgstr "добавяне на поле за подпис — „Signed-off-by:“"
 
-#: builtin/commit.c:1466
+#: builtin/commit.c:1500
 msgid "use specified template file"
-msgstr ""
+msgstr "използване на указания шаблонен файл"
 
-#: builtin/commit.c:1467
+#: builtin/commit.c:1501
 msgid "force edit of commit"
-msgstr ""
+msgstr "редактиране на подаване"
 
-#: builtin/commit.c:1468
+#: builtin/commit.c:1502
 msgid "default"
-msgstr ""
+msgstr "стандартно"
 
-#: builtin/commit.c:1468 builtin/tag.c:460
+#: builtin/commit.c:1502 builtin/tag.c:515
 msgid "how to strip spaces and #comments from message"
-msgstr ""
+msgstr "кои празни знаци и #коментари да се махат от съобщенията"
 
-#: builtin/commit.c:1469
+#: builtin/commit.c:1503
 msgid "include status in commit message template"
-msgstr ""
+msgstr "вмъкване на състоянието в шаблона за съобщението при подаване"
 
-#: builtin/commit.c:1470 builtin/merge.c:223 builtin/tag.c:461
-msgid "key id"
-msgstr ""
+#: builtin/commit.c:1504 builtin/merge.c:223 builtin/revert.c:92
+#: builtin/tag.c:516
+msgid "key-id"
+msgstr "ИДЕНТИФИКАТОР_НА_КЛЮЧ"
 
-#: builtin/commit.c:1471 builtin/merge.c:224
+#: builtin/commit.c:1505 builtin/merge.c:224 builtin/revert.c:93
 msgid "GPG sign commit"
-msgstr ""
+msgstr "подписване на подаването с GPG"
 
-#. end commit message options
-#: builtin/commit.c:1474
+#: builtin/commit.c:1508
 msgid "Commit contents options"
-msgstr ""
+msgstr "Опции за избор на файлове при подаване"
 
-#: builtin/commit.c:1475
+#: builtin/commit.c:1509
 msgid "commit all changed files"
-msgstr ""
+msgstr "подаване на всички променени файлове"
 
-#: builtin/commit.c:1476
+#: builtin/commit.c:1510
 msgid "add specified files to index for commit"
-msgstr ""
+msgstr "добавяне на указаните файлове към индекса за подаване"
 
-#: builtin/commit.c:1477
+#: builtin/commit.c:1511
 msgid "interactively add files"
-msgstr ""
+msgstr "интерактивно добавяне на файлове"
 
-#: builtin/commit.c:1478
+#: builtin/commit.c:1512
 msgid "interactively add changes"
-msgstr ""
+msgstr "интерактивно добавяне на промени"
 
-#: builtin/commit.c:1479
+#: builtin/commit.c:1513
 msgid "commit only specified files"
-msgstr ""
+msgstr "подаване само на указаните файлове"
 
-#: builtin/commit.c:1480
+#: builtin/commit.c:1514
 msgid "bypass pre-commit hook"
-msgstr ""
+msgstr "без изпълнение на куката преди подаване (pre-commit)"
 
-#: builtin/commit.c:1481
+#: builtin/commit.c:1515
 msgid "show what would be committed"
-msgstr ""
+msgstr "отпечатване на това, което би било подадено"
 
-#: builtin/commit.c:1492
+#: builtin/commit.c:1526
 msgid "amend previous commit"
-msgstr ""
+msgstr "поправяне на предишното подаване"
 
-#: builtin/commit.c:1493
+#: builtin/commit.c:1527
 msgid "bypass post-rewrite hook"
-msgstr ""
+msgstr "без изпълнение на куката след презаписване (post-rewrite)"
 
-#: builtin/commit.c:1498
+#: builtin/commit.c:1532
 msgid "ok to record an empty change"
-msgstr ""
+msgstr "позволяване на празни подавания"
 
-#: builtin/commit.c:1500
+#: builtin/commit.c:1534
 msgid "ok to record a change with an empty message"
-msgstr ""
+msgstr "позволяване на подавания с празни съобщения"
 
-#: builtin/commit.c:1529
+#: builtin/commit.c:1562
 msgid "could not parse HEAD commit"
-msgstr ""
+msgstr "върховото подаване „HEAD“ не може да бъде прочетено"
 
-#: builtin/commit.c:1567 builtin/merge.c:518
+#: builtin/commit.c:1601 builtin/merge.c:518
 #, c-format
 msgid "could not open '%s' for reading"
-msgstr ""
+msgstr "файлът не може да бъде прочетен: „%s“"
 
-#: builtin/commit.c:1574
+#: builtin/commit.c:1608
 #, c-format
 msgid "Corrupt MERGE_HEAD file (%s)"
-msgstr ""
+msgstr "Повреден файл за върха за сливането „MERGE_HEAD“ (%s)"
 
-#: builtin/commit.c:1581
+#: builtin/commit.c:1615
 msgid "could not read MERGE_MODE"
-msgstr ""
+msgstr "режимът на сливане „MERGE_MODE“ не може да бъде прочетен"
 
-#: builtin/commit.c:1600
+#: builtin/commit.c:1634
 #, c-format
 msgid "could not read commit message: %s"
-msgstr ""
+msgstr "съобщението за подаване не може да бъде прочетено: %s"
 
-#: builtin/commit.c:1611
+#: builtin/commit.c:1645
 #, c-format
 msgid "Aborting commit; you did not edit the message.\n"
-msgstr ""
+msgstr "Неизвършване на подаване поради нередактирано съобщение.\n"
 
-#: builtin/commit.c:1616
+#: builtin/commit.c:1650
 #, c-format
 msgid "Aborting commit due to empty commit message.\n"
-msgstr ""
+msgstr "Неизвършване на подаване поради празно съобщение.\n"
 
-#: builtin/commit.c:1631 builtin/merge.c:854 builtin/merge.c:879
+#: builtin/commit.c:1665 builtin/merge.c:857 builtin/merge.c:882
 msgid "failed to write commit object"
-msgstr ""
+msgstr "обектът за подаването не може да бъде записан"
 
-#: builtin/commit.c:1652
+#: builtin/commit.c:1686
 msgid "cannot lock HEAD ref"
-msgstr ""
+msgstr "указателят към върха „HEAD“ не може да бъде заключен"
 
-#: builtin/commit.c:1656
+#: builtin/commit.c:1690
 msgid "cannot update HEAD ref"
-msgstr ""
+msgstr "указателят към върха „HEAD“ не може да бъде обновен"
 
-#: builtin/commit.c:1667
+#: builtin/commit.c:1701
 msgid ""
 "Repository has been updated, but unable to write\n"
 "new_index file. Check that disk is not full or quota is\n"
 "not exceeded, and then \"git reset HEAD\" to recover."
 msgstr ""
+"Хранилището е обновено, но новият файл за индекс „new_index“\n"
+"не е записан. Проверете дали не е препълнен диска или не сте\n"
+"превишили дисковата си квота. След това изпълнете „git reset HEAD“."
 
 #: builtin/config.c:8
 msgid "git config [options]"
-msgstr ""
+msgstr "git config [ОПЦИИ]"
 
-#: builtin/config.c:54
+#: builtin/config.c:53
 msgid "Config file location"
-msgstr ""
+msgstr "Местоположение на конфигурационния файл"
 
-#: builtin/config.c:55
+#: builtin/config.c:54
 msgid "use global config file"
-msgstr ""
+msgstr "използване на глобалния конфигурационен файл"
 
-#: builtin/config.c:56
+#: builtin/config.c:55
 msgid "use system config file"
-msgstr ""
+msgstr "използване на системния конфигурационен файл"
 
-#: builtin/config.c:57
+#: builtin/config.c:56
 msgid "use repository config file"
-msgstr ""
+msgstr "използване на конфигурационния файл на хранилището"
 
-#: builtin/config.c:58
+#: builtin/config.c:57
 msgid "use given config file"
-msgstr ""
+msgstr "използване на зададения конфигурационен файл"
 
-#: builtin/config.c:59
+#: builtin/config.c:58
 msgid "blob-id"
-msgstr ""
+msgstr "идентификатор на BLOB"
 
-#: builtin/config.c:59
+#: builtin/config.c:58
 msgid "read config from given blob object"
 msgstr ""
+"изчитане на конфигурацията от BLOB с този идентификатор на съдържанието"
 
-#: builtin/config.c:60
+#: builtin/config.c:59
 msgid "Action"
-msgstr ""
+msgstr "Действие"
 
-#: builtin/config.c:61
+#: builtin/config.c:60
 msgid "get value: name [value-regex]"
-msgstr ""
+msgstr "извеждане на стойност: ИМЕ [РЕГУЛЯРЕН_ИЗРАЗ_ЗА_СТОЙНОСТТА]"
 
-#: builtin/config.c:62
+#: builtin/config.c:61
 msgid "get all values: key [value-regex]"
-msgstr ""
+msgstr "извеждане на всички стойности: ключ [РЕГУЛЯРЕН_ИЗРАЗ_ЗА_СТОЙНОСТТА]"
 
-#: builtin/config.c:63
+#: builtin/config.c:62
 msgid "get values for regexp: name-regex [value-regex]"
 msgstr ""
+"извеждане на стойностите за РЕГУЛЯРНия_ИЗРАЗ: РЕГУЛЯРЕН_ИЗРАЗ_ЗА_ИМЕТО "
+"[РЕГУЛЯРЕН_ИЗРАЗ_ЗА_СТОЙНОСТТА]"
 
-#: builtin/config.c:64
+#: builtin/config.c:63
 msgid "get value specific for the URL: section[.var] URL"
-msgstr ""
+msgstr "извеждане на стойността за указания адрес: РАЗДЕЛ[.ПРОМЕНЛИВА] АДРЕС"
 
-#: builtin/config.c:65
+#: builtin/config.c:64
 msgid "replace all matching variables: name value [value_regex]"
 msgstr ""
+"замяна на всички съвпадащи променливи: ИМЕ СТОЙНОСТ "
+"[РЕГУЛЯРЕН_ИЗРАЗ_ЗА_СТОЙНОСТТА]"
 
-#: builtin/config.c:66
+#: builtin/config.c:65
 msgid "add a new variable: name value"
-msgstr ""
+msgstr "добавяне на нова променлива: ИМЕ СТОЙНОСТ"
 
-#: builtin/config.c:67
+#: builtin/config.c:66
 msgid "remove a variable: name [value-regex]"
-msgstr ""
+msgstr "изтриване на променлива: ИМЕ [РЕГУЛЯРЕН_ИЗРАЗ_ЗА_СТОЙНОСТТА]"
 
-#: builtin/config.c:68
+#: builtin/config.c:67
 msgid "remove all matches: name [value-regex]"
-msgstr ""
+msgstr "изтриване на всички съвпадащи: ИМЕ [РЕГУЛЯРЕН_ИЗРАЗ_ЗА_СТОЙНОСТТА]"
 
-#: builtin/config.c:69
+#: builtin/config.c:68
 msgid "rename section: old-name new-name"
-msgstr ""
+msgstr "преименуване на раздел: СТАРО_ИМЕ НОВО_ИМЕ"
 
-#: builtin/config.c:70
+#: builtin/config.c:69
 msgid "remove a section: name"
-msgstr ""
+msgstr "изтриване на раздел: ИМЕ"
 
-#: builtin/config.c:71
+#: builtin/config.c:70
 msgid "list all"
-msgstr ""
+msgstr "изброяване на всички"
 
-#: builtin/config.c:72
+#: builtin/config.c:71
 msgid "open an editor"
-msgstr ""
+msgstr "отваряне на редактор"
 
-#: builtin/config.c:73 builtin/config.c:74
+#: builtin/config.c:72 builtin/config.c:73
 msgid "slot"
-msgstr ""
+msgstr "настройка"
 
-#: builtin/config.c:73
+#: builtin/config.c:72
 msgid "find the color configured: [default]"
-msgstr ""
+msgstr "извеждане на зададения цвят на настройката: [стандартно]"
 
-#: builtin/config.c:74
+#: builtin/config.c:73
 msgid "find the color setting: [stdout-is-tty]"
 msgstr ""
+"извеждане на зададения цвят на настройката: [стандартният изход е терминал]"
 
-#: builtin/config.c:75
+#: builtin/config.c:74
 msgid "Type"
-msgstr ""
+msgstr "Вид"
 
-#: builtin/config.c:76
+#: builtin/config.c:75
 msgid "value is \"true\" or \"false\""
-msgstr ""
+msgstr "СТОЙНОСТТА е „true“ (истина) или „false“ (лъжа)"
 
-#: builtin/config.c:77
+#: builtin/config.c:76
 msgid "value is decimal number"
-msgstr ""
+msgstr "СТОЙНОСТТА е цяло, десетично число"
 
-#: builtin/config.c:78
+#: builtin/config.c:77
 msgid "value is --bool or --int"
-msgstr ""
+msgstr "СТОЙНОСТТА е „--bool“ (булева) или „--int“ (десетично цяло число)"
 
-#: builtin/config.c:79
+#: builtin/config.c:78
 msgid "value is a path (file or directory name)"
-msgstr ""
+msgstr "СТОЙНОСТТА е път (до файл или директория)"
 
-#: builtin/config.c:80
+#: builtin/config.c:79
 msgid "Other"
-msgstr ""
+msgstr "Други"
 
-#: builtin/config.c:81
+# FIXME NUL byte to null char, terminate -> razdelitel - da stane ednakvo
+#: builtin/config.c:80
 msgid "terminate values with NUL byte"
-msgstr ""
+msgstr "разделяне на стойностите с нулевия знак „NUL“"
 
-#: builtin/config.c:82
+#: builtin/config.c:81
 msgid "respect include directives on lookup"
-msgstr ""
+msgstr "при търсене да се уважат и директивите за включване"
 
 #: builtin/count-objects.c:82
 msgid "git count-objects [-v] [-H | --human-readable]"
-msgstr ""
+msgstr "git count-objects [-v] [-H | --human-readable]"
 
 #: builtin/count-objects.c:97
 msgid "print sizes in human readable format"
-msgstr ""
+msgstr "извеждане на размерите на обектите във формат лесно четим от хора"
 
+# FIXME ... instead of *???
 #: builtin/describe.c:16
 msgid "git describe [options] <commit-ish>*"
-msgstr ""
+msgstr "git describe [ОПЦИИ] указател към подаване…"
 
 #: builtin/describe.c:17
 msgid "git describe [options] --dirty"
 msgstr ""
 
-#: builtin/describe.c:237
+#: builtin/describe.c:225
 #, c-format
 msgid "annotated tag %s not available"
 msgstr ""
 
-#: builtin/describe.c:241
+#: builtin/describe.c:229
 #, c-format
 msgid "annotated tag %s has no embedded name"
 msgstr ""
 
-#: builtin/describe.c:243
+#: builtin/describe.c:231
 #, c-format
 msgid "tag '%s' is really '%s' here"
 msgstr ""
 
-#: builtin/describe.c:270
+#: builtin/describe.c:258
 #, c-format
 msgid "Not a valid object name %s"
 msgstr ""
 
-#: builtin/describe.c:273
+#: builtin/describe.c:261
 #, c-format
 msgid "%s is not a valid '%s' object"
 msgstr ""
 
-#: builtin/describe.c:290
+#: builtin/describe.c:278
 #, c-format
 msgid "no tag exactly matches '%s'"
 msgstr ""
 
-#: builtin/describe.c:292
+#: builtin/describe.c:280
 #, c-format
 msgid "searching to describe %s\n"
 msgstr ""
 
-#: builtin/describe.c:332
+#: builtin/describe.c:327
 #, c-format
 msgid "finished search at %s\n"
 msgstr ""
 
-#: builtin/describe.c:359
+#: builtin/describe.c:354
 #, c-format
 msgid ""
 "No annotated tags can describe '%s'.\n"
 "However, there were unannotated tags: try --tags."
 msgstr ""
 
-#: builtin/describe.c:363
+#: builtin/describe.c:358
 #, c-format
 msgid ""
 "No tags can describe '%s'.\n"
 "Try --always, or create some tags."
 msgstr ""
 
-#: builtin/describe.c:384
+#: builtin/describe.c:379
 #, c-format
 msgid "traversed %lu commits\n"
 msgstr ""
 
-#: builtin/describe.c:387
+#: builtin/describe.c:382
 #, c-format
 msgid ""
 "more than %i tags found; listed %i most recent\n"
 "gave up search at %s\n"
 msgstr ""
 
-#: builtin/describe.c:409
+#: builtin/describe.c:404
 msgid "find the tag that comes after the commit"
 msgstr ""
 
-#: builtin/describe.c:410
+#: builtin/describe.c:405
 msgid "debug search strategy on stderr"
 msgstr ""
 
-#: builtin/describe.c:411
+#: builtin/describe.c:406
 msgid "use any ref"
 msgstr ""
 
-#: builtin/describe.c:412
+#: builtin/describe.c:407
 msgid "use any tag, even unannotated"
 msgstr ""
 
-#: builtin/describe.c:413
+#: builtin/describe.c:408
 msgid "always use long format"
 msgstr ""
 
-#: builtin/describe.c:414
+#: builtin/describe.c:409
 msgid "only follow first parent"
 msgstr ""
 
-#: builtin/describe.c:417
+#: builtin/describe.c:412
 msgid "only output exact matches"
 msgstr ""
 
-#: builtin/describe.c:419
-#, fuzzy
+#: builtin/describe.c:414
 msgid "consider <n> most recent tags (default: 10)"
-msgstr "<брой>"
+msgstr "да се търси само в този БРОЙ последни етикети (стандартно: 10)"
 
-#: builtin/describe.c:421
+#: builtin/describe.c:416
 msgid "only consider tags matching <pattern>"
 msgstr ""
 
-#: builtin/describe.c:423 builtin/name-rev.c:321
+#: builtin/describe.c:418 builtin/name-rev.c:321
 msgid "show abbreviated commit object as fallback"
 msgstr ""
 
-#: builtin/describe.c:424
+#: builtin/describe.c:419
 msgid "mark"
 msgstr ""
 
-#: builtin/describe.c:425
+#: builtin/describe.c:420
 msgid "append <mark> on dirty working tree (default: \"-dirty\")"
 msgstr ""
 
-#: builtin/describe.c:443
+#: builtin/describe.c:438
 msgid "--long is incompatible with --abbrev=0"
 msgstr ""
 
-#: builtin/describe.c:469
+#: builtin/describe.c:464
 msgid "No names found, cannot describe anything."
 msgstr ""
 
-#: builtin/describe.c:489
+#: builtin/describe.c:484
 msgid "--dirty is incompatible with commit-ishes"
-msgstr ""
+msgstr "опцията „--dirty“ е несъвместима с указател към подаване"
 
 #: builtin/diff.c:85
 #, c-format
 msgid "'%s': not a regular file or symlink"
-msgstr ""
+msgstr "„%s“: не е нито обикновен файл, нито символна връзка"
 
 #: builtin/diff.c:236
 #, c-format
 msgid "invalid option: %s"
-msgstr ""
+msgstr "неправилна опция: %s"
 
 #: builtin/diff.c:357
 msgid "Not a git repository"
-msgstr ""
+msgstr "Не е хранилище на Git"
 
 #: builtin/diff.c:400
 #, c-format
 msgid "invalid object '%s' given."
-msgstr ""
+msgstr "зададен е неправилен обект „%s“."
 
 #: builtin/diff.c:409
 #, c-format
 msgid "more than two blobs given: '%s'"
-msgstr ""
+msgstr "зададени са повече от 2 обекта: „%s“"
 
 #: builtin/diff.c:416
 #, c-format
 msgid "unhandled object '%s' given."
-msgstr ""
+msgstr "зададен е неподдържан обект „%s“."
 
 #: builtin/fast-export.c:22
 msgid "git fast-export [rev-list-opts]"
 msgstr ""
 
 #: builtin/fast-export.c:673
-#, fuzzy
 msgid "show progress after <n> objects"
-msgstr "<брой>"
+msgstr "съобщение за напредъка на всеки такъв БРОЙ обекта"
 
 #: builtin/fast-export.c:675
 msgid "select handling of signed tags"
@@ -4865,165 +5058,168 @@ msgstr ""
 
 #: builtin/fetch.c:20
 msgid "git fetch [<options>] [<repository> [<refspec>...]]"
-msgstr ""
+msgstr "git fetch [ОПЦИИ] [ХРАНИЛИЩЕ [УКАЗАТЕЛ…]]"
 
 #: builtin/fetch.c:21
 msgid "git fetch [<options>] <group>"
-msgstr ""
+msgstr "git fetch [ОПЦИИ] ГРУПА"
 
 #: builtin/fetch.c:22
 msgid "git fetch --multiple [<options>] [(<repository> | <group>)...]"
-msgstr ""
+msgstr "git fetch --multiple [ОПЦИИ] [(ХРАНИЛИЩЕ | ГРУПА)…]"
 
 #: builtin/fetch.c:23
 msgid "git fetch --all [<options>]"
-msgstr ""
+msgstr "git fetch --all [ОПЦИИ]"
 
 #: builtin/fetch.c:75
 msgid "fetch from all remotes"
-msgstr ""
+msgstr "доставяне от всички отдалечени хранилища"
 
 #: builtin/fetch.c:77
 msgid "append to .git/FETCH_HEAD instead of overwriting"
-msgstr ""
+msgstr "добавяне към вместо замяна на „.git/FETCH_HEAD“"
 
 #: builtin/fetch.c:79
 msgid "path to upload pack on remote end"
-msgstr ""
+msgstr "отдалечен път, където да се качи пакетът"
 
 #: builtin/fetch.c:80
 msgid "force overwrite of local branch"
-msgstr ""
+msgstr "принудително презаписване на локалния клон"
 
 #: builtin/fetch.c:82
 msgid "fetch from multiple remotes"
-msgstr ""
+msgstr "доставяне от множество отдалечени хранилища"
 
 #: builtin/fetch.c:84
 msgid "fetch all tags and associated objects"
-msgstr ""
+msgstr "доставяне на всички етикети и принадлежащи обекти"
 
 #: builtin/fetch.c:86
 msgid "do not fetch all tags (--no-tags)"
-msgstr ""
+msgstr "без доставянето на всички етикети „--no-tags“"
 
 #: builtin/fetch.c:88
 msgid "prune remote-tracking branches no longer on remote"
-msgstr ""
+msgstr "окастряне на клоните следящи вече не съществуващи отдалечени клони"
 
 #: builtin/fetch.c:89
 msgid "on-demand"
-msgstr ""
+msgstr "при нужда"
 
 #: builtin/fetch.c:90
 msgid "control recursive fetching of submodules"
-msgstr ""
+msgstr "управление на рекурсивното доставяне на подмодулите"
 
 #: builtin/fetch.c:94
 msgid "keep downloaded pack"
-msgstr ""
+msgstr "запазване на изтеглените пакети с обекти"
 
 #: builtin/fetch.c:96
 msgid "allow updating of HEAD ref"
-msgstr ""
+msgstr "позволяване на обновяването на указателя „HEAD“"
 
 #: builtin/fetch.c:99
 msgid "deepen history of shallow clone"
-msgstr ""
+msgstr "задълбочаване на историята на плитко хранилище"
 
 #: builtin/fetch.c:101
 msgid "convert to a complete repository"
-msgstr ""
+msgstr "превръщане в пълно хранилище"
 
 #: builtin/fetch.c:103 builtin/log.c:1197
 msgid "dir"
-msgstr ""
+msgstr "директория"
 
 #: builtin/fetch.c:104
 msgid "prepend this to submodule path output"
-msgstr ""
+msgstr "добавяне на това пред пътя на подмодула"
 
 #: builtin/fetch.c:107
 msgid "default mode for recursion"
-msgstr ""
+msgstr "стандартен режим на рекурсия"
 
 #: builtin/fetch.c:109
 msgid "accept refs that update .git/shallow"
-msgstr ""
+msgstr "приемане на указатели, които обновяват „.git/shallow“"
 
 #: builtin/fetch.c:347
 msgid "Couldn't find remote ref HEAD"
-msgstr ""
+msgstr "Указателят „HEAD“ в отдалеченото хранилище не може да бъде открит"
 
 #: builtin/fetch.c:411
 #, c-format
 msgid "object %s not found"
-msgstr ""
+msgstr "обектът „%s“ липсва"
 
 #: builtin/fetch.c:416
 msgid "[up to date]"
-msgstr ""
+msgstr "[актуализиран]"
 
+# FIXME - the signs
 #: builtin/fetch.c:430
 #, c-format
 msgid "! %-*s %-*s -> %s  (can't fetch in current branch)"
-msgstr ""
+msgstr "! %-*s %-*s -> %s  (в текущия клон не може да се доставя)"
 
 #: builtin/fetch.c:431 builtin/fetch.c:517
 msgid "[rejected]"
-msgstr ""
+msgstr "[отхвърлен]"
 
 #: builtin/fetch.c:442
 msgid "[tag update]"
-msgstr ""
+msgstr "[обновяване на етикетите]"
 
 #: builtin/fetch.c:444 builtin/fetch.c:479 builtin/fetch.c:497
 msgid "  (unable to update local ref)"
-msgstr ""
+msgstr "  (локалните указатели не могат да бъдат обновени)"
 
 #: builtin/fetch.c:462
 msgid "[new tag]"
-msgstr ""
+msgstr "[нов етикет]"
 
 #: builtin/fetch.c:465
 msgid "[new branch]"
-msgstr ""
+msgstr "[нов клон]"
 
 #: builtin/fetch.c:468
 msgid "[new ref]"
-msgstr ""
+msgstr "[нов указател]"
 
 #: builtin/fetch.c:513
 msgid "unable to update local ref"
-msgstr ""
+msgstr "локален указател не може да бъде обновен"
 
 #: builtin/fetch.c:513
 msgid "forced update"
-msgstr ""
+msgstr "принудително обновяване"
 
 #: builtin/fetch.c:519
 msgid "(non-fast-forward)"
-msgstr ""
+msgstr "(сливането не е тривиално)"
 
 #: builtin/fetch.c:552 builtin/fetch.c:785
 #, c-format
 msgid "cannot open %s: %s\n"
-msgstr ""
+msgstr "файлът „%s“ не може да бъде отворен: %s\n"
 
 #: builtin/fetch.c:561
 #, c-format
 msgid "%s did not send all necessary objects\n"
-msgstr ""
+msgstr "хранилището „%s“ не изпрати всички необходими обекти\n"
 
 #: builtin/fetch.c:579
 #, c-format
 msgid "reject %s because shallow roots are not allowed to be updated"
 msgstr ""
+"отхвърляне на върха „%s“, защото плитките хранилища не могат да бъдат "
+"обновявани"
 
 #: builtin/fetch.c:667 builtin/fetch.c:750
 #, c-format
 msgid "From %.*s\n"
-msgstr ""
+msgstr "От %.*s\n"
 
 #: builtin/fetch.c:678
 #, c-format
@@ -5031,20 +5227,23 @@ msgid ""
 "some local refs could not be updated; try running\n"
 " 'git remote prune %s' to remove any old, conflicting branches"
 msgstr ""
+"някои локални указатели не могат да бъдат обновени. Изпълнете командата\n"
+"  „git remote prune %s“, за да премахнете остарелите клони, които "
+"предизвикват конфликта"
 
 #: builtin/fetch.c:730
 #, c-format
 msgid "   (%s will become dangling)"
-msgstr ""
+msgstr "   (обектът „%s“ ще се окаже извън клон)"
 
 #: builtin/fetch.c:731
 #, c-format
 msgid "   (%s has become dangling)"
-msgstr ""
+msgstr "   (обектът „%s“ вече е извън клон)"
 
 #: builtin/fetch.c:755
 msgid "[deleted]"
-msgstr ""
+msgstr "[изтрит]"
 
 #: builtin/fetch.c:756 builtin/remote.c:1050
 msgid "(none)"
@@ -5054,98 +5253,103 @@ msgstr "(нищо)"
 #, c-format
 msgid "Refusing to fetch into current branch %s of non-bare repository"
 msgstr ""
+"Не може да изтегляте в текущия клон „%s“, на хранилище, което не е голо"
 
 #: builtin/fetch.c:794
 #, c-format
 msgid "Option \"%s\" value \"%s\" is not valid for %s"
-msgstr ""
+msgstr "Стойността „%2$s“ за опцията „%1$s“ не е съвместима с „%3$s“"
 
 #: builtin/fetch.c:797
 #, c-format
 msgid "Option \"%s\" is ignored for %s\n"
-msgstr ""
+msgstr "Опцията „%s“ се игнорира при „%s“\n"
 
 #: builtin/fetch.c:853
 #, c-format
 msgid "Don't know how to fetch from %s"
-msgstr ""
+msgstr "Не се поддържа доставяне от „%s“"
 
 #: builtin/fetch.c:1015
 #, c-format
 msgid "Fetching %s\n"
-msgstr ""
+msgstr "Доставяне на „%s“\n"
 
 #: builtin/fetch.c:1017 builtin/remote.c:90
 #, c-format
 msgid "Could not fetch %s"
 msgstr "„%s“ не може да се достави"
 
-#: builtin/fetch.c:1036
+#: builtin/fetch.c:1035
 msgid ""
 "No remote repository specified.  Please, specify either a URL or a\n"
 "remote name from which new revisions should be fetched."
 msgstr ""
+"Не сте указали отдалечено хранилище. Задайте или адрес, или име\n"
+"на отдалечено хранилище, от където да се доставят новите версии."
 
 #: builtin/fetch.c:1059
 msgid "You need to specify a tag name."
-msgstr ""
+msgstr "Трябва да укажете име на етикет."
 
 #: builtin/fetch.c:1107
 msgid "--depth and --unshallow cannot be used together"
-msgstr ""
+msgstr "опциите „--depth“ и „--unshallow“ са несъвместими"
 
 #: builtin/fetch.c:1109
 msgid "--unshallow on a complete repository does not make sense"
-msgstr ""
+msgstr "не можете да използвате опцията „--unshallow“ върху пълно хранилище"
 
 #: builtin/fetch.c:1132
 msgid "fetch --all does not take a repository argument"
-msgstr ""
+msgstr "към „git fetch --all“ не можете да добавите хранилище аргумент"
 
 #: builtin/fetch.c:1134
 msgid "fetch --all does not make sense with refspecs"
 msgstr ""
+"към „git fetch --all“ не можете да добавите указател на версия за аргумент"
 
 #: builtin/fetch.c:1145
 #, c-format
 msgid "No such remote or remote group: %s"
-msgstr ""
+msgstr "Няма нито отдалечено хранилище, нито група от хранилища на име „%s“"
 
 #: builtin/fetch.c:1153
 msgid "Fetching a group and specifying refspecs does not make sense"
-msgstr ""
+msgstr "Указването на група и указването на версия са несъвместими"
 
 #: builtin/fmt-merge-msg.c:13
-#, fuzzy
 msgid "git fmt-merge-msg [-m <message>] [--log[=<n>]|--no-log] [--file <file>]"
-msgstr "<брой>"
+msgstr "git fmt-merge-msg [-m СЪОБЩЕНИЕ] [--log[=БРОЙ]|--no-log] [--file ФАЙЛ]"
 
-#: builtin/fmt-merge-msg.c:663 builtin/fmt-merge-msg.c:666 builtin/grep.c:702
-#: builtin/merge.c:196 builtin/show-branch.c:654 builtin/show-ref.c:178
-#: builtin/tag.c:446 parse-options.h:135 parse-options.h:242
+#: builtin/fmt-merge-msg.c:663 builtin/fmt-merge-msg.c:666 builtin/grep.c:700
+#: builtin/merge.c:196 builtin/repack.c:175 builtin/repack.c:179
+#: builtin/show-branch.c:654 builtin/show-ref.c:178 builtin/tag.c:501
+#: parse-options.h:132 parse-options.h:239
 msgid "n"
-msgstr "бÑ\80ой"
+msgstr "Ð\91РÐ\9eÐ\99"
 
 #: builtin/fmt-merge-msg.c:664
-#, fuzzy
 msgid "populate log with at most <n> entries from shortlog"
-msgstr "<брой>"
+msgstr ""
+"вмъкване на журнал състоящ се от не повече от БРОЙ записа от съкратения "
+"журнал"
 
 #: builtin/fmt-merge-msg.c:667
 msgid "alias for --log (deprecated)"
-msgstr ""
+msgstr "синоним на „--log“ (остаряло)"
 
 #: builtin/fmt-merge-msg.c:670
 msgid "text"
-msgstr ""
+msgstr "ТЕКСТ"
 
 #: builtin/fmt-merge-msg.c:671
 msgid "use <text> as start of message"
-msgstr ""
+msgstr "за начало на съобщението да се ползва ТЕКСТ"
 
 #: builtin/fmt-merge-msg.c:672
 msgid "file to read from"
-msgstr ""
+msgstr "файл, от който да се чете"
 
 #: builtin/for-each-ref.c:1063
 msgid "git for-each-ref [options] [<pattern>]"
@@ -5168,17 +5372,16 @@ msgid "quote placeholders suitably for tcl"
 msgstr ""
 
 #: builtin/for-each-ref.c:1087
-#, fuzzy
 msgid "show only <n> matched refs"
-msgstr "<брой>"
+msgstr "извеждане само на този БРОЙ напаснати указатели"
 
 #: builtin/for-each-ref.c:1088 builtin/replace.c:177
 msgid "format"
-msgstr ""
+msgstr "ФОРМАТ"
 
 #: builtin/for-each-ref.c:1088
 msgid "format to use for the output"
-msgstr ""
+msgstr "ФОРМАТ за изхода"
 
 #: builtin/for-each-ref.c:1089
 msgid "key"
@@ -5188,9 +5391,17 @@ msgstr ""
 msgid "field name to sort on"
 msgstr ""
 
+#: builtin/fsck.c:147 builtin/prune.c:172
+msgid "Checking connectivity"
+msgstr "Проверка на връзката"
+
+#: builtin/fsck.c:544
+msgid "Checking object directories"
+msgstr "Проверка на директориите с обекти"
+
 #: builtin/fsck.c:607
 msgid "git fsck [options] [<object>...]"
-msgstr "git fsck [ОПЦИИ] [<ОБЕКТ>…]"
+msgstr "git fsck [ОПЦИИ] [ОБЕКТ…]"
 
 #: builtin/fsck.c:613
 msgid "show unreachable objects"
@@ -5212,13 +5423,12 @@ msgstr "показване на кореновите възли"
 msgid "make index objects head nodes"
 msgstr "задаване на обекти от индекса да са коренови"
 
+# FIXME bad message
 #: builtin/fsck.c:618
-#, fuzzy
 msgid "make reflogs head nodes (default)"
 msgstr "проследяване на указателите от журнала като глави (стандартно)"
 
 #: builtin/fsck.c:619
-#, fuzzy
 msgid "also consider packs and alternate objects"
 msgstr "допълнително да се проверяват пакетите и алтернативните обекти"
 
@@ -5234,51 +5444,61 @@ msgstr "запазване на обектите извън клоните в д
 msgid "show progress"
 msgstr "показване на напредъка"
 
+#: builtin/fsck.c:673
+msgid "Checking objects"
+msgstr "Проверка на обектите"
+
 #: builtin/gc.c:24
 msgid "git gc [options]"
 msgstr "git gc [ОПЦИИ]"
 
-#: builtin/gc.c:80
+#: builtin/gc.c:90
 #, c-format
 msgid "Invalid %s: '%s'"
 msgstr "Неправилна стойност за „%s“: „%s“"
 
-#: builtin/gc.c:107
+#: builtin/gc.c:117
 #, c-format
 msgid "insanely long object directory %.*s"
 msgstr "прекалено дълга директория с обекти „%.*s“"
 
-#: builtin/gc.c:262
+#: builtin/gc.c:273
 msgid "prune unreferenced objects"
 msgstr "окастряне на обектите, към които нищо не сочи"
 
-#: builtin/gc.c:264
+#: builtin/gc.c:275
 msgid "be more thorough (increased runtime)"
 msgstr "изчерпателно търсене на боклука (за сметка на повече време работа)"
 
-#: builtin/gc.c:265
+#: builtin/gc.c:276
 msgid "enable auto-gc mode"
 msgstr "включване на автоматичното събиране на боклука (auto-gc)"
 
-#: builtin/gc.c:266
+#: builtin/gc.c:277
 msgid "force running gc even if there may be another gc running"
 msgstr ""
 "изрично стартиране на събирането на боклука, дори и ако вече работи друго "
 "събиране"
 
-#: builtin/gc.c:306
+#: builtin/gc.c:318
 #, c-format
-msgid ""
-"Auto packing the repository for optimum performance. You may also\n"
-"run \"git gc\" manually. See \"git help gc\" for more information.\n"
+msgid "Auto packing the repository in background for optimum performance.\n"
 msgstr ""
-"Автоматично пакетиране на хранилището за най-добра производителност. Можете "
-"и\n"
-"ръчно да стартирате „git gc“. За подробности погледнете помощта: „git help "
-"gc“.\n"
+"Автоматично пакетиране на заден фон на хранилището за по-добра "
+"производителност.\n"
 
-#. be quiet on --auto
-#: builtin/gc.c:316
+#: builtin/gc.c:320
+#, c-format
+msgid "Auto packing the repository for optimum performance.\n"
+msgstr "Автоматично пакетиране на хранилището за по-добра производителност.\n"
+
+#: builtin/gc.c:321
+#, c-format
+msgid "See \"git help gc\" for manual housekeeping.\n"
+msgstr ""
+"Вижте ръководството за повече информация как да изпълните „git help gc“.\n"
+
+#: builtin/gc.c:336
 #, c-format
 msgid ""
 "gc is already running on machine '%s' pid %<PRIuMAX> (use --force if not)"
@@ -5287,7 +5507,7 @@ msgstr ""
 "процеса: %<PRIuMAX> (ако сте сигурни, че това не е вярно, това използвайте\n"
 "опцията „--force“)"
 
-#: builtin/gc.c:341
+#: builtin/gc.c:361
 msgid ""
 "There are too many unreachable loose objects; run 'git prune' to remove them."
 msgstr ""
@@ -5297,236 +5517,248 @@ msgstr ""
 
 #: builtin/grep.c:23
 msgid "git grep [options] [-e] <pattern> [<rev>...] [[--] <path>...]"
-msgstr ""
+msgstr "git grep [ОПЦИИ] [-e] ШАБЛОН [ВЕРСИЯ…] [[--] ПЪТ…]"
 
 #: builtin/grep.c:218
 #, c-format
 msgid "grep: failed to create thread: %s"
-msgstr ""
+msgstr "grep: неуспешно създаване на нишка: %s"
 
 #: builtin/grep.c:365
 #, c-format
 msgid "Failed to chdir: %s"
-msgstr ""
+msgstr "Неуспешна смяна на директория: %s"
 
 #: builtin/grep.c:443 builtin/grep.c:478
 #, c-format
 msgid "unable to read tree (%s)"
-msgstr ""
+msgstr "дървото не може да бъде прочетено (%s)"
 
 #: builtin/grep.c:493
 #, c-format
 msgid "unable to grep from object of type %s"
-msgstr ""
+msgstr "не може да се изпълни „grep“ от обект от вида %s"
 
-#: builtin/grep.c:551
+#: builtin/grep.c:549
 #, c-format
 msgid "switch `%c' expects a numerical value"
-msgstr ""
+msgstr "опцията „%c“ очаква число за аргумент"
 
-#: builtin/grep.c:568
+#: builtin/grep.c:566
 #, c-format
 msgid "cannot open '%s'"
-msgstr ""
+msgstr "„%s“ не може да бъде отворен"
 
-#: builtin/grep.c:642
+#: builtin/grep.c:640
 msgid "search in index instead of in the work tree"
-msgstr ""
+msgstr "търсене в индекса, а не в работното дърво"
 
-#: builtin/grep.c:644
+#: builtin/grep.c:642
 msgid "find in contents not managed by git"
-msgstr ""
+msgstr "търсене и във файловете, които не са под управлението на git"
 
-#: builtin/grep.c:646
+#: builtin/grep.c:644
 msgid "search in both tracked and untracked files"
-msgstr ""
+msgstr "търсене и в следените, и в неследените файлове"
 
-#: builtin/grep.c:648
+#: builtin/grep.c:646
 msgid "search also in ignored files"
-msgstr ""
+msgstr "търсене и в игнорираните файлове"
 
-#: builtin/grep.c:651
+#: builtin/grep.c:649
 msgid "show non-matching lines"
-msgstr ""
+msgstr "извеждане на редовете, които не съвпадат"
 
-#: builtin/grep.c:653
+#: builtin/grep.c:651
 msgid "case insensitive matching"
-msgstr ""
+msgstr "без значение на регистъра на буквите (главни/малки)"
 
-#: builtin/grep.c:655
+#: builtin/grep.c:653
 msgid "match patterns only at word boundaries"
-msgstr ""
+msgstr "напасване на шаблоните само по границите на думите"
 
-#: builtin/grep.c:657
+#: builtin/grep.c:655
 msgid "process binary files as text"
-msgstr ""
+msgstr "обработване на двоичните файлове като текстови"
 
-#: builtin/grep.c:659
+#: builtin/grep.c:657
 msgid "don't match patterns in binary files"
-msgstr ""
+msgstr "прескачане на двоичните файлове"
 
-#: builtin/grep.c:662
+#: builtin/grep.c:660
 msgid "process binary files with textconv filters"
 msgstr ""
+"обработване на двоичните файлове чрез филтри за преобразуване към текст"
 
-#: builtin/grep.c:664
+#: builtin/grep.c:662
 msgid "descend at most <depth> levels"
-msgstr ""
+msgstr "навлизане максимално на тази ДЪЛБОЧИНА в дървото"
 
-#: builtin/grep.c:668
+#: builtin/grep.c:666
 msgid "use extended POSIX regular expressions"
-msgstr ""
+msgstr "разширени регулярни изрази по POSIX"
 
-#: builtin/grep.c:671
+#: builtin/grep.c:669
 msgid "use basic POSIX regular expressions (default)"
-msgstr ""
+msgstr "основни регулярни изрази по POSIX (стандартно)"
 
-#: builtin/grep.c:674
+#: builtin/grep.c:672
 msgid "interpret patterns as fixed strings"
-msgstr ""
+msgstr "шаблоните са дословни низове"
 
-#: builtin/grep.c:677
+#: builtin/grep.c:675
 msgid "use Perl-compatible regular expressions"
-msgstr ""
+msgstr "регулярни изрази на Perl"
 
-#: builtin/grep.c:680
+#: builtin/grep.c:678
 msgid "show line numbers"
-msgstr ""
+msgstr "извеждане на номерата на редовете"
 
-#: builtin/grep.c:681
+#: builtin/grep.c:679
 msgid "don't show filenames"
-msgstr ""
+msgstr "без извеждане на имената на файловете"
 
-#: builtin/grep.c:682
+#: builtin/grep.c:680
 msgid "show filenames"
-msgstr ""
+msgstr "извеждане на имената на файловете"
 
-#: builtin/grep.c:684
+#: builtin/grep.c:682
 msgid "show filenames relative to top directory"
 msgstr ""
+"извеждане на относителните имена на файловете спрямо основната директория на "
+"хранилището"
 
-#: builtin/grep.c:686
+#: builtin/grep.c:684
 msgid "show only filenames instead of matching lines"
-msgstr ""
+msgstr "извеждане само на имената на файловете без напасващите редове"
 
-#: builtin/grep.c:688
+#: builtin/grep.c:686
 msgid "synonym for --files-with-matches"
-msgstr ""
+msgstr "синоним на „--files-with-matches“"
 
-#: builtin/grep.c:691
+#: builtin/grep.c:689
 msgid "show only the names of files without match"
 msgstr ""
+"извеждане само на имената на файловете, които не съдържат ред, напасващ на "
+"шаблона"
 
-#: builtin/grep.c:693
+#: builtin/grep.c:691
 msgid "print NUL after filenames"
-msgstr ""
+msgstr "извеждане на нулевия знак „NUL“ след всяко име на файл"
 
-#: builtin/grep.c:695
+#: builtin/grep.c:693
 msgid "show the number of matches instead of matching lines"
-msgstr ""
+msgstr "извеждане на броя на съвпаденията вместо напасващите редове"
 
-#: builtin/grep.c:696
+#: builtin/grep.c:694
 msgid "highlight matches"
-msgstr ""
+msgstr "оцветяване на напасванията"
 
-#: builtin/grep.c:698
+#: builtin/grep.c:696
 msgid "print empty line between matches from different files"
-msgstr ""
+msgstr "извеждане на празен ред между напасванията от различни файлове"
 
-#: builtin/grep.c:700
+#: builtin/grep.c:698
 msgid "show filename only once above matches from same file"
 msgstr ""
+"извеждане на името на файла само веднъж за всички напасвания от този файл"
 
-#: builtin/grep.c:703
-#, fuzzy
+#: builtin/grep.c:701
 msgid "show <n> context lines before and after matches"
-msgstr "<брой>"
+msgstr "извеждане на такъв БРОЙ редове преди и след напасванията"
 
-#: builtin/grep.c:706
-#, fuzzy
+#: builtin/grep.c:704
 msgid "show <n> context lines before matches"
-msgstr "<брой>"
+msgstr "извеждане на такъв БРОЙ редове преди напасванията"
 
-#: builtin/grep.c:708
-#, fuzzy
+#: builtin/grep.c:706
 msgid "show <n> context lines after matches"
-msgstr "<брой>"
+msgstr "извеждане на такъв БРОЙ редове след напасванията"
 
-#: builtin/grep.c:709
+#: builtin/grep.c:707
 msgid "shortcut for -C NUM"
-msgstr ""
+msgstr "синоним на „-C БРОЙ“"
 
-#: builtin/grep.c:712
+#: builtin/grep.c:710
 msgid "show a line with the function name before matches"
-msgstr ""
+msgstr "извеждане на ред с името на функцията, в която е напаснат шаблона"
 
-#: builtin/grep.c:714
+#: builtin/grep.c:712
 msgid "show the surrounding function"
-msgstr ""
+msgstr "извеждане на обхващащата функция"
 
-#: builtin/grep.c:717
+#: builtin/grep.c:715
 msgid "read patterns from file"
-msgstr ""
+msgstr "изчитане на шаблоните от файл"
 
-#: builtin/grep.c:719
+#: builtin/grep.c:717
 msgid "match <pattern>"
-msgstr ""
+msgstr "напасване на ШАБЛОН"
 
-#: builtin/grep.c:721
+#: builtin/grep.c:719
 msgid "combine patterns specified with -e"
-msgstr ""
+msgstr "комбиниране на шаблоните указани с опцията „-e“"
 
-#: builtin/grep.c:733
+#: builtin/grep.c:731
 msgid "indicate hit with exit status without output"
 msgstr ""
+"без извеждане на стандартния изход. Изходният код указва наличието на "
+"напасване"
 
-#: builtin/grep.c:735
+#: builtin/grep.c:733
 msgid "show only matches from files that match all patterns"
 msgstr ""
+"извеждане на редове само от файловете, които напасват на всички шаблони"
 
-#: builtin/grep.c:737
+#: builtin/grep.c:735
 msgid "show parse tree for grep expression"
-msgstr ""
+msgstr "извеждане на дървото за анализ на регулярния израз"
 
-#: builtin/grep.c:741
+#: builtin/grep.c:739
 msgid "pager"
-msgstr ""
+msgstr "програма за обхождане"
 
-#: builtin/grep.c:741
+#: builtin/grep.c:739
 msgid "show matching files in the pager"
-msgstr ""
+msgstr "извеждане на съвпадащите файлове в програма за обхождане"
 
-#: builtin/grep.c:744
+#: builtin/grep.c:742
 msgid "allow calling of grep(1) (ignored by this build)"
 msgstr ""
+"позволяване на стартирането на grep(1) (текущият компилат пренебрегва тази "
+"опция)"
 
-#: builtin/grep.c:745 builtin/show-ref.c:187
+#: builtin/grep.c:743 builtin/show-ref.c:187
 msgid "show usage"
-msgstr ""
+msgstr "извеждане на начина на употреба на командата"
 
-#: builtin/grep.c:812
+#: builtin/grep.c:810
 msgid "no pattern given."
-msgstr ""
+msgstr "липсва шаблон."
 
-#: builtin/grep.c:870
+#: builtin/grep.c:868
 msgid "--open-files-in-pager only works on the worktree"
 msgstr ""
+"опцията „--open-files-in-pager“ е съвместима само с търсене в работното дърво"
 
-#: builtin/grep.c:893
+#: builtin/grep.c:891
 msgid "--cached or --untracked cannot be used with --no-index."
-msgstr ""
+msgstr "опциите „--cached“ и „--untracked“ са несъвместими с „--no-index“."
 
-#: builtin/grep.c:898
+#: builtin/grep.c:896
 msgid "--no-index or --untracked cannot be used with revs."
 msgstr ""
+"опциите „--cached“ и „--untracked“ са несъвместими с търсене във версии."
 
-#: builtin/grep.c:901
+#: builtin/grep.c:899
 msgid "--[no-]exclude-standard cannot be used for tracked contents."
 msgstr ""
+"опциите „--(no-)exclude-standard“ са несъвместими с търсене по следени "
+"файлове."
 
-#: builtin/grep.c:909
+#: builtin/grep.c:907
 msgid "both --cached and trees are given."
-msgstr ""
+msgstr "опцията „--cached“ е несъвместима със задаване на дърво."
 
 #: builtin/hash-object.c:60
 msgid ""
@@ -5538,7 +5770,7 @@ msgstr ""
 msgid "git hash-object  --stdin-paths < <list-of-paths>"
 msgstr ""
 
-#: builtin/hash-object.c:72
+#: builtin/hash-object.c:72 builtin/tag.c:521
 msgid "type"
 msgstr ""
 
@@ -5777,8 +6009,8 @@ msgstr ""
 msgid "SHA1 COLLISION FOUND WITH %s !"
 msgstr ""
 
-#: builtin/index-pack.c:669 builtin/pack-objects.c:171
-#: builtin/pack-objects.c:263
+#: builtin/index-pack.c:669 builtin/pack-objects.c:162
+#: builtin/pack-objects.c:254
 #, c-format
 msgid "unable to read %s"
 msgstr ""
@@ -5895,7 +6127,7 @@ msgstr ""
 
 #: builtin/index-pack.c:1325
 msgid "cannot store index file"
-msgstr ""
+msgstr "файлът за индекса не може да бъде съхранен"
 
 #: builtin/index-pack.c:1358
 #, c-format
@@ -6044,424 +6276,435 @@ msgstr ""
 msgid "unable to move %s to %s"
 msgstr ""
 
-#.
-#. * TRANSLATORS: The first '%s' is either "Reinitialized
-#. * existing" or "Initialized empty", the second " shared" or
-#. * "", and the last '%s%s' is the verbatim directory name.
-#.
-#: builtin/init-db.c:420
+#. TRANSLATORS: The first '%s' is either "Reinitialized
+#. existing" or "Initialized empty", the second " shared" or
+#. "", and the last '%s%s' is the verbatim directory name.
+#: builtin/init-db.c:418
 #, c-format
 msgid "%s%s Git repository in %s%s\n"
 msgstr ""
 
-#: builtin/init-db.c:421
+#: builtin/init-db.c:419
 msgid "Reinitialized existing"
 msgstr ""
 
-#: builtin/init-db.c:421
+#: builtin/init-db.c:419
 msgid "Initialized empty"
 msgstr ""
 
-#: builtin/init-db.c:422
+#: builtin/init-db.c:420
 msgid " shared"
 msgstr ""
 
-#: builtin/init-db.c:441
+#: builtin/init-db.c:439
 msgid "cannot tell cwd"
 msgstr ""
 
-#: builtin/init-db.c:467
+#: builtin/init-db.c:465
 msgid ""
 "git init [-q | --quiet] [--bare] [--template=<template-directory>] [--"
 "shared[=<permissions>]] [directory]"
 msgstr ""
 
-#: builtin/init-db.c:490
+#: builtin/init-db.c:488
 msgid "permissions"
 msgstr ""
 
-#: builtin/init-db.c:491
+#: builtin/init-db.c:489
 msgid "specify that the git repository is to be shared amongst several users"
 msgstr ""
 
-#: builtin/init-db.c:493 builtin/prune-packed.c:79 builtin/repack.c:155
+#: builtin/init-db.c:491 builtin/prune-packed.c:79 builtin/repack.c:168
 msgid "be quiet"
-msgstr ""
+msgstr "без извеждане на информация"
 
-#: builtin/init-db.c:522 builtin/init-db.c:529
+#: builtin/init-db.c:523 builtin/init-db.c:528
 #, c-format
 msgid "cannot mkdir %s"
 msgstr ""
 
-#: builtin/init-db.c:533
+#: builtin/init-db.c:532
 #, c-format
 msgid "cannot chdir to %s"
 msgstr ""
 
-#: builtin/init-db.c:555
+#: builtin/init-db.c:554
 #, c-format
 msgid ""
 "%s (or --work-tree=<directory>) not allowed without specifying %s (or --git-"
 "dir=<directory>)"
 msgstr ""
 
-#: builtin/init-db.c:579
+#: builtin/init-db.c:578
 msgid "Cannot access current working directory"
 msgstr ""
 
-#: builtin/init-db.c:586
+#: builtin/init-db.c:585
 #, c-format
 msgid "Cannot access work tree '%s'"
 msgstr ""
 
 #: builtin/log.c:41
 msgid "git log [<options>] [<revision range>] [[--] <path>...]\n"
-msgstr ""
+msgstr "git log [ОПЦИИ] [ДИАПАЗОН_НА_ВЕРСИИТЕ] [[--] ПЪТ…]\n"
 
 #: builtin/log.c:42
 msgid "   or: git show [options] <object>..."
-msgstr ""
+msgstr "   или: git show [ОПЦИИ] ОБЕКТ…"
 
 #: builtin/log.c:125
 msgid "suppress diff output"
-msgstr ""
+msgstr "без извеждане на разликите"
 
 #: builtin/log.c:126
 msgid "show source"
-msgstr ""
+msgstr "извеждане на изходния код"
 
 #: builtin/log.c:127
 msgid "Use mail map file"
 msgstr ""
+"Използване на файл за съответствията на имената и адресите на е-поща („."
+"mailmap“)"
 
 #: builtin/log.c:128
 msgid "decorate options"
-msgstr ""
+msgstr "настройки на форма̀та на извежданата информация"
 
 #: builtin/log.c:231
 #, c-format
 msgid "Final output: %d %s\n"
-msgstr ""
+msgstr "Резултат: %d %s\n"
 
 #: builtin/log.c:473 builtin/log.c:565
 #, c-format
 msgid "Could not read object %s"
-msgstr ""
+msgstr "Обектът не може да бъде прочетен: %s"
 
 #: builtin/log.c:589
 #, c-format
 msgid "Unknown type: %d"
-msgstr ""
+msgstr "Неизвестен вид: %d"
 
 #: builtin/log.c:689
 msgid "format.headers without value"
-msgstr ""
+msgstr "не е зададена стойност на „format.headers“"
 
 #: builtin/log.c:771
 msgid "name of output directory is too long"
-msgstr ""
+msgstr "прекалено дълго име на директорията за изходната информация"
 
 #: builtin/log.c:787
 #, c-format
 msgid "Cannot open patch file %s"
-msgstr ""
+msgstr "Файлът-кръпка „%s“ не може да бъде отворен"
 
 #: builtin/log.c:801
 msgid "Need exactly one range."
-msgstr ""
+msgstr "Трябва да зададете точно един диапазон."
 
 #: builtin/log.c:809
 msgid "Not a range."
-msgstr ""
+msgstr "Не е диапазон."
 
 #: builtin/log.c:911
 msgid "Cover letter needs email format"
-msgstr ""
+msgstr "Придружаващото писмо трябва да е форматирано като е-писмо"
 
 #: builtin/log.c:987
 #, c-format
 msgid "insane in-reply-to: %s"
-msgstr ""
+msgstr "неправилен формат на заглавната част  за отговор „in-reply-to“: %s"
 
 #: builtin/log.c:1015
 msgid "git format-patch [options] [<since> | <revision range>]"
-msgstr ""
+msgstr "git format-patch [ОПЦИИ] [ОТ | ДИАПАЗОН_НА_ВЕРСИИТЕ]"
 
+# FIXME message
 #: builtin/log.c:1060
 msgid "Two output directories?"
 msgstr ""
+"Можете да укажете максимум една директория за изход, а сте задали поне две."
 
 #: builtin/log.c:1175
 msgid "use [PATCH n/m] even with a single patch"
-msgstr ""
+msgstr "номерация „[PATCH n/m]“ дори и при единствена кръпка"
 
 #: builtin/log.c:1178
 msgid "use [PATCH] even with multiple patches"
-msgstr ""
+msgstr "номерация „[PATCH]“ дори и при множество кръпки"
 
 #: builtin/log.c:1182
 msgid "print patches to standard out"
-msgstr ""
+msgstr "извеждане на кръпките на стандартния изход"
 
 #: builtin/log.c:1184
 msgid "generate a cover letter"
-msgstr ""
+msgstr "създаване на придружаващо писмо"
 
 #: builtin/log.c:1186
 msgid "use simple number sequence for output file names"
-msgstr ""
+msgstr "проста числова последователност за имената на файловете-кръпки"
 
 #: builtin/log.c:1187
 msgid "sfx"
-msgstr ""
+msgstr "ЗНАЦИ"
 
 #: builtin/log.c:1188
 msgid "use <sfx> instead of '.patch'"
-msgstr ""
+msgstr "използване на тези ЗНАЦИ за суфикс вместо „.patch“"
 
 #: builtin/log.c:1190
-#, fuzzy
 msgid "start numbering patches at <n> instead of 1"
-msgstr "<брой>"
+msgstr "номерирането на кръпките да започва от този БРОЙ, а не с 1"
 
 #: builtin/log.c:1192
 msgid "mark the series as Nth re-roll"
-msgstr ""
+msgstr "отбелязване, че това е N-тата поредна редакция на поредицата от кръпки"
 
 #: builtin/log.c:1194
 msgid "Use [<prefix>] instead of [PATCH]"
-msgstr ""
+msgstr "Използване на този „[ПРЕФИКС]“ вместо „[PATCH]“"
 
 #: builtin/log.c:1197
 msgid "store resulting files in <dir>"
-msgstr ""
+msgstr "запазване на изходните файлове в тази ДИРЕКТОРИЯ"
 
 #: builtin/log.c:1200
 msgid "don't strip/add [PATCH]"
-msgstr ""
+msgstr "без добавяне/махане на префикса „[PATCH]“"
 
 #: builtin/log.c:1203
 msgid "don't output binary diffs"
-msgstr ""
+msgstr "без извеждане на разлики между двоични файлове"
 
 #: builtin/log.c:1205
 msgid "don't include a patch matching a commit upstream"
-msgstr ""
+msgstr "да не се включват кръпки, които присъстват в следения клон"
 
 #: builtin/log.c:1207
 msgid "show patch format instead of default (patch + stat)"
 msgstr ""
+"извеждане във формат за кръпки, а на в стандартния (кръпка и статистика)"
 
 #: builtin/log.c:1209
 msgid "Messaging"
-msgstr ""
+msgstr "Опции при изпращане"
 
 #: builtin/log.c:1210
 msgid "header"
-msgstr ""
+msgstr "ЗАГЛАВНА_ЧАСТ"
 
 #: builtin/log.c:1211
 msgid "add email header"
-msgstr ""
+msgstr "добавяне на тази ЗАГЛАВНА_ЧАСТ"
 
 #: builtin/log.c:1212 builtin/log.c:1214
 msgid "email"
-msgstr ""
+msgstr "Е-ПОЩА"
 
 #: builtin/log.c:1212
 msgid "add To: header"
-msgstr ""
+msgstr "добавяне на заглавна част „To:“ (до)"
 
 #: builtin/log.c:1214
 msgid "add Cc: header"
-msgstr ""
+msgstr "добавяне на заглавна част „Cc:“ (и до)"
 
 #: builtin/log.c:1216
 msgid "ident"
-msgstr ""
+msgstr "ИДЕНТИЧНОСТ"
 
 #: builtin/log.c:1217
 msgid "set From address to <ident> (or committer ident if absent)"
 msgstr ""
+"задаване на адреса в заглавната част „From“ да е тази ИДЕНТИЧНОСТ. Ако не е "
+"зададена такава, се взима адреса на подаващия"
 
 #: builtin/log.c:1219
 msgid "message-id"
-msgstr ""
+msgstr "ИДЕНТИФИКАТОР_НА_СЪОБЩЕНИЕ"
 
 #: builtin/log.c:1220
 msgid "make first mail a reply to <message-id>"
 msgstr ""
+"първото съобщение да е в отговор на е-писмото с този "
+"ИДЕНТИФИКАТОР_НА_СЪОБЩЕНИЕ"
 
 #: builtin/log.c:1221 builtin/log.c:1224
 msgid "boundary"
-msgstr ""
+msgstr "граница"
 
 #: builtin/log.c:1222
 msgid "attach the patch"
-msgstr ""
+msgstr "прикрепяне на кръпката"
 
 #: builtin/log.c:1225
 msgid "inline the patch"
-msgstr ""
+msgstr "включване на кръпката в текста на писмата"
 
 #: builtin/log.c:1229
 msgid "enable message threading, styles: shallow, deep"
 msgstr ""
+"използване на нишки за съобщенията. Стилът е „shallow“ (плитък) или "
+"„deep“ (дълбок)"
 
 #: builtin/log.c:1231
 msgid "signature"
-msgstr ""
+msgstr "подпис"
 
 #: builtin/log.c:1232
 msgid "add a signature"
-msgstr ""
+msgstr "добавяне на поле за подпис"
 
 #: builtin/log.c:1233
 msgid "don't print the patch filenames"
-msgstr ""
+msgstr "без извеждане на имената на кръпките"
 
 #: builtin/log.c:1307
 #, c-format
 msgid "invalid ident line: %s"
-msgstr ""
+msgstr "грешна идентичност: %s"
 
 #: builtin/log.c:1322
 msgid "-n and -k are mutually exclusive."
-msgstr ""
+msgstr "опциите „-n“ и „-k“ са несъвместими."
 
 #: builtin/log.c:1324
 msgid "--subject-prefix and -k are mutually exclusive."
-msgstr ""
+msgstr "опциите „--subject-prefix“ и „-k“ са несъвместими."
 
 #: builtin/log.c:1332
 msgid "--name-only does not make sense"
-msgstr ""
+msgstr "опцията „--name-only“ е несъвместима с генерирането на кръпки"
 
 #: builtin/log.c:1334
 msgid "--name-status does not make sense"
-msgstr ""
+msgstr "опцията „--name-status“ е несъвместима с генерирането на кръпки"
 
 #: builtin/log.c:1336
 msgid "--check does not make sense"
-msgstr ""
+msgstr "опцията „--check“ е несъвместима с генерирането на кръпки"
 
 #: builtin/log.c:1359
 msgid "standard output, or directory, which one?"
 msgstr ""
+"изходът може да или стандартният, или да е в директория, но не и двете."
 
 #: builtin/log.c:1361
 #, c-format
 msgid "Could not create directory '%s'"
-msgstr ""
+msgstr "Папката „%s“ не може да бъде създадена"
 
 #: builtin/log.c:1509
 msgid "Failed to create output files"
-msgstr ""
+msgstr "Изходните файлове не могат да бъдат създадени"
 
 #: builtin/log.c:1558
 msgid "git cherry [-v] [<upstream> [<head> [<limit>]]]"
-msgstr ""
+msgstr "git cherry [-v] [ОТДАЛЕЧЕН_КЛОН [ВРЪХ [ПРЕДЕЛ]]]"
 
 #: builtin/log.c:1613
 #, c-format
 msgid ""
 "Could not find a tracked remote branch, please specify <upstream> manually.\n"
 msgstr ""
+"Следеният отдалечен клон не бе открит, затова изрично задайте "
+"ОТДАЛЕЧЕН_КЛОН.\n"
 
 #: builtin/log.c:1626 builtin/log.c:1628 builtin/log.c:1640
 #, c-format
 msgid "Unknown commit %s"
-msgstr ""
+msgstr "Непознато подаване „%s“"
 
-#: builtin/ls-files.c:398
+#: builtin/ls-files.c:401
 msgid "git ls-files [options] [<file>...]"
 msgstr ""
 
-#: builtin/ls-files.c:455
+#: builtin/ls-files.c:458
 msgid "identify the file status with tags"
 msgstr ""
 
-#: builtin/ls-files.c:457
+#: builtin/ls-files.c:460
 msgid "use lowercase letters for 'assume unchanged' files"
 msgstr ""
 
-#: builtin/ls-files.c:459
+#: builtin/ls-files.c:462
 msgid "show cached files in the output (default)"
 msgstr ""
 
-#: builtin/ls-files.c:461
+#: builtin/ls-files.c:464
 msgid "show deleted files in the output"
 msgstr ""
 
-#: builtin/ls-files.c:463
+#: builtin/ls-files.c:466
 msgid "show modified files in the output"
 msgstr ""
 
-#: builtin/ls-files.c:465
+#: builtin/ls-files.c:468
 msgid "show other files in the output"
 msgstr ""
 
-#: builtin/ls-files.c:467
+#: builtin/ls-files.c:470
 msgid "show ignored files in the output"
 msgstr ""
 
-#: builtin/ls-files.c:470
+#: builtin/ls-files.c:473
 msgid "show staged contents' object name in the output"
 msgstr ""
 
-#: builtin/ls-files.c:472
+#: builtin/ls-files.c:475
 msgid "show files on the filesystem that need to be removed"
 msgstr ""
 
-#: builtin/ls-files.c:474
+#: builtin/ls-files.c:477
 msgid "show 'other' directories' name only"
 msgstr ""
 
-#: builtin/ls-files.c:477
+#: builtin/ls-files.c:480
 msgid "don't show empty directories"
 msgstr ""
 
-#: builtin/ls-files.c:480
+#: builtin/ls-files.c:483
 msgid "show unmerged files in the output"
 msgstr ""
 
-#: builtin/ls-files.c:482
+#: builtin/ls-files.c:485
 msgid "show resolve-undo information"
 msgstr ""
 
-#: builtin/ls-files.c:484
+#: builtin/ls-files.c:487
 msgid "skip files matching pattern"
 msgstr ""
 
-#: builtin/ls-files.c:487
+#: builtin/ls-files.c:490
 msgid "exclude patterns are read from <file>"
 msgstr ""
 
-#: builtin/ls-files.c:490
+#: builtin/ls-files.c:493
 msgid "read additional per-directory exclude patterns in <file>"
 msgstr ""
 
-#: builtin/ls-files.c:492
+#: builtin/ls-files.c:495
 msgid "add the standard git exclusions"
 msgstr ""
 
-#: builtin/ls-files.c:495
+#: builtin/ls-files.c:498
 msgid "make the output relative to the project top directory"
 msgstr ""
 
-#: builtin/ls-files.c:498
+#: builtin/ls-files.c:501
 msgid "if any <file> is not in the index, treat this as an error"
 msgstr ""
 
-#: builtin/ls-files.c:499
+#: builtin/ls-files.c:502
 msgid "tree-ish"
 msgstr ""
 
-#: builtin/ls-files.c:500
+#: builtin/ls-files.c:503
 msgid "pretend that paths removed since <tree-ish> are still present"
 msgstr ""
 
-#: builtin/ls-files.c:502
+#: builtin/ls-files.c:505
 msgid "show debugging data"
 msgstr ""
 
@@ -6483,7 +6726,7 @@ msgstr ""
 
 #: builtin/ls-tree.c:133
 msgid "terminate entries with NUL byte"
-msgstr ""
+msgstr "разделяне на обектите с нулевия знак „NUL“"
 
 #: builtin/ls-tree.c:134
 msgid "include object size"
@@ -6545,9 +6788,10 @@ msgid "(synonym to --stat)"
 msgstr ""
 
 #: builtin/merge.c:197
-#, fuzzy
 msgid "add (at most <n>) entries from shortlog to merge commit message"
-msgstr "<брой>"
+msgstr ""
+"добавяне (на максимум такъв БРОЙ) записи от съкратения журнал в съобщението "
+"за подаване"
 
 #: builtin/merge.c:200
 msgid "create a single commit instead of doing a merge"
@@ -6573,9 +6817,9 @@ msgstr ""
 msgid "Verify that the named commit has a valid GPG signature"
 msgstr ""
 
-#: builtin/merge.c:212 builtin/notes.c:738 builtin/revert.c:89
+#: builtin/merge.c:212 builtin/notes.c:742 builtin/revert.c:89
 msgid "strategy"
-msgstr ""
+msgstr "стратегия"
 
 #: builtin/merge.c:213
 msgid "merge strategy to use"
@@ -6646,35 +6890,35 @@ msgstr ""
 msgid "Bad branch.%s.mergeoptions string: %s"
 msgstr ""
 
-#: builtin/merge.c:650
+#: builtin/merge.c:653
 msgid "git write-tree failed to write a tree"
-msgstr ""
+msgstr "Командата „git write-tree“ не успя да запише обект-дърво"
 
-#: builtin/merge.c:678
+#: builtin/merge.c:681
 msgid "Not handling anything other than two heads merge."
 msgstr ""
 
-#: builtin/merge.c:692
+#: builtin/merge.c:695
 #, c-format
 msgid "Unknown option for merge-recursive: -X%s"
 msgstr ""
 
-#: builtin/merge.c:706
+#: builtin/merge.c:709
 #, c-format
 msgid "unable to write %s"
 msgstr ""
 
-#: builtin/merge.c:795
+#: builtin/merge.c:798
 #, c-format
 msgid "Could not read from '%s'"
 msgstr ""
 
-#: builtin/merge.c:804
+#: builtin/merge.c:807
 #, c-format
 msgid "Not committing merge; use 'git commit' to complete the merge.\n"
 msgstr ""
 
-#: builtin/merge.c:810
+#: builtin/merge.c:813
 #, c-format
 msgid ""
 "Please enter a commit message to explain why this merge is necessary,\n"
@@ -6684,157 +6928,162 @@ msgid ""
 "the commit.\n"
 msgstr ""
 
-#: builtin/merge.c:834
+#: builtin/merge.c:837
 msgid "Empty commit message."
 msgstr ""
 
-#: builtin/merge.c:846
+#: builtin/merge.c:849
 #, c-format
 msgid "Wonderful.\n"
 msgstr ""
 
-#: builtin/merge.c:911
+#: builtin/merge.c:914
 #, c-format
 msgid "Automatic merge failed; fix conflicts and then commit the result.\n"
 msgstr ""
 
-#: builtin/merge.c:927
+#: builtin/merge.c:930
 #, c-format
 msgid "'%s' is not a commit"
 msgstr ""
 
-#: builtin/merge.c:968
+#: builtin/merge.c:971
 msgid "No current branch."
 msgstr ""
 
-#: builtin/merge.c:970
+#: builtin/merge.c:973
 msgid "No remote for the current branch."
 msgstr ""
 
-#: builtin/merge.c:972
+#: builtin/merge.c:975
 msgid "No default upstream defined for the current branch."
 msgstr ""
 
-#: builtin/merge.c:977
+#: builtin/merge.c:980
 #, c-format
 msgid "No remote-tracking branch for %s from %s"
 msgstr ""
 
-#: builtin/merge.c:1133
+#: builtin/merge.c:1136
 msgid "There is no merge to abort (MERGE_HEAD missing)."
 msgstr ""
 
-#: builtin/merge.c:1149 git-pull.sh:31
+#: builtin/merge.c:1152 git-pull.sh:31
 msgid ""
 "You have not concluded your merge (MERGE_HEAD exists).\n"
 "Please, commit your changes before you can merge."
 msgstr ""
+"Не сте завършили сливане. (Указателят „MERGE_HEAD“ съществува).\n"
+"Подайте промените си, преди да започнете ново сливане."
 
-#: builtin/merge.c:1152 git-pull.sh:34
+#: builtin/merge.c:1155 git-pull.sh:34
 msgid "You have not concluded your merge (MERGE_HEAD exists)."
-msgstr ""
+msgstr "Не сте завършили сливане. (Указателят „MERGE_HEAD“ съществува)."
 
-#: builtin/merge.c:1156
+#: builtin/merge.c:1159
 msgid ""
 "You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists).\n"
 "Please, commit your changes before you can merge."
 msgstr ""
+"Не сте завършили отбиране на подаване (указателят „CHERRY_PICK_HEAD“\n"
+"съществува). Подайте промените си, преди да започнете ново сливане."
 
-#: builtin/merge.c:1159
+#: builtin/merge.c:1162
 msgid "You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists)."
 msgstr ""
+"Не сте завършили отбиране на подаване (указателят „CHERRY_PICK_HEAD“\n"
+"съществува)."
 
-#: builtin/merge.c:1168
+#: builtin/merge.c:1171
 msgid "You cannot combine --squash with --no-ff."
 msgstr ""
 
-#: builtin/merge.c:1177
+#: builtin/merge.c:1180
 msgid "No commit specified and merge.defaultToUpstream not set."
 msgstr ""
 
-#: builtin/merge.c:1209
+#: builtin/merge.c:1212
 msgid "Can merge only exactly one commit into empty head"
 msgstr ""
 
-#: builtin/merge.c:1212
+#: builtin/merge.c:1215
 msgid "Squash commit into empty head not supported yet"
 msgstr ""
 
-#: builtin/merge.c:1214
+#: builtin/merge.c:1217
 msgid "Non-fast-forward commit does not make sense into an empty head"
 msgstr ""
 
-#: builtin/merge.c:1219
+#: builtin/merge.c:1222
 #, c-format
 msgid "%s - not something we can merge"
 msgstr ""
 
-#: builtin/merge.c:1270
+#: builtin/merge.c:1273
 #, c-format
 msgid "Commit %s has an untrusted GPG signature, allegedly by %s."
 msgstr ""
 
-#: builtin/merge.c:1273
+#: builtin/merge.c:1276
 #, c-format
 msgid "Commit %s has a bad GPG signature allegedly by %s."
 msgstr ""
 
-#. 'N'
-#: builtin/merge.c:1276
+#: builtin/merge.c:1279
 #, c-format
 msgid "Commit %s does not have a GPG signature."
 msgstr ""
 
-#: builtin/merge.c:1279
+#: builtin/merge.c:1282
 #, c-format
 msgid "Commit %s has a good GPG signature by %s\n"
 msgstr ""
 
-#: builtin/merge.c:1363
+#: builtin/merge.c:1366
 #, c-format
 msgid "Updating %s..%s\n"
 msgstr ""
 
-#: builtin/merge.c:1402
+#: builtin/merge.c:1405
 #, c-format
 msgid "Trying really trivial in-index merge...\n"
 msgstr ""
 
-#: builtin/merge.c:1409
+#: builtin/merge.c:1412
 #, c-format
 msgid "Nope.\n"
 msgstr ""
 
-#: builtin/merge.c:1441
+#: builtin/merge.c:1444
 msgid "Not possible to fast-forward, aborting."
 msgstr ""
 
-#: builtin/merge.c:1464 builtin/merge.c:1543
+#: builtin/merge.c:1467 builtin/merge.c:1546
 #, c-format
 msgid "Rewinding the tree to pristine...\n"
 msgstr ""
 
-#: builtin/merge.c:1468
+#: builtin/merge.c:1471
 #, c-format
 msgid "Trying merge strategy %s...\n"
 msgstr ""
 
-#: builtin/merge.c:1534
+#: builtin/merge.c:1537
 #, c-format
 msgid "No merge strategy handled the merge.\n"
 msgstr ""
 
-#: builtin/merge.c:1536
+#: builtin/merge.c:1539
 #, c-format
 msgid "Merge with strategy %s failed.\n"
 msgstr ""
 
-#: builtin/merge.c:1545
+#: builtin/merge.c:1548
 #, c-format
 msgid "Using the %s to prepare resolving by hand.\n"
 msgstr ""
 
-#: builtin/merge.c:1557
+#: builtin/merge.c:1560
 #, c-format
 msgid "Automatic merge went well; stopped before committing as requested\n"
 msgstr ""
@@ -6917,108 +7166,109 @@ msgstr ""
 msgid "set labels for file1/orig_file/file2"
 msgstr ""
 
-#: builtin/mktree.c:67
+#: builtin/mktree.c:64
 msgid "git mktree [-z] [--missing] [--batch]"
-msgstr ""
+msgstr "git mktree [-z] [--missing] [--batch]"
 
-#: builtin/mktree.c:153
+#: builtin/mktree.c:150
 msgid "input is NUL terminated"
-msgstr ""
+msgstr "входните записа са разделени с нулевия знак „NUL“"
 
-#: builtin/mktree.c:154 builtin/write-tree.c:24
+#: builtin/mktree.c:151 builtin/write-tree.c:24
 msgid "allow missing objects"
-msgstr ""
+msgstr "разрешаване на липсващи обекти"
 
-#: builtin/mktree.c:155
+#: builtin/mktree.c:152
 msgid "allow creation of more than one tree"
-msgstr ""
+msgstr "разрешаване на създаването на повече от едно дърво"
 
 #: builtin/mv.c:15
 msgid "git mv [options] <source>... <destination>"
-msgstr ""
+msgstr "git mv [ОПЦИИ] ОБЕКТ… ЦЕЛ"
 
 #: builtin/mv.c:71
 msgid "force move/rename even if target exists"
-msgstr ""
+msgstr "принудително преместване/преименуване дори целта да съществува"
 
 #: builtin/mv.c:72
 msgid "skip move/rename errors"
-msgstr ""
+msgstr "прескачане на грешките при преместване/преименуване"
 
 #: builtin/mv.c:122
 #, c-format
 msgid "Checking rename of '%s' to '%s'\n"
-msgstr ""
+msgstr "Проверка на преименуването на обект от „%s“ на „%s“\n"
 
 #: builtin/mv.c:126
 msgid "bad source"
-msgstr ""
+msgstr "неправилен обект"
 
 #: builtin/mv.c:129
 msgid "can not move directory into itself"
-msgstr ""
+msgstr "директория не може да се премести в себе си"
 
 #: builtin/mv.c:132
 msgid "cannot move directory over file"
-msgstr ""
+msgstr "директория не може да се премести върху файл"
 
+# FIXME message<
 #: builtin/mv.c:138
 #, c-format
 msgid "Huh? Directory %s is in index and no submodule?"
-msgstr ""
+msgstr "Директорията „%s“ е в индекса, но не е подмодул"
 
 #: builtin/mv.c:140 builtin/rm.c:318
 msgid "Please, stage your changes to .gitmodules or stash them to proceed"
 msgstr ""
-"За да продължите или вкарайте промените по файла „.gitmodules“ в индекса, "
-"или\n"
-"ги скътайте"
+"За да продължите или вкарайте промените по файла „.gitmodules“ в индекса,\n"
+"или ги скатайте"
 
+# FIXME message
 #: builtin/mv.c:156
 #, c-format
 msgid "Huh? %.*s is in index?"
-msgstr ""
+msgstr "„%.*s“ вече е в индекса"
 
-#: builtin/mv.c:168
+#: builtin/mv.c:169
 msgid "source directory is empty"
-msgstr ""
+msgstr "първоначалната директория е празна"
 
-#: builtin/mv.c:200
+#: builtin/mv.c:205
 msgid "not under version control"
-msgstr ""
+msgstr "не е под контрола на Git"
 
-#: builtin/mv.c:202
+#: builtin/mv.c:207
 msgid "destination exists"
-msgstr ""
+msgstr "целта съществува"
 
-#: builtin/mv.c:210
+#: builtin/mv.c:215
 #, c-format
 msgid "overwriting '%s'"
-msgstr ""
+msgstr "презаписване на „%s“"
 
-#: builtin/mv.c:213
+#: builtin/mv.c:218
 msgid "Cannot overwrite"
-msgstr ""
+msgstr "Презаписването е невъзможно"
 
-#: builtin/mv.c:216
+#: builtin/mv.c:221
 msgid "multiple sources for the same target"
-msgstr ""
+msgstr "множество източници за една цел"
 
-#: builtin/mv.c:218
+#: builtin/mv.c:223
 msgid "destination directory does not exist"
-msgstr ""
+msgstr "целевата директория не съществува"
 
-#: builtin/mv.c:233
+#: builtin/mv.c:243
 #, c-format
 msgid "%s, source=%s, destination=%s"
-msgstr ""
+msgstr "%s, обект: „%s“, цел: „%s“"
 
-#: builtin/mv.c:243
+#: builtin/mv.c:253
 #, c-format
 msgid "Renaming %s to %s\n"
-msgstr ""
+msgstr "Преименуване на „%s“ на „%s“\n"
 
-#: builtin/mv.c:246 builtin/remote.c:726 builtin/repack.c:328
+#: builtin/mv.c:256 builtin/remote.c:726 builtin/repack.c:355
 #, c-format
 msgid "renaming '%s' failed"
 msgstr "неуспешно преименуване на „%s“"
@@ -7183,7 +7433,7 @@ msgstr ""
 msgid "failed to finish 'show' for object '%s'"
 msgstr ""
 
-#: builtin/notes.c:167 builtin/tag.c:341
+#: builtin/notes.c:167 builtin/tag.c:373
 #, c-format
 msgid "could not create file '%s'"
 msgstr ""
@@ -7192,7 +7442,7 @@ msgstr ""
 msgid "Please supply the note contents using either -m or -F option"
 msgstr ""
 
-#: builtin/notes.c:207 builtin/notes.c:844
+#: builtin/notes.c:207 builtin/notes.c:848
 #, c-format
 msgid "Removing note for object %s\n"
 msgstr ""
@@ -7206,20 +7456,20 @@ msgstr ""
 msgid "The note contents has been left in %s"
 msgstr ""
 
-#: builtin/notes.c:248 builtin/tag.c:537
+#: builtin/notes.c:248 builtin/tag.c:604
 #, c-format
 msgid "cannot read '%s'"
 msgstr ""
 
-#: builtin/notes.c:250 builtin/tag.c:540
+#: builtin/notes.c:250 builtin/tag.c:607
 #, c-format
 msgid "could not open or read '%s'"
 msgstr ""
 
-#: builtin/notes.c:269 builtin/notes.c:316 builtin/notes.c:318
-#: builtin/notes.c:378 builtin/notes.c:432 builtin/notes.c:515
-#: builtin/notes.c:520 builtin/notes.c:595 builtin/notes.c:637
-#: builtin/notes.c:839 builtin/tag.c:553
+#: builtin/notes.c:269 builtin/notes.c:320 builtin/notes.c:322
+#: builtin/notes.c:382 builtin/notes.c:436 builtin/notes.c:519
+#: builtin/notes.c:524 builtin/notes.c:599 builtin/notes.c:641
+#: builtin/notes.c:843 builtin/tag.c:620
 #, c-format
 msgid "Failed to resolve '%s' as a valid ref."
 msgstr ""
@@ -7229,355 +7479,391 @@ msgstr ""
 msgid "Failed to read object '%s'."
 msgstr ""
 
-#: builtin/notes.c:312
+#: builtin/notes.c:276
+#, c-format
+msgid "Cannot read note data from non-blob object '%s'."
+msgstr ""
+
+#: builtin/notes.c:316
 #, c-format
 msgid "Malformed input line: '%s'."
 msgstr ""
 
-#: builtin/notes.c:327
+#: builtin/notes.c:331
 #, c-format
 msgid "Failed to copy notes from '%s' to '%s'"
 msgstr ""
 
-#: builtin/notes.c:371 builtin/notes.c:425 builtin/notes.c:498
-#: builtin/notes.c:510 builtin/notes.c:583 builtin/notes.c:630
-#: builtin/notes.c:904
+#: builtin/notes.c:375 builtin/notes.c:429 builtin/notes.c:502
+#: builtin/notes.c:514 builtin/notes.c:587 builtin/notes.c:634
+#: builtin/notes.c:908
 msgid "too many parameters"
 msgstr ""
 
-#: builtin/notes.c:384 builtin/notes.c:643
+#: builtin/notes.c:388 builtin/notes.c:647
 #, c-format
 msgid "No note found for object %s."
 msgstr ""
 
-#: builtin/notes.c:406 builtin/notes.c:563
+#: builtin/notes.c:410 builtin/notes.c:567
 msgid "note contents as a string"
 msgstr ""
 
-#: builtin/notes.c:409 builtin/notes.c:566
+#: builtin/notes.c:413 builtin/notes.c:570
 msgid "note contents in a file"
 msgstr ""
 
-#: builtin/notes.c:411 builtin/notes.c:414 builtin/notes.c:568
-#: builtin/notes.c:571 builtin/tag.c:474
+#: builtin/notes.c:415 builtin/notes.c:418 builtin/notes.c:572
+#: builtin/notes.c:575 builtin/tag.c:539
 msgid "object"
 msgstr ""
 
-#: builtin/notes.c:412 builtin/notes.c:569
+#: builtin/notes.c:416 builtin/notes.c:573
 msgid "reuse and edit specified note object"
 msgstr ""
 
-#: builtin/notes.c:415 builtin/notes.c:572
+#: builtin/notes.c:419 builtin/notes.c:576
 msgid "reuse specified note object"
 msgstr ""
 
-#: builtin/notes.c:417 builtin/notes.c:485
+#: builtin/notes.c:421 builtin/notes.c:489
 msgid "replace existing notes"
 msgstr ""
 
-#: builtin/notes.c:451
+#: builtin/notes.c:455
 #, c-format
 msgid ""
 "Cannot add notes. Found existing notes for object %s. Use '-f' to overwrite "
 "existing notes"
 msgstr ""
 
-#: builtin/notes.c:456 builtin/notes.c:533
+#: builtin/notes.c:460 builtin/notes.c:537
 #, c-format
 msgid "Overwriting existing notes for object %s\n"
 msgstr ""
 
-#: builtin/notes.c:486
+#: builtin/notes.c:490
 msgid "read objects from stdin"
 msgstr ""
 
-#: builtin/notes.c:488
+#: builtin/notes.c:492
 msgid "load rewriting config for <command> (implies --stdin)"
 msgstr ""
 
-#: builtin/notes.c:506
+#: builtin/notes.c:510
 msgid "too few parameters"
 msgstr ""
 
-#: builtin/notes.c:527
+#: builtin/notes.c:531
 #, c-format
 msgid ""
 "Cannot copy notes. Found existing notes for object %s. Use '-f' to overwrite "
 "existing notes"
 msgstr ""
 
-#: builtin/notes.c:539
+#: builtin/notes.c:543
 #, c-format
 msgid "Missing notes on source object %s. Cannot copy."
 msgstr ""
 
-#: builtin/notes.c:588
+#: builtin/notes.c:592
 #, c-format
 msgid ""
 "The -m/-F/-c/-C options have been deprecated for the 'edit' subcommand.\n"
 "Please use 'git notes add -f -m/-F/-c/-C' instead.\n"
 msgstr ""
 
-#: builtin/notes.c:735
+#: builtin/notes.c:739
 msgid "General options"
 msgstr ""
 
-#: builtin/notes.c:737
+#: builtin/notes.c:741
 msgid "Merge options"
 msgstr ""
 
-#: builtin/notes.c:739
+#: builtin/notes.c:743
 msgid ""
 "resolve notes conflicts using the given strategy (manual/ours/theirs/union/"
 "cat_sort_uniq)"
 msgstr ""
 
-#: builtin/notes.c:741
+#: builtin/notes.c:745
 msgid "Committing unmerged notes"
 msgstr ""
 
-#: builtin/notes.c:743
+#: builtin/notes.c:747
 msgid "finalize notes merge by committing unmerged notes"
 msgstr ""
 
-#: builtin/notes.c:745
+#: builtin/notes.c:749
 msgid "Aborting notes merge resolution"
 msgstr ""
 
-#: builtin/notes.c:747
+#: builtin/notes.c:751
 msgid "abort notes merge"
 msgstr ""
 
-#: builtin/notes.c:842
+#: builtin/notes.c:846
 #, c-format
 msgid "Object %s has no note\n"
 msgstr ""
 
-#: builtin/notes.c:854
+#: builtin/notes.c:858
 msgid "attempt to remove non-existent note is not an error"
 msgstr ""
 
-#: builtin/notes.c:857
+#: builtin/notes.c:861
 msgid "read object names from the standard input"
 msgstr ""
 
-#: builtin/notes.c:938
-msgid "notes_ref"
+#: builtin/notes.c:942
+msgid "notes-ref"
 msgstr ""
 
-#: builtin/notes.c:939
+#: builtin/notes.c:943
 msgid "use notes from <notes_ref>"
 msgstr ""
 
-#: builtin/notes.c:974 builtin/remote.c:1593
+#: builtin/notes.c:978 builtin/remote.c:1593
 #, c-format
 msgid "Unknown subcommand: %s"
 msgstr "Непозната подкоманда: %s"
 
-#: builtin/pack-objects.c:23
+#: builtin/pack-objects.c:25
 msgid "git pack-objects --stdout [options...] [< ref-list | < object-list]"
 msgstr ""
 
-#: builtin/pack-objects.c:24
+#: builtin/pack-objects.c:26
 msgid "git pack-objects [options...] base-name [< ref-list | < object-list]"
 msgstr ""
 
-#: builtin/pack-objects.c:184 builtin/pack-objects.c:187
+#: builtin/pack-objects.c:175 builtin/pack-objects.c:178
 #, c-format
 msgid "deflate error (%d)"
 msgstr ""
 
-#: builtin/pack-objects.c:2396
+#: builtin/pack-objects.c:771
+msgid "Writing objects"
+msgstr "Записване на обектите"
+
+#: builtin/pack-objects.c:1012
+msgid "disabling bitmap writing, as some objects are not being packed"
+msgstr ""
+
+#: builtin/pack-objects.c:2174
+msgid "Compressing objects"
+msgstr "Компресиране на обектите"
+
+#: builtin/pack-objects.c:2530
 #, c-format
 msgid "unsupported index version %s"
 msgstr ""
 
-#: builtin/pack-objects.c:2400
+#: builtin/pack-objects.c:2534
 #, c-format
 msgid "bad index version '%s'"
 msgstr ""
 
-#: builtin/pack-objects.c:2423
+#: builtin/pack-objects.c:2557
 #, c-format
 msgid "option %s does not accept negative form"
 msgstr ""
 
-#: builtin/pack-objects.c:2427
+#: builtin/pack-objects.c:2561
 #, c-format
 msgid "unable to parse value '%s' for option %s"
 msgstr ""
 
-#: builtin/pack-objects.c:2446
+#: builtin/pack-objects.c:2580
 msgid "do not show progress meter"
 msgstr ""
 
-#: builtin/pack-objects.c:2448
+#: builtin/pack-objects.c:2582
 msgid "show progress meter"
 msgstr ""
 
-#: builtin/pack-objects.c:2450
+#: builtin/pack-objects.c:2584
 msgid "show progress meter during object writing phase"
 msgstr ""
 
-#: builtin/pack-objects.c:2453
+#: builtin/pack-objects.c:2587
 msgid "similar to --all-progress when progress meter is shown"
 msgstr ""
 
-#: builtin/pack-objects.c:2454
+#: builtin/pack-objects.c:2588
 msgid "version[,offset]"
 msgstr ""
 
-#: builtin/pack-objects.c:2455
+#: builtin/pack-objects.c:2589
 msgid "write the pack index file in the specified idx format version"
 msgstr ""
 
-#: builtin/pack-objects.c:2458
+#: builtin/pack-objects.c:2592
 msgid "maximum size of each output pack file"
 msgstr ""
 
-#: builtin/pack-objects.c:2460
+#: builtin/pack-objects.c:2594
 msgid "ignore borrowed objects from alternate object store"
 msgstr ""
 
-#: builtin/pack-objects.c:2462
+#: builtin/pack-objects.c:2596
 msgid "ignore packed objects"
 msgstr ""
 
-#: builtin/pack-objects.c:2464
+#: builtin/pack-objects.c:2598
 msgid "limit pack window by objects"
 msgstr ""
 
-#: builtin/pack-objects.c:2466
+#: builtin/pack-objects.c:2600
 msgid "limit pack window by memory in addition to object limit"
 msgstr ""
 
-#: builtin/pack-objects.c:2468
+#: builtin/pack-objects.c:2602
 msgid "maximum length of delta chain allowed in the resulting pack"
 msgstr ""
 
-#: builtin/pack-objects.c:2470
+#: builtin/pack-objects.c:2604
 msgid "reuse existing deltas"
 msgstr ""
 
-#: builtin/pack-objects.c:2472
+#: builtin/pack-objects.c:2606
 msgid "reuse existing objects"
 msgstr ""
 
-#: builtin/pack-objects.c:2474
+#: builtin/pack-objects.c:2608
 msgid "use OFS_DELTA objects"
 msgstr ""
 
-#: builtin/pack-objects.c:2476
+#: builtin/pack-objects.c:2610
 msgid "use threads when searching for best delta matches"
 msgstr ""
 
-#: builtin/pack-objects.c:2478
+#: builtin/pack-objects.c:2612
 msgid "do not create an empty pack output"
 msgstr ""
 
-#: builtin/pack-objects.c:2480
+#: builtin/pack-objects.c:2614
 msgid "read revision arguments from standard input"
 msgstr ""
 
-#: builtin/pack-objects.c:2482
+#: builtin/pack-objects.c:2616
 msgid "limit the objects to those that are not yet packed"
 msgstr ""
 
-#: builtin/pack-objects.c:2485
+#: builtin/pack-objects.c:2619
 msgid "include objects reachable from any reference"
 msgstr ""
 
-#: builtin/pack-objects.c:2488
+#: builtin/pack-objects.c:2622
 msgid "include objects referred by reflog entries"
 msgstr ""
 
-#: builtin/pack-objects.c:2491
+#: builtin/pack-objects.c:2625
 msgid "output pack to stdout"
 msgstr ""
 
-#: builtin/pack-objects.c:2493
+#: builtin/pack-objects.c:2627
 msgid "include tag objects that refer to objects to be packed"
 msgstr ""
 
-#: builtin/pack-objects.c:2495
+#: builtin/pack-objects.c:2629
 msgid "keep unreachable objects"
 msgstr ""
 
-#: builtin/pack-objects.c:2496 parse-options.h:143
+#: builtin/pack-objects.c:2630 parse-options.h:140
 msgid "time"
 msgstr "време"
 
-#: builtin/pack-objects.c:2497
+#: builtin/pack-objects.c:2631
 msgid "unpack unreachable objects newer than <time>"
 msgstr ""
 
-#: builtin/pack-objects.c:2500
+#: builtin/pack-objects.c:2634
 msgid "create thin packs"
 msgstr ""
 
-#: builtin/pack-objects.c:2502
+#: builtin/pack-objects.c:2636
 msgid "ignore packs that have companion .keep file"
 msgstr ""
 
-#: builtin/pack-objects.c:2504
+#: builtin/pack-objects.c:2638
 msgid "pack compression level"
 msgstr ""
 
-#: builtin/pack-objects.c:2506
+#: builtin/pack-objects.c:2640
 msgid "do not hide commits by grafts"
 msgstr ""
 
+#: builtin/pack-objects.c:2642
+msgid "use a bitmap index if available to speed up counting objects"
+msgstr ""
+
+#: builtin/pack-objects.c:2644
+msgid "write a bitmap index together with the pack index"
+msgstr ""
+
+#: builtin/pack-objects.c:2723
+msgid "Counting objects"
+msgstr "Преброяване на обектите"
+
 #: builtin/pack-refs.c:6
 msgid "git pack-refs [options]"
-msgstr ""
+msgstr "git pack-refs [ОПЦИИ]"
 
 #: builtin/pack-refs.c:14
 msgid "pack everything"
-msgstr ""
+msgstr "пакетиране на всичко"
 
 #: builtin/pack-refs.c:15
 msgid "prune loose refs (default)"
-msgstr ""
+msgstr "окастряне на недостижимите указатели (стандартно)"
 
 #: builtin/prune-packed.c:7
 msgid "git prune-packed [-n|--dry-run] [-q|--quiet]"
-msgstr ""
+msgstr "git prune-packed [-n|--dry-run] [-q|--quiet]"
+
+#: builtin/prune-packed.c:49
+msgid "Removing duplicate objects"
+msgstr "Изтриване на повтарящите се обекти"
 
 #: builtin/prune.c:12
 msgid "git prune [-n] [-v] [--expire <time>] [--] [<head>...]"
-msgstr ""
+msgstr "git prune [-n] [-v] [--expire ВРЕМЕ] [--] [ВРЪХ…]"
 
 #: builtin/prune.c:142
 msgid "do not remove, show only"
-msgstr ""
+msgstr "само извеждане без действително окастряне"
 
 #: builtin/prune.c:143
 msgid "report pruned objects"
-msgstr ""
+msgstr "информация за окастрените обекти"
 
 #: builtin/prune.c:146
 msgid "expire objects older than <time>"
-msgstr ""
+msgstr "окастряне на обектите по-стари от това ВРЕМЕ"
 
 #: builtin/push.c:14
 msgid "git push [<options>] [<repository> [<refspec>...]]"
-msgstr ""
+msgstr "git push [ОПЦИИ] [ХРАНИЛИЩЕ [УКАЗАТЕЛ_НА_ВЕРСИЯ…]]"
 
-#: builtin/push.c:86
+#: builtin/push.c:85
 msgid "tag shorthand without <tag>"
-msgstr ""
+msgstr "съкращение за етикет без ЕТИКЕТ"
 
-#: builtin/push.c:96
+#: builtin/push.c:95
 msgid "--delete only accepts plain target ref names"
-msgstr ""
+msgstr "опцията „--delete“ приема за цел само прости имена на указатели"
 
-#: builtin/push.c:141
+#: builtin/push.c:140
 msgid ""
 "\n"
 "To choose either option permanently, see push.default in 'git help config'."
 msgstr ""
+"\n"
+"За да включите тази опция за постоянно вижте документацията за настройката "
+"„push.default“ в „git help config“."
 
-#: builtin/push.c:144
+#: builtin/push.c:143
 #, c-format
 msgid ""
 "The upstream branch of your current branch does not match\n"
@@ -7591,8 +7877,18 @@ msgid ""
 "    git push %s %s\n"
 "%s"
 msgstr ""
+"Името на текущия клон се различава от името на клона, който той следи.\n"
+"За да изтласкате към следения клон използвайте командата:\n"
+"\n"
+"    git push %s HEAD:%s\n"
+"\n"
+"За да изтласкате към отдалечения клон с име като локалния, използвайте "
+"командата:\n"
+"\n"
+"    git push %s %s\n"
+"%s"
 
-#: builtin/push.c:159
+#: builtin/push.c:158
 #, c-format
 msgid ""
 "You are not currently on a branch.\n"
@@ -7601,8 +7897,12 @@ msgid ""
 "\n"
 "    git push %s HEAD:<name-of-remote-branch>\n"
 msgstr ""
+"В момента не сте на никой клон. За да изтласкате историята до състоянието,\n"
+"сочено в момента от указателя „HEAD“, използвайте командата:\n"
+"\n"
+"    git push %s HEAD:ИМЕ_НА_ОТДАЛЕЧЕНИЯ_КЛОН\n"
 
-#: builtin/push.c:173
+#: builtin/push.c:172
 #, c-format
 msgid ""
 "The current branch %s has no upstream branch.\n"
@@ -7610,25 +7910,36 @@ msgid ""
 "\n"
 "    git push --set-upstream %s %s\n"
 msgstr ""
+"Не е зададен отдалечен клон, който текущият клон „%s“ да следи.\n"
+"За да изтласкате локалния клон към отдалечен и същевременно да зададете\n"
+"втория като този, който първият следи, използвайте командата:\n"
+"\n"
+"    git push --set-upstream %s %s\n"
 
-#: builtin/push.c:181
+#: builtin/push.c:180
 #, c-format
 msgid "The current branch %s has multiple upstream branches, refusing to push."
 msgstr ""
+"Текущият клон „%s“ следи няколко отдалечени клона, не можете просто да "
+"изтласкате."
 
-#: builtin/push.c:184
+#: builtin/push.c:183
 #, c-format
 msgid ""
 "You are pushing to remote '%s', which is not the upstream of\n"
 "your current branch '%s', without telling me what to push\n"
 "to update which remote branch."
 msgstr ""
+"Изтласквате към отдалечения клон „%s“, който не е следен от текущия клон "
+"„%s“.\n"
+"Трябва да укажете коя версия да се изтласка, за обновяване на отдалечения "
+"клон."
 
-#: builtin/push.c:207
+#: builtin/push.c:206
 msgid ""
-"push.default is unset; its implicit value is changing in\n"
+"push.default is unset; its implicit value has changed in\n"
 "Git 2.0 from 'matching' to 'simple'. To squelch this message\n"
-"and maintain the current behavior after the default changes, use:\n"
+"and maintain the traditional behavior, use:\n"
 "\n"
 "  git config --global push.default matching\n"
 "\n"
@@ -7639,7 +7950,7 @@ msgid ""
 "When push.default is set to 'matching', git will push local branches\n"
 "to the remote branches that already exist with the same name.\n"
 "\n"
-"In Git 2.0, Git will default to the more conservative 'simple'\n"
+"Since Git 2.0, Git defaults to the more conservative 'simple'\n"
 "behavior, which only pushes the current branch to the corresponding\n"
 "remote branch that 'git pull' uses to update the current branch.\n"
 "\n"
@@ -7648,37 +7959,71 @@ msgid ""
 "(the 'simple' mode was introduced in Git 1.7.11. Use the similar mode\n"
 "'current' instead of 'simple' if you sometimes use older versions of Git)"
 msgstr ""
+"Настройката „push.default“ не е зададена. Стойността ѝ по подразбиране е "
+"сменена\n"
+"в Git 2.0 от „matching“ (всички съвпадащи клони) на „simple“ (само текущия\n"
+"клон). За да подтиснете това съобщение и да използвате традиционното "
+"поведение\n"
+"на Git 1.x, изпълнете командата:\n"
+"\n"
+"  git config --global push.default matching\n"
+"\n"
+"За да подтиснете това съобщение и да използвате новото поведение на Git 2."
+"x,\n"
+"изпълнете командата:\n"
+"\n"
+"  git config --global push.default simple\n"
+"\n"
+"Когато настройката „push.default“ е „matching“, git ще изтласка всички "
+"локални\n"
+"клони, които имат отдалечен аналог със същото име.\n"
+"\n"
+"От версия 2.0 Git стандартно започва да ползва по-консервативния вариант\n"
+"„simple“, при който „push“ изтласква само текущия клон към отдалечения, "
+"следен\n"
+"клон — същия, който „git pull“ използва, за да обнови текущия.\n"
+"\n"
+"За повече информация погледнете „git help config“ и потърсете „push."
+"default“.\n"
+"Новата стойност „simple“ бе въведена с версия 1.7.11 на Git. Ако понякога\n"
+"ползвате стари версии на Git, задайте стойност „current“ вместо „simple“."
 
-#: builtin/push.c:274
+#: builtin/push.c:273
 msgid ""
 "You didn't specify any refspecs to push, and push.default is \"nothing\"."
 msgstr ""
+"Не сте указали версия за подаване, а настройката „push.default“ не е "
+"зададена."
 
-#: builtin/push.c:281
+#: builtin/push.c:280
 msgid ""
 "Updates were rejected because the tip of your current branch is behind\n"
 "its remote counterpart. Integrate the remote changes (e.g.\n"
 "'git pull ...') before pushing again.\n"
 "See the 'Note about fast-forwards' in 'git push --help' for details."
 msgstr ""
+"Обновяването е отхвърлено, защото върхът на текущия ви клон е преди върха "
+"на\n"
+"отдалечения клон. Внесете отдалечените промени (напр. с командата „git "
+"pull…“),\n"
+"преди отново да изтласкате промените. За повече информация вижте раздела\n"
+"„Note about fast-forwards“ в страницата от ръководството „git push --help“."
 
-#: builtin/push.c:287
-msgid ""
-"Updates were rejected because a pushed branch tip is behind its remote\n"
-"counterpart. If you did not intend to push that branch, you may want to\n"
-"specify branches to push or set the 'push.default' configuration variable\n"
-"to 'simple', 'current' or 'upstream' to push only the current branch."
-msgstr ""
-
-#: builtin/push.c:293
+#: builtin/push.c:286
 msgid ""
 "Updates were rejected because a pushed branch tip is behind its remote\n"
 "counterpart. Check out this branch and integrate the remote changes\n"
 "(e.g. 'git pull ...') before pushing again.\n"
 "See the 'Note about fast-forwards' in 'git push --help' for details."
 msgstr ""
+"Обновяването е отхвърлено, защото върха на изтласквания клон е преди върха "
+"на\n"
+"отдалечения клон. Проверете клона и внесете отдалечените промени (напр. с\n"
+"командата „git pull…“), преди отново да изтласкате промените. За повече\n"
+"информация вижте раздела „Note about fast-forwards“ в страницата от\n"
+"ръководството „git push --help“."
 
-#: builtin/push.c:299
+#: builtin/push.c:292
 msgid ""
 "Updates were rejected because the remote contains work that you do\n"
 "not have locally. This is usually caused by another repository pushing\n"
@@ -7686,34 +8031,51 @@ msgid ""
 "(e.g., 'git pull ...') before pushing again.\n"
 "See the 'Note about fast-forwards' in 'git push --help' for details."
 msgstr ""
+"Обновяването е отхвърлено, защото хранилището, към което изтласквате, "
+"съдържа\n"
+"промени, които липсват в локалното хранилище. Най-честата причина за това "
+"е,\n"
+"че някой друг е изтласквал към същия клон. Първо внесете отдалечените "
+"промени\n"
+"(напр. с командата „git pull…“), преди отново да изтласкате промените.\n"
+"За повече информация вижте раздела „Note about fast-forwards“ в страницата "
+"от\n"
+"ръководството „git push --help“."
 
-#: builtin/push.c:306
+#: builtin/push.c:299
 msgid "Updates were rejected because the tag already exists in the remote."
 msgstr ""
+"Изтласкването е отхвърлено, защото в отдалеченото хранилище съществува "
+"етикет,\n"
+"който ще припокриете с етикет от вашето хранилище."
 
-#: builtin/push.c:309
+#: builtin/push.c:302
 msgid ""
 "You cannot update a remote ref that points at a non-commit object,\n"
 "or update a remote ref to make it point at a non-commit object,\n"
 "without using the '--force' option.\n"
 msgstr ""
+"Не можете да обновите отдалечен указател, който вече сочи към обект, който "
+"не е\n"
+"подаване, както и тепърва да го промените да сочи към подобен обект, без да\n"
+"укажете опцията опцията „--force“.\n"
 
-#: builtin/push.c:375
+#: builtin/push.c:361
 #, c-format
 msgid "Pushing to %s\n"
-msgstr ""
+msgstr "Изтласкване към „%s“\n"
 
-#: builtin/push.c:379
+#: builtin/push.c:365
 #, c-format
 msgid "failed to push some refs to '%s'"
-msgstr ""
+msgstr "част от указателите не бяха изтласкани към „%s“"
 
-#: builtin/push.c:412
+#: builtin/push.c:395
 #, c-format
 msgid "bad repository '%s'"
-msgstr ""
+msgstr "неправилно указано хранилище „%s“"
 
-#: builtin/push.c:413
+#: builtin/push.c:396
 msgid ""
 "No configured push destination.\n"
 "Either specify the URL from the command-line or configure a remote "
@@ -7725,98 +8087,111 @@ msgid ""
 "\n"
 "    git push <name>\n"
 msgstr ""
+"Не е указано хранилище, към което да се изтласква.\n"
+"Или укажете адреса на командния ред, или настройте отдалечено хранилище с "
+"командата:\n"
+"\n"
+"    git remote add ИМЕ АДРЕС\n"
+"\n"
+"и след това изтласкайте, като укажете името на отдалеченото хранилище:\n"
+"\n"
+"    git push ИМЕ\n"
 
-#: builtin/push.c:428
+#: builtin/push.c:411
 msgid "--all and --tags are incompatible"
-msgstr ""
+msgstr "опциите „--all“ и „--tags“ са несъвместими"
 
-#: builtin/push.c:429
+#: builtin/push.c:412
 msgid "--all can't be combined with refspecs"
-msgstr ""
+msgstr "опцията „--all“ е несъвместима с указването на версия"
 
-#: builtin/push.c:434
+#: builtin/push.c:417
 msgid "--mirror and --tags are incompatible"
-msgstr ""
+msgstr "опциите „--mirror“ и „--tags“ са несъвместими"
 
-#: builtin/push.c:435
+#: builtin/push.c:418
 msgid "--mirror can't be combined with refspecs"
-msgstr ""
+msgstr "опцията „--mirror“ е несъвместима с указването на версия"
 
-#: builtin/push.c:440
+#: builtin/push.c:423
 msgid "--all and --mirror are incompatible"
-msgstr ""
+msgstr "опциите „--all“ и „--mirror“ са несъвместими"
 
-#: builtin/push.c:500
+#: builtin/push.c:483
 msgid "repository"
-msgstr ""
+msgstr "хранилище"
 
-#: builtin/push.c:501
+#: builtin/push.c:484
 msgid "push all refs"
-msgstr ""
+msgstr "изтласкване на всички указатели"
 
-#: builtin/push.c:502
+#: builtin/push.c:485
 msgid "mirror all refs"
-msgstr ""
+msgstr "огледално копие на всички указатели"
 
-#: builtin/push.c:504
+#: builtin/push.c:487
 msgid "delete refs"
-msgstr ""
+msgstr "изтриване на указателите"
 
-#: builtin/push.c:505
+#: builtin/push.c:488
 msgid "push tags (can't be used with --all or --mirror)"
-msgstr ""
+msgstr "изтласкване на етикетите (несъвместимо с опциите „--all“ и „--mirror“)"
 
-#: builtin/push.c:508
+#: builtin/push.c:491
 msgid "force updates"
-msgstr ""
+msgstr "принудително обновяване"
 
-#: builtin/push.c:510
+# # FIXME double check this
+#: builtin/push.c:493
 msgid "refname>:<expect"
-msgstr ""
+msgstr "УКАЗАТЕЛ>:<ОЧАКВАНА_СТОЙНОСТ"
 
-#: builtin/push.c:511
+#: builtin/push.c:494
 msgid "require old value of ref to be at this value"
-msgstr ""
+msgstr "УКАЗАТЕЛят трябва първоначално да е с тази ОЧАКВАНА_СТОЙНОСТ"
 
-#: builtin/push.c:513
+#: builtin/push.c:496
 msgid "check"
-msgstr ""
+msgstr "проверка"
 
-#: builtin/push.c:514
+#: builtin/push.c:497
 msgid "control recursive pushing of submodules"
-msgstr ""
+msgstr "управление на рекурсивното изтласкване на подмодулите"
 
-#: builtin/push.c:516
+#: builtin/push.c:499
 msgid "use thin pack"
-msgstr ""
+msgstr "използване на съкратени пакети"
 
-#: builtin/push.c:517 builtin/push.c:518
+#: builtin/push.c:500 builtin/push.c:501
 msgid "receive pack program"
-msgstr ""
+msgstr "програма за получаването на пакети"
 
-#: builtin/push.c:519
+#: builtin/push.c:502
 msgid "set upstream for git pull/status"
-msgstr ""
+msgstr "задаване на отдалеченото хранилище за командите „git pull/status“"
 
-#: builtin/push.c:522
+#: builtin/push.c:505
 msgid "prune locally removed refs"
-msgstr ""
+msgstr "окастряне на указателите, които са премахнати от локалното хранилище"
 
-#: builtin/push.c:524
+#: builtin/push.c:507
 msgid "bypass pre-push hook"
-msgstr ""
+msgstr "без изпълнение на куката преди изтласкване (pre-push)"
 
-#: builtin/push.c:525
+#: builtin/push.c:508
 msgid "push missing but relevant tags"
 msgstr ""
+"изтласкване на липсващите в отдалеченото хранилище, но свързани с текущото "
+"изтласкване, етикети"
 
-#: builtin/push.c:535
+#: builtin/push.c:518
 msgid "--delete is incompatible with --all, --mirror and --tags"
 msgstr ""
+"опцията „--delete“ е несъвместима с опциите  „--all“, „--mirror“ и „--tags“"
 
-#: builtin/push.c:537
+#: builtin/push.c:520
 msgid "--delete doesn't make sense without any refs"
-msgstr ""
+msgstr "опцията „--delete“ изисква поне един указател на версия"
 
 #: builtin/read-tree.c:36
 msgid ""
@@ -7909,92 +8284,93 @@ msgid ""
 "git remote add [-t <branch>] [-m <master>] [-f] [--tags|--no-tags] [--"
 "mirror=<fetch|push>] <name> <url>"
 msgstr ""
-"git remote add [-t <КЛОН>] [-m <ОСНОВЕН_КЛОН>] [-f] [--tags|--no-tags] [--"
-"mirror=<fetch|push>] <ИМЕ> <АДРЕС>"
+"git remote add [-t КЛОН] [-m ОСНОВЕН_КЛОН] [-f] [--tags|--no-tags] [--"
+"mirror=<fetch|push>] ИМЕ АДРЕС"
 
 #: builtin/remote.c:14 builtin/remote.c:33
 msgid "git remote rename <old> <new>"
-msgstr "git remote rename <СТАРО_ИМЕ> <НОВО_ИМЕ>"
+msgstr "git remote rename СТАРО_ИМЕ НОВО_ИМЕ"
 
 #: builtin/remote.c:15 builtin/remote.c:38
 msgid "git remote remove <name>"
-msgstr "git remote remove <ИМЕ>"
+msgstr "git remote remove ИМЕ"
 
 #: builtin/remote.c:16
 msgid "git remote set-head <name> (-a | --auto | -d | --delete |<branch>)"
-msgstr "git remote set-head <ИМЕ> (-a | --auto | -d | --delete |<КЛОН>)"
+msgstr "git remote set-head ИМЕ (-a | --auto | -d | --delete | КЛОН)"
 
 #: builtin/remote.c:17
 msgid "git remote [-v | --verbose] show [-n] <name>"
-msgstr "git remote [-v | --verbose] show [-n] <ИМЕ>"
+msgstr "git remote [-v | --verbose] show [-n] ИМЕ"
 
 #: builtin/remote.c:18
 msgid "git remote prune [-n | --dry-run] <name>"
-msgstr "git remote prune [-n | --dry-run] <ИМЕ>"
+msgstr "git remote prune [-n | --dry-run] ИМЕ"
 
 #: builtin/remote.c:19
 msgid ""
 "git remote [-v | --verbose] update [-p | --prune] [(<group> | <remote>)...]"
 msgstr ""
-"git remote [-v | --verbose] update [-p | --prune] [(<ГРУПА> | "
-"<ОТДАЛЕЧЕНО_ХРАНИЛИЩЕ>)…]"
+"git remote [-v | --verbose] update [-p | --prune] [(ГРУПА | "
+"ОТДАЛЕЧЕНО_ХРАНИЛИЩЕ)…]"
 
 #: builtin/remote.c:20
 msgid "git remote set-branches [--add] <name> <branch>..."
-msgstr "git remote set-branches [--add] <ИМЕ> <КЛОН>…"
+msgstr "git remote set-branches [--add] ИМЕ КЛОН…"
 
 #: builtin/remote.c:21 builtin/remote.c:69
 msgid "git remote set-url [--push] <name> <newurl> [<oldurl>]"
-msgstr "git remote set-url [--push] <ИМЕ> <НОВ_АДРЕС> [<СТАР_АДРЕС>]"
+msgstr "git remote set-url [--push] ИМЕ НОВ_АДРЕС [СТАР_АДРЕС]"
 
 #: builtin/remote.c:22 builtin/remote.c:70
 msgid "git remote set-url --add <name> <newurl>"
-msgstr "git remote set-url --add <ИМЕ> <НОВ_АДРЕС>"
+msgstr "git remote set-url --add ИМЕ НОВ_АДРЕС"
 
 #: builtin/remote.c:23 builtin/remote.c:71
 msgid "git remote set-url --delete <name> <url>"
-msgstr "git remote set-url --delete <ИМЕ> <АДРЕС>"
+msgstr "git remote set-url --delete ИМЕ АДРЕС"
 
 #: builtin/remote.c:28
 msgid "git remote add [<options>] <name> <url>"
-msgstr "git remote add [<ОПЦИИ>] <ИМЕ> <АДРЕС>"
+msgstr "git remote add [ОПЦИИ] ИМЕ АДРЕС"
 
 #: builtin/remote.c:43
 msgid "git remote set-head <name> (-a | --auto | -d | --delete | <branch>)"
-msgstr "git remote set-head <ИМЕ> (-a | --auto | -d | --delete | <КЛОН>)"
+msgstr "git remote set-head ИМЕ (-a | --auto | -d | --delete | КЛОН)"
 
 #: builtin/remote.c:48
 msgid "git remote set-branches <name> <branch>..."
-msgstr "git remote set-branches <ИМЕ> <КЛОН>…"
+msgstr "git remote set-branches ИМЕ КЛОН…"
 
 #: builtin/remote.c:49
 msgid "git remote set-branches --add <name> <branch>..."
-msgstr "git remote set-branches --add <ИМЕ> <КЛОН>…"
+msgstr "git remote set-branches --add ИМЕ КЛОН…"
 
 #: builtin/remote.c:54
 msgid "git remote show [<options>] <name>"
-msgstr "git remote show [<ОПЦИИ>] <ИМЕ>"
+msgstr "git remote show [ОПЦИИ] ИМЕ"
 
 #: builtin/remote.c:59
 msgid "git remote prune [<options>] <name>"
-msgstr "git remote prune [<ОПЦИИ>] <ИМЕ>"
+msgstr "git remote prune [ОПЦИИ] ИМЕ"
 
 #: builtin/remote.c:64
 msgid "git remote update [<options>] [<group> | <remote>]..."
-msgstr "git remote update [<ОПЦИИ>] [<ГРУПА> | <ОТДАЛЕЧЕНО_ХРАНИЛИЩЕ>]…"
+msgstr "git remote update [ОПЦИИ] [ГРУПА | ОТДАЛЕЧЕНО_ХРАНИЛИЩЕ]…"
 
 #: builtin/remote.c:88
 #, c-format
 msgid "Updating %s"
 msgstr "Обновяване на „%s“"
 
+# FIXME tabulator
 #: builtin/remote.c:120
 msgid ""
 "--mirror is dangerous and deprecated; please\n"
 "\t use --mirror=fetch or --mirror=push instead"
 msgstr ""
 "Използването само на „--mirror“ е опасно. Вместо това\n"
-"\tползвайте „--mirror=fetch“ или „--mirror=push“"
+"ползвайте „--mirror=fetch“ или „--mirror=push“"
 
 #: builtin/remote.c:137
 #, c-format
@@ -8087,14 +8463,14 @@ msgstr "Такова отдалечено хранилище няма: %s"
 #: builtin/remote.c:651
 #, c-format
 msgid "Could not rename config section '%s' to '%s'"
-msgstr "СекÑ\86иÑ\8fÑ\82а Ð² Ð½Ð°Ñ\81Ñ\82Ñ\80ойкиÑ\82е â\80\9e%sâ\80\9c Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð´Ð° Ð±Ñ\8aде Ð¿Ñ\80еименÑ\83вана на „%s“"
+msgstr "РазделÑ\8aÑ\82 â\80\9e%sâ\80\9c Ð² Ð½Ð°Ñ\81Ñ\82Ñ\80ойкиÑ\82е Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð´Ð° Ð±Ñ\8aде Ð¿Ñ\80еименÑ\83ван на „%s“"
 
 #: builtin/remote.c:657 builtin/remote.c:794
 #, c-format
 msgid "Could not remove config section '%s'"
-msgstr "СекÑ\86иÑ\8fÑ\82а Ð² Ð½Ð°Ñ\81Ñ\82Ñ\80ойкиÑ\82е â\80\9e%sâ\80\9c Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð´Ð° Ð±Ñ\8aде Ð¸Ð·Ñ\82Ñ\80иÑ\82а"
+msgstr "РазделÑ\8aÑ\82 â\80\9e%sâ\80\9c Ð² Ð½Ð°Ñ\81Ñ\82Ñ\80ойкиÑ\82е Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð´Ð° Ð±Ñ\8aде Ð¸Ð·Ñ\82Ñ\80иÑ\82"
 
-# FIXME
+# FIXME tabulator
 #: builtin/remote.c:672
 #, c-format
 msgid ""
@@ -8109,12 +8485,12 @@ msgstr ""
 #: builtin/remote.c:678
 #, c-format
 msgid "Could not append '%s'"
-msgstr "СекÑ\86иÑ\8fÑ\82а â\80\9e%sâ\80\9c Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð´Ð° Ð±Ñ\8aде Ð´Ð¾Ð±Ð°Ð²ÐµÐ½Ð° в настройките"
+msgstr "РазделÑ\8aÑ\82 â\80\9e%sâ\80\9c Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð´Ð° Ð±Ñ\8aде Ð´Ð¾Ð±Ð°Ð²ÐµÐ½ в настройките"
 
 #: builtin/remote.c:689
 #, c-format
 msgid "Could not set '%s'"
-msgstr "СекÑ\86иÑ\8fÑ\82а â\80\9e%sâ\80\9c Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð´Ð° Ð±Ñ\8aде Ð·Ð°Ð´Ð°Ð´ÐµÐ½Ð° в настройките"
+msgstr "РазделÑ\8aÑ\82 â\80\9e%sâ\80\9c Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð´Ð° Ð±Ñ\8aде Ð·Ð°Ð´Ð°Ð´ÐµÐ½ в настройките"
 
 #: builtin/remote.c:711
 #, c-format
@@ -8158,6 +8534,7 @@ msgstr " следен"
 msgid " stale (use 'git remote prune' to remove)"
 msgstr " стар (изтрийте чрез „git remote prune“)"
 
+# FIXME
 #: builtin/remote.c:945
 msgid " ???"
 msgstr " неясно"
@@ -8240,7 +8617,7 @@ msgstr "без заявки към отдалечените хранилища"
 #: builtin/remote.c:1171
 #, c-format
 msgid "* remote %s"
-msgstr "* отдалечено хранилище „%s“"
+msgstr " отдалечено хранилище „%s“"
 
 #: builtin/remote.c:1172
 #, c-format
@@ -8299,11 +8676,11 @@ msgstr[1] "  Локалните указатели, настроени за „g
 
 #: builtin/remote.c:1252
 msgid "set refs/remotes/<name>/HEAD according to remote"
-msgstr "задаване на refs/remotes/<ИМЕ>/HEAD според отдалеченото хранилище"
+msgstr "задаване на refs/remotes/ИМЕ/HEAD според отдалеченото хранилище"
 
 #: builtin/remote.c:1254
 msgid "delete refs/remotes/<name>/HEAD"
-msgstr "изтриване на refs/remotes/<ИМЕ>/HEAD"
+msgstr "изтриване на refs/remotes/ИМЕ/HEAD"
 
 #: builtin/remote.c:1269
 msgid "Cannot determine remote HEAD"
@@ -8352,12 +8729,12 @@ msgstr "адрес: %s"
 #: builtin/remote.c:1328
 #, c-format
 msgid " * [would prune] %s"
-msgstr " * [ще бъде окастрено] %s"
+msgstr "  [ще бъде окастрено] %s"
 
 #: builtin/remote.c:1331
 #, c-format
 msgid " * [pruned] %s"
-msgstr " * [окастрено] %s"
+msgstr "  [окастрено] %s"
 
 #: builtin/remote.c:1374
 msgid "prune remotes after fetching"
@@ -8402,7 +8779,7 @@ msgstr "Неправилен (стар) формат за адрес: %s"
 msgid "No such URL found: %s"
 msgstr "Такъв адрес не е открит: %s"
 
-# MEANING
+# FIXME CHECK MEANING
 #: builtin/remote.c:1550
 msgid "Will not delete all non-push URLs"
 msgstr "Никой от адресите, които не са за изтласкване, няма да се изтрие"
@@ -8411,242 +8788,269 @@ msgstr "Никой от адресите, които не са за изтлас
 msgid "be verbose; must be placed before a subcommand"
 msgstr "повече подробности. Поставя се пред подкоманда"
 
-#: builtin/repack.c:15
+#: builtin/repack.c:16
 msgid "git repack [options]"
 msgstr ""
 
-#: builtin/repack.c:143
+#: builtin/repack.c:156
 msgid "pack everything in a single pack"
 msgstr ""
 
-#: builtin/repack.c:145
+#: builtin/repack.c:158
 msgid "same as -a, and turn unreachable objects loose"
 msgstr ""
 
-#: builtin/repack.c:148
+#: builtin/repack.c:161
 msgid "remove redundant packs, and run git-prune-packed"
 msgstr ""
 
-#: builtin/repack.c:150
+#: builtin/repack.c:163
 msgid "pass --no-reuse-delta to git-pack-objects"
 msgstr ""
 
-#: builtin/repack.c:152
+#: builtin/repack.c:165
 msgid "pass --no-reuse-object to git-pack-objects"
 msgstr ""
 
-#: builtin/repack.c:154
+#: builtin/repack.c:167
 msgid "do not run git-update-server-info"
 msgstr ""
 
-#: builtin/repack.c:157
+#: builtin/repack.c:170
 msgid "pass --local to git-pack-objects"
 msgstr ""
 
-#: builtin/repack.c:158
+#: builtin/repack.c:172
+msgid "write bitmap index"
+msgstr ""
+
+#: builtin/repack.c:173
 msgid "approxidate"
 msgstr ""
 
-#: builtin/repack.c:159
+#: builtin/repack.c:174
 msgid "with -A, do not loosen objects older than this"
 msgstr ""
 
-#: builtin/repack.c:161
+#: builtin/repack.c:176
 msgid "size of the window used for delta compression"
 msgstr ""
 
-#: builtin/repack.c:163
+#: builtin/repack.c:177 builtin/repack.c:181
+msgid "bytes"
+msgstr ""
+
+#: builtin/repack.c:178
 msgid "same as the above, but limit memory size instead of entries count"
 msgstr ""
 
-#: builtin/repack.c:165
+#: builtin/repack.c:180
 msgid "limits the maximum delta depth"
 msgstr ""
 
-#: builtin/repack.c:167
+#: builtin/repack.c:182
 msgid "maximum size of each packfile"
 msgstr ""
 
-#: builtin/repack.c:343
+#: builtin/repack.c:184
+msgid "repack objects in packs marked with .keep"
+msgstr ""
+
+#: builtin/repack.c:371
 #, c-format
 msgid "removing '%s' failed"
 msgstr ""
 
 #: builtin/replace.c:17
 msgid "git replace [-f] <object> <replacement>"
-msgstr ""
+msgstr "git replace [-f] ОБЕКТ ЗАМЯНА"
 
 #: builtin/replace.c:18
 msgid "git replace -d <object>..."
-msgstr ""
+msgstr "git replace -d ОБЕКТ…"
 
 #: builtin/replace.c:19
 msgid "git replace [--format=<format>] [-l [<pattern>]]"
-msgstr ""
+msgstr "git replace [--format=ФОРМАТ] [-l [ШАБЛОН]]"
 
 #: builtin/replace.c:174
 msgid "list replace refs"
-msgstr ""
+msgstr "извеждане на списъка с указателите за замяна"
 
 #: builtin/replace.c:175
 msgid "delete replace refs"
-msgstr ""
+msgstr "изтриване на указателите за замяна"
 
 #: builtin/replace.c:176
 msgid "replace the ref if it exists"
-msgstr ""
+msgstr "замяна на указателите, ако съществуват"
 
 #: builtin/replace.c:177
 msgid "use this format"
-msgstr ""
+msgstr "използване на този ФОРМАТ"
 
 #: builtin/rerere.c:12
 msgid "git rerere [clear | forget path... | status | remaining | diff | gc]"
-msgstr ""
+msgstr "git rerere [clear | forget ПЪТ… | status | remaining | diff | gc]"
 
 #: builtin/rerere.c:57
 msgid "register clean resolutions in index"
-msgstr ""
+msgstr "регистриране на чисти корекции на конфликти в индекса"
 
 #: builtin/reset.c:25
 msgid ""
 "git reset [--mixed | --soft | --hard | --merge | --keep] [-q] [<commit>]"
 msgstr ""
+"git reset [--mixed | --soft | --hard | --merge | --keep] [-q] [ПОДАВАНЕ]"
 
 #: builtin/reset.c:26
 msgid "git reset [-q] <tree-ish> [--] <paths>..."
-msgstr ""
+msgstr "git reset [-q] ДЪРВО [--] ПЪТИЩА…"
 
 #: builtin/reset.c:27
 msgid "git reset --patch [<tree-ish>] [--] [<paths>...]"
-msgstr ""
+msgstr "git reset --patch [ДЪРВО] [--] [ПЪТИЩА…]"
 
 #: builtin/reset.c:33
 msgid "mixed"
-msgstr ""
+msgstr "смесено (mixed)"
 
 #: builtin/reset.c:33
 msgid "soft"
-msgstr ""
+msgstr "меко (soft)"
 
 #: builtin/reset.c:33
 msgid "hard"
-msgstr ""
+msgstr "пълно (hard)"
 
 #: builtin/reset.c:33
 msgid "merge"
-msgstr ""
+msgstr "слято (merge)"
 
 #: builtin/reset.c:33
 msgid "keep"
-msgstr ""
+msgstr "запазващо (keep)"
 
 #: builtin/reset.c:73
 msgid "You do not have a valid HEAD."
-msgstr ""
+msgstr "Указателят „HEAD“ е повреден."
 
 #: builtin/reset.c:75
 msgid "Failed to find tree of HEAD."
-msgstr ""
+msgstr "Дървото, сочено от указателя „HEAD“, не може да бъде открито."
 
 #: builtin/reset.c:81
 #, c-format
 msgid "Failed to find tree of %s."
-msgstr ""
+msgstr "Дървото, сочено от „%s“, не може да бъде открито."
 
 #: builtin/reset.c:99
 #, c-format
 msgid "HEAD is now at %s"
-msgstr ""
+msgstr "Указателят „HEAD“ сочи към „%s“"
 
-#: builtin/reset.c:172
+#: builtin/reset.c:182
 #, c-format
 msgid "Cannot do a %s reset in the middle of a merge."
-msgstr ""
+msgstr "Не може да се извърши %s зануляване по време на сливане."
 
-#: builtin/reset.c:262
+#: builtin/reset.c:273
 msgid "be quiet, only report errors"
-msgstr ""
+msgstr "по-малко подробности, да се извеждат само грешките"
 
-#: builtin/reset.c:264
+#: builtin/reset.c:275
 msgid "reset HEAD and index"
-msgstr ""
+msgstr "индекса и указателя „HEAD“, без работното дърво"
 
-#: builtin/reset.c:265
+#: builtin/reset.c:276
 msgid "reset only HEAD"
-msgstr ""
+msgstr "само указателя „HEAD“, без индекса и работното дърво"
 
-#: builtin/reset.c:267 builtin/reset.c:269
+# FIXME vs man page
+#: builtin/reset.c:278 builtin/reset.c:280
 msgid "reset HEAD, index and working tree"
-msgstr ""
+msgstr "указателя „HEAD“, индекса и работното дърво"
 
-#: builtin/reset.c:271
+# FIXME vs man page
+#: builtin/reset.c:282
 msgid "reset HEAD but keep local changes"
+msgstr "зануляване на указателя „HEAD“, но запазване на локалните промени"
+
+#: builtin/reset.c:285
+msgid "record only the fact that removed paths will be added later"
 msgstr ""
+"отбелязване само на факта, че изтритите пътища ще бъдат добавени по-късно"
 
-#: builtin/reset.c:289
+#: builtin/reset.c:302
 #, c-format
 msgid "Failed to resolve '%s' as a valid revision."
-msgstr ""
+msgstr "Стойността „%s“ не е разпозната като съществуваща версия."
 
-#: builtin/reset.c:292 builtin/reset.c:300
+#: builtin/reset.c:305 builtin/reset.c:313
 #, c-format
 msgid "Could not parse object '%s'."
-msgstr ""
+msgstr "„%s“ не е разпознат като обект."
 
-#: builtin/reset.c:297
+#: builtin/reset.c:310
 #, c-format
 msgid "Failed to resolve '%s' as a valid tree."
-msgstr ""
+msgstr "„%s“ не е разпознат като дърво."
 
-#: builtin/reset.c:306
+#: builtin/reset.c:319
 msgid "--patch is incompatible with --{hard,mixed,soft}"
 msgstr ""
+"опцията „--patch“ е несъвместима с всяка от опциите „--hard/--mixed/--soft“"
 
-#: builtin/reset.c:315
+#: builtin/reset.c:328
 msgid "--mixed with paths is deprecated; use 'git reset -- <paths>' instead."
 msgstr ""
+"опцията „--mixed“ не бива да се използва заедно с пътища. Вместо това "
+"изпълнете „git reset -- ПЪТ…“."
 
-#: builtin/reset.c:317
+#: builtin/reset.c:330
 #, c-format
 msgid "Cannot do %s reset with paths."
-msgstr ""
+msgstr "Не може да извършите %s зануляване, когато сте задали ПЪТ."
 
-#: builtin/reset.c:327
+#: builtin/reset.c:340
 #, c-format
 msgid "%s reset is not allowed in a bare repository"
-msgstr ""
+msgstr "В голо хранилище не може да извършите %s зануляване"
 
 #: builtin/reset.c:344
+msgid "-N can only be used with --mixed"
+msgstr "Опцията „-N“ е съвместима само с „--mixed“"
+
+#: builtin/reset.c:361
 msgid "Unstaged changes after reset:"
-msgstr ""
+msgstr "Промени извън индекса след зануляването:"
 
-#: builtin/reset.c:350
+#: builtin/reset.c:367
 #, c-format
 msgid "Could not reset index file to revision '%s'."
-msgstr ""
+msgstr "Индексът не може да бъде занулен към версия „%s“."
 
-#: builtin/reset.c:355
+#: builtin/reset.c:372
 msgid "Could not write new index file."
-msgstr ""
+msgstr "Новият индекс не може да бъде записан."
 
 #: builtin/rev-parse.c:359
 msgid "git rev-parse --parseopt [options] -- [<args>...]"
-msgstr ""
+msgstr "git rev-parse --parseopt [ОПЦИИ] -- [АРГУМЕНТИ…]"
 
 #: builtin/rev-parse.c:364
 msgid "keep the `--` passed as an arg"
-msgstr ""
+msgstr "зададеният низ „--“ да се тълкува като аргумент"
 
 #: builtin/rev-parse.c:366
 msgid "stop parsing after the first non-option argument"
-msgstr ""
+msgstr "спиране на анализа след първия аргумент, който не е опция"
 
 #: builtin/rev-parse.c:369
 msgid "output in stuck long form"
-msgstr ""
+msgstr "изход в дългия формат"
 
-#: builtin/rev-parse.c:486
+#: builtin/rev-parse.c:497
 msgid ""
 "git rev-parse --parseopt [options] -- [<args>...]\n"
 "   or: git rev-parse --sq-quote [<arg>...]\n"
@@ -8654,99 +9058,105 @@ msgid ""
 "\n"
 "Run \"git rev-parse --parseopt -h\" for more information on the first usage."
 msgstr ""
+"git rev-parse --parseopt [ОПЦИИ] -- [АРГУМЕНТИ…]\n"
+"   или: git rev-parse --sq-quote [АРГУМЕНТИ…]\n"
+"   или: git rev-parse [ОПЦИИ] [АРГУМЕНТИ…]\n"
+"\n"
+"За повече информация за първия вариант изпълнете „git rev-parse --parseopt -"
+"h“"
 
 #: builtin/revert.c:22
 msgid "git revert [options] <commit-ish>..."
-msgstr ""
+msgstr "git revert [ОПЦИИ] УКАЗАТЕЛ_КЪМ_ПОДАВАНЕ…"
 
 #: builtin/revert.c:23
 msgid "git revert <subcommand>"
-msgstr ""
+msgstr "git revert ПОДКОМАНДА"
 
 #: builtin/revert.c:28
 msgid "git cherry-pick [options] <commit-ish>..."
-msgstr ""
+msgstr "git cherry-pick [ОПЦИИ] УКАЗАТЕЛ_КЪМ_ПОДАВАНЕ…"
 
 #: builtin/revert.c:29
 msgid "git cherry-pick <subcommand>"
-msgstr ""
+msgstr "git cherry-pick ПОДКОМАНДА"
 
 #: builtin/revert.c:71
 #, c-format
 msgid "%s: %s cannot be used with %s"
-msgstr ""
+msgstr "%s: опцията „%s“ е несъвместима с „%s“"
 
 #: builtin/revert.c:80
 msgid "end revert or cherry-pick sequence"
-msgstr ""
+msgstr "завършване на поредица от отбиране или отмяна на подавания"
 
 #: builtin/revert.c:81
 msgid "resume revert or cherry-pick sequence"
-msgstr ""
+msgstr "завършване на поредица от отбиране или отмяна на подавания"
 
 #: builtin/revert.c:82
 msgid "cancel revert or cherry-pick sequence"
-msgstr ""
+msgstr "отмяна на поредица от отбиране или отмяна на подавания"
 
 #: builtin/revert.c:83
 msgid "don't automatically commit"
-msgstr ""
+msgstr "без автоматично подаване"
 
 #: builtin/revert.c:84
 msgid "edit the commit message"
-msgstr ""
+msgstr "редактиране на съобщението при подаване"
 
 #: builtin/revert.c:87
 msgid "parent number"
-msgstr ""
+msgstr "номер на родителя"
 
 #: builtin/revert.c:89
 msgid "merge strategy"
-msgstr ""
+msgstr "стратегия на сливане"
 
 #: builtin/revert.c:90
 msgid "option"
-msgstr ""
+msgstr "опция"
 
 #: builtin/revert.c:91
 msgid "option for merge strategy"
-msgstr ""
+msgstr "опция за стратегията на сливане"
 
-#: builtin/revert.c:102
+#: builtin/revert.c:104
 msgid "append commit name"
-msgstr ""
+msgstr "добавяне на името на подаването"
 
-#: builtin/revert.c:103
+#: builtin/revert.c:105
 msgid "allow fast-forward"
-msgstr ""
+msgstr "позволяване на тривиални сливания"
 
-#: builtin/revert.c:104
+#: builtin/revert.c:106
 msgid "preserve initially empty commits"
-msgstr ""
+msgstr "запазване на първоначално празните подавания"
 
-#: builtin/revert.c:105
+#: builtin/revert.c:107
 msgid "allow commits with empty messages"
-msgstr ""
+msgstr "позволяване на празни съобщения при подаване"
 
-#: builtin/revert.c:106
+#: builtin/revert.c:108
 msgid "keep redundant, empty commits"
-msgstr ""
+msgstr "запазване на излишните, празни подавания"
 
-#: builtin/revert.c:110
+#: builtin/revert.c:112
 msgid "program error"
-msgstr ""
+msgstr "грешка в програмата"
 
-#: builtin/revert.c:195
+#: builtin/revert.c:197
 msgid "revert failed"
-msgstr ""
+msgstr "неуспешна отмяна"
 
-#: builtin/revert.c:210
+#: builtin/revert.c:212
 msgid "cherry-pick failed"
-msgstr ""
+msgstr "неуспешно отбиране"
 
 #: builtin/rm.c:17
 msgid "git rm [options] [--] <file>..."
-msgstr "git rm [ОПЦИИ] [--] <ФАЙЛ>…"
+msgstr "git rm [ОПЦИИ] [--] ФАЙЛ…"
 
 #: builtin/rm.c:65
 msgid ""
@@ -8756,11 +9166,13 @@ msgid_plural ""
 "the following submodules (or one of its nested submodules)\n"
 "use a .git directory:"
 msgstr[0] ""
-"следният подмодул или някой от неговите подмодули\n"
-"използват директория на име „.git“:"
+"следният подмодул или някой от неговите подмодули използват директория на "
+"име\n"
+"„.git“:"
 msgstr[1] ""
-"следните подмодули или някои от техните подмодули\n"
-"използват директория на име „.git“:"
+"следните подмодули или някои от техните подмодули използват директория на "
+"име\n"
+"„.git“:"
 
 #: builtin/rm.c:71
 msgid ""
@@ -8877,92 +9289,95 @@ msgid "Linewrap output"
 msgstr ""
 
 #: builtin/show-branch.c:9
-#, fuzzy
 msgid ""
 "git show-branch [-a|--all] [-r|--remotes] [--topo-order | --date-order] [--"
 "current] [--color[=<when>] | --no-color] [--sparse] [--more=<n> | --list | --"
 "independent | --merge-base] [--no-name | --sha1-name] [--topics] [(<rev> | "
 "<glob>)...]"
-msgstr "<брой>"
+msgstr ""
+"git show-branch [-a|--all] [-r|--remotes] [--topo-order | --date-order] [--"
+"current] [--color[=КОГА] | --no-color] [--sparse] [--more=БРОЙ | --list | --"
+"independent | --merge-base] [--no-name | --sha1-name] [--topics] [(РЕВИЗИЯ | "
+"УКАЗАТЕЛ)…]"
 
 #: builtin/show-branch.c:10
-#, fuzzy
 msgid "git show-branch (-g|--reflog)[=<n>[,<base>]] [--list] [<ref>]"
-msgstr "<брой>"
+msgstr "git show-branch (-g|--reflog)[=БРОЙ[,БАЗА]] [--list] [УКАЗАТЕЛ]"
 
 #: builtin/show-branch.c:649
 msgid "show remote-tracking and local branches"
-msgstr ""
+msgstr "извеждане на следящите и локалните клони"
 
 #: builtin/show-branch.c:651
 msgid "show remote-tracking branches"
-msgstr ""
+msgstr "извеждане на следящите клони"
 
 #: builtin/show-branch.c:653
 msgid "color '*!+-' corresponding to the branch"
-msgstr ""
+msgstr "оцветяване на „*!+-“ според клоните"
 
 #: builtin/show-branch.c:655
-#, fuzzy
 msgid "show <n> more commits after the common ancestor"
-msgstr "<брой>"
+msgstr "извеждане на такъв БРОЙ подавания от общия предшественик"
 
 #: builtin/show-branch.c:657
 msgid "synonym to more=-1"
-msgstr ""
+msgstr "синоним на „more=-1“"
 
 #: builtin/show-branch.c:658
 msgid "suppress naming strings"
-msgstr ""
+msgstr "без низове за имената на клоните"
 
 #: builtin/show-branch.c:660
 msgid "include the current branch"
-msgstr ""
+msgstr "включване и на текущия клон"
 
 #: builtin/show-branch.c:662
 msgid "name commits with their object names"
-msgstr ""
+msgstr "именоване на подаванията с имената им на обекти"
 
 #: builtin/show-branch.c:664
 msgid "show possible merge bases"
-msgstr ""
+msgstr "извеждане на възможните бази за сливания"
 
 #: builtin/show-branch.c:666
 msgid "show refs unreachable from any other ref"
-msgstr ""
+msgstr "извеждане на недостижимите указатели"
 
 #: builtin/show-branch.c:668
 msgid "show commits in topological order"
-msgstr ""
+msgstr "извеждане на подаванията в топологическа подредба"
 
 #: builtin/show-branch.c:671
 msgid "show only commits not on the first branch"
-msgstr ""
+msgstr "извеждане само на подаванията, които не са от първия клон"
 
 #: builtin/show-branch.c:673
 msgid "show merges reachable from only one tip"
-msgstr ""
+msgstr "извеждане на сливанията, които могат да се достигнат само от един връх"
 
 #: builtin/show-branch.c:675
 msgid "topologically sort, maintaining date order where possible"
 msgstr ""
+"топологическа подредба, при запазване на подредбата по дата, доколкото е\n"
+"възможно"
 
 #: builtin/show-branch.c:678
-#, fuzzy
 msgid "<n>[,<base>]"
-msgstr "<брой>"
+msgstr "БРОЙ[,БАЗА]"
 
 #: builtin/show-branch.c:679
-#, fuzzy
 msgid "show <n> most recent ref-log entries starting at base"
-msgstr "<брой>"
+msgstr "показване на най-много БРОЙ журнални записа с начало съответната БАЗА"
 
+# FIXME * -> ...
 #: builtin/show-ref.c:10
-#, fuzzy
 msgid ""
 "git show-ref [-q|--quiet] [--verify] [--head] [-d|--dereference] [-s|--"
 "hash[=<n>]] [--abbrev[=<n>]] [--tags] [--heads] [--] [pattern*] "
-msgstr "<брой>"
+msgstr ""
+"git show-ref [-q|--quiet] [--verify] [--head] [-d|--dereference] [-s|--"
+"hash[=ЧИСЛО]] [--abbrev[=ЧИСЛО]] [--tags] [--heads] [--] [ШАБЛОН…]"
 
 #: builtin/show-ref.c:11
 msgid "git show-ref --exclude-existing[=pattern] < ref-list"
@@ -8989,9 +9404,8 @@ msgid "dereference tags into object IDs"
 msgstr ""
 
 #: builtin/show-ref.c:179
-#, fuzzy
 msgid "only show SHA1 hash using <n> digits"
-msgstr "<брой>"
+msgstr "извеждане само на този БРОЙ цифри от всяка сума по SHA1"
 
 #: builtin/show-ref.c:183
 msgid "do not print results to stdout (useful with --verify)"
@@ -9003,42 +9417,44 @@ msgstr ""
 
 #: builtin/symbolic-ref.c:7
 msgid "git symbolic-ref [options] name [ref]"
-msgstr ""
+msgstr "git symbolic-ref [ОПЦИИ] ИМЕ [УКАЗАТЕЛ]"
 
 #: builtin/symbolic-ref.c:8
 msgid "git symbolic-ref -d [-q] name"
-msgstr ""
+msgstr "git symbolic-ref -d [-q] ИМЕ"
 
 #: builtin/symbolic-ref.c:40
 msgid "suppress error message for non-symbolic (detached) refs"
-msgstr ""
+msgstr "без извеждане на грешка за несвързани (несимволни) указатели"
 
 #: builtin/symbolic-ref.c:41
 msgid "delete symbolic ref"
-msgstr ""
+msgstr "изтриване на символен указател"
 
 #: builtin/symbolic-ref.c:42
 msgid "shorten ref output"
-msgstr ""
+msgstr "кратка информация за указателя"
 
-#: builtin/symbolic-ref.c:43 builtin/update-ref.c:254
+#: builtin/symbolic-ref.c:43 builtin/update-ref.c:255
 msgid "reason"
-msgstr ""
+msgstr "причина"
 
-#: builtin/symbolic-ref.c:43 builtin/update-ref.c:254
+#: builtin/symbolic-ref.c:43 builtin/update-ref.c:255
 msgid "reason of the update"
-msgstr ""
+msgstr "причина за обновяването"
 
 #: builtin/tag.c:22
 msgid ""
 "git tag [-a|-s|-u <key-id>] [-f] [-m <msg>|-F <file>] <tagname> [<head>]"
 msgstr ""
+"git tag [-a|-s|-u ИДЕНТИФИКАТОР_НА_КЛЮЧ] [-f] [-m СЪОБЩЕНИЕ|-F ФАЙЛ] ЕТИКЕТ "
+"[ВРЪХ]"
 
 #: builtin/tag.c:23
 msgid "git tag -d <tagname>..."
 msgstr ""
 
-# FIXME
+# FIXME tabulator
 #: builtin/tag.c:24
 msgid ""
 "git tag -l [-n[<num>]] [--contains <commit>] [--points-at <object>] \n"
@@ -9049,32 +9465,32 @@ msgstr ""
 msgid "git tag -v <tagname>..."
 msgstr ""
 
-#: builtin/tag.c:60
+#: builtin/tag.c:67
 #, c-format
 msgid "malformed object at '%s'"
 msgstr ""
 
-#: builtin/tag.c:207
+#: builtin/tag.c:239
 #, c-format
 msgid "tag name too long: %.*s..."
 msgstr ""
 
-#: builtin/tag.c:212
+#: builtin/tag.c:244
 #, c-format
 msgid "tag '%s' not found."
 msgstr ""
 
-#: builtin/tag.c:227
+#: builtin/tag.c:259
 #, c-format
 msgid "Deleted tag '%s' (was %s)\n"
 msgstr ""
 
-#: builtin/tag.c:239
+#: builtin/tag.c:271
 #, c-format
 msgid "could not verify the tag '%s'"
 msgstr ""
 
-#: builtin/tag.c:249
+#: builtin/tag.c:281
 #, c-format
 msgid ""
 "\n"
@@ -9082,7 +9498,7 @@ msgid ""
 "Lines starting with '%c' will be ignored.\n"
 msgstr ""
 
-#: builtin/tag.c:253
+#: builtin/tag.c:285
 #, c-format
 msgid ""
 "\n"
@@ -9091,329 +9507,348 @@ msgid ""
 "want to.\n"
 msgstr ""
 
-#: builtin/tag.c:292
+#: builtin/tag.c:324
 msgid "unable to sign the tag"
 msgstr ""
 
-#: builtin/tag.c:294
+#: builtin/tag.c:326
 msgid "unable to write tag file"
 msgstr ""
 
-#: builtin/tag.c:319
+#: builtin/tag.c:351
 msgid "bad object type."
 msgstr ""
 
-#: builtin/tag.c:332
+#: builtin/tag.c:364
 msgid "tag header too big."
 msgstr ""
 
-#: builtin/tag.c:368
+#: builtin/tag.c:400
 msgid "no tag message?"
 msgstr ""
 
-#: builtin/tag.c:374
+#: builtin/tag.c:406
 #, c-format
 msgid "The tag message has been left in %s\n"
 msgstr ""
 
-#: builtin/tag.c:423
+#: builtin/tag.c:455
 msgid "switch 'points-at' requires an object"
 msgstr ""
 
-#: builtin/tag.c:425
+#: builtin/tag.c:457
 #, c-format
 msgid "malformed object name '%s'"
 msgstr ""
 
-#: builtin/tag.c:445
+#: builtin/tag.c:480
+#, c-format
+msgid "unsupported sort specification %s"
+msgstr "зададена е неподдържана подредба: „%s“"
+
+#: builtin/tag.c:500
 msgid "list tag names"
 msgstr ""
 
-#: builtin/tag.c:447
-#, fuzzy
+#: builtin/tag.c:502
 msgid "print <n> lines of each tag message"
-msgstr "<брой>"
+msgstr "извеждане на този БРОЙ редове от всяко съобщение за етикет"
 
-#: builtin/tag.c:449
+#: builtin/tag.c:504
 msgid "delete tags"
 msgstr ""
 
-#: builtin/tag.c:450
+#: builtin/tag.c:505
 msgid "verify tags"
 msgstr ""
 
-#: builtin/tag.c:452
+#: builtin/tag.c:507
 msgid "Tag creation options"
 msgstr ""
 
-#: builtin/tag.c:454
+#: builtin/tag.c:509
 msgid "annotated tag, needs a message"
 msgstr ""
 
-#: builtin/tag.c:456
+#: builtin/tag.c:511
 msgid "tag message"
 msgstr ""
 
-#: builtin/tag.c:458
+#: builtin/tag.c:513
 msgid "annotated and GPG-signed tag"
 msgstr ""
 
-#: builtin/tag.c:462
+#: builtin/tag.c:517
 msgid "use another key to sign the tag"
 msgstr ""
 
-#: builtin/tag.c:463
+#: builtin/tag.c:518
 msgid "replace the tag if exists"
 msgstr ""
 
-#: builtin/tag.c:464
+#: builtin/tag.c:519
 msgid "show tag list in columns"
 msgstr ""
 
-#: builtin/tag.c:466
+#: builtin/tag.c:521
+msgid "sort tags"
+msgstr "подреждане на етикетите"
+
+#: builtin/tag.c:525
 msgid "Tag listing options"
 msgstr ""
 
-#: builtin/tag.c:469
+#: builtin/tag.c:528 builtin/tag.c:534
 msgid "print only tags that contain the commit"
 msgstr ""
 
-#: builtin/tag.c:475
+#: builtin/tag.c:540
 msgid "print only tags of the object"
 msgstr ""
 
-#: builtin/tag.c:501
+#: builtin/tag.c:566
 msgid "--column and -n are incompatible"
 msgstr ""
 
-#: builtin/tag.c:518
+#: builtin/tag.c:578
+msgid "--sort and -n are incompatible"
+msgstr "Опциите „--long“ и „-n“ са несъвместими"
+
+#: builtin/tag.c:585
 msgid "-n option is only allowed with -l."
 msgstr ""
 
-#: builtin/tag.c:520
+#: builtin/tag.c:587
 msgid "--contains option is only allowed with -l."
 msgstr ""
 
-#: builtin/tag.c:522
+#: builtin/tag.c:589
 msgid "--points-at option is only allowed with -l."
 msgstr ""
 
-#: builtin/tag.c:530
+#: builtin/tag.c:597
 msgid "only one -F or -m option is allowed."
 msgstr ""
 
-#: builtin/tag.c:550
+#: builtin/tag.c:617
 msgid "too many params"
 msgstr ""
 
-#: builtin/tag.c:556
+#: builtin/tag.c:623
 #, c-format
 msgid "'%s' is not a valid tag name."
 msgstr ""
 
-#: builtin/tag.c:561
+#: builtin/tag.c:628
 #, c-format
 msgid "tag '%s' already exists"
 msgstr ""
 
-#: builtin/tag.c:579
+#: builtin/tag.c:646
 #, c-format
 msgid "%s: cannot lock the ref"
 msgstr ""
 
-#: builtin/tag.c:581
+#: builtin/tag.c:648
 #, c-format
 msgid "%s: cannot update the ref"
 msgstr ""
 
-#: builtin/tag.c:583
+#: builtin/tag.c:650
 #, c-format
 msgid "Updated tag '%s' (was %s)\n"
 msgstr ""
 
-#: builtin/update-index.c:402
+#: builtin/unpack-objects.c:483
+msgid "Unpacking objects"
+msgstr "Разпакетиране на обектите"
+
+#: builtin/update-index.c:399
 msgid "git update-index [options] [--] [<file>...]"
 msgstr ""
 
-#: builtin/update-index.c:720
+#: builtin/update-index.c:748
 msgid "continue refresh even when index needs update"
 msgstr ""
 
-#: builtin/update-index.c:723
+#: builtin/update-index.c:751
 msgid "refresh: ignore submodules"
 msgstr ""
 
-#: builtin/update-index.c:726
+#: builtin/update-index.c:754
 msgid "do not ignore new files"
 msgstr ""
 
-#: builtin/update-index.c:728
+#: builtin/update-index.c:756
 msgid "let files replace directories and vice-versa"
 msgstr ""
 
-#: builtin/update-index.c:730
+#: builtin/update-index.c:758
 msgid "notice files missing from worktree"
 msgstr ""
 
-#: builtin/update-index.c:732
+#: builtin/update-index.c:760
 msgid "refresh even if index contains unmerged entries"
 msgstr ""
 
-#: builtin/update-index.c:735
+#: builtin/update-index.c:763
 msgid "refresh stat information"
 msgstr ""
 
-#: builtin/update-index.c:739
+#: builtin/update-index.c:767
 msgid "like --refresh, but ignore assume-unchanged setting"
 msgstr ""
 
-#: builtin/update-index.c:743
-msgid "<mode> <object> <path>"
+#: builtin/update-index.c:771
+msgid "<mode>,<object>,<path>"
 msgstr ""
 
-#: builtin/update-index.c:744
+#: builtin/update-index.c:772
 msgid "add the specified entry to the index"
 msgstr ""
 
-#: builtin/update-index.c:748
+#: builtin/update-index.c:776
 msgid "(+/-)x"
 msgstr ""
 
-#: builtin/update-index.c:749
+#: builtin/update-index.c:777
 msgid "override the executable bit of the listed files"
 msgstr ""
 
-#: builtin/update-index.c:753
+#: builtin/update-index.c:781
 msgid "mark files as \"not changing\""
 msgstr ""
 
-#: builtin/update-index.c:756
+#: builtin/update-index.c:784
 msgid "clear assumed-unchanged bit"
 msgstr ""
 
-#: builtin/update-index.c:759
+#: builtin/update-index.c:787
 msgid "mark files as \"index-only\""
 msgstr ""
 
-#: builtin/update-index.c:762
+#: builtin/update-index.c:790
 msgid "clear skip-worktree bit"
 msgstr ""
 
-#: builtin/update-index.c:765
+#: builtin/update-index.c:793
 msgid "add to index only; do not add content to object database"
 msgstr ""
 
-#: builtin/update-index.c:767
+#: builtin/update-index.c:795
 msgid "remove named paths even if present in worktree"
 msgstr ""
 
-#: builtin/update-index.c:769
+#: builtin/update-index.c:797
 msgid "with --stdin: input lines are terminated by null bytes"
 msgstr ""
 
-#: builtin/update-index.c:771
+#: builtin/update-index.c:799
 msgid "read list of paths to be updated from standard input"
 msgstr ""
 
-#: builtin/update-index.c:775
+#: builtin/update-index.c:803
 msgid "add entries from standard input to the index"
 msgstr ""
 
-#: builtin/update-index.c:779
+#: builtin/update-index.c:807
 msgid "repopulate stages #2 and #3 for the listed paths"
 msgstr ""
 
-#: builtin/update-index.c:783
+#: builtin/update-index.c:811
 msgid "only update entries that differ from HEAD"
 msgstr ""
 
-#: builtin/update-index.c:787
+#: builtin/update-index.c:815
 msgid "ignore files missing from worktree"
 msgstr ""
 
-#: builtin/update-index.c:790
+#: builtin/update-index.c:818
 msgid "report actions to standard output"
 msgstr ""
 
-#: builtin/update-index.c:792
+#: builtin/update-index.c:820
 msgid "(for porcelains) forget saved unresolved conflicts"
 msgstr ""
 
-#: builtin/update-index.c:796
+#: builtin/update-index.c:824
 msgid "write index in this format"
 msgstr ""
 
 #: builtin/update-ref.c:9
 msgid "git update-ref [options] -d <refname> [<oldval>]"
-msgstr ""
+msgstr "git update-ref [ОПЦИИ] -d ИМЕ_НА_УКАЗАТЕЛ [СТАРА_СТОЙНОСТ]"
 
 #: builtin/update-ref.c:10
 msgid "git update-ref [options]    <refname> <newval> [<oldval>]"
 msgstr ""
+"git update-ref [ОПЦИИ]    ИМЕ_НА_УКАЗАТЕЛ НОВА_СТОЙНОСТ [СТАРА_СТОЙНОСТ]"
 
 #: builtin/update-ref.c:11
 msgid "git update-ref [options] --stdin [-z]"
-msgstr ""
+msgstr "git update-ref [ОПЦИИ] --stdin [-z]"
 
-#: builtin/update-ref.c:255
+#: builtin/update-ref.c:256
 msgid "delete the reference"
-msgstr ""
+msgstr "изтриване на указателя"
 
-#: builtin/update-ref.c:257
+#: builtin/update-ref.c:258
 msgid "update <refname> not the one it points to"
-msgstr ""
+msgstr "обновяване на ИМЕто_НА_УКАЗАТЕЛя, а не това, към което сочи"
 
-#: builtin/update-ref.c:258
+#: builtin/update-ref.c:259
 msgid "stdin has NUL-terminated arguments"
 msgstr ""
+"някои от елементите подадени на стандартния вход завършват с нулевия знак "
+"„NUL“"
 
-#: builtin/update-ref.c:259
+#: builtin/update-ref.c:260
 msgid "read updates from stdin"
-msgstr ""
+msgstr "изчитане на указателите от стандартния вход"
 
 #: builtin/update-server-info.c:6
 msgid "git update-server-info [--force]"
-msgstr ""
+msgstr "git update-server-info [--force]"
 
 #: builtin/update-server-info.c:14
 msgid "update the info files from scratch"
-msgstr ""
+msgstr "обновяване на информационните файлове от нулата"
 
 #: builtin/verify-pack.c:56
 msgid "git verify-pack [-v|--verbose] [-s|--stat-only] <pack>..."
-msgstr ""
+msgstr "git verify-pack [-v|--verbose] [-s|--stat-only] ПАКЕТ…"
 
 #: builtin/verify-pack.c:66
 msgid "verbose"
-msgstr ""
+msgstr "извеждане на подробна информация"
 
 #: builtin/verify-pack.c:68
 msgid "show statistics only"
-msgstr ""
+msgstr "извеждане само на статистиката"
 
 #: builtin/verify-tag.c:17
 msgid "git verify-tag [-v|--verbose] <tag>..."
-msgstr ""
+msgstr "git verify-tag [-v|--verbose] ЕТИКЕТ…"
 
 #: builtin/verify-tag.c:73
 msgid "print tag contents"
-msgstr ""
+msgstr "извеждане на съдържанието на ЕТИКЕТи"
 
 #: builtin/write-tree.c:13
 msgid "git write-tree [--missing-ok] [--prefix=<prefix>/]"
-msgstr ""
+msgstr "git write-tree [--missing-ok] [--prefix=ПРЕДСТАВКА/]"
 
 #: builtin/write-tree.c:26
 msgid "<prefix>/"
-msgstr ""
+msgstr "ПРЕДСТАВКА/"
 
 #: builtin/write-tree.c:27
 msgid "write tree object for a subdirectory <prefix>"
-msgstr ""
+msgstr "запис на обект-дърво за поддиректорията започваща с тази ПРЕДСТАВКА"
 
 #: builtin/write-tree.c:30
 msgid "only useful for debugging"
-msgstr ""
+msgstr "само за изчистване на грешки"
 
 #: git.c:17
 msgid ""
@@ -9421,123 +9856,130 @@ msgid ""
 "concept guides. See 'git help <command>' or 'git help <concept>'\n"
 "to read about a specific subcommand or concept."
 msgstr ""
+"„git help -a“ извежда наличните подкоманди, а „git help -g“ извежда "
+"наличните\n"
+"ръководства. За помощ за специфична КОМАНДА ползвайте „git help КОМАНДА“, а "
+"за\n"
+"някое определено ПОНЯТИЕ използвайте „git help ПОНЯТИЕ“."
 
-#: parse-options.h:146
-msgid "expiry date"
-msgstr "период на валидност"
+#: parse-options.h:143
+msgid "expiry-date"
+msgstr "период на валидност/запазване"
 
-#: parse-options.h:161
+#: parse-options.h:158
 msgid "no-op (backward compatibility)"
 msgstr "нулева операция (за съвместимост с предишни версии)"
 
-#: parse-options.h:235
+#: parse-options.h:232
 msgid "be more verbose"
 msgstr "повече подробности"
 
-#: parse-options.h:237
+#: parse-options.h:234
 msgid "be more quiet"
 msgstr "по-малко подробности"
 
-# FIXME
-#: parse-options.h:243
+# FIXME SHA-1 -> SHA1
+#: parse-options.h:240
 msgid "use <n> digits to display SHA-1s"
-msgstr "да се показват такъв <брой> цифри от сумите по SHA1"
+msgstr "да се показват такъв БРОЙ цифри от сумите по SHA1"
 
 #: common-cmds.h:8
 msgid "Add file contents to the index"
-msgstr ""
+msgstr "Добавяне на съдържанието на файла към индекса"
 
 #: common-cmds.h:9
 msgid "Find by binary search the change that introduced a bug"
-msgstr ""
+msgstr "Двоично търсене на промяната, която е причинила грешка"
 
+# FIXME - should be similar to tag
 #: common-cmds.h:10
 msgid "List, create, or delete branches"
-msgstr ""
+msgstr "Извеждане, създаване, изтриване на клони"
 
 #: common-cmds.h:11
 msgid "Checkout a branch or paths to the working tree"
-msgstr ""
+msgstr "Изтегляне на цял клон или файлове/директории в работното дърво"
 
 #: common-cmds.h:12
 msgid "Clone a repository into a new directory"
-msgstr ""
+msgstr "Клониране на хранилище в нова директория"
 
 #: common-cmds.h:13
 msgid "Record changes to the repository"
-msgstr ""
+msgstr "Подаване на промени в хранилището"
 
 #: common-cmds.h:14
 msgid "Show changes between commits, commit and working tree, etc"
-msgstr ""
+msgstr "Извеждане на разликите между подаванията, версиите, работното дърво"
 
 #: common-cmds.h:15
 msgid "Download objects and refs from another repository"
-msgstr ""
+msgstr "Изтегляне на обекти и указатели от друго хранилище"
 
 #: common-cmds.h:16
 msgid "Print lines matching a pattern"
-msgstr ""
+msgstr "Извеждане на редовете напасващи на шаблон"
 
 #: common-cmds.h:17
 msgid "Create an empty Git repository or reinitialize an existing one"
-msgstr ""
+msgstr "Създаване на празно хранилище на Git или зануляване на съществуващо"
 
 #: common-cmds.h:18
 msgid "Show commit logs"
-msgstr ""
+msgstr "Извеждане на журнала с подаванията"
 
 #: common-cmds.h:19
 msgid "Join two or more development histories together"
-msgstr ""
+msgstr "Сливане на две или повече поредици/истории от промени"
 
 #: common-cmds.h:20
 msgid "Move or rename a file, a directory, or a symlink"
-msgstr ""
+msgstr "Преместване или преименуване на файл, директория или символна връзка"
 
 #: common-cmds.h:21
 msgid "Fetch from and integrate with another repository or a local branch"
-msgstr ""
+msgstr "Доставяне и интегрирането на промените от друго хранилище или клон"
 
 #: common-cmds.h:22
 msgid "Update remote refs along with associated objects"
-msgstr ""
+msgstr "Обновяване на отдалечените указатели и свързаните с тях обекти"
 
 #: common-cmds.h:23
 msgid "Forward-port local commits to the updated upstream head"
-msgstr ""
+msgstr "Пребазиране на промени към нова основа"
 
 #: common-cmds.h:24
 msgid "Reset current HEAD to the specified state"
-msgstr ""
+msgstr "Привеждане на указателя „HEAD“ към зададеното състояние"
 
 #: common-cmds.h:25
 msgid "Remove files from the working tree and from the index"
-msgstr ""
+msgstr "Изтриване на файлове от работното дърво и индекса"
 
 #: common-cmds.h:26
 msgid "Show various types of objects"
-msgstr ""
+msgstr "Извеждане на различните видове обекти в Git"
 
 #: common-cmds.h:27
 msgid "Show the working tree status"
-msgstr ""
+msgstr "Извеждане на състоянието на работното дърво"
 
+# FIXME - should be similar to branch
 #: common-cmds.h:28
 msgid "Create, list, delete or verify a tag object signed with GPG"
-msgstr ""
+msgstr "Извеждане, създаване, изтриване, проверка на етикети подписани с GPG"
 
-#: git-am.sh:50
+#: git-am.sh:52
 msgid "You need to set your committer info first"
 msgstr ""
 
-#: git-am.sh:95
+#: git-am.sh:97
 msgid ""
 "You seem to have moved HEAD since the last 'am' failure.\n"
 "Not rewinding to ORIG_HEAD"
 msgstr ""
 
-#: git-am.sh:105
+#: git-am.sh:107
 #, sh-format
 msgid ""
 "When you have resolved this problem, run \"$cmdline --continue\".\n"
@@ -9545,77 +9987,77 @@ msgid ""
 "To restore the original branch and stop patching, run \"$cmdline --abort\"."
 msgstr ""
 
-#: git-am.sh:121
+#: git-am.sh:123
 msgid "Cannot fall back to three-way merge."
 msgstr ""
 
-#: git-am.sh:137
+#: git-am.sh:139
 msgid "Repository lacks necessary blobs to fall back on 3-way merge."
 msgstr ""
 
-#: git-am.sh:139
+#: git-am.sh:141
 msgid "Using index info to reconstruct a base tree..."
 msgstr ""
 
-#: git-am.sh:154
+#: git-am.sh:156
 msgid ""
 "Did you hand edit your patch?\n"
 "It does not apply to blobs recorded in its index."
 msgstr ""
 
-#: git-am.sh:163
+#: git-am.sh:165
 msgid "Falling back to patching base and 3-way merge..."
 msgstr ""
 
-#: git-am.sh:179
+#: git-am.sh:181
 msgid "Failed to merge in the changes."
 msgstr ""
 
-#: git-am.sh:274
+#: git-am.sh:276
 msgid "Only one StGIT patch series can be applied at once"
 msgstr ""
 
-#: git-am.sh:361
+#: git-am.sh:363
 #, sh-format
 msgid "Patch format $patch_format is not supported."
 msgstr ""
 
-#: git-am.sh:363
+#: git-am.sh:365
 msgid "Patch format detection failed."
 msgstr ""
 
-#: git-am.sh:389
+#: git-am.sh:392
 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."
 msgstr ""
 
-#: git-am.sh:479
+#: git-am.sh:486
 #, sh-format
 msgid "previous rebase directory $dotest still exists but mbox given."
 msgstr ""
 
-#: git-am.sh:484
+#: git-am.sh:491
 msgid "Please make up your mind. --skip or --abort?"
 msgstr ""
 
-#: git-am.sh:520
+#: git-am.sh:527
 #, sh-format
 msgid ""
 "Stray $dotest directory found.\n"
 "Use \"git am --abort\" to remove it."
 msgstr ""
 
-#: git-am.sh:528
+#: git-am.sh:535
 msgid "Resolve operation not in progress, we are not resuming."
 msgstr ""
 
-#: git-am.sh:594
+#: git-am.sh:601
 #, sh-format
 msgid "Dirty index: cannot apply patches (dirty: $files)"
 msgstr ""
 
-#: git-am.sh:698
+#: git-am.sh:705
 #, sh-format
 msgid ""
 "Patch is empty.  Was it split wrong?\n"
@@ -9623,60 +10065,60 @@ msgid ""
 "To restore the original branch and stop patching run \"$cmdline --abort\"."
 msgstr ""
 
-#: git-am.sh:725
+#: git-am.sh:732
 msgid "Patch does not have a valid e-mail address."
 msgstr ""
 
-#: git-am.sh:772
+#: git-am.sh:779
 msgid "cannot be interactive without stdin connected to a terminal."
 msgstr ""
 
-#: git-am.sh:776
+#: git-am.sh:783
 msgid "Commit Body is:"
 msgstr ""
 
 #. TRANSLATORS: Make sure to include [y], [n], [e], [v] and [a]
 #. in your translation. The program will only accept English
 #. input at this point.
-#: git-am.sh:783
+#: git-am.sh:790
 msgid "Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all "
 msgstr ""
 
-#: git-am.sh:819
+#: git-am.sh:826
 #, sh-format
 msgid "Applying: $FIRSTLINE"
 msgstr ""
 
-#: git-am.sh:840
+#: git-am.sh:847
 msgid ""
 "No changes - did you forget to use 'git add'?\n"
 "If there is nothing left to stage, chances are that something else\n"
 "already introduced the same changes; you might want to skip this patch."
 msgstr ""
 
-#: git-am.sh:848
+#: git-am.sh:855
 msgid ""
 "You still have unmerged paths in your index\n"
 "did you forget to use 'git add'?"
 msgstr ""
 
-#: git-am.sh:864
+#: git-am.sh:871
 msgid "No changes -- Patch already applied."
 msgstr ""
 
-#: git-am.sh:874
+#: git-am.sh:881
 #, sh-format
 msgid "Patch failed at $msgnum $FIRSTLINE"
 msgstr ""
 
-#: git-am.sh:877
+#: git-am.sh:884
 #, sh-format
 msgid ""
 "The copy of the patch that failed is found in:\n"
 "   $dotest/patch"
 msgstr ""
 
-#: git-am.sh:895
+#: git-am.sh:902
 msgid "applying to an empty history"
 msgstr ""
 
@@ -9742,8 +10184,6 @@ msgstr ""
 msgid "'git bisect bad' can take only one argument."
 msgstr ""
 
-#. have bad but not good.  we could bisect although
-#. this is less optimum.
 #: git-bisect.sh:273
 msgid "Warning: bisecting only with a bad commit."
 msgstr ""
@@ -9830,96 +10270,115 @@ msgid ""
 "Please, fix them up in the work tree, and then use 'git add/rm <file>'\n"
 "as appropriate to mark resolution, or use 'git commit -a'."
 msgstr ""
+"Невъзможно е да издърпвате в момента, защото някои файлове не са слети. "
+"Трябва\n"
+"да ги прегледате, коригирате, ако е необходимо и да ги добавите или извадите "
+"от\n"
+"индекса с командата „git add/rm ФАЙЛ“. Ако всичко е наред, можете да "
+"ползвате и\n"
+"командата „git commit -a“."
 
 #: git-pull.sh:25
 msgid "Pull is not possible because you have unmerged files."
 msgstr ""
+"Невъзможно е да издърпвате в момента, защото някои файлове не са слети."
 
-#: git-pull.sh:223
+#: git-pull.sh:247
 msgid "updating an unborn branch with changes added to the index"
-msgstr ""
+msgstr "обновяване на още несъздаден клон с промените от индекса"
 
-#. 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.
-#: git-pull.sh:247
+#: git-pull.sh:271
 #, sh-format
 msgid ""
 "Warning: fetch updated the current branch head.\n"
 "Warning: fast-forwarding your working tree from\n"
 "Warning: commit $orig_head."
 msgstr ""
+"ПРЕДУПРЕЖДЕНИЕ: доставянето обнови върха на текущия клон.Работното ви копие\n"
+"ПРЕДУПРЕЖДЕНИЕ: бе тривиално слято от подаване „$orig_head“."
 
-#: git-pull.sh:272
+#: git-pull.sh:296
 msgid "Cannot merge multiple branches into empty head"
-msgstr ""
+msgstr "Не може да сливате множество клони в празен върхов указател"
 
-#: git-pull.sh:276
+#: git-pull.sh:300
 msgid "Cannot rebase onto multiple branches"
-msgstr ""
+msgstr "Не може да пребазирате върху повече от един клон"
 
-#: git-rebase.sh:55
+#: git-rebase.sh:57
 msgid ""
 "When you have resolved this problem, run \"git rebase --continue\".\n"
 "If you prefer to skip this patch, run \"git rebase --skip\" instead.\n"
 "To check out the original branch and stop rebasing, run \"git rebase --abort"
 "\"."
 msgstr ""
+"След коригирането на този проблем изпълнете „git rebase --continue“.\n"
+"Ако предпочитате да прескочите тази кръпка, изпълнете „git rebase --skip“.\n"
+"За да откажете пребазирането и да се върнете към първоначалното състояние,\n"
+"изпълнете „git rebase --abort“."
 
-#: git-rebase.sh:158
+#: git-rebase.sh:164
 msgid "Applied autostash."
-msgstr ""
+msgstr "Автоматично скатаното е приложено."
 
-#: git-rebase.sh:161
+#: git-rebase.sh:167
 #, sh-format
 msgid "Cannot store $stash_sha1"
-msgstr ""
+msgstr "„$stash_sha1“ не може да бъде запазен"
 
-#: git-rebase.sh:162
+#: git-rebase.sh:168
 msgid ""
 "Applying autostash resulted in conflicts.\n"
 "Your changes are safe in the stash.\n"
 "You can run \"git stash pop\" or \"git stash drop\" at any time.\n"
 msgstr ""
+"Прилагането на автоматично скатаното доведе до конфликти. Промените ви са\n"
+"надеждно скатани. Можете да пробвате да ги приложите чрез „git stash pop“\n"
+"или да ги изхвърлите чрез „git stash drop“, когато поискате.\n"
 
-#: git-rebase.sh:201
+#: git-rebase.sh:207
 msgid "The pre-rebase hook refused to rebase."
-msgstr ""
+msgstr "Куката за изпълнение преди пребазиране отхвърли пребазирането."
 
-#: git-rebase.sh:206
+#: git-rebase.sh:212
 msgid "It looks like git-am is in progress. Cannot rebase."
 msgstr ""
+"Изглежда, че сега се прилагат кръпки чрез командата „git-am“. Не може да "
+"пребазирате в момента."
 
-#: git-rebase.sh:346
+#: git-rebase.sh:350
 msgid "The --exec option must be used with the --interactive option"
-msgstr ""
+msgstr "Опцията „--exec“ задължително изисква опцията „--interactive“"
 
-#: git-rebase.sh:351
+# FIXME message
+#: git-rebase.sh:355
 msgid "No rebase in progress?"
-msgstr ""
+msgstr "Изглежда в момента не тече пребазиране"
 
-#: git-rebase.sh:362
+#: git-rebase.sh:366
 msgid "The --edit-todo action can only be used during interactive rebase."
 msgstr ""
+"Опцията „--edit-todo“ е достъпна само по време на интерактивно пребазиране."
 
-#: git-rebase.sh:369
+#: git-rebase.sh:373
 msgid "Cannot read HEAD"
-msgstr ""
+msgstr "Указателят „HEAD“ не може да бъде прочетен"
 
-#: git-rebase.sh:372
+#: git-rebase.sh:376
 msgid ""
 "You must edit all merge conflicts and then\n"
 "mark them as resolved using git add"
 msgstr ""
+"Трябва да редактирате всички конфликти при сливането. След това\n"
+"отбележете коригирането им чрез командата „git add“"
 
-#: git-rebase.sh:390
+#: git-rebase.sh:394
 #, sh-format
 msgid "Could not move back to $head_name"
-msgstr ""
+msgstr "Връщането към „$head_name“ е невъзможно"
 
-# FIXME
-#: git-rebase.sh:409
+# FIXME tabulators, I, double spaces
+#: git-rebase.sh:413
 #, sh-format
 msgid ""
 "It seems that there is already a $state_dir_base directory, and\n"
@@ -9931,102 +10390,117 @@ msgid ""
 "and run me again.  I am stopping in case you still have something\n"
 "valuable there."
 msgstr ""
+"Вече съществува директория „$state_dir_base directory“. Възможно ли е да "
+"сте\n"
+"в процес на друго пребазиране? Ако това е така, изпълнете:\n"
+"    $cmd_live_rebase\n"
+"Ако не сте в процес на друго пребазиране, изпълнете:\n"
+"    $cmd_clear_stale_rebase\n"
+"и отново започнете пребазирането. Текущото пребазиране се преустановява, за\n"
+"да не загубите случайно промени."
 
-#: git-rebase.sh:456
+#: git-rebase.sh:464
 #, sh-format
 msgid "invalid upstream $upstream_name"
-msgstr ""
+msgstr "неправилна основа за сравнение „$upstream_name“"
 
-#: git-rebase.sh:480
+#: git-rebase.sh:488
 #, sh-format
 msgid "$onto_name: there are more than one merge bases"
 msgstr ""
+"указателят „$onto_name“ може да сочи към повече от една основа за "
+"пребазирането"
 
-#: git-rebase.sh:483 git-rebase.sh:487
+#: git-rebase.sh:491 git-rebase.sh:495
 #, sh-format
 msgid "$onto_name: there is no merge base"
-msgstr ""
+msgstr "указателят „$onto_name“ не сочи към никаква основа за пребазирането"
 
-#: git-rebase.sh:492
+#: git-rebase.sh:500
 #, sh-format
 msgid "Does not point to a valid commit: $onto_name"
-msgstr ""
+msgstr "Указателят „$onto_name“ не сочи към подаване"
 
-#: git-rebase.sh:515
+#: git-rebase.sh:523
 #, sh-format
 msgid "fatal: no such branch: $branch_name"
-msgstr ""
+msgstr "фатална грешка: не съществува клон „$branch_name“"
 
-#: git-rebase.sh:548
+#: git-rebase.sh:556
 msgid "Cannot autostash"
-msgstr ""
+msgstr "Не може да се скатае автоматично"
 
-#: git-rebase.sh:553
+#: git-rebase.sh:561
 #, sh-format
 msgid "Created autostash: $stash_abbrev"
-msgstr ""
+msgstr "Автоматично скатано: „$stash_abbrev“"
 
-#: git-rebase.sh:557
+#: git-rebase.sh:565
 msgid "Please commit or stash them."
-msgstr ""
+msgstr "Промените трябва или да се подадат, или да се скатаят."
 
-#: git-rebase.sh:577
+#: git-rebase.sh:585
 #, sh-format
 msgid "Current branch $branch_name is up to date."
-msgstr ""
+msgstr "Текущият клон „$branch_name“ е напълно актуален."
 
-#: git-rebase.sh:581
+#: git-rebase.sh:589
 #, sh-format
 msgid "Current branch $branch_name is up to date, rebase forced."
 msgstr ""
+"Текущият клон „$branch_name“ е напълно актуален. Пребазирането е "
+"принудително."
 
-#: git-rebase.sh:592
+#: git-rebase.sh:600
 #, sh-format
 msgid "Changes from $mb to $onto:"
-msgstr ""
+msgstr "Промените от „$mb“ към „$onto“:"
 
-#. Detach HEAD and reset the tree
-#: git-rebase.sh:601
+#: git-rebase.sh:609
 msgid "First, rewinding head to replay your work on top of it..."
 msgstr ""
+"Първо, указателят „HEAD“ започва да сочи към базата, върху която пребазирате…"
 
-#: git-rebase.sh:611
+#: git-rebase.sh:619
 #, sh-format
 msgid "Fast-forwarded $branch_name to $onto_name."
-msgstr ""
+msgstr "Тривиално сливане на „$branch_name“ върху „$onto_name“."
 
+# FIXME - should 'clear' not take parameters in principle?
 #: git-stash.sh:51
 msgid "git stash clear with parameters is unimplemented"
-msgstr ""
+msgstr "Командата „git stash clear“ не поддържа аргументи"
 
 #: git-stash.sh:74
 msgid "You do not have the initial commit yet"
-msgstr ""
+msgstr "Все още липсва първоначално подаване"
 
 #: git-stash.sh:89
 msgid "Cannot save the current index state"
-msgstr ""
+msgstr "Състоянието на текущия индекс не може да бъде запазено"
 
 #: git-stash.sh:123 git-stash.sh:136
 msgid "Cannot save the current worktree state"
-msgstr ""
+msgstr "Състоянието на работното дърво не може да бъде запазено"
 
 #: git-stash.sh:140
 msgid "No changes selected"
-msgstr ""
+msgstr "Не са избрани никакви промени"
 
+# FIXME can't happen??? може, може
 #: git-stash.sh:143
 msgid "Cannot remove temporary index (can't happen)"
-msgstr ""
+msgstr "Временният индекс не може да бъде изтрит"
 
 #: git-stash.sh:156
 msgid "Cannot record working tree state"
-msgstr ""
+msgstr "Състоянието на работното дърво не може да бъде запазено"
 
 #: git-stash.sh:190
 #, sh-format
 msgid "Cannot update $ref_stash with $w_commit"
 msgstr ""
+"Указателят „$ref_stash“ не може да бъде обновен да сочи към „$w_commit“"
 
 #. TRANSLATORS: $option is an invalid option, like
 #. `--blah-blah'. The 7 spaces at the beginning of the
@@ -10044,88 +10518,92 @@ msgid ""
 "error: unknown option for 'stash save': $option\n"
 "       To provide a message, use git stash save -- '$option'"
 msgstr ""
+"грешка: командата „git stash save“ не поддържа опция „$option“\n"
+"        За да зададете съобщение, изпълнете „git stash save -- '$option'“"
 
 #: git-stash.sh:258
 msgid "No local changes to save"
-msgstr ""
+msgstr "Няма никакви локални промени за скатаване"
 
 #: git-stash.sh:262
 msgid "Cannot initialize stash"
-msgstr ""
+msgstr "Скатаването не може да стартира"
 
 #: git-stash.sh:266
 msgid "Cannot save the current status"
-msgstr ""
+msgstr "Текущото състояние не може да бъде запазено"
 
 #: git-stash.sh:284
 msgid "Cannot remove worktree changes"
-msgstr ""
+msgstr "Промените в работното дърво не могат да бъдат занулени"
 
 #: git-stash.sh:383
 msgid "No stash found."
-msgstr ""
+msgstr "Не е открито нищо скатано."
 
 #: git-stash.sh:390
 #, sh-format
 msgid "Too many revisions specified: $REV"
-msgstr ""
+msgstr "Указани са прекалено много версии: „$REV“"
 
 #: git-stash.sh:396
 #, sh-format
 msgid "$reference is not valid reference"
-msgstr ""
+msgstr "Указателят „$reference“ е грешен"
 
 #: git-stash.sh:424
 #, sh-format
 msgid "'$args' is not a stash-like commit"
-msgstr ""
+msgstr "„$args“ не е подаване приличащо на нещо скатано"
 
 #: git-stash.sh:435
 #, sh-format
 msgid "'$args' is not a stash reference"
-msgstr ""
+msgstr "„$args“ не е указател към нещо скатано"
 
 #: git-stash.sh:443
 msgid "unable to refresh index"
-msgstr ""
+msgstr "индексът не може да бъде обновен"
 
 #: git-stash.sh:447
 msgid "Cannot apply a stash in the middle of a merge"
-msgstr ""
+msgstr "По време на сливане не може да приложите нещо скатано"
 
 #: git-stash.sh:455
 msgid "Conflicts in index. Try without --index."
 msgstr ""
+"В индекса има конфликти. Пробвайте да изпълните командата без опцията „--"
+"index“."
 
 #: git-stash.sh:457
 msgid "Could not save index tree"
-msgstr ""
+msgstr "Дървото сочено от индекса не може да бъде запазено"
 
 #: git-stash.sh:491
 msgid "Cannot unstage modified files"
-msgstr ""
+msgstr "Променените файлове не могат да бъдат извадени от индекса"
 
 #: git-stash.sh:506
 msgid "Index was not unstashed."
-msgstr ""
+msgstr "Индексът не е скатан."
 
-#: git-stash.sh:523
+#: git-stash.sh:529
 #, sh-format
 msgid "Dropped ${REV} ($s)"
-msgstr ""
+msgstr "Изтрито е скатаното „${REV}“ ($s)"
 
-#: git-stash.sh:524
+#: git-stash.sh:530
 #, sh-format
 msgid "${REV}: Could not drop stash entry"
-msgstr ""
+msgstr "Скатаното „${REV}“ не може да бъде изтрито"
 
-#: git-stash.sh:531
+#: git-stash.sh:537
 msgid "No branch name specified"
-msgstr ""
+msgstr "Не е указано име на клон"
 
-#: git-stash.sh:603
+#: git-stash.sh:609
 msgid "(To restore them type \"git stash apply\")"
-msgstr ""
+msgstr "(За да ги възстановите, изпълнете командата „git stash apply“)"
 
 #: git-submodule.sh:95
 #, sh-format
@@ -10137,31 +10615,31 @@ msgstr ""
 msgid "No submodule mapping found in .gitmodules for path '$sm_path'"
 msgstr ""
 
-#: git-submodule.sh:281
+#: git-submodule.sh:287
 #, sh-format
 msgid "Clone of '$url' into submodule path '$sm_path' failed"
 msgstr ""
 
-#: git-submodule.sh:293
+#: git-submodule.sh:299
 #, sh-format
 msgid "Gitdir '$a' is part of the submodule path '$b' or vice versa"
 msgstr ""
 
-#: git-submodule.sh:403
+#: git-submodule.sh:409
 msgid "Relative path can only be used from the toplevel of the working tree"
 msgstr ""
 
-#: git-submodule.sh:413
+#: git-submodule.sh:419
 #, sh-format
 msgid "repo URL: '$repo' must be absolute or begin with ./|../"
 msgstr ""
 
-#: git-submodule.sh:430
+#: git-submodule.sh:436
 #, sh-format
 msgid "'$sm_path' already exists in the index"
 msgstr ""
 
-#: git-submodule.sh:434
+#: git-submodule.sh:440
 #, sh-format
 msgid ""
 "The following path is ignored by one of your .gitignore files:\n"
@@ -10169,236 +10647,235 @@ msgid ""
 "Use -f if you really want to add it."
 msgstr ""
 
-#: git-submodule.sh:452
+#: git-submodule.sh:458
 #, sh-format
 msgid "Adding existing repo at '$sm_path' to the index"
 msgstr ""
 
-#: git-submodule.sh:454
+#: git-submodule.sh:460
 #, sh-format
 msgid "'$sm_path' already exists and is not a valid git repo"
 msgstr ""
 
-#: git-submodule.sh:462
+#: git-submodule.sh:468
 #, sh-format
 msgid "A git directory for '$sm_name' is found locally with remote(s):"
 msgstr ""
 
-#: git-submodule.sh:464
+#: git-submodule.sh:470
 #, sh-format
 msgid ""
 "If you want to reuse this local git directory instead of cloning again from"
 msgstr ""
 
-#: git-submodule.sh:466
+#: git-submodule.sh:472
 #, sh-format
 msgid ""
 "use the '--force' option. If the local git directory is not the correct repo"
 msgstr ""
 
-#: git-submodule.sh:467
+#: git-submodule.sh:473
 #, sh-format
 msgid ""
 "or you are unsure what this means choose another name with the '--name' "
 "option."
 msgstr ""
 
-#: git-submodule.sh:469
+#: git-submodule.sh:475
 #, sh-format
 msgid "Reactivating local git directory for submodule '$sm_name'."
 msgstr ""
 
-#: git-submodule.sh:481
+#: git-submodule.sh:487
 #, sh-format
 msgid "Unable to checkout submodule '$sm_path'"
 msgstr ""
 
-#: git-submodule.sh:486
+#: git-submodule.sh:492
 #, sh-format
 msgid "Failed to add submodule '$sm_path'"
 msgstr ""
 
-#: git-submodule.sh:495
+#: git-submodule.sh:501
 #, sh-format
 msgid "Failed to register submodule '$sm_path'"
 msgstr ""
 
-#: git-submodule.sh:539
+#: git-submodule.sh:545
 #, sh-format
 msgid "Entering '$prefix$displaypath'"
 msgstr ""
 
-#: git-submodule.sh:559
+#: git-submodule.sh:565
 #, sh-format
 msgid "Stopping at '$prefix$displaypath'; script returned non-zero status."
 msgstr ""
 
-#: git-submodule.sh:605
+#: git-submodule.sh:611
 #, sh-format
 msgid "No url found for submodule path '$displaypath' in .gitmodules"
 msgstr ""
 
-#: git-submodule.sh:614
+#: git-submodule.sh:620
 #, sh-format
 msgid "Failed to register url for submodule path '$displaypath'"
 msgstr ""
 
-#: git-submodule.sh:616
+#: git-submodule.sh:622
 #, sh-format
 msgid "Submodule '$name' ($url) registered for path '$displaypath'"
 msgstr ""
 
-#: git-submodule.sh:633
+#: git-submodule.sh:639
 #, sh-format
 msgid "Failed to register update mode for submodule path '$displaypath'"
 msgstr ""
 
-#: git-submodule.sh:671
+#: git-submodule.sh:677
 #, sh-format
 msgid "Use '.' if you really want to deinitialize all submodules"
 msgstr ""
 
-#: git-submodule.sh:688
+#: git-submodule.sh:694
 #, sh-format
 msgid "Submodule work tree '$displaypath' contains a .git directory"
 msgstr ""
 
-#: git-submodule.sh:689
+#: git-submodule.sh:695
 #, sh-format
 msgid ""
 "(use 'rm -rf' if you really want to remove it including all of its history)"
 msgstr ""
 
-#: git-submodule.sh:695
+#: git-submodule.sh:701
 #, sh-format
 msgid ""
 "Submodule work tree '$displaypath' contains local modifications; use '-f' to "
 "discard them"
 msgstr ""
 
-#: git-submodule.sh:698
+#: git-submodule.sh:704
 #, sh-format
 msgid "Cleared directory '$displaypath'"
 msgstr ""
 
-#: git-submodule.sh:699
+#: git-submodule.sh:705
 #, sh-format
 msgid "Could not remove submodule work tree '$displaypath'"
 msgstr ""
 
-#: git-submodule.sh:702
+#: git-submodule.sh:708
 #, sh-format
 msgid "Could not create empty submodule directory '$displaypath'"
 msgstr ""
 
-#: git-submodule.sh:711
+#: git-submodule.sh:717
 #, sh-format
 msgid "Submodule '$name' ($url) unregistered for path '$displaypath'"
 msgstr ""
 
-#: git-submodule.sh:834
+#: git-submodule.sh:833
 #, sh-format
 msgid ""
 "Submodule path '$displaypath' not initialized\n"
 "Maybe you want to use 'update --init'?"
 msgstr ""
 
-#: git-submodule.sh:847
+#: git-submodule.sh:846
 #, sh-format
 msgid "Unable to find current revision in submodule path '$displaypath'"
 msgstr ""
 
-#: git-submodule.sh:856
+#: git-submodule.sh:855
 #, sh-format
 msgid "Unable to fetch in submodule path '$sm_path'"
 msgstr ""
 
-#: git-submodule.sh:880
+#: git-submodule.sh:879
 #, sh-format
 msgid "Unable to fetch in submodule path '$displaypath'"
 msgstr ""
 
+#: git-submodule.sh:893
+#, sh-format
+msgid "Unable to checkout '$sha1' in submodule path '$displaypath'"
+msgstr ""
+
 #: git-submodule.sh:894
 #, sh-format
+msgid "Submodule path '$displaypath': checked out '$sha1'"
+msgstr ""
+
+#: git-submodule.sh:898
+#, sh-format
 msgid "Unable to rebase '$sha1' in submodule path '$displaypath'"
 msgstr ""
 
-#: git-submodule.sh:895
+#: git-submodule.sh:899
 #, sh-format
 msgid "Submodule path '$displaypath': rebased into '$sha1'"
 msgstr ""
 
-#: git-submodule.sh:900
+#: git-submodule.sh:904
 #, sh-format
 msgid "Unable to merge '$sha1' in submodule path '$displaypath'"
 msgstr ""
 
-#: git-submodule.sh:901
+#: git-submodule.sh:905
 #, sh-format
 msgid "Submodule path '$displaypath': merged in '$sha1'"
 msgstr ""
 
-#: git-submodule.sh:906
+#: git-submodule.sh:910
 #, sh-format
 msgid ""
 "Execution of '$command $sha1' failed in submodule  path '$prefix$sm_path'"
 msgstr ""
 
-#: git-submodule.sh:907
+#: git-submodule.sh:911
 #, sh-format
 msgid "Submodule path '$prefix$sm_path': '$command $sha1'"
 msgstr ""
 
-#: git-submodule.sh:912
-#, sh-format
-msgid "Unable to checkout '$sha1' in submodule path '$displaypath'"
-msgstr ""
-
-#: git-submodule.sh:913
-#, sh-format
-msgid "Submodule path '$displaypath': checked out '$sha1'"
-msgstr ""
-
-#: git-submodule.sh:940
+#: git-submodule.sh:941
 #, sh-format
 msgid "Failed to recurse into submodule path '$displaypath'"
 msgstr ""
 
-#: git-submodule.sh:1048
+#: git-submodule.sh:1049
 msgid "The --cached option cannot be used with the --files option"
 msgstr ""
 
-#. unexpected type
-#: git-submodule.sh:1096
+#: git-submodule.sh:1097
 #, sh-format
 msgid "unexpected mode $mod_dst"
 msgstr ""
 
-#: git-submodule.sh:1116
+#: git-submodule.sh:1117
 #, sh-format
 msgid "  Warn: $display_name doesn't contain commit $sha1_src"
 msgstr ""
 
-#: git-submodule.sh:1119
+#: git-submodule.sh:1120
 #, sh-format
 msgid "  Warn: $display_name doesn't contain commit $sha1_dst"
 msgstr ""
 
-#: git-submodule.sh:1122
+#: git-submodule.sh:1123
 #, sh-format
 msgid "  Warn: $display_name doesn't contain commits $sha1_src and $sha1_dst"
 msgstr ""
 
-#: git-submodule.sh:1147
+#: git-submodule.sh:1148
 msgid "blob"
 msgstr ""
 
-#: git-submodule.sh:1261
+#: git-submodule.sh:1262
 #, sh-format
 msgid "Failed to recurse into submodule path '$sm_path'"
 msgstr ""
 
-#: git-submodule.sh:1325
+#: git-submodule.sh:1326
 #, sh-format
 msgid "Synchronizing submodule url for '$displaypath'"
 msgstr ""
index ba10b5f616e54078c2d2df3a05e97c28f24d2e27..6b32da05bcf11bf34c8c0202afc3483d76b006f6 100644 (file)
--- a/po/fr.po
+++ b/po/fr.po
@@ -296,11 +296,11 @@ msgid ""
 msgstr ""
 "\n"
 "Si vous comptez baser votre travail sur une branche\n"
-"amont qui existe déjà sur le serveur distant, vous pourriez\n"
-"devoir lancer \"git fetch\" pour la récupérer.\n"
+"amont qui existe déjà sur le serveur distant, vous pouvez\n"
+"lancer \"git fetch\" pour la récupérer.\n"
 "\n"
 "Si vous comptez pousser une nouvelle branche locale qui suivra\n"
-"sa jumelle distante, vous souhaiterez utiliser \"git push -u\"\n"
+"sa jumelle distante, vous pouvez utiliser \"git push -u\"\n"
 "pour paramétrer le suivi distant en même temps que vous poussez."
 
 #: branch.c:260
@@ -343,7 +343,7 @@ msgstr "impossible d'ouvrir '%s'"
 
 #: bundle.c:138
 msgid "Repository lacks these prerequisite commits:"
-msgstr "Le dépôt ne dispose pas des commits prérequis :"
+msgstr "Le dépôt ne dispose pas des commits prérequis suivants :"
 
 #: bundle.c:162 sequencer.c:669 sequencer.c:1123 builtin/log.c:332
 #: builtin/log.c:821 builtin/log.c:1418 builtin/log.c:1644 builtin/merge.c:357
@@ -620,7 +620,7 @@ msgid ""
 msgstr ""
 "ATTENTION : vous avez invoqué une commande Git nommée '%s' qui n'existe "
 "pas.\n"
-"Poursuite en supposant que vous avez voulu dire '%s'"
+"Continuons en supposant que vous avez voulu dire '%s'"
 
 #: help.c:373
 #, c-format
@@ -3480,12 +3480,12 @@ msgid_plural ""
 "\n"
 "%s\n"
 msgstr[0] ""
-"Attention : vous laissez %d commit en retard, non connectés à\n"
+"Attention : vous abandonnez %d commit, non connecté à\n"
 "une branche :\n"
 "\n"
 "%s\n"
 msgstr[1] ""
-"Attention : vous laissez %d commits en retard, non connectés à\n"
+"Attention : vous abandonnez %d commits, non connectés à\n"
 "une branche :\n"
 "\n"
 "%s\n"
@@ -3501,7 +3501,7 @@ msgid ""
 msgstr ""
 "Si vous souhaitez les garder en créant une nouvelle branche, c'est le bon "
 "moment\n"
-"de le faire avec :\n"
+"pour le faire avec :\n"
 "\n"
 "git branch nouvelle_branche %s\n"
 "\n"
@@ -3576,7 +3576,7 @@ msgstr "détacher la HEAD à la validation nommée"
 
 #: builtin/checkout.c:1096
 msgid "set upstream info for new branch"
-msgstr "paramétrer l'information de branche amont pour une nouvelle branche"
+msgstr "paramétrer les coordonnées de branche amont pour une nouvelle branche"
 
 #: builtin/checkout.c:1098
 msgid "new-branch"
@@ -3846,7 +3846,7 @@ msgstr "git clone [options] [--] <dépôt> [<répertoire>]"
 #: builtin/clone.c:64 builtin/fetch.c:97 builtin/merge.c:222
 #: builtin/push.c:504
 msgid "force progress reporting"
-msgstr "forcer l'état d'avancement"
+msgstr "forcer l'affichage de l'état d'avancement"
 
 #: builtin/clone.c:66
 msgid "don't create a checkout"
@@ -4156,7 +4156,7 @@ msgid ""
 msgstr ""
 "Votre nom et votre adresse e-mail ont été configurés automatiquement en se "
 "fondant\n"
-"sur votre nom d'utilisateur et votre nom d'ordinateur. Veuillez vérifier "
+"sur votre nom d'utilisateur et le nom de votre machine. Veuillez vérifier "
 "qu'ils sont corrects.\n"
 "Vous pouvez supprimer ce message en les paramétrant explicitement :\n"
 "\n"
@@ -4565,12 +4565,12 @@ msgstr "réutiliser le message du commit spécifié"
 #: builtin/commit.c:1496
 msgid "use autosquash formatted message to fixup specified commit"
 msgstr ""
-"utiliser un message formaté par autosquash pour corriger le commit spécifié"
+"utiliser un message au format autosquash pour corriger le commit spécifié"
 
 #: builtin/commit.c:1497
 msgid "use autosquash formatted message to squash specified commit"
 msgstr ""
-"utiliser un message formaté par autosquash pour compresser le commit spécifié"
+"utiliser un message au format autosquash pour compresser le commit spécifié"
 
 #: builtin/commit.c:1498
 msgid "the commit is authored by me now (used with -C/-c/--amend)"
@@ -6404,7 +6404,7 @@ msgstr "Exactement une plage nécessaire."
 
 #: builtin/log.c:809
 msgid "Not a range."
-msgstr "Pas une plage."
+msgstr "Ceci n'est pas une plage."
 
 #: builtin/log.c:911
 msgid "Cover letter needs email format"
@@ -6527,7 +6527,7 @@ msgstr "répondre dans le premier message à <id-message>"
 
 #: builtin/log.c:1221 builtin/log.c:1224
 msgid "boundary"
-msgstr "frontière"
+msgstr "limite"
 
 #: builtin/log.c:1222
 msgid "attach the patch"
@@ -8092,7 +8092,7 @@ msgstr ""
 #: builtin/push.c:361
 #, c-format
 msgid "Pushing to %s\n"
-msgstr "Poussage vers %s\n"
+msgstr "Poussée vers %s\n"
 
 #: builtin/push.c:365
 #, c-format
@@ -8185,7 +8185,7 @@ msgstr "check"
 
 #: builtin/push.c:497
 msgid "control recursive pushing of submodules"
-msgstr "contrôler le poussage récursif des sous-modules"
+msgstr "contrôler la poussée récursive des sous-modules"
 
 #: builtin/push.c:499
 msgid "use thin pack"
@@ -8736,12 +8736,12 @@ msgstr "Impossible de paramétrer %s"
 #: builtin/remote.c:1307
 #, c-format
 msgid " %s will become dangling!"
-msgstr " %s deviendra en suspens !"
+msgstr " %s se retrouvera en suspens !"
 
 #: builtin/remote.c:1308
 #, c-format
 msgid " %s has become dangling!"
-msgstr " %s est devenu en suspens !"
+msgstr " %s se retrouve en suspens !"
 
 #: builtin/remote.c:1314
 #, c-format
@@ -10643,7 +10643,7 @@ msgstr "Conflits dans l'index. Essayez sans --index."
 
 #: git-stash.sh:457
 msgid "Could not save index tree"
-msgstr "Impossible de sauver l'arbre d'index"
+msgstr "Impossible de sauvegarder l'arbre d'index"
 
 #: git-stash.sh:491
 msgid "Cannot unstage modified files"
@@ -10799,7 +10799,7 @@ msgstr ""
 #, sh-format
 msgid "No url found for submodule path '$displaypath' in .gitmodules"
 msgstr ""
-"URL non trouvé pour le chemin de sous-module '$displaypath' dans .gitmodules"
+"URL non trouvée pour le chemin de sous-module '$displaypath' dans .gitmodules"
 
 #: git-submodule.sh:620
 #, sh-format
index ffe6c646d83c4c4c491d85073ed4f87360ca1b39..f1658aad5e1393b231b5e7867c411d2df0593110 100644 (file)
--- a/po/sv.po
+++ b/po/sv.po
@@ -5,10 +5,10 @@
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: git 1.8.4\n"
+"Project-Id-Version: git 2.0.0\n"
 "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
 "POT-Creation-Date: 2014-04-19 12:50+0800\n"
-"PO-Revision-Date: 2014-04-22 10:24+0100\n"
+"PO-Revision-Date: 2014-05-07 07:04+0100\n"
 "Last-Translator: Peter Krefting <peter@softwolves.pp.se>\n"
 "Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n"
 "Language: sv\n"
@@ -282,8 +282,8 @@ msgstr "misslyckades skapa revisionstraversering"
 #, c-format
 msgid "The bundle contains this ref:"
 msgid_plural "The bundle contains these %d refs:"
-msgstr[0] "Paketet (bundlen) denna referens:"
-msgstr[1] "Paketet (bundlen) dessa %d referenser:"
+msgstr[0] "Paketet (bundlen) innehåller denna referens:"
+msgstr[1] "Paketet (bundlen) innehåller dessa %d referenser:"
 
 #: bundle.c:191
 msgid "The bundle records a complete history."
@@ -635,7 +635,7 @@ msgstr "misslyckades öppna \"%s\""
 #: merge-recursive.c:784
 #, c-format
 msgid "failed to symlink '%s'"
-msgstr "misslyckades ta skapa symboliska länken \"%s\""
+msgstr "misslyckades skapa symboliska länken \"%s\""
 
 #: merge-recursive.c:787
 #, c-format
@@ -9542,7 +9542,7 @@ msgstr "läs lista över sökvägar att uppdatera från standard in"
 
 #: builtin/update-index.c:803
 msgid "add entries from standard input to the index"
-msgstr "lägg poster från från standard in till indexet"
+msgstr "lägg poster från standard in till indexet"
 
 #: builtin/update-index.c:807
 msgid "repopulate stages #2 and #3 for the listed paths"
@@ -9789,7 +9789,7 @@ msgstr ""
 
 #: git-am.sh:141
 msgid "Using index info to reconstruct a base tree..."
-msgstr "Använder indexinfo för att åteskapa ett basträd..."
+msgstr "Använder indexinfo för att återskapa ett basträd..."
 
 #: git-am.sh:156
 msgid ""
index 3c43db558aee43b0ea69c23c6611dcc9fae0661f..e1e2cad36d6d2d2773f05c6e69b0013ed8d01240 100644 (file)
--- a/pretty.c
+++ b/pretty.c
@@ -393,8 +393,8 @@ static void add_rfc2047(struct strbuf *sb, const char *line, size_t len,
        strbuf_addstr(sb, "?=");
 }
 
-static const char *show_ident_date(const struct ident_split *ident,
-                                  enum date_mode mode)
+const char *show_ident_date(const struct ident_split *ident,
+                           enum date_mode mode)
 {
        unsigned long date = 0;
        long tz = 0;
index ba13353b377d4f27b9ff6cf1b85811fcca61e224..7f5645e74546e459efdb584dbf63e1fd75857317 100644 (file)
@@ -1477,6 +1477,7 @@ int read_index_from(struct index_state *istate, const char *path)
        if (verify_hdr(hdr, mmap_size) < 0)
                goto unmap;
 
+       hashcpy(istate->sha1, (unsigned char *)hdr + mmap_size - 20);
        istate->version = ntohl(hdr->hdr_version);
        istate->cache_nr = ntohl(hdr->hdr_entries);
        istate->cache_alloc = alloc_nr(istate->cache_nr);
@@ -1760,6 +1761,50 @@ static int ce_write_entry(git_SHA_CTX *c, int fd, struct cache_entry *ce,
        return result;
 }
 
+/*
+ * This function verifies if index_state has the correct sha1 of the
+ * index file.  Don't die if we have any other failure, just return 0.
+ */
+static int verify_index_from(const struct index_state *istate, const char *path)
+{
+       int fd;
+       ssize_t n;
+       struct stat st;
+       unsigned char sha1[20];
+
+       if (!istate->initialized)
+               return 0;
+
+       fd = open(path, O_RDONLY);
+       if (fd < 0)
+               return 0;
+
+       if (fstat(fd, &st))
+               goto out;
+
+       if (st.st_size < sizeof(struct cache_header) + 20)
+               goto out;
+
+       n = pread_in_full(fd, sha1, 20, st.st_size - 20);
+       if (n != 20)
+               goto out;
+
+       if (hashcmp(istate->sha1, sha1))
+               goto out;
+
+       close(fd);
+       return 1;
+
+out:
+       close(fd);
+       return 0;
+}
+
+static int verify_index(const struct index_state *istate)
+{
+       return verify_index_from(istate, get_index_file());
+}
+
 static int has_racy_timestamp(struct index_state *istate)
 {
        int entries = istate->cache_nr;
@@ -1779,7 +1824,7 @@ static int has_racy_timestamp(struct index_state *istate)
 void update_index_if_able(struct index_state *istate, struct lock_file *lockfile)
 {
        if ((istate->cache_changed || has_racy_timestamp(istate)) &&
-           !write_index(istate, lockfile->fd))
+           verify_index(istate) && !write_index(istate, lockfile->fd))
                commit_locked_index(lockfile);
        else
                rollback_lock_file(lockfile);
diff --git a/refs.c b/refs.c
index 28d5eca8eaff7be48a4b89e6217886b8c96eb3b2..728a76164830368637e95390d95ce3f7c7df659e 100644 (file)
--- a/refs.c
+++ b/refs.c
@@ -3243,9 +3243,9 @@ static struct ref_lock *update_ref_lock(const char *refname,
        if (!lock) {
                const char *str = "Cannot lock the ref '%s'.";
                switch (onerr) {
-               case MSG_ON_ERR: error(str, refname); break;
-               case DIE_ON_ERR: die(str, refname); break;
-               case QUIET_ON_ERR: break;
+               case UPDATE_REFS_MSG_ON_ERR: error(str, refname); break;
+               case UPDATE_REFS_DIE_ON_ERR: die(str, refname); break;
+               case UPDATE_REFS_QUIET_ON_ERR: break;
                }
        }
        return lock;
@@ -3258,15 +3258,118 @@ static int update_ref_write(const char *action, const char *refname,
        if (write_ref_sha1(lock, sha1, action) < 0) {
                const char *str = "Cannot update the ref '%s'.";
                switch (onerr) {
-               case MSG_ON_ERR: error(str, refname); break;
-               case DIE_ON_ERR: die(str, refname); break;
-               case QUIET_ON_ERR: break;
+               case UPDATE_REFS_MSG_ON_ERR: error(str, refname); break;
+               case UPDATE_REFS_DIE_ON_ERR: die(str, refname); break;
+               case UPDATE_REFS_QUIET_ON_ERR: break;
                }
                return 1;
        }
        return 0;
 }
 
+/**
+ * Information needed for a single ref update.  Set new_sha1 to the
+ * new value or to zero to delete the ref.  To check the old value
+ * while locking the ref, set have_old to 1 and set old_sha1 to the
+ * value or to zero to ensure the ref does not exist before update.
+ */
+struct ref_update {
+       unsigned char new_sha1[20];
+       unsigned char old_sha1[20];
+       int flags; /* REF_NODEREF? */
+       int have_old; /* 1 if old_sha1 is valid, 0 otherwise */
+       struct ref_lock *lock;
+       int type;
+       const char refname[FLEX_ARRAY];
+};
+
+/*
+ * Data structure for holding a reference transaction, which can
+ * consist of checks and updates to multiple references, carried out
+ * as atomically as possible.  This structure is opaque to callers.
+ */
+struct ref_transaction {
+       struct ref_update **updates;
+       size_t alloc;
+       size_t nr;
+};
+
+struct ref_transaction *ref_transaction_begin(void)
+{
+       return xcalloc(1, sizeof(struct ref_transaction));
+}
+
+static void ref_transaction_free(struct ref_transaction *transaction)
+{
+       int i;
+
+       for (i = 0; i < transaction->nr; i++)
+               free(transaction->updates[i]);
+
+       free(transaction->updates);
+       free(transaction);
+}
+
+void ref_transaction_rollback(struct ref_transaction *transaction)
+{
+       ref_transaction_free(transaction);
+}
+
+static struct ref_update *add_update(struct ref_transaction *transaction,
+                                    const char *refname)
+{
+       size_t len = strlen(refname);
+       struct ref_update *update = xcalloc(1, sizeof(*update) + len + 1);
+
+       strcpy((char *)update->refname, refname);
+       ALLOC_GROW(transaction->updates, transaction->nr + 1, transaction->alloc);
+       transaction->updates[transaction->nr++] = update;
+       return update;
+}
+
+void ref_transaction_update(struct ref_transaction *transaction,
+                           const char *refname,
+                           unsigned char *new_sha1, unsigned char *old_sha1,
+                           int flags, int have_old)
+{
+       struct ref_update *update = add_update(transaction, refname);
+
+       hashcpy(update->new_sha1, new_sha1);
+       update->flags = flags;
+       update->have_old = have_old;
+       if (have_old)
+               hashcpy(update->old_sha1, old_sha1);
+}
+
+void ref_transaction_create(struct ref_transaction *transaction,
+                           const char *refname,
+                           unsigned char *new_sha1,
+                           int flags)
+{
+       struct ref_update *update = add_update(transaction, refname);
+
+       assert(!is_null_sha1(new_sha1));
+       hashcpy(update->new_sha1, new_sha1);
+       hashclr(update->old_sha1);
+       update->flags = flags;
+       update->have_old = 1;
+}
+
+void ref_transaction_delete(struct ref_transaction *transaction,
+                           const char *refname,
+                           unsigned char *old_sha1,
+                           int flags, int have_old)
+{
+       struct ref_update *update = add_update(transaction, refname);
+
+       update->flags = flags;
+       update->have_old = have_old;
+       if (have_old) {
+               assert(!is_null_sha1(old_sha1));
+               hashcpy(update->old_sha1, old_sha1);
+       }
+}
+
 int update_ref(const char *action, const char *refname,
               const unsigned char *sha1, const unsigned char *oldval,
               int flags, enum action_on_err onerr)
@@ -3282,7 +3385,7 @@ static int ref_update_compare(const void *r1, const void *r2)
 {
        const struct ref_update * const *u1 = r1;
        const struct ref_update * const *u2 = r2;
-       return strcmp((*u1)->ref_name, (*u2)->ref_name);
+       return strcmp((*u1)->refname, (*u2)->refname);
 }
 
 static int ref_update_reject_duplicates(struct ref_update **updates, int n,
@@ -3290,15 +3393,15 @@ static int ref_update_reject_duplicates(struct ref_update **updates, int n,
 {
        int i;
        for (i = 1; i < n; i++)
-               if (!strcmp(updates[i - 1]->ref_name, updates[i]->ref_name)) {
+               if (!strcmp(updates[i - 1]->refname, updates[i]->refname)) {
                        const char *str =
                                "Multiple updates for ref '%s' not allowed.";
                        switch (onerr) {
-                       case MSG_ON_ERR:
-                               error(str, updates[i]->ref_name); break;
-                       case DIE_ON_ERR:
-                               die(str, updates[i]->ref_name); break;
-                       case QUIET_ON_ERR:
+                       case UPDATE_REFS_MSG_ON_ERR:
+                               error(str, updates[i]->refname); break;
+                       case UPDATE_REFS_DIE_ON_ERR:
+                               die(str, updates[i]->refname); break;
+                       case UPDATE_REFS_QUIET_ON_ERR:
                                break;
                        }
                        return 1;
@@ -3306,26 +3409,21 @@ static int ref_update_reject_duplicates(struct ref_update **updates, int n,
        return 0;
 }
 
-int update_refs(const char *action, const struct ref_update **updates_orig,
-               int n, enum action_on_err onerr)
+int ref_transaction_commit(struct ref_transaction *transaction,
+                          const char *msg, enum action_on_err onerr)
 {
        int ret = 0, delnum = 0, i;
-       struct ref_update **updates;
-       int *types;
-       struct ref_lock **locks;
        const char **delnames;
+       int n = transaction->nr;
+       struct ref_update **updates = transaction->updates;
 
-       if (!updates_orig || !n)
+       if (!n)
                return 0;
 
        /* Allocate work space */
-       updates = xmalloc(sizeof(*updates) * n);
-       types = xmalloc(sizeof(*types) * n);
-       locks = xcalloc(n, sizeof(*locks));
        delnames = xmalloc(sizeof(*delnames) * n);
 
        /* Copy, sort, and reject duplicate refs */
-       memcpy(updates, updates_orig, sizeof(*updates) * n);
        qsort(updates, n, sizeof(*updates), ref_update_compare);
        ret = ref_update_reject_duplicates(updates, n, onerr);
        if (ret)
@@ -3333,35 +3431,44 @@ int update_refs(const char *action, const struct ref_update **updates_orig,
 
        /* Acquire all locks while verifying old values */
        for (i = 0; i < n; i++) {
-               locks[i] = update_ref_lock(updates[i]->ref_name,
-                                          (updates[i]->have_old ?
-                                           updates[i]->old_sha1 : NULL),
-                                          updates[i]->flags,
-                                          &types[i], onerr);
-               if (!locks[i]) {
+               struct ref_update *update = updates[i];
+
+               update->lock = update_ref_lock(update->refname,
+                                              (update->have_old ?
+                                               update->old_sha1 : NULL),
+                                              update->flags,
+                                              &update->type, onerr);
+               if (!update->lock) {
                        ret = 1;
                        goto cleanup;
                }
        }
 
        /* Perform updates first so live commits remain referenced */
-       for (i = 0; i < n; i++)
-               if (!is_null_sha1(updates[i]->new_sha1)) {
-                       ret = update_ref_write(action,
-                                              updates[i]->ref_name,
-                                              updates[i]->new_sha1,
-                                              locks[i], onerr);
-                       locks[i] = NULL; /* freed by update_ref_write */
+       for (i = 0; i < n; i++) {
+               struct ref_update *update = updates[i];
+
+               if (!is_null_sha1(update->new_sha1)) {
+                       ret = update_ref_write(msg,
+                                              update->refname,
+                                              update->new_sha1,
+                                              update->lock, onerr);
+                       update->lock = NULL; /* freed by update_ref_write */
                        if (ret)
                                goto cleanup;
                }
+       }
 
        /* Perform deletes now that updates are safely completed */
-       for (i = 0; i < n; i++)
-               if (locks[i]) {
-                       delnames[delnum++] = locks[i]->ref_name;
-                       ret |= delete_ref_loose(locks[i], types[i]);
+       for (i = 0; i < n; i++) {
+               struct ref_update *update = updates[i];
+
+               if (update->lock) {
+                       delnames[delnum++] = update->lock->ref_name;
+                       ret |= delete_ref_loose(update->lock, update->type);
                }
+       }
+
        ret |= repack_without_refs(delnames, delnum);
        for (i = 0; i < delnum; i++)
                unlink_or_warn(git_path("logs/%s", delnames[i]));
@@ -3369,12 +3476,10 @@ int update_refs(const char *action, const struct ref_update **updates_orig,
 
 cleanup:
        for (i = 0; i < n; i++)
-               if (locks[i])
-                       unlock_ref(locks[i]);
-       free(updates);
-       free(types);
-       free(locks);
+               if (updates[i]->lock)
+                       unlock_ref(updates[i]->lock);
        free(delnames);
+       ref_transaction_free(transaction);
        return ret;
 }
 
diff --git a/refs.h b/refs.h
index 87a1a79ad659f3520a22ae14bac1d5082cf2c27b..0f08def21020a166902de169dd46c63c85fdfd0e 100644 (file)
--- a/refs.h
+++ b/refs.h
@@ -10,19 +10,7 @@ struct ref_lock {
        int force_write;
 };
 
-/**
- * Information needed for a single ref update.  Set new_sha1 to the
- * new value or to zero to delete the ref.  To check the old value
- * while locking the ref, set have_old to 1 and set old_sha1 to the
- * value or to zero to ensure the ref does not exist before update.
- */
-struct ref_update {
-       const char *ref_name;
-       unsigned char new_sha1[20];
-       unsigned char old_sha1[20];
-       int flags; /* REF_NODEREF? */
-       int have_old; /* 1 if old_sha1 is valid, 0 otherwise */
-};
+struct ref_transaction;
 
 /*
  * Bit values set in the flags argument passed to each_ref_fn():
@@ -166,7 +154,7 @@ extern void unlock_ref(struct ref_lock *lock);
 extern int write_ref_sha1(struct ref_lock *lock, const unsigned char *sha1, const char *msg);
 
 /** Setup reflog before using. **/
-int log_ref_setup(const char *ref_name, char *logfile, int bufsize);
+int log_ref_setup(const char *refname, char *logfile, int bufsize);
 
 /** Reads log for the value of ref during at_time. **/
 extern int read_ref_at(const char *refname, unsigned long at_time, int cnt,
@@ -214,18 +202,80 @@ extern int rename_ref(const char *oldref, const char *newref, const char *logmsg
  */
 extern int resolve_gitlink_ref(const char *path, const char *refname, unsigned char *sha1);
 
-/** lock a ref and then write its file */
-enum action_on_err { MSG_ON_ERR, DIE_ON_ERR, QUIET_ON_ERR };
+enum action_on_err {
+       UPDATE_REFS_MSG_ON_ERR,
+       UPDATE_REFS_DIE_ON_ERR,
+       UPDATE_REFS_QUIET_ON_ERR
+};
+
+/*
+ * Begin a reference transaction.  The reference transaction must
+ * eventually be commited using ref_transaction_commit() or rolled
+ * back using ref_transaction_rollback().
+ */
+struct ref_transaction *ref_transaction_begin(void);
+
+/*
+ * Roll back a ref_transaction and free all associated data.
+ */
+void ref_transaction_rollback(struct ref_transaction *transaction);
+
+
+/*
+ * The following functions add a reference check or update to a
+ * ref_transaction.  In all of them, refname is the name of the
+ * reference to be affected.  The functions make internal copies of
+ * refname, so the caller retains ownership of the parameter.  flags
+ * can be REF_NODEREF; it is passed to update_ref_lock().
+ */
+
+
+/*
+ * Add a reference update to transaction.  new_sha1 is the value that
+ * the reference should have after the update, or zeros if it should
+ * be deleted.  If have_old is true, then old_sha1 holds the value
+ * that the reference should have had before the update, or zeros if
+ * it must not have existed beforehand.
+ */
+void ref_transaction_update(struct ref_transaction *transaction,
+                           const char *refname,
+                           unsigned char *new_sha1, unsigned char *old_sha1,
+                           int flags, int have_old);
+
+/*
+ * Add a reference creation to transaction.  new_sha1 is the value
+ * that the reference should have after the update; it must not be the
+ * null SHA-1.  It is verified that the reference does not exist
+ * already.
+ */
+void ref_transaction_create(struct ref_transaction *transaction,
+                           const char *refname,
+                           unsigned char *new_sha1,
+                           int flags);
+
+/*
+ * Add a reference deletion to transaction.  If have_old is true, then
+ * old_sha1 holds the value that the reference should have had before
+ * the update (which must not be the null SHA-1).
+ */
+void ref_transaction_delete(struct ref_transaction *transaction,
+                           const char *refname,
+                           unsigned char *old_sha1,
+                           int flags, int have_old);
+
+/*
+ * Commit all of the changes that have been queued in transaction, as
+ * atomically as possible.  Return a nonzero value if there is a
+ * problem.  The ref_transaction is freed by this function.
+ */
+int ref_transaction_commit(struct ref_transaction *transaction,
+                          const char *msg, enum action_on_err onerr);
+
+/** Lock a ref and then write its file */
 int update_ref(const char *action, const char *refname,
                const unsigned char *sha1, const unsigned char *oldval,
                int flags, enum action_on_err onerr);
 
-/**
- * Lock all refs and then perform all modifications.
- */
-int update_refs(const char *action, const struct ref_update **updates,
-               int n, enum action_on_err onerr);
-
 extern int parse_hide_refs_config(const char *var, const char *value, const char *);
 extern int ref_is_hidden(const char *);
 
index bde5f047b01376e05255a55516d3bdd261f497ea..0a80c58d1194c3476dfd2861a98fbd08610597a3 100644 (file)
@@ -281,8 +281,12 @@ static int fast_forward_to(const unsigned char *to, const unsigned char *from,
                exit(1); /* the callee should have complained already */
        ref_lock = lock_any_ref_for_update("HEAD", unborn ? null_sha1 : from,
                                           0, NULL);
+       if (!ref_lock)
+               return error(_("Failed to lock HEAD during fast_forward_to"));
+
        strbuf_addf(&sb, "%s: fast-forward", action_name(opts));
        ret = write_ref_sha1(ref_lock, to, sb.buf);
+
        strbuf_release(&sb);
        return ret;
 }
index ee96dcfb816625436582833d812a7156513d5d39..4d31567a1a6a67ae9697816d78da442f87ab5803 100644 (file)
--- a/strbuf.c
+++ b/strbuf.c
@@ -78,15 +78,8 @@ void strbuf_grow(struct strbuf *sb, size_t extra)
 
 void strbuf_trim(struct strbuf *sb)
 {
-       char *b = sb->buf;
-       while (sb->len > 0 && isspace((unsigned char)sb->buf[sb->len - 1]))
-               sb->len--;
-       while (sb->len > 0 && isspace(*b)) {
-               b++;
-               sb->len--;
-       }
-       memmove(sb->buf, b, sb->len);
-       sb->buf[sb->len] = '\0';
+       strbuf_rtrim(sb);
+       strbuf_ltrim(sb);
 }
 void strbuf_rtrim(struct strbuf *sb)
 {
index 957ae936e8b785f8b1afbffd9a5918a3260d213f..9e7d7962b0678dceefb93e3706b742cbfdc5b45e 100755 (executable)
@@ -281,7 +281,7 @@ helper_test_timeout() {
 cat >askpass <<\EOF
 #!/bin/sh
 echo >&2 askpass: $*
-what=`echo $1 | cut -d" " -f1 | tr A-Z a-z | tr -cd a-z`
+what=$(echo $1 | cut -d" " -f1 | tr A-Z a-z | tr -cd a-z)
 echo "askpass-$what"
 EOF
 chmod +x askpass
index 5076718916388d6abf483220cd35f9f61394abc4..9b2bcfb1b0e38ec75e4d6d772e530a69eaaad874 100644 (file)
@@ -13,7 +13,7 @@ fi
 CVS="cvs -f"
 export CVS
 
-cvsps_version=`cvsps -h 2>&1 | sed -ne 's/cvsps version //p'`
+cvsps_version=$(cvsps -h 2>&1 | sed -ne 's/cvsps version //p')
 case "$cvsps_version" in
 2.1 | 2.2*)
        ;;
index 05824fa8e4d18252f74c51531d6504039986c078..fd499e7c498449834992e67645f098d49c6290b8 100755 (executable)
@@ -1,6 +1,6 @@
 #!/bin/sh
 
-gpg_version=`gpg --version 2>&1`
+gpg_version=$(gpg --version 2>&1)
 if test $? = 127; then
        say "You do not seem to have gpg installed"
 else
index 6cb5b0d55b6d6ed4a91f6d0674c210d98b962b66..5ee9211f988dce1f334d796623feccda85641bbe 100755 (executable)
@@ -8,7 +8,7 @@ test_perf_large_repo
 
 test_expect_success 'repack' '
        git repack -ad &&
-       PACK=`ls .git/objects/pack/*.pack | head -n1` &&
+       PACK=$(ls .git/objects/pack/*.pack | head -n1) &&
        test -f "$PACK" &&
        export PACK
 '
index bbc9cb60ddea49f1ce3f0b0d124f704c30a61346..2f3020342a75f0d382af88e6ad35691ad0f183d5 100755 (executable)
@@ -185,14 +185,14 @@ test_expect_success 'init --bare/--shared overrides system/global config' '
        git init --bare --shared=0666 init-bare-shared-override &&
        check_config init-bare-shared-override true unset &&
        test x0666 = \
-       x`git config -f init-bare-shared-override/config core.sharedRepository`
+       x$(git config -f init-bare-shared-override/config core.sharedRepository)
 '
 
 test_expect_success 'init honors global core.sharedRepository' '
        test_config_global core.sharedRepository 0666 &&
        git init shared-honor-global &&
        test x0666 = \
-       x`git config -f shared-honor-global/.git/config core.sharedRepository`
+       x$(git config -f shared-honor-global/.git/config core.sharedRepository)
 '
 
 test_expect_success 'init rejects insanely long --template' '
@@ -285,7 +285,7 @@ test_expect_success 'init prefers command line to GIT_DIR' '
 test_expect_success 'init with separate gitdir' '
        rm -rf newdir &&
        git init --separate-git-dir realgitdir newdir &&
-       echo "gitdir: `pwd`/realgitdir" >expected &&
+       echo "gitdir: $(pwd)/realgitdir" >expected &&
        test_cmp expected newdir/.git &&
        test_path_is_dir realgitdir/refs
 '
@@ -299,7 +299,7 @@ test_expect_success 're-init to update git link' '
        cd newdir &&
        git init --separate-git-dir ../surrealgitdir
        ) &&
-       echo "gitdir: `pwd`/surrealgitdir" >expected &&
+       echo "gitdir: $(pwd)/surrealgitdir" >expected &&
        test_cmp expected newdir/.git &&
        test_path_is_dir surrealgitdir/refs &&
        test_path_is_missing realgitdir/refs
@@ -312,7 +312,7 @@ test_expect_success 're-init to move gitdir' '
        cd newdir &&
        git init --separate-git-dir ../realgitdir
        ) &&
-       echo "gitdir: `pwd`/realgitdir" >expected &&
+       echo "gitdir: $(pwd)/realgitdir" >expected &&
        test_cmp expected newdir/.git &&
        test_path_is_dir realgitdir/refs
 '
@@ -326,7 +326,7 @@ test_expect_success SYMLINKS 're-init to move gitdir symlink' '
        ln -s here .git &&
        git init --separate-git-dir ../realgitdir
        ) &&
-       echo "gitdir: `pwd`/realgitdir" >expected &&
+       echo "gitdir: $(pwd)/realgitdir" >expected &&
        test_cmp expected newdir/.git &&
        test_cmp expected newdir/here &&
        test_path_is_dir realgitdir/refs
index e45a9e40e432524454e94a041599b201a092879a..5657c5a87b6e253b8c8ca7d18dfa7535c295dc83 100755 (executable)
@@ -14,7 +14,7 @@ do
        git update-index --add infocom
        echo xyzzy >infocom
 
-       files=`git diff-files -p`
+       files=$(git diff-files -p)
        test_expect_success \
        "Racy GIT trial #$trial part A" \
        'test "" != "$files"'
@@ -23,7 +23,7 @@ do
        echo xyzzy >cornerstone
        git update-index --add cornerstone
 
-       files=`git diff-files -p`
+       files=$(git diff-files -p)
        test_expect_success \
        "Racy GIT trial #$trial part B" \
        'test "" != "$files"'
index e526184a0bfa3c8ad2171d0c41a7bee22cf9a04e..d2e51a81bc0897b19f8f087894187ed705ce29e3 100755 (executable)
@@ -20,14 +20,14 @@ test_expect_success setup '
 
        git commit -m initial &&
 
-       one=`git rev-parse HEAD:one` &&
-       dir=`git rev-parse HEAD:dir` &&
-       two=`git rev-parse HEAD:dir/two` &&
-       three=`git rev-parse HEAD:three` &&
+       one=$(git rev-parse HEAD:one) &&
+       dir=$(git rev-parse HEAD:dir) &&
+       two=$(git rev-parse HEAD:dir/two) &&
+       three=$(git rev-parse HEAD:three) &&
 
        for w in Some extra lines here; do echo $w; done >>one &&
        git diff >patch.file &&
-       patched=`git hash-object --stdin <one` &&
+       patched=$(git hash-object --stdin <one) &&
        git read-tree --reset -u HEAD &&
 
        echo happy.
@@ -111,7 +111,7 @@ test_expect_success 'update with autocrlf=input' '
                }
        done &&
 
-       differs=`git diff-index --cached HEAD` &&
+       differs=$(git diff-index --cached HEAD) &&
        test -z "$differs" || {
                echo Oops "$differs"
                false
@@ -135,7 +135,7 @@ test_expect_success 'update with autocrlf=true' '
                }
        done &&
 
-       differs=`git diff-index --cached HEAD` &&
+       differs=$(git diff-index --cached HEAD) &&
        test -z "$differs" || {
                echo Oops "$differs"
                false
@@ -158,9 +158,9 @@ test_expect_success 'checkout with autocrlf=true' '
                        break
                }
        done &&
-       test "$one" = `git hash-object --stdin <one` &&
-       test "$two" = `git hash-object --stdin <dir/two` &&
-       differs=`git diff-index --cached HEAD` &&
+       test "$one" = $(git hash-object --stdin <one) &&
+       test "$two" = $(git hash-object --stdin <dir/two) &&
+       differs=$(git diff-index --cached HEAD) &&
        test -z "$differs" || {
                echo Oops "$differs"
                false
@@ -184,9 +184,9 @@ test_expect_success 'checkout with autocrlf=input' '
                        git update-index -- $f
                fi
        done &&
-       test "$one" = `git hash-object --stdin <one` &&
-       test "$two" = `git hash-object --stdin <dir/two` &&
-       differs=`git diff-index --cached HEAD` &&
+       test "$one" = $(git hash-object --stdin <one) &&
+       test "$two" = $(git hash-object --stdin <dir/two) &&
+       differs=$(git diff-index --cached HEAD) &&
        test -z "$differs" || {
                echo Oops "$differs"
                false
@@ -200,7 +200,7 @@ test_expect_success 'apply patch (autocrlf=input)' '
        git read-tree --reset -u HEAD &&
 
        git apply patch.file &&
-       test "$patched" = "`git hash-object --stdin <one`" || {
+       test "$patched" = "$(git hash-object --stdin <one)" || {
                echo "Eh?  apply without index"
                false
        }
@@ -213,7 +213,7 @@ test_expect_success 'apply patch --cached (autocrlf=input)' '
        git read-tree --reset -u HEAD &&
 
        git apply --cached patch.file &&
-       test "$patched" = `git rev-parse :one` || {
+       test "$patched" = $(git rev-parse :one) || {
                echo "Eh?  apply with --cached"
                false
        }
@@ -226,8 +226,8 @@ test_expect_success 'apply patch --index (autocrlf=input)' '
        git read-tree --reset -u HEAD &&
 
        git apply --index patch.file &&
-       test "$patched" = `git rev-parse :one` &&
-       test "$patched" = `git hash-object --stdin <one` || {
+       test "$patched" = $(git rev-parse :one) &&
+       test "$patched" = $(git hash-object --stdin <one) || {
                echo "Eh?  apply with --index"
                false
        }
@@ -240,7 +240,7 @@ test_expect_success 'apply patch (autocrlf=true)' '
        git read-tree --reset -u HEAD &&
 
        git apply patch.file &&
-       test "$patched" = "`remove_cr <one | git hash-object --stdin`" || {
+       test "$patched" = "$(remove_cr <one | git hash-object --stdin)" || {
                echo "Eh?  apply without index"
                false
        }
@@ -253,7 +253,7 @@ test_expect_success 'apply patch --cached (autocrlf=true)' '
        git read-tree --reset -u HEAD &&
 
        git apply --cached patch.file &&
-       test "$patched" = `git rev-parse :one` || {
+       test "$patched" = $(git rev-parse :one) || {
                echo "Eh?  apply without index"
                false
        }
@@ -266,8 +266,8 @@ test_expect_success 'apply patch --index (autocrlf=true)' '
        git read-tree --reset -u HEAD &&
 
        git apply --index patch.file &&
-       test "$patched" = `git rev-parse :one` &&
-       test "$patched" = "`remove_cr <one | git hash-object --stdin`" || {
+       test "$patched" = $(git rev-parse :one) &&
+       test "$patched" = "$(remove_cr <one | git hash-object --stdin)" || {
                echo "Eh?  apply with --index"
                false
        }
index f5f67a6337320c11a285b78be299fa955663991d..b0e5694ebd07b59e80823cd87825cc9ec8187c21 100755 (executable)
@@ -19,9 +19,9 @@ test_expect_success setup '
 
        git commit -m initial &&
 
-       one=`git rev-parse HEAD:one` &&
-       two=`git rev-parse HEAD:two` &&
-       three=`git rev-parse HEAD:three` &&
+       one=$(git rev-parse HEAD:one) &&
+       two=$(git rev-parse HEAD:two) &&
+       three=$(git rev-parse HEAD:three) &&
 
        echo happy.
 '
@@ -33,9 +33,9 @@ test_expect_success 'default settings cause no changes' '
 
        ! has_cr one &&
        has_cr two &&
-       onediff=`git diff one` &&
-       twodiff=`git diff two` &&
-       threediff=`git diff three` &&
+       onediff=$(git diff one) &&
+       twodiff=$(git diff two) &&
+       threediff=$(git diff three) &&
        test -z "$onediff" -a -z "$twodiff" -a -z "$threediff"
 '
 
@@ -48,7 +48,7 @@ test_expect_success 'crlf=true causes a CRLF file to be normalized' '
 
        # Note, "normalized" means that git will normalize it if added
        has_cr two &&
-       twodiff=`git diff two` &&
+       twodiff=$(git diff two) &&
        test -n "$twodiff"
 '
 
@@ -60,7 +60,7 @@ test_expect_success 'text=true causes a CRLF file to be normalized' '
 
        # Note, "normalized" means that git will normalize it if added
        has_cr two &&
-       twodiff=`git diff two` &&
+       twodiff=$(git diff two) &&
        test -n "$twodiff"
 '
 
@@ -72,7 +72,7 @@ test_expect_success 'eol=crlf gives a normalized file CRLFs with autocrlf=false'
        git read-tree --reset -u HEAD &&
 
        has_cr one &&
-       onediff=`git diff one` &&
+       onediff=$(git diff one) &&
        test -z "$onediff"
 '
 
@@ -84,7 +84,7 @@ test_expect_success 'eol=crlf gives a normalized file CRLFs with autocrlf=input'
        git read-tree --reset -u HEAD &&
 
        has_cr one &&
-       onediff=`git diff one` &&
+       onediff=$(git diff one) &&
        test -z "$onediff"
 '
 
@@ -96,7 +96,7 @@ test_expect_success 'eol=lf gives a normalized file LFs with autocrlf=true' '
        git read-tree --reset -u HEAD &&
 
        ! has_cr one &&
-       onediff=`git diff one` &&
+       onediff=$(git diff one) &&
        test -z "$onediff"
 '
 
@@ -108,9 +108,9 @@ test_expect_success 'autocrlf=true does not normalize CRLF files' '
 
        has_cr one &&
        has_cr two &&
-       onediff=`git diff one` &&
-       twodiff=`git diff two` &&
-       threediff=`git diff three` &&
+       onediff=$(git diff one) &&
+       twodiff=$(git diff two) &&
+       threediff=$(git diff three) &&
        test -z "$onediff" -a -z "$twodiff" -a -z "$threediff"
 '
 
@@ -123,9 +123,9 @@ test_expect_success 'text=auto, autocrlf=true _does_ normalize CRLF files' '
 
        has_cr one &&
        has_cr two &&
-       onediff=`git diff one` &&
-       twodiff=`git diff two` &&
-       threediff=`git diff three` &&
+       onediff=$(git diff one) &&
+       twodiff=$(git diff two) &&
+       threediff=$(git diff three) &&
        test -z "$onediff" -a -n "$twodiff" -a -z "$threediff"
 '
 
@@ -137,7 +137,7 @@ test_expect_success 'text=auto, autocrlf=true does not normalize binary files' '
        git read-tree --reset -u HEAD &&
 
        ! has_cr three &&
-       threediff=`git diff three` &&
+       threediff=$(git diff three) &&
        test -z "$threediff"
 '
 
@@ -148,7 +148,7 @@ test_expect_success 'eol=crlf _does_ normalize binary files' '
        git read-tree --reset -u HEAD &&
 
        has_cr three &&
-       threediff=`git diff three` &&
+       threediff=$(git diff three) &&
        test -z "$threediff"
 '
 
index fe0164be62ad9ae7a2ea426c6e576cd1133f3d67..e1126aa7cc05ff61ddf087fe13880da7f48219a6 100755 (executable)
@@ -20,8 +20,8 @@ test_expect_success setup '
 
        git commit -m initial &&
 
-       one=`git rev-parse HEAD:one` &&
-       two=`git rev-parse HEAD:two` &&
+       one=$(git rev-parse HEAD:one) &&
+       two=$(git rev-parse HEAD:two) &&
 
        echo happy.
 '
@@ -34,8 +34,8 @@ test_expect_success 'eol=lf puts LFs in normalized file' '
 
        ! has_cr one &&
        ! has_cr two &&
-       onediff=`git diff one` &&
-       twodiff=`git diff two` &&
+       onediff=$(git diff one) &&
+       twodiff=$(git diff two) &&
        test -z "$onediff" -a -z "$twodiff"
 '
 
@@ -47,8 +47,8 @@ test_expect_success 'eol=crlf puts CRLFs in normalized file' '
 
        has_cr one &&
        ! has_cr two &&
-       onediff=`git diff one` &&
-       twodiff=`git diff two` &&
+       onediff=$(git diff one) &&
+       twodiff=$(git diff two) &&
        test -z "$onediff" -a -z "$twodiff"
 '
 
@@ -61,8 +61,8 @@ test_expect_success 'autocrlf=true overrides eol=lf' '
 
        has_cr one &&
        has_cr two &&
-       onediff=`git diff one` &&
-       twodiff=`git diff two` &&
+       onediff=$(git diff one) &&
+       twodiff=$(git diff two) &&
        test -z "$onediff" -a -z "$twodiff"
 '
 
@@ -75,8 +75,8 @@ test_expect_success 'autocrlf=true overrides unset eol' '
 
        has_cr one &&
        has_cr two &&
-       onediff=`git diff one` &&
-       twodiff=`git diff two` &&
+       onediff=$(git diff one) &&
+       twodiff=$(git diff two) &&
        test -z "$onediff" -a -z "$twodiff"
 '
 
index a8e84d854636178224b1bbd52272d47fc686ece9..0333dd9875af9fbbad04cf05eb9f0e9fe37ae182 100755 (executable)
@@ -225,22 +225,22 @@ test_expect_success \
 
 test_expect_success \
     'text without newline at end should end with newline' '
-    test `printf "$ttt" | git stripspace | wc -l` -gt 0 &&
-    test `printf "$ttt$ttt" | git stripspace | wc -l` -gt 0 &&
-    test `printf "$ttt$ttt$ttt" | git stripspace | wc -l` -gt 0 &&
-    test `printf "$ttt$ttt$ttt$ttt" | git stripspace | wc -l` -gt 0
+    test $(printf "$ttt" | git stripspace | wc -l) -gt 0 &&
+    test $(printf "$ttt$ttt" | git stripspace | wc -l) -gt 0 &&
+    test $(printf "$ttt$ttt$ttt" | git stripspace | wc -l) -gt 0 &&
+    test $(printf "$ttt$ttt$ttt$ttt" | git stripspace | wc -l) -gt 0
 '
 
 # text plus spaces at the end:
 
 test_expect_success \
     'text plus spaces without newline at end should end with newline' '
-    test `printf "$ttt$sss" | git stripspace | wc -l` -gt 0 &&
-    test `printf "$ttt$ttt$sss" | git stripspace | wc -l` -gt 0 &&
-    test `printf "$ttt$ttt$ttt$sss" | git stripspace | wc -l` -gt 0 &&
-    test `printf "$ttt$sss$sss" | git stripspace | wc -l` -gt 0 &&
-    test `printf "$ttt$ttt$sss$sss" | git stripspace | wc -l` -gt 0 &&
-    test `printf "$ttt$sss$sss$sss" | git stripspace | wc -l` -gt 0
+    test $(printf "$ttt$sss" | git stripspace | wc -l) -gt 0 &&
+    test $(printf "$ttt$ttt$sss" | git stripspace | wc -l) -gt 0 &&
+    test $(printf "$ttt$ttt$ttt$sss" | git stripspace | wc -l) -gt 0 &&
+    test $(printf "$ttt$sss$sss" | git stripspace | wc -l) -gt 0 &&
+    test $(printf "$ttt$ttt$sss$sss" | git stripspace | wc -l) -gt 0 &&
+    test $(printf "$ttt$sss$sss$sss" | git stripspace | wc -l) -gt 0
 '
 
 test_expect_success \
index 538ea5fb1c27bf5e4f9c4a0268f219f5d6d6e9c5..57ea5a10c5c716f52a8c8c7335ac7f68fe9dd92d 100755 (executable)
@@ -6,7 +6,7 @@ test_description='basic credential helper tests'
 
 test_expect_success 'setup helper scripts' '
        cat >dump <<-\EOF &&
-       whoami=`echo $0 | sed s/.*git-credential-//`
+       whoami=$(echo $0 | sed s/.*git-credential-//)
        echo >&2 "$whoami: $*"
        OIFS=$IFS
        IFS==
index babcdd23433348cd0e2397b2fb6968f7cfae4b0a..a0b79b4839fb21a96bf8aca769542d93b21bb90f 100755 (executable)
@@ -519,10 +519,10 @@ test_expect_success \
     'rm -f .git/index F16 &&
     echo F16 >F16 &&
     git update-index --add F16 &&
-    tree0=`git write-tree` &&
+    tree0=$(git write-tree) &&
     echo E16 >F16 &&
     git update-index F16 &&
-    tree1=`git write-tree` &&
+    tree1=$(git write-tree) &&
     read_tree_must_succeed -m $tree0 $tree1 $tree1 $tree0 &&
     git ls-files --stage'
 
index 3a24abf5496c76862e772907442dc24bdcb4d78a..db1b6f5cf4dd8c7932946a53bc2e1c30b09b762b 100755 (executable)
@@ -36,7 +36,7 @@ compare_change () {
 }
 
 check_cache_at () {
-       clean_if_empty=`git diff-files -- "$1"`
+       clean_if_empty=$(git diff-files -- "$1")
        case "$clean_if_empty" in
        '')  echo "$1: clean" ;;
        ?*)  echo "$1: dirty" ;;
@@ -68,14 +68,14 @@ test_expect_success \
      echo rezrov >rezrov &&
      echo yomin >yomin &&
      git update-index --add nitfol bozbar rezrov &&
-     treeH=`git write-tree` &&
+     treeH=$(git write-tree) &&
      echo treeH $treeH &&
      git ls-tree $treeH &&
 
      cat bozbar-new >bozbar &&
      git update-index --add frotz bozbar --force-remove rezrov &&
      git ls-files --stage >M.out &&
-     treeM=`git write-tree` &&
+     treeM=$(git write-tree) &&
      echo treeM $treeM &&
      git ls-tree $treeM &&
      git diff-tree $treeH $treeM'
@@ -315,7 +315,7 @@ test_expect_success \
     'rm -f .git/index &&
      echo DF >DF &&
      git update-index --add DF &&
-     treeDF=`git write-tree` &&
+     treeDF=$(git write-tree) &&
      echo treeDF $treeDF &&
      git ls-tree $treeDF &&
 
@@ -323,7 +323,7 @@ test_expect_success \
      mkdir DF &&
      echo DF/DF >DF/DF &&
      git update-index --add --remove DF DF/DF &&
-     treeDFDF=`git write-tree` &&
+     treeDFDF=$(git write-tree) &&
      echo treeDFDF $treeDFDF &&
      git ls-tree $treeDFDF &&
      git ls-files --stage >DFDF.out'
@@ -345,7 +345,7 @@ test_expect_success \
     'rm -f .git/index &&
      : >a &&
      git update-index --add a &&
-     treeM=`git write-tree` &&
+     treeM=$(git write-tree) &&
      echo treeM $treeM &&
      git ls-tree $treeM &&
      git ls-files --stage >treeM.out &&
@@ -354,7 +354,7 @@ test_expect_success \
      git update-index --remove a &&
      mkdir a &&
      : >a/b &&
-     treeH=`git write-tree` &&
+     treeH=$(git write-tree) &&
      echo treeH $treeH &&
      git ls-tree $treeH'
 
@@ -372,7 +372,7 @@ test_expect_success \
      mkdir c &&
      : >c/d &&
      git update-index --add a c/d &&
-     treeM=`git write-tree` &&
+     treeM=$(git write-tree) &&
      echo treeM $treeM &&
      git ls-tree $treeM &&
      git ls-files --stage >treeM.out &&
@@ -381,7 +381,7 @@ test_expect_success \
      mkdir a &&
      : >a/b &&
      git update-index --add --remove a a/b &&
-     treeH=`git write-tree` &&
+     treeH=$(git write-tree) &&
      echo treeH $treeH &&
      git ls-tree $treeH'
 
index a847709a1354a824c90a13d2c9e9ab6d6bc69b6c..fed877b20f428a1987357ad1f66dc678f5c7e2eb 100755 (executable)
@@ -21,7 +21,7 @@ compare_change () {
 }
 
 check_cache_at () {
-       clean_if_empty=`git diff-files -- "$1"`
+       clean_if_empty=$(git diff-files -- "$1")
        case "$clean_if_empty" in
        '')  echo "$1: clean" ;;
        ?*)  echo "$1: dirty" ;;
@@ -41,14 +41,14 @@ test_expect_success \
      echo bozbar >bozbar &&
      echo rezrov >rezrov &&
      git update-index --add nitfol bozbar rezrov &&
-     treeH=`git write-tree` &&
+     treeH=$(git write-tree) &&
      echo treeH $treeH &&
      git ls-tree $treeH &&
 
      echo gnusto >bozbar &&
      git update-index --add frotz bozbar --force-remove rezrov &&
      git ls-files --stage >M.out &&
-     treeM=`git write-tree` &&
+     treeM=$(git write-tree) &&
      echo treeM $treeM &&
      git ls-tree $treeM &&
      sum bozbar frotz nitfol >M.sum &&
@@ -318,7 +318,7 @@ test_expect_success \
     'rm -f .git/index &&
      echo DF >DF &&
      git update-index --add DF &&
-     treeDF=`git write-tree` &&
+     treeDF=$(git write-tree) &&
      echo treeDF $treeDF &&
      git ls-tree $treeDF &&
 
@@ -326,7 +326,7 @@ test_expect_success \
      mkdir DF &&
      echo DF/DF >DF/DF &&
      git update-index --add --remove DF DF/DF &&
-     treeDFDF=`git write-tree` &&
+     treeDFDF=$(git write-tree) &&
      echo treeDFDF $treeDFDF &&
      git ls-tree $treeDFDF &&
      git ls-files --stage >DFDF.out'
index 8c6d67edda1468ba0f1c7afc6d13ea3a7bbe0a90..b6111cd150fdd69973142808cf4a86a4fa6b7e76 100755 (executable)
@@ -11,7 +11,7 @@ test_description='git read-tree --prefix test.
 test_expect_success setup '
        echo hello >one &&
        git update-index --add one &&
-       tree=`git write-tree` &&
+       tree=$(git write-tree) &&
        echo tree is $tree
 '
 
index 3e72aff470f8d9e5e79689de459904d1f3271d0d..c70cf423008cfb6f3f3fd735c1f6ee2d1408de2c 100755 (executable)
@@ -30,7 +30,7 @@ test_expect_success 'two-way not clobbering' '
 
        echo >file2 master creates untracked file2 &&
        echo >subdir/file2 master creates untracked subdir/file2 &&
-       if err=`read_tree_u_must_succeed -m -u master side 2>&1`
+       if err=$(read_tree_u_must_succeed -m -u master side 2>&1)
        then
                echo should have complained
                false
@@ -43,7 +43,7 @@ echo file2 >.gitignore
 
 test_expect_success 'two-way with incorrect --exclude-per-directory (1)' '
 
-       if err=`read_tree_u_must_succeed -m --exclude-per-directory=.gitignore master side 2>&1`
+       if err=$(read_tree_u_must_succeed -m --exclude-per-directory=.gitignore master side 2>&1)
        then
                echo should have complained
                false
@@ -54,7 +54,7 @@ test_expect_success 'two-way with incorrect --exclude-per-directory (1)' '
 
 test_expect_success 'two-way with incorrect --exclude-per-directory (2)' '
 
-       if err=`read_tree_u_must_succeed -m -u --exclude-per-directory=foo --exclude-per-directory=.gitignore master side 2>&1`
+       if err=$(read_tree_u_must_succeed -m -u --exclude-per-directory=foo --exclude-per-directory=.gitignore master side 2>&1)
        then
                echo should have complained
                false
@@ -95,7 +95,7 @@ test_expect_success 'three-way not clobbering a working tree file' '
        git checkout master &&
        echo >file3 file three created in master, untracked &&
        echo >subdir/file3 file three created in master, untracked &&
-       if err=`read_tree_u_must_succeed -m -u branch-point master side 2>&1`
+       if err=$(read_tree_u_must_succeed -m -u branch-point master side 2>&1)
        then
                echo should have complained
                false
index 6902320e819651553beac7d80971b984b9168a8a..62c0d25af4ca1c8ef5d0d63b6e3ea329a6d75205 100755 (executable)
@@ -20,27 +20,27 @@ test_expect_success setup '
 
 test_expect_success 'update-index and ls-files' '
        git update-index --add one &&
-       case "`git ls-files`" in
+       case "$(git ls-files)" in
        one) echo pass one ;;
        *) echo bad one; exit 1 ;;
        esac &&
        (
                cd dir &&
                git update-index --add two &&
-               case "`git ls-files`" in
+               case "$(git ls-files)" in
                two) echo pass two ;;
                *) echo bad two; exit 1 ;;
                esac
        ) &&
-       case "`git ls-files`" in
+       case "$(git ls-files)" in
        dir/two"$LF"one) echo pass both ;;
        *) echo bad; exit 1 ;;
        esac
 '
 
 test_expect_success 'cat-file' '
-       two=`git ls-files -s dir/two` &&
-       two=`expr "$two" : "[0-7]* \\([0-9a-f]*\\)"` &&
+       two=$(git ls-files -s dir/two) &&
+       two=$(expr "$two" : "[0-7]* \\([0-9a-f]*\\)") &&
        echo "$two" &&
        git cat-file -p "$two" >actual &&
        cmp dir/two actual &&
@@ -55,18 +55,18 @@ rm -f actual dir/actual
 test_expect_success 'diff-files' '
        echo a >>one &&
        echo d >>dir/two &&
-       case "`git diff-files --name-only`" in
+       case "$(git diff-files --name-only)" in
        dir/two"$LF"one) echo pass top ;;
        *) echo bad top; exit 1 ;;
        esac &&
        # diff should not omit leading paths
        (
                cd dir &&
-               case "`git diff-files --name-only`" in
+               case "$(git diff-files --name-only)" in
                dir/two"$LF"one) echo pass subdir ;;
                *) echo bad subdir; exit 1 ;;
                esac &&
-               case "`git diff-files --name-only .`" in
+               case "$(git diff-files --name-only .)" in
                dir/two) echo pass subdir limited ;;
                *) echo bad subdir limited; exit 1 ;;
                esac
@@ -74,11 +74,11 @@ test_expect_success 'diff-files' '
 '
 
 test_expect_success 'write-tree' '
-       top=`git write-tree` &&
+       top=$(git write-tree) &&
        echo $top &&
        (
                cd dir &&
-               sub=`git write-tree` &&
+               sub=$(git write-tree) &&
                echo $sub &&
                test "z$top" = "z$sub"
        )
@@ -96,7 +96,7 @@ test_expect_success 'checkout-index' '
 
 test_expect_success 'read-tree' '
        rm -f one dir/two &&
-       tree=`git write-tree` &&
+       tree=$(git write-tree) &&
        read_tree_u_must_succeed --reset -u "$tree" &&
        cmp one original.one &&
        cmp dir/two original.two &&
index fd105280092b7f655f5c48f09b2e8f5e0ee6d351..aea493646e4400e733749768e48f2a3d1a470299 100755 (executable)
@@ -131,7 +131,7 @@ test_expect_success 'git-show a large file' '
 '
 
 test_expect_success 'index-pack' '
-       git clone file://"`pwd`"/.git foo &&
+       git clone file://"$(pwd)"/.git foo &&
        GIT_DIR=non-existent git index-pack --strict --verify foo/.git/objects/pack/*.pack
 '
 
@@ -140,7 +140,7 @@ test_expect_success 'repack' '
 '
 
 test_expect_success 'pack-objects with large loose object' '
-       SHA1=`git hash-object huge` &&
+       SHA1=$(git hash-object huge) &&
        test_create_repo loose &&
        echo $SHA1 | git pack-objects --stdout |
                GIT_ALLOC_LIMIT=0 GIT_DIR=loose/.git git unpack-objects &&
index 58cd5435be59107c3bac323e0d53816ab0f8e4ae..3f80ff0c14c47b87bbbecb74d1951a1abe6bc5ba 100755 (executable)
@@ -1158,4 +1158,14 @@ test_expect_failure 'adding a key into an empty section reuses header' '
        test_cmp expect .git/config
 '
 
+test_expect_success POSIXPERM,PERL 'preserves existing permissions' '
+       chmod 0600 .git/config &&
+       git config imap.pass Hunter2 &&
+       perl -e \
+         "die q(badset) if ((stat(q(.git/config)))[2] & 07777) != 0600" &&
+       git config --rename-section imap pop &&
+       perl -e \
+         "die q(badrename) if ((stat(q(.git/config)))[2] & 07777) != 0600"
+'
+
 test_done
index e130c528fe5a0115c99b1203cfe9dced046cece3..4e2459afc549d5d2985024e8c23bf5fa117d570a 100755 (executable)
@@ -350,22 +350,28 @@ test_expect_success 'stdin fails on unknown command' '
        grep "fatal: unknown command: unknown $a" err
 '
 
-test_expect_success 'stdin fails on badly quoted input' '
+test_expect_success 'stdin fails on unbalanced quotes' '
        echo "create $a \"master" >stdin &&
        test_must_fail git update-ref --stdin <stdin 2>err &&
        grep "fatal: badly quoted argument: \\\"master" err
 '
 
-test_expect_success 'stdin fails on arguments not separated by space' '
+test_expect_success 'stdin fails on invalid escape' '
+       echo "create $a \"ma\zter\"" >stdin &&
+       test_must_fail git update-ref --stdin <stdin 2>err &&
+       grep "fatal: badly quoted argument: \\\"ma\\\\zter\\\"" err
+'
+
+test_expect_success 'stdin fails on junk after quoted argument' '
        echo "create \"$a\"master" >stdin &&
        test_must_fail git update-ref --stdin <stdin 2>err &&
-       grep "fatal: expected SP but got: master" err
+       grep "fatal: unexpected character after quoted argument: \\\"$a\\\"master" err
 '
 
 test_expect_success 'stdin fails create with no ref' '
        echo "create " >stdin &&
        test_must_fail git update-ref --stdin <stdin 2>err &&
-       grep "fatal: create line missing <ref>" err
+       grep "fatal: create: missing <ref>" err
 '
 
 test_expect_success 'stdin fails create with bad ref name' '
@@ -377,19 +383,19 @@ test_expect_success 'stdin fails create with bad ref name' '
 test_expect_success 'stdin fails create with no new value' '
        echo "create $a" >stdin &&
        test_must_fail git update-ref --stdin <stdin 2>err &&
-       grep "fatal: create $a missing <newvalue>" err
+       grep "fatal: create $a: missing <newvalue>" err
 '
 
 test_expect_success 'stdin fails create with too many arguments' '
        echo "create $a $m $m" >stdin &&
        test_must_fail git update-ref --stdin <stdin 2>err &&
-       grep "fatal: create $a has extra input:  $m" err
+       grep "fatal: create $a: extra input:  $m" err
 '
 
 test_expect_success 'stdin fails update with no ref' '
        echo "update " >stdin &&
        test_must_fail git update-ref --stdin <stdin 2>err &&
-       grep "fatal: update line missing <ref>" err
+       grep "fatal: update: missing <ref>" err
 '
 
 test_expect_success 'stdin fails update with bad ref name' '
@@ -401,19 +407,19 @@ test_expect_success 'stdin fails update with bad ref name' '
 test_expect_success 'stdin fails update with no new value' '
        echo "update $a" >stdin &&
        test_must_fail git update-ref --stdin <stdin 2>err &&
-       grep "fatal: update $a missing <newvalue>" err
+       grep "fatal: update $a: missing <newvalue>" err
 '
 
 test_expect_success 'stdin fails update with too many arguments' '
        echo "update $a $m $m $m" >stdin &&
        test_must_fail git update-ref --stdin <stdin 2>err &&
-       grep "fatal: update $a has extra input:  $m" err
+       grep "fatal: update $a: extra input:  $m" err
 '
 
 test_expect_success 'stdin fails delete with no ref' '
        echo "delete " >stdin &&
        test_must_fail git update-ref --stdin <stdin 2>err &&
-       grep "fatal: delete line missing <ref>" err
+       grep "fatal: delete: missing <ref>" err
 '
 
 test_expect_success 'stdin fails delete with bad ref name' '
@@ -425,13 +431,13 @@ test_expect_success 'stdin fails delete with bad ref name' '
 test_expect_success 'stdin fails delete with too many arguments' '
        echo "delete $a $m $m" >stdin &&
        test_must_fail git update-ref --stdin <stdin 2>err &&
-       grep "fatal: delete $a has extra input:  $m" err
+       grep "fatal: delete $a: extra input:  $m" err
 '
 
 test_expect_success 'stdin fails verify with too many arguments' '
        echo "verify $a $m $m" >stdin &&
        test_must_fail git update-ref --stdin <stdin 2>err &&
-       grep "fatal: verify $a has extra input:  $m" err
+       grep "fatal: verify $a: extra input:  $m" err
 '
 
 test_expect_success 'stdin fails option with unknown name' '
@@ -458,6 +464,24 @@ test_expect_success 'stdin create ref works' '
        test_cmp expect actual
 '
 
+test_expect_success 'stdin succeeds with quoted argument' '
+       git update-ref -d $a &&
+       echo "create $a \"$m\"" >stdin &&
+       git update-ref --stdin <stdin &&
+       git rev-parse $m >expect &&
+       git rev-parse $a >actual &&
+       test_cmp expect actual
+'
+
+test_expect_success 'stdin succeeds with escaped character' '
+       git update-ref -d $a &&
+       echo "create $a \"ma\\163ter\"" >stdin &&
+       git update-ref --stdin <stdin &&
+       git rev-parse $m >expect &&
+       git rev-parse $a >actual &&
+       test_cmp expect actual
+'
+
 test_expect_success 'stdin update ref creates with zero old value' '
        echo "update $b $m $Z" >stdin &&
        git update-ref --stdin <stdin &&
@@ -494,21 +518,21 @@ test_expect_success 'stdin update ref fails with wrong old value' '
 test_expect_success 'stdin update ref fails with bad old value' '
        echo "update $c $m does-not-exist" >stdin &&
        test_must_fail git update-ref --stdin <stdin 2>err &&
-       grep "fatal: invalid old value for ref $c: does-not-exist" err &&
+       grep "fatal: update $c: invalid <oldvalue>: does-not-exist" err &&
        test_must_fail git rev-parse --verify -q $c
 '
 
 test_expect_success 'stdin create ref fails with bad new value' '
        echo "create $c does-not-exist" >stdin &&
        test_must_fail git update-ref --stdin <stdin 2>err &&
-       grep "fatal: invalid new value for ref $c: does-not-exist" err &&
+       grep "fatal: create $c: invalid <newvalue>: does-not-exist" err &&
        test_must_fail git rev-parse --verify -q $c
 '
 
 test_expect_success 'stdin create ref fails with zero new value' '
        echo "create $c " >stdin &&
        test_must_fail git update-ref --stdin <stdin 2>err &&
-       grep "fatal: create $c given zero new value" err &&
+       grep "fatal: create $c: zero <newvalue>" err &&
        test_must_fail git rev-parse --verify -q $c
 '
 
@@ -532,7 +556,7 @@ test_expect_success 'stdin delete ref fails with wrong old value' '
 test_expect_success 'stdin delete ref fails with zero old value' '
        echo "delete $a " >stdin &&
        test_must_fail git update-ref --stdin <stdin 2>err &&
-       grep "fatal: delete $a given zero old value" err &&
+       grep "fatal: delete $a: zero <oldvalue>" err &&
        git rev-parse $m >expect &&
        git rev-parse $a >actual &&
        test_cmp expect actual
@@ -673,7 +697,7 @@ test_expect_success 'stdin -z fails on unknown command' '
 test_expect_success 'stdin -z fails create with no ref' '
        printf $F "create " >stdin &&
        test_must_fail git update-ref -z --stdin <stdin 2>err &&
-       grep "fatal: create line missing <ref>" err
+       grep "fatal: create: missing <ref>" err
 '
 
 test_expect_success 'stdin -z fails create with bad ref name' '
@@ -685,7 +709,7 @@ test_expect_success 'stdin -z fails create with bad ref name' '
 test_expect_success 'stdin -z fails create with no new value' '
        printf $F "create $a" >stdin &&
        test_must_fail git update-ref -z --stdin <stdin 2>err &&
-       grep "fatal: create $a missing <newvalue>" err
+       grep "fatal: create $a: unexpected end of input when reading <newvalue>" err
 '
 
 test_expect_success 'stdin -z fails create with too many arguments' '
@@ -697,25 +721,39 @@ test_expect_success 'stdin -z fails create with too many arguments' '
 test_expect_success 'stdin -z fails update with no ref' '
        printf $F "update " >stdin &&
        test_must_fail git update-ref -z --stdin <stdin 2>err &&
-       grep "fatal: update line missing <ref>" err
+       grep "fatal: update: missing <ref>" err
+'
+
+test_expect_success 'stdin -z fails update with too few args' '
+       printf $F "update $a" "$m" >stdin &&
+       test_must_fail git update-ref -z --stdin <stdin 2>err &&
+       grep "fatal: update $a: unexpected end of input when reading <oldvalue>" err
 '
 
 test_expect_success 'stdin -z fails update with bad ref name' '
-       printf $F "update ~a" "$m" >stdin &&
+       printf $F "update ~a" "$m" "" >stdin &&
        test_must_fail git update-ref -z --stdin <stdin 2>err &&
        grep "fatal: invalid ref format: ~a" err
 '
 
+test_expect_success 'stdin -z emits warning with empty new value' '
+       git update-ref $a $m &&
+       printf $F "update $a" "" "" >stdin &&
+       git update-ref -z --stdin <stdin 2>err &&
+       grep "warning: update $a: missing <newvalue>, treating as zero" err &&
+       test_must_fail git rev-parse --verify -q $a
+'
+
 test_expect_success 'stdin -z fails update with no new value' '
        printf $F "update $a" >stdin &&
        test_must_fail git update-ref -z --stdin <stdin 2>err &&
-       grep "fatal: update $a missing <newvalue>" err
+       grep "fatal: update $a: unexpected end of input when reading <newvalue>" err
 '
 
 test_expect_success 'stdin -z fails update with no old value' '
        printf $F "update $a" "$m" >stdin &&
        test_must_fail git update-ref -z --stdin <stdin 2>err &&
-       grep "fatal: update $a missing \\[<oldvalue>\\] NUL" err
+       grep "fatal: update $a: unexpected end of input when reading <oldvalue>" err
 '
 
 test_expect_success 'stdin -z fails update with too many arguments' '
@@ -727,7 +765,7 @@ test_expect_success 'stdin -z fails update with too many arguments' '
 test_expect_success 'stdin -z fails delete with no ref' '
        printf $F "delete " >stdin &&
        test_must_fail git update-ref -z --stdin <stdin 2>err &&
-       grep "fatal: delete line missing <ref>" err
+       grep "fatal: delete: missing <ref>" err
 '
 
 test_expect_success 'stdin -z fails delete with bad ref name' '
@@ -739,7 +777,7 @@ test_expect_success 'stdin -z fails delete with bad ref name' '
 test_expect_success 'stdin -z fails delete with no old value' '
        printf $F "delete $a" >stdin &&
        test_must_fail git update-ref -z --stdin <stdin 2>err &&
-       grep "fatal: delete $a missing \\[<oldvalue>\\] NUL" err
+       grep "fatal: delete $a: unexpected end of input when reading <oldvalue>" err
 '
 
 test_expect_success 'stdin -z fails delete with too many arguments' '
@@ -757,7 +795,7 @@ test_expect_success 'stdin -z fails verify with too many arguments' '
 test_expect_success 'stdin -z fails verify with no old value' '
        printf $F "verify $a" >stdin &&
        test_must_fail git update-ref -z --stdin <stdin 2>err &&
-       grep "fatal: verify $a missing \\[<oldvalue>\\] NUL" err
+       grep "fatal: verify $a: unexpected end of input when reading <oldvalue>" err
 '
 
 test_expect_success 'stdin -z fails option with unknown name' '
@@ -816,7 +854,7 @@ test_expect_success 'stdin -z update ref fails with wrong old value' '
 test_expect_success 'stdin -z update ref fails with bad old value' '
        printf $F "update $c" "$m" "does-not-exist" >stdin &&
        test_must_fail git update-ref -z --stdin <stdin 2>err &&
-       grep "fatal: invalid old value for ref $c: does-not-exist" err &&
+       grep "fatal: update $c: invalid <oldvalue>: does-not-exist" err &&
        test_must_fail git rev-parse --verify -q $c
 '
 
@@ -834,14 +872,14 @@ test_expect_success 'stdin -z create ref fails with bad new value' '
        git update-ref -d "$c" &&
        printf $F "create $c" "does-not-exist" >stdin &&
        test_must_fail git update-ref -z --stdin <stdin 2>err &&
-       grep "fatal: invalid new value for ref $c: does-not-exist" err &&
+       grep "fatal: create $c: invalid <newvalue>: does-not-exist" err &&
        test_must_fail git rev-parse --verify -q $c
 '
 
-test_expect_success 'stdin -z create ref fails with zero new value' '
+test_expect_success 'stdin -z create ref fails with empty new value' '
        printf $F "create $c" "" >stdin &&
        test_must_fail git update-ref -z --stdin <stdin 2>err &&
-       grep "fatal: create $c given zero new value" err &&
+       grep "fatal: create $c: missing <newvalue>" err &&
        test_must_fail git rev-parse --verify -q $c
 '
 
@@ -865,7 +903,7 @@ test_expect_success 'stdin -z delete ref fails with wrong old value' '
 test_expect_success 'stdin -z delete ref fails with zero old value' '
        printf $F "delete $a" "$Z" >stdin &&
        test_must_fail git update-ref -z --stdin <stdin 2>err &&
-       grep "fatal: delete $a given zero old value" err &&
+       grep "fatal: delete $a: zero <oldvalue>" err &&
        git rev-parse $m >expect &&
        git rev-parse $a >actual &&
        test_cmp expect actual
@@ -923,7 +961,7 @@ test_expect_success 'stdin -z update refs works with identity updates' '
 
 test_expect_success 'stdin -z update refs fails with wrong old value' '
        git update-ref $c $m &&
-       printf $F "update $a" "$m" "$m" "update $b" "$m" "$m" "update $c" "" "$Z" >stdin &&
+       printf $F "update $a" "$m" "$m" "update $b" "$m" "$m" "update $c" "$m" "$Z" >stdin &&
        test_must_fail git update-ref -z --stdin <stdin 2>err &&
        grep "fatal: Cannot lock the ref '"'"'$c'"'"'" err &&
        git rev-parse $m >expect &&
index 19c99d7ef1bc02e67a7b995206b9f66c04c1b31c..b457333e1865de794e47fa6b601648fd67a02a7c 100755 (executable)
@@ -65,12 +65,15 @@ test_expect_success 'output to keep user entertained during multi-pick' '
        cat <<-\EOF >expected &&
        [master OBJID] second
         Author: A U Thor <author@example.com>
+        Date: Thu Apr 7 15:14:13 2005 -0700
         1 file changed, 1 insertion(+)
        [master OBJID] third
         Author: A U Thor <author@example.com>
+        Date: Thu Apr 7 15:15:13 2005 -0700
         1 file changed, 1 insertion(+)
        [master OBJID] fourth
         Author: A U Thor <author@example.com>
+        Date: Thu Apr 7 15:16:13 2005 -0700
         1 file changed, 1 insertion(+)
        EOF
 
@@ -98,14 +101,17 @@ test_expect_success 'output during multi-pick indicates merge strategy' '
        Trying simple merge.
        [master OBJID] second
         Author: A U Thor <author@example.com>
+        Date: Thu Apr 7 15:14:13 2005 -0700
         1 file changed, 1 insertion(+)
        Trying simple merge.
        [master OBJID] third
         Author: A U Thor <author@example.com>
+        Date: Thu Apr 7 15:15:13 2005 -0700
         1 file changed, 1 insertion(+)
        Trying simple merge.
        [master OBJID] fourth
         Author: A U Thor <author@example.com>
+        Date: Thu Apr 7 15:16:13 2005 -0700
         1 file changed, 1 insertion(+)
        EOF
 
index a5e7e6b2ba3138d06c400e965decf1389da3274a..f372fc8ca8e3b311b03313a46db1aa8f35de2ea9 100755 (executable)
@@ -96,8 +96,8 @@ test_expect_success 'stash pop after save --include-untracked leaves files untra
        git stash pop &&
        git status --porcelain >actual &&
        test_cmp expect actual &&
-       test "1" = "`cat file2`" &&
-       test untracked = "`cat untracked/untracked`"
+       test "1" = "$(cat file2)" &&
+       test untracked = "$(cat untracked/untracked)"
 '
 
 git clean --force --quiet -d
index e4ba6013e41927bc0ec3ff3876648a71a71ce6e1..831935665e012c04bbe4c57feee92c0310df5c04 100755 (executable)
@@ -14,13 +14,13 @@ then
 fi
 
 # create utf-8 variables
-Adiarnfc=`printf '\303\204'`
-Adiarnfd=`printf 'A\314\210'`
+Adiarnfc=$(printf '\303\204')
+Adiarnfd=$(printf 'A\314\210')
 
-Odiarnfc=`printf '\303\226'`
-Odiarnfd=`printf 'O\314\210'`
-AEligatu=`printf '\303\206'`
-Invalidu=`printf '\303\377'`
+Odiarnfc=$(printf '\303\226')
+Odiarnfd=$(printf 'O\314\210')
+AEligatu=$(printf '\303\206')
+Invalidu=$(printf '\303\377')
 
 
 #Create a string with 255 bytes (decomposed)
@@ -35,7 +35,7 @@ Alongc=$Alongc$Alongc$Alongc$Alongc$Alongc           #250 Byte
 Alongc=$Alongc$AEligatu$AEligatu                     #254 Byte
 
 test_expect_success "detect if nfd needed" '
-       precomposeunicode=`git config core.precomposeunicode` &&
+       precomposeunicode=$(git config core.precomposeunicode) &&
        test "$precomposeunicode" = true &&
        git config core.precomposeunicode true
 '
@@ -140,13 +140,23 @@ test_expect_success "Add long precomposed filename" '
        git add * &&
        git commit -m "Long filename"
 '
+
+test_expect_failure 'handle existing decomposed filenames' '
+       echo content >"verbatim.$Adiarnfd" &&
+       git -c core.precomposeunicode=false add "verbatim.$Adiarnfd" &&
+       git commit -m "existing decomposed file" &&
+       >expect &&
+       git ls-files --exclude-standard -o "verbatim*" >untracked &&
+       test_cmp expect untracked
+'
+
 # Test if the global core.precomposeunicode stops autosensing
 # Must be the last test case
 test_expect_success "respect git config --global core.precomposeunicode" '
        git config --global core.precomposeunicode true &&
        rm -rf .git &&
        git init &&
-       precomposeunicode=`git config core.precomposeunicode` &&
+       precomposeunicode=$(git config core.precomposeunicode) &&
        test "$precomposeunicode" = "true"
 '
 
index 05911492ca6df386bfe344ffcfb9562beeaceabf..76f643b2c2a2c7e307135de6942cf46743b6cbef 100755 (executable)
@@ -13,7 +13,7 @@ sed_script='s/\(:100644 100755\) \('"$_x40"'\) \2 /\1 X X /'
 test_expect_success 'setup' '
        echo frotz >rezrov &&
        git update-index --add rezrov &&
-       tree=`git write-tree` &&
+       tree=$(git write-tree) &&
        echo $tree
 '
 
index 2bb973655bf043cc43292764ffd68becda25aa2e..bf078418662c4bab4e512be8fc22a5aa76466119 100755 (executable)
@@ -18,7 +18,7 @@ test_expect_success \
      mkdir path1 &&
      echo rezrov >path1/file1 &&
      git update-index --add file0 path1/file1 &&
-     tree=`git write-tree` &&
+     tree=$(git write-tree) &&
      echo "$tree" &&
      echo nitfol >file0 &&
      echo yomin >path1/file1 &&
@@ -131,7 +131,7 @@ test_expect_success 'diff multiple wildcard pathspecs' '
        mkdir path2 &&
        echo rezrov >path2/file1 &&
        git update-index --add path2/file1 &&
-       tree3=`git write-tree` &&
+       tree3=$(git write-tree) &&
        git diff --name-only $tree $tree3 -- "path2*1" "path1*1" >actual &&
        cat <<-\EOF >expect &&
        path1/file1
index 1215ae544b6915fe2cc6df4d193c8f3a805beba1..643d729157d23ce501258710640e4090c34922fc 100755 (executable)
@@ -67,18 +67,18 @@ test_expect_success C_LOCALE_OUTPUT 'apply detecting corrupt patch correctly' '
        git diff >output &&
        sed -e "s/-CIT/xCIT/" <output >broken &&
        test_must_fail git apply --stat --summary broken 2>detected &&
-       detected=`cat detected` &&
-       detected=`expr "$detected" : "fatal.*at line \\([0-9]*\\)\$"` &&
-       detected=`sed -ne "${detected}p" broken` &&
+       detected=$(cat detected) &&
+       detected=$(expr "$detected" : "fatal.*at line \\([0-9]*\\)\$") &&
+       detected=$(sed -ne "${detected}p" broken) &&
        test "$detected" = xCIT
 '
 
 test_expect_success C_LOCALE_OUTPUT 'apply detecting corrupt patch correctly' '
        git diff --binary | sed -e "s/-CIT/xCIT/" >broken &&
        test_must_fail git apply --stat --summary broken 2>detected &&
-       detected=`cat detected` &&
-       detected=`expr "$detected" : "fatal.*at line \\([0-9]*\\)\$"` &&
-       detected=`sed -ne "${detected}p" broken` &&
+       detected=$(cat detected) &&
+       detected=$(expr "$detected" : "fatal.*at line \\([0-9]*\\)\$") &&
+       detected=$(sed -ne "${detected}p" broken) &&
        test "$detected" = xCIT
 '
 
@@ -88,7 +88,7 @@ test_expect_success 'initial commit' 'git commit -a -m initial'
 test_expect_success 'diff-index with --binary' '
        echo AIT >a && mv b e && echo CIT >c && cat e >d &&
        git update-index --add --remove a b c d e &&
-       tree0=`git write-tree` &&
+       tree0=$(git write-tree) &&
        git diff --cached --binary >current &&
        git apply --stat --summary current
 '
@@ -96,7 +96,7 @@ test_expect_success 'diff-index with --binary' '
 test_expect_success 'apply binary patch' '
        git reset --hard &&
        git apply --binary --index <current &&
-       tree1=`git write-tree` &&
+       tree1=$(git write-tree) &&
        test "$tree1" = "$tree0"
 '
 
index e77c09c37eede2f039610199ba8e3c45e94213d4..805b055c899e7c9f5653eb740572f67417c9dcb6 100755 (executable)
@@ -107,14 +107,14 @@ test_expect_success setup '
 +*++ [initial] Initial
 EOF
 
-V=`git version | sed -e 's/^git version //' -e 's/\./\\./g'`
+V=$(git version | sed -e 's/^git version //' -e 's/\./\\./g')
 while read cmd
 do
        case "$cmd" in
        '' | '#'*) continue ;;
        esac
-       test=`echo "$cmd" | sed -e 's|[/ ][/ ]*|_|g'`
-       pfx=`printf "%04d" $test_count`
+       test=$(echo "$cmd" | sed -e 's|[/ ][/ ]*|_|g')
+       pfx=$(printf "%04d" $test_count)
        expect="$TEST_DIRECTORY/t4013/diff.$test"
        actual="$pfx-diff.$test"
 
index 9c8063314688ec0c03d3fb2099379cbbf4ff2e19..282bee4a54c924b8168b6a28dfdbeb7ab300d7b7 100755 (executable)
@@ -43,7 +43,7 @@ test_expect_success setup '
 test_expect_success "format-patch --ignore-if-in-upstream" '
 
        git format-patch --stdout master..side >patch0 &&
-       cnt=`grep "^From " patch0 | wc -l` &&
+       cnt=$(grep "^From " patch0 | wc -l) &&
        test $cnt = 3
 
 '
@@ -52,7 +52,7 @@ test_expect_success "format-patch --ignore-if-in-upstream" '
 
        git format-patch --stdout \
                --ignore-if-in-upstream master..side >patch1 &&
-       cnt=`grep "^From " patch1 | wc -l` &&
+       cnt=$(grep "^From " patch1 | wc -l) &&
        test $cnt = 2
 
 '
@@ -69,7 +69,7 @@ test_expect_success "format-patch doesn't consider merge commits" '
        git checkout -b merger master &&
        test_tick &&
        git merge --no-ff slave &&
-       cnt=`git format-patch -3 --stdout | grep "^From " | wc -l` &&
+       cnt=$(git format-patch -3 --stdout | grep "^From " | wc -l) &&
        test $cnt = 3
 '
 
@@ -77,7 +77,7 @@ test_expect_success "format-patch result applies" '
 
        git checkout -b rebuild-0 master &&
        git am -3 patch0 &&
-       cnt=`git rev-list master.. | wc -l` &&
+       cnt=$(git rev-list master.. | wc -l) &&
        test $cnt = 2
 '
 
@@ -85,7 +85,7 @@ test_expect_success "format-patch --ignore-if-in-upstream result applies" '
 
        git checkout -b rebuild-1 master &&
        git am -3 patch1 &&
-       cnt=`git rev-list master.. | wc -l` &&
+       cnt=$(git rev-list master.. | wc -l) &&
        test $cnt = 2
 '
 
index ba43f185494630c50fc2a168df8dcd45c0b2421b..98d9713d8b2454eb1dfc4f137133a7cb0174bd0d 100755 (executable)
@@ -42,7 +42,7 @@ test_expect_success 'attach and signoff do not duplicate mime headers' '
 
        GIT_COMMITTER_NAME="はまの ふにおう" \
        git format-patch -s --stdout -1 --attach >output &&
-       test `grep -ci ^MIME-Version: output` = 1
+       test $(grep -ci ^MIME-Version: output) = 1
 
 '
 
index 1019d7b35fcb350761a44cf4ccd5ae156ce8d577..41913c3aa30de6d55b016fa9331e0877579b2d6b 100755 (executable)
@@ -94,7 +94,7 @@ test_expect_success 'setup for --cc --raw' '
        blob=$(echo file | git hash-object --stdin -w) &&
        base_tree=$(echo "100644 blob $blob     file" | git mktree) &&
        trees= &&
-       for i in `test_seq 1 40`
+       for i in $(test_seq 1 40)
        do
                blob=$(echo file$i | git hash-object --stdin -w) &&
                trees="$trees$(echo "100644 blob $blob  file" | git mktree)$LF"
index 097e63215e1ffc349ae9e3803f953aa70882b6a4..dff36b77ec8856573da26685376d156d49f8e021 100755 (executable)
@@ -5,7 +5,7 @@ test_description='combined diff show only paths that are different to all parent
 . ./test-lib.sh
 
 # verify that diffc.expect matches output of
-# `git diff -c --name-only HEAD HEAD^ HEAD^2`
+# $(git diff -c --name-only HEAD HEAD^ HEAD^2)
 diffc_verify () {
        git diff -c --name-only HEAD HEAD^ HEAD^2 >diffc.actual &&
        test_cmp diffc.expect diffc.actual
index b04fc8fc12238c3326306ed0e055b7d67bf950b4..9e29b5262d3f2e8514d5742951e28a3a339218dc 100755 (executable)
@@ -111,7 +111,6 @@ sed -e 's/T/        /g' > main.c.final <<\EOF
 #include <stdio.h>
 
 void print_int(int num);
-T/* a comment */
 int func(int num);
 
 int main() {
@@ -154,7 +153,8 @@ test_expect_success 'patch2 reverse applies with --ignore-space-change' '
 git config apply.ignorewhitespace change
 
 test_expect_success 'patch2 applies (apply.ignorewhitespace = change)' '
-       git apply patch2.patch
+       git apply patch2.patch &&
+       test_cmp main.c.final main.c
 '
 
 test_expect_success 'patch3 fails (missing string at EOL)' '
@@ -165,12 +165,8 @@ test_expect_success 'patch4 fails (missing EOL at EOF)' '
        test_must_fail git apply patch4.patch
 '
 
-test_expect_success 'patch5 applies (leading whitespace)' '
-       git apply patch5.patch
-'
-
-test_expect_success 'patches do not mangle whitespace' '
-       test_cmp main.c main.c.final
+test_expect_success 'patch5 fails (leading whitespace differences matter)' '
+       test_must_fail git apply patch5.patch
 '
 
 test_expect_success 're-create file (with --ignore-whitespace)' '
index 1e4d4380bf01c081aeb1df44cef40319063f2faa..ce8567f496438c18501f30632269ecbe7de15fd3 100755 (executable)
@@ -30,10 +30,10 @@ test_expect_success setup '
 
 test_expect_success 'apply in forward' '
 
-       T0=`git rev-parse "second^{tree}"` &&
+       T0=$(git rev-parse "second^{tree}") &&
        git reset --hard initial &&
        git apply --index --binary patch &&
-       T1=`git write-tree` &&
+       T1=$(git write-tree) &&
        test "$T0" = "$T1"
 '
 
@@ -62,22 +62,22 @@ test_expect_success 'setup separate repository lacking postimage' '
 
 test_expect_success 'apply in forward without postimage' '
 
-       T0=`git rev-parse "second^{tree}"` &&
+       T0=$(git rev-parse "second^{tree}") &&
        (
                cd initial &&
                git apply --index --binary ../patch &&
-               T1=`git write-tree` &&
+               T1=$(git write-tree) &&
                test "$T0" = "$T1"
        )
 '
 
 test_expect_success 'apply in reverse without postimage' '
 
-       T0=`git rev-parse "initial^{tree}"` &&
+       T0=$(git rev-parse "initial^{tree}") &&
        (
                cd second &&
                git apply --index --binary --reverse ../patch &&
-               T1=`git write-tree` &&
+               T1=$(git write-tree) &&
                test "$T0" = "$T1"
        )
 '
index 3d0384daa8a7b7369826b05bcb793cb445c3f9ee..c393be691be42a0b0a982c07ffeee489d4075bce 100755 (executable)
@@ -68,7 +68,7 @@ test_expect_success 'apply --whitespace=strip from config' '
        check_result sub/file1
 '
 
-D=`pwd`
+D=$(pwd)
 
 test_expect_success 'apply --whitespace=strip in subdir' '
 
index d2c930de87f721a0e876351e511295ae0b094108..7940f6f0b952b5accd3f1263f08e131a018de140 100755 (executable)
@@ -45,8 +45,8 @@ test_expect_success 'patch-id supports git-format-patch output' '
        git checkout same &&
        git format-patch -1 --stdout | calc_patch_id same &&
        test_cmp patch-id_master patch-id_same &&
-       set `git format-patch -1 --stdout | git patch-id` &&
-       test "$2" = `git rev-parse HEAD`
+       set $(git format-patch -1 --stdout | git patch-id) &&
+       test "$2" = $(git rev-parse HEAD)
 '
 
 test_expect_success 'whitespace is irrelevant in footer' '
index 1cf0a4e10301fe1bbfb3acced0c010da7b8df7f8..74fc5a88ecdaf66e34449df1a3429f8ee22cb1da 100755 (executable)
@@ -123,7 +123,7 @@ test_expect_success \
     'add files to repository' \
     'find a -type f | xargs git update-index --add &&
      find a -type l | xargs git update-index --add &&
-     treeid=`git write-tree` &&
+     treeid=$(git write-tree) &&
      echo $treeid >treeid &&
      git update-ref HEAD $(TZ=GMT GIT_COMMITTER_DATE="2005-05-27 22:00:00" \
      git commit-tree $treeid </dev/null)'
@@ -207,7 +207,7 @@ test_expect_success \
 
 test_expect_success 'clients cannot access unreachable commits' '
        test_commit unreachable &&
-       sha1=`git rev-parse HEAD` &&
+       sha1=$(git rev-parse HEAD) &&
        git reset --hard HEAD^ &&
        git archive $sha1 >remote.tar &&
        test_must_fail git archive --remote=. $sha1 >remote.tar
@@ -215,7 +215,7 @@ test_expect_success 'clients cannot access unreachable commits' '
 
 test_expect_success 'upload-archive can allow unreachable commits' '
        test_commit unreachable1 &&
-       sha1=`git rev-parse HEAD` &&
+       sha1=$(git rev-parse HEAD) &&
        git reset --hard HEAD^ &&
        git archive $sha1 >remote.tar &&
        test_config uploadarchive.allowUnreachable true &&
index 75d6b3843ad4070f225e82aec160eca494ab6238..93e2c65de65f8dd8544332dd512e6d61dad1746c 100755 (executable)
@@ -223,7 +223,13 @@ test_expect_success 'pull request format' '
                git request-pull initial "$downstream_url" tags/full:refs/tags/full
        ) >request &&
        sed -nf fuzz.sed <request >request.fuzzy &&
-       test_i18ncmp expect request.fuzzy
+       test_i18ncmp expect request.fuzzy &&
+
+       (
+               cd local &&
+               git request-pull initial "$downstream_url" full
+       ) >request &&
+       grep ' tags/full$'
 '
 
 test_expect_success 'request-pull ignores OPTIONS_KEEPDASHDASH poison' '
index be951a46797c6b88d2a8d420cf160ea4f3ad71b0..a980574682012fbb3f5f7c28a011df980f45c3de 100755 (executable)
@@ -173,33 +173,6 @@ EOF
        )
 '
 
-if test -n "$NO_CURL" -o -z "$GIT_TEST_HTTPD"; then
-       say 'skipping remaining tests, git built without http support'
-       test_done
-fi
-
-LIB_HTTPD_PORT=${LIB_HTTPD_PORT-'5537'}
-. "$TEST_DIRECTORY"/lib-httpd.sh
-start_httpd
-
-test_expect_success 'clone http repository' '
-       git clone --bare --no-local shallow "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
-       git clone $HTTPD_URL/smart/repo.git clone &&
-       (
-       cd clone &&
-       git fsck &&
-       git log --format=%s origin/master >actual &&
-       cat <<EOF >expect &&
-7
-6
-5
-4
-3
-EOF
-       test_cmp expect actual
-       )
-'
-
 test_expect_success POSIXPERM,SANITY 'shallow fetch from a read-only repo' '
        cp -R .git read-only.git &&
        find read-only.git -print | xargs chmod -w &&
@@ -213,5 +186,4 @@ EOF
        test_cmp expect actual
 '
 
-stop_httpd
 test_done
index 143a8ea60507a35bbdfb310eb74a33cf5b88bf1f..e4ab0f5b64194da05b159782a5e41479bf47de20 100755 (executable)
@@ -1423,4 +1423,30 @@ EOF
        test_cmp expect actual
 '
 
+run_with_limited_stack () {
+       (ulimit -s 64 && "$@")
+}
+
+test_lazy_prereq ULIMIT 'run_with_limited_stack true'
+
+# we require ulimit, this excludes Windows
+test_expect_success ULIMIT '--contains works in a deep repo' '
+       >expect &&
+       i=1 &&
+       while test $i -lt 4000
+       do
+               echo "commit refs/heads/master
+committer A U Thor <author@example.com> $((1000000000 + $i * 100)) +0200
+data <<EOF
+commit #$i
+EOF"
+               test $i = 1 && echo "from refs/heads/master^0"
+               i=$(($i + 1))
+       done | git fast-import &&
+       git checkout master &&
+       git tag far-far-away HEAD^ &&
+       run_with_limited_stack git tag --contains HEAD >actual &&
+       test_cmp expect actual
+'
+
 test_done
index bdc1f295030b61fd6d4fc0ef672dffa99c027d8b..116885a260a56f94550ace2b541498a5e6f8e877 100755 (executable)
@@ -223,7 +223,8 @@ test_expect_success 'Commit without message is allowed with --allow-empty-messag
        git add foo &&
        >empty &&
        git commit --allow-empty-message <empty &&
-       commit_msg_is ""
+       commit_msg_is "" &&
+       git tag empty-message-commit
 '
 
 test_expect_success 'Commit without message is no-no without --allow-empty-message' '
@@ -240,6 +241,14 @@ test_expect_success 'Commit a message with --allow-empty-message' '
        commit_msg_is "hello there"
 '
 
+test_expect_success 'commit -C empty respects --allow-empty-message' '
+       echo more >>foo &&
+       git add foo &&
+       test_must_fail git commit -C empty-message-commit &&
+       git commit -C empty-message-commit --allow-empty-message &&
+       commit_msg_is ""
+'
+
 commit_for_rebase_autosquash_setup () {
        echo "first content line" >>foo &&
        git add foo &&
index d58b097ff3b3d0e6e68d15491d38f1f32460f6e7..63e04277f99a08b15e12c3392f9e128147180fad 100755 (executable)
@@ -346,8 +346,21 @@ test_expect_success 'amend commit to fix date' '
 
 '
 
-test_expect_success 'commit complains about bogus date' '
-       test_must_fail git commit --amend --date=10.11.2010
+test_expect_success 'commit mentions forced date in output' '
+       git commit --amend --date=2010-01-02T03:04:05 >output &&
+       grep "Date: *Sat Jan 2 03:04:05 2010" output
+'
+
+test_expect_success 'commit complains about completely bogus dates' '
+       test_must_fail git commit --amend --date=seventeen
+'
+
+test_expect_success 'commit --date allows approxidate' '
+       git commit --amend \
+               --date="midnight the 12th of october, anno domini 1979" &&
+       echo "Fri Oct 12 00:00:00 1979 +0000" >expect &&
+       git log -1 --format=%ad >actual &&
+       test_cmp expect actual
 '
 
 test_expect_success 'sign off (1)' '
index 9a3f3a1b4151ebf16cfd773a0f9efcb1b61d40d7..6465cd59afb6dcd4c2e554947da4755a1beb883e 100755 (executable)
@@ -344,6 +344,13 @@ test_expect_success 'message shows author when it is not equal to committer' '
          .git/COMMIT_EDITMSG
 '
 
+test_expect_success 'message shows date when it is explicitly set' '
+       git commit --allow-empty -e -m foo --date="2010-01-02T03:04:05" &&
+       test_i18ngrep \
+         "^# Date: *Sat Jan 2 03:04:05 2010 +0000" \
+         .git/COMMIT_EDITMSG
+'
+
 test_expect_success AUTOIDENT 'message shows committer when it is automatic' '
 
        echo >>negative &&
index 5a193c500d282cc2b13e8de6e128229585897a16..dc30a514bf681dde44dea32e671632ef6f0a47a7 100755 (executable)
@@ -58,7 +58,7 @@ test_expect_success PERL 'custom tool commands override built-ins' '
 
 test_expect_success PERL 'difftool ignores bad --tool values' '
        : >expect &&
-       test_expect_code 1 \
+       test_must_fail \
                git difftool --no-prompt --tool=bad-tool branch >actual &&
        test_cmp expect actual
 '
index 6efd0d9c78fda8b28e79fad7153b610a0b40173f..915098418495b488b748db9e610c79f81223a960 100755 (executable)
@@ -578,12 +578,12 @@ test_expect_success 'prompt - bash color pc mode - untracked files status indica
 '
 
 test_expect_success 'prompt - zsh color pc mode' '
-       printf "BEFORE: (%%F{green}\${__git_ps1_branch_name}%%f):AFTER\\nmaster" >expected &&
+       printf "BEFORE: (%%F{green}master%%f):AFTER" >expected &&
        (
                ZSH_VERSION=5.0.0 &&
                GIT_PS1_SHOWCOLORHINTS=y &&
-               __git_ps1 "BEFORE:" ":AFTER" >"$actual"
-               printf "%s\\n%s" "$PS1" "${__git_ps1_branch_name}" >"$actual"
+               __git_ps1 "BEFORE:" ":AFTER" &&
+               printf "%s" "$PS1" >"$actual"
        ) &&
        test_cmp expected "$actual"
 '
index 11c3550177dbaab30596be2fc3c1633f2a0485f8..e7b378c8b2c8f145519410bb17811bf60eb29384 100644 (file)
 #include "diffcore.h"
 #include "tree.h"
 
-static void show_entry(struct diff_options *opt, const char *prefix,
-                      struct tree_desc *desc, struct strbuf *base);
+/*
+ * internal mode marker, saying a tree entry != entry of tp[imin]
+ * (see ll_diff_tree_paths for what it means there)
+ *
+ * we will update/use/emit entry for diff only with it unset.
+ */
+#define S_IFXMIN_NEQ   S_DIFFTREE_IFXMIN_NEQ
 
-static int compare_tree_entry(struct tree_desc *t1, struct tree_desc *t2,
-                             struct strbuf *base, struct diff_options *opt)
-{
-       unsigned mode1, mode2;
-       const char *path1, *path2;
-       const unsigned char *sha1, *sha2;
-       int cmp, pathlen1, pathlen2;
-       int old_baselen = base->len;
 
-       sha1 = tree_entry_extract(t1, &path1, &mode1);
-       sha2 = tree_entry_extract(t2, &path2, &mode2);
+static struct combine_diff_path *ll_diff_tree_paths(
+       struct combine_diff_path *p, const unsigned char *sha1,
+       const unsigned char **parents_sha1, int nparent,
+       struct strbuf *base, struct diff_options *opt);
+static int ll_diff_tree_sha1(const unsigned char *old, const unsigned char *new,
+                            struct strbuf *base, struct diff_options *opt);
+
+/*
+ * Compare two tree entries, taking into account only path/S_ISDIR(mode),
+ * but not their sha1's.
+ *
+ * NOTE files and directories *always* compare differently, even when having
+ *      the same name - thanks to base_name_compare().
+ *
+ * NOTE empty (=invalid) descriptor(s) take part in comparison as +infty,
+ *      so that they sort *after* valid tree entries.
+ *
+ *      Due to this convention, if trees are scanned in sorted order, all
+ *      non-empty descriptors will be processed first.
+ */
+static int tree_entry_pathcmp(struct tree_desc *t1, struct tree_desc *t2)
+{
+       struct name_entry *e1, *e2;
+       int cmp;
 
-       pathlen1 = tree_entry_len(&t1->entry);
-       pathlen2 = tree_entry_len(&t2->entry);
-       cmp = base_name_compare(path1, pathlen1, mode1, path2, pathlen2, mode2);
-       if (cmp < 0) {
-               show_entry(opt, "-", t1, base);
+       /* empty descriptors sort after valid tree entries */
+       if (!t1->size)
+               return t2->size ? 1 : 0;
+       else if (!t2->size)
                return -1;
-       }
-       if (cmp > 0) {
-               show_entry(opt, "+", t2, base);
-               return 1;
-       }
-       if (!DIFF_OPT_TST(opt, FIND_COPIES_HARDER) && !hashcmp(sha1, sha2) && mode1 == mode2)
-               return 0;
 
-       /*
-        * If the filemode has changed to/from a directory from/to a regular
-        * file, we need to consider it a remove and an add.
-        */
-       if (S_ISDIR(mode1) != S_ISDIR(mode2)) {
-               show_entry(opt, "-", t1, base);
-               show_entry(opt, "+", t2, base);
-               return 0;
-       }
+       e1 = &t1->entry;
+       e2 = &t2->entry;
+       cmp = base_name_compare(e1->path, tree_entry_len(e1), e1->mode,
+                               e2->path, tree_entry_len(e2), e2->mode);
+       return cmp;
+}
 
-       strbuf_add(base, path1, pathlen1);
-       if (DIFF_OPT_TST(opt, RECURSIVE) && S_ISDIR(mode1)) {
-               if (DIFF_OPT_TST(opt, TREE_IN_RECURSIVE)) {
-                       opt->change(opt, mode1, mode2,
-                                   sha1, sha2, 1, 1, base->buf, 0, 0);
+
+/*
+ * convert path -> opt->diff_*() callbacks
+ *
+ * emits diff to first parent only, and tells diff tree-walker that we are done
+ * with p and it can be freed.
+ */
+static int emit_diff_first_parent_only(struct diff_options *opt, struct combine_diff_path *p)
+{
+       struct combine_diff_parent *p0 = &p->parent[0];
+       if (p->mode && p0->mode) {
+               opt->change(opt, p0->mode, p->mode, p0->sha1, p->sha1,
+                       1, 1, p->path, 0, 0);
+       }
+       else {
+               const unsigned char *sha1;
+               unsigned int mode;
+               int addremove;
+
+               if (p->mode) {
+                       addremove = '+';
+                       sha1 = p->sha1;
+                       mode = p->mode;
+               } else {
+                       addremove = '-';
+                       sha1 = p0->sha1;
+                       mode = p0->mode;
                }
-               strbuf_addch(base, '/');
-               diff_tree_sha1(sha1, sha2, base->buf, opt);
-       } else {
-               opt->change(opt, mode1, mode2, sha1, sha2, 1, 1, base->buf, 0, 0);
+
+               opt->add_remove(opt, addremove, mode, sha1, 1, p->path, 0);
        }
-       strbuf_setlen(base, old_baselen);
-       return 0;
+
+       return 0;       /* we are done with p */
 }
 
-/* A whole sub-tree went away or appeared */
-static void show_tree(struct diff_options *opt, const char *prefix,
-                     struct tree_desc *desc, struct strbuf *base)
+
+/*
+ * Make a new combine_diff_path from path/mode/sha1
+ * and append it to paths list tail.
+ *
+ * Memory for created elements could be reused:
+ *
+ *     - if last->next == NULL, the memory is allocated;
+ *
+ *     - if last->next != NULL, it is assumed that p=last->next was returned
+ *       earlier by this function, and p->next was *not* modified.
+ *       The memory is then reused from p.
+ *
+ * so for clients,
+ *
+ * - if you do need to keep the element
+ *
+ *     p = path_appendnew(p, ...);
+ *     process(p);
+ *     p->next = NULL;
+ *
+ * - if you don't need to keep the element after processing
+ *
+ *     pprev = p;
+ *     p = path_appendnew(p, ...);
+ *     process(p);
+ *     p = pprev;
+ *     ; don't forget to free tail->next in the end
+ *
+ * p->parent[] remains uninitialized.
+ */
+static struct combine_diff_path *path_appendnew(struct combine_diff_path *last,
+       int nparent, const struct strbuf *base, const char *path, int pathlen,
+       unsigned mode, const unsigned char *sha1)
 {
-       enum interesting match = entry_not_interesting;
-       for (; desc->size; update_tree_entry(desc)) {
-               if (match != all_entries_interesting) {
-                       match = tree_entry_interesting(&desc->entry, base, 0,
-                                                      &opt->pathspec);
-                       if (match == all_entries_not_interesting)
-                               break;
-                       if (match == entry_not_interesting)
-                               continue;
-               }
-               show_entry(opt, prefix, desc, base);
+       struct combine_diff_path *p;
+       int len = base->len + pathlen;
+       int alloclen = combine_diff_path_size(nparent, len);
+
+       /* if last->next is !NULL - it is a pre-allocated memory, we can reuse */
+       p = last->next;
+       if (p && (alloclen > (intptr_t)p->next)) {
+               free(p);
+               p = NULL;
+       }
+
+       if (!p) {
+               p = xmalloc(alloclen);
+
+               /*
+                * until we go to it next round, .next holds how many bytes we
+                * allocated (for faster realloc - we don't need copying old data).
+                */
+               p->next = (struct combine_diff_path *)(intptr_t)alloclen;
        }
+
+       last->next = p;
+
+       p->path = (char *)&(p->parent[nparent]);
+       memcpy(p->path, base->buf, base->len);
+       memcpy(p->path + base->len, path, pathlen);
+       p->path[len] = 0;
+       p->mode = mode;
+       hashcpy(p->sha1, sha1 ? sha1 : null_sha1);
+
+       return p;
 }
 
-/* A file entry went away or appeared */
-static void show_entry(struct diff_options *opt, const char *prefix,
-                      struct tree_desc *desc, struct strbuf *base)
+/*
+ * new path should be added to combine diff
+ *
+ * 3 cases on how/when it should be called and behaves:
+ *
+ *      t, !tp         -> path added, all parents lack it
+ *     !t,  tp         -> path removed from all parents
+ *      t,  tp         -> path modified/added
+ *                        (M for tp[i]=tp[imin], A otherwise)
+ */
+static struct combine_diff_path *emit_path(struct combine_diff_path *p,
+       struct strbuf *base, struct diff_options *opt, int nparent,
+       struct tree_desc *t, struct tree_desc *tp,
+       int imin)
 {
        unsigned mode;
        const char *path;
-       const unsigned char *sha1 = tree_entry_extract(desc, &path, &mode);
-       int pathlen = tree_entry_len(&desc->entry);
+       const unsigned char *sha1;
+       int pathlen;
        int old_baselen = base->len;
+       int i, isdir, recurse = 0, emitthis = 1;
+
+       /* at least something has to be valid */
+       assert(t || tp);
 
-       strbuf_add(base, path, pathlen);
-       if (DIFF_OPT_TST(opt, RECURSIVE) && S_ISDIR(mode)) {
-               enum object_type type;
-               struct tree_desc inner;
-               void *tree;
-               unsigned long size;
+       if (t) {
+               /* path present in resulting tree */
+               sha1 = tree_entry_extract(t, &path, &mode);
+               pathlen = tree_entry_len(&t->entry);
+               isdir = S_ISDIR(mode);
+       } else {
+               /*
+                * a path was removed - take path from imin parent. Also take
+                * mode from that parent, to decide on recursion(1).
+                *
+                * 1) all modes for tp[i]=tp[imin] should be the same wrt
+                *    S_ISDIR, thanks to base_name_compare().
+                */
+               tree_entry_extract(&tp[imin], &path, &mode);
+               pathlen = tree_entry_len(&tp[imin].entry);
 
-               tree = read_sha1_file(sha1, &type, &size);
-               if (!tree || type != OBJ_TREE)
-                       die("corrupt tree sha %s", sha1_to_hex(sha1));
+               isdir = S_ISDIR(mode);
+               sha1 = NULL;
+               mode = 0;
+       }
 
-               if (DIFF_OPT_TST(opt, TREE_IN_RECURSIVE))
-                       opt->add_remove(opt, *prefix, mode, sha1, 1, base->buf, 0);
+       if (DIFF_OPT_TST(opt, RECURSIVE) && isdir) {
+               recurse = 1;
+               emitthis = DIFF_OPT_TST(opt, TREE_IN_RECURSIVE);
+       }
 
-               strbuf_addch(base, '/');
+       if (emitthis) {
+               int keep;
+               struct combine_diff_path *pprev = p;
+               p = path_appendnew(p, nparent, base, path, pathlen, mode, sha1);
 
-               init_tree_desc(&inner, tree, size);
-               show_tree(opt, prefix, &inner, base);
-               free(tree);
-       } else
-               opt->add_remove(opt, prefix[0], mode, sha1, 1, base->buf, 0);
+               for (i = 0; i < nparent; ++i) {
+                       /*
+                        * tp[i] is valid, if present and if tp[i]==tp[imin] -
+                        * otherwise, we should ignore it.
+                        */
+                       int tpi_valid = tp && !(tp[i].entry.mode & S_IFXMIN_NEQ);
+
+                       const unsigned char *sha1_i;
+                       unsigned mode_i;
+
+                       p->parent[i].status =
+                               !t ? DIFF_STATUS_DELETED :
+                                       tpi_valid ?
+                                               DIFF_STATUS_MODIFIED :
+                                               DIFF_STATUS_ADDED;
+
+                       if (tpi_valid) {
+                               sha1_i = tp[i].entry.sha1;
+                               mode_i = tp[i].entry.mode;
+                       }
+                       else {
+                               sha1_i = NULL;
+                               mode_i = 0;
+                       }
+
+                       p->parent[i].mode = mode_i;
+                       hashcpy(p->parent[i].sha1, sha1_i ? sha1_i : null_sha1);
+               }
+
+               keep = 1;
+               if (opt->pathchange)
+                       keep = opt->pathchange(opt, p);
+
+               /*
+                * If a path was filtered or consumed - we don't need to add it
+                * to the list and can reuse its memory, leaving it as
+                * pre-allocated element on the tail.
+                *
+                * On the other hand, if path needs to be kept, we need to
+                * correct its .next to NULL, as it was pre-initialized to how
+                * much memory was allocated.
+                *
+                * see path_appendnew() for details.
+                */
+               if (!keep)
+                       p = pprev;
+               else
+                       p->next = NULL;
+       }
+
+       if (recurse) {
+               const unsigned char **parents_sha1;
+
+               parents_sha1 = xalloca(nparent * sizeof(parents_sha1[0]));
+               for (i = 0; i < nparent; ++i) {
+                       /* same rule as in emitthis */
+                       int tpi_valid = tp && !(tp[i].entry.mode & S_IFXMIN_NEQ);
+
+                       parents_sha1[i] = tpi_valid ? tp[i].entry.sha1
+                                                   : NULL;
+               }
+
+               strbuf_add(base, path, pathlen);
+               strbuf_addch(base, '/');
+               p = ll_diff_tree_paths(p, sha1, parents_sha1, nparent, base, opt);
+               xalloca_free(parents_sha1);
+       }
 
        strbuf_setlen(base, old_baselen);
+       return p;
 }
 
 static void skip_uninteresting(struct tree_desc *t, struct strbuf *base,
-                              struct diff_options *opt,
-                              enum interesting *match)
+                              struct diff_options *opt)
 {
+       enum interesting match;
+
        while (t->size) {
-               *match = tree_entry_interesting(&t->entry, base, 0, &opt->pathspec);
-               if (*match) {
-                       if (*match == all_entries_not_interesting)
+               match = tree_entry_interesting(&t->entry, base, 0, &opt->pathspec);
+               if (match) {
+                       if (match == all_entries_not_interesting)
                                t->size = 0;
                        break;
                }
@@ -128,55 +300,260 @@ static void skip_uninteresting(struct tree_desc *t, struct strbuf *base,
        }
 }
 
-int diff_tree(struct tree_desc *t1, struct tree_desc *t2,
-             const char *base_str, struct diff_options *opt)
+
+/*
+ * generate paths for combined diff D(sha1,parents_sha1[])
+ *
+ * Resulting paths are appended to combine_diff_path linked list, and also, are
+ * emitted on the go via opt->pathchange() callback, so it is possible to
+ * process the result as batch or incrementally.
+ *
+ * The paths are generated scanning new tree and all parents trees
+ * simultaneously, similarly to what diff_tree() was doing for 2 trees.
+ * The theory behind such scan is as follows:
+ *
+ *
+ * D(T,P1...Pn) calculation scheme
+ * -------------------------------
+ *
+ * D(T,P1...Pn) = D(T,P1) ^ ... ^ D(T,Pn)      (regarding resulting paths set)
+ *
+ *     D(T,Pj)         - diff between T..Pj
+ *     D(T,P1...Pn)    - combined diff from T to parents P1,...,Pn
+ *
+ *
+ * We start from all trees, which are sorted, and compare their entries in
+ * lock-step:
+ *
+ *      T     P1       Pn
+ *      -     -        -
+ *     |t|   |p1|     |pn|
+ *     |-|   |--| ... |--|      imin = argmin(p1...pn)
+ *     | |   |  |     |  |
+ *     |-|   |--|     |--|
+ *     |.|   |. |     |. |
+ *      .     .        .
+ *      .     .        .
+ *
+ * at any time there could be 3 cases:
+ *
+ *     1)  t < p[imin];
+ *     2)  t > p[imin];
+ *     3)  t = p[imin].
+ *
+ * Schematic deduction of what every case means, and what to do, follows:
+ *
+ * 1)  t < p[imin]  ->  ∀j t ∉ Pj  ->  "+t" ∈ D(T,Pj)  ->  D += "+t";  t↓
+ *
+ * 2)  t > p[imin]
+ *
+ *     2.1) ∃j: pj > p[imin]  ->  "-p[imin]" ∉ D(T,Pj)  ->  D += ø;  ∀ pi=p[imin]  pi↓
+ *     2.2) ∀i  pi = p[imin]  ->  pi ∉ T  ->  "-pi" ∈ D(T,Pi)  ->  D += "-p[imin]";  ∀i pi↓
+ *
+ * 3)  t = p[imin]
+ *
+ *     3.1) ∃j: pj > p[imin]  ->  "+t" ∈ D(T,Pj)  ->  only pi=p[imin] remains to investigate
+ *     3.2) pi = p[imin]  ->  investigate δ(t,pi)
+ *      |
+ *      |
+ *      v
+ *
+ *     3.1+3.2) looking at δ(t,pi) ∀i: pi=p[imin] - if all != ø  ->
+ *
+ *                       ⎧δ(t,pi)  - if pi=p[imin]
+ *              ->  D += ⎨
+ *                       ⎩"+t"     - if pi>p[imin]
+ *
+ *
+ *     in any case t↓  ∀ pi=p[imin]  pi↓
+ *
+ *
+ * ~~~~~~~~
+ *
+ * NOTE
+ *
+ *     Usual diff D(A,B) is by definition the same as combined diff D(A,[B]),
+ *     so this diff paths generator can, and is used, for plain diffs
+ *     generation too.
+ *
+ *     Please keep attention to the common D(A,[B]) case when working on the
+ *     code, in order not to slow it down.
+ *
+ * NOTE
+ *     nparent must be > 0.
+ */
+
+
+/* ∀ pi=p[imin]  pi↓ */
+static inline void update_tp_entries(struct tree_desc *tp, int nparent)
 {
-       struct strbuf base;
-       int baselen = strlen(base_str);
-       enum interesting t1_match = entry_not_interesting;
-       enum interesting t2_match = entry_not_interesting;
+       int i;
+       for (i = 0; i < nparent; ++i)
+               if (!(tp[i].entry.mode & S_IFXMIN_NEQ))
+                       update_tree_entry(&tp[i]);
+}
+
+static struct combine_diff_path *ll_diff_tree_paths(
+       struct combine_diff_path *p, const unsigned char *sha1,
+       const unsigned char **parents_sha1, int nparent,
+       struct strbuf *base, struct diff_options *opt)
+{
+       struct tree_desc t, *tp;
+       void *ttree, **tptree;
+       int i;
+
+       tp     = xalloca(nparent * sizeof(tp[0]));
+       tptree = xalloca(nparent * sizeof(tptree[0]));
+
+       /*
+        * load parents first, as they are probably already cached.
+        *
+        * ( log_tree_diff() parses commit->parent before calling here via
+        *   diff_tree_sha1(parent, commit) )
+        */
+       for (i = 0; i < nparent; ++i)
+               tptree[i] = fill_tree_descriptor(&tp[i], parents_sha1[i]);
+       ttree = fill_tree_descriptor(&t, sha1);
 
        /* Enable recursion indefinitely */
        opt->pathspec.recursive = DIFF_OPT_TST(opt, RECURSIVE);
 
-       strbuf_init(&base, PATH_MAX);
-       strbuf_add(&base, base_str, baselen);
-
        for (;;) {
+               int imin, cmp;
+
                if (diff_can_quit_early(opt))
                        break;
+
                if (opt->pathspec.nr) {
-                       skip_uninteresting(t1, &base, opt, &t1_match);
-                       skip_uninteresting(t2, &base, opt, &t2_match);
+                       skip_uninteresting(&t, base, opt);
+                       for (i = 0; i < nparent; i++)
+                               skip_uninteresting(&tp[i], base, opt);
                }
-               if (!t1->size) {
-                       if (!t2->size)
+
+               /* comparing is finished when all trees are done */
+               if (!t.size) {
+                       int done = 1;
+                       for (i = 0; i < nparent; ++i)
+                               if (tp[i].size) {
+                                       done = 0;
+                                       break;
+                               }
+                       if (done)
                                break;
-                       show_entry(opt, "+", t2, &base);
-                       update_tree_entry(t2);
-                       continue;
                }
-               if (!t2->size) {
-                       show_entry(opt, "-", t1, &base);
-                       update_tree_entry(t1);
-                       continue;
+
+               /*
+                * lookup imin = argmin(p1...pn),
+                * mark entries whether they =p[imin] along the way
+                */
+               imin = 0;
+               tp[0].entry.mode &= ~S_IFXMIN_NEQ;
+
+               for (i = 1; i < nparent; ++i) {
+                       cmp = tree_entry_pathcmp(&tp[i], &tp[imin]);
+                       if (cmp < 0) {
+                               imin = i;
+                               tp[i].entry.mode &= ~S_IFXMIN_NEQ;
+                       }
+                       else if (cmp == 0) {
+                               tp[i].entry.mode &= ~S_IFXMIN_NEQ;
+                       }
+                       else {
+                               tp[i].entry.mode |= S_IFXMIN_NEQ;
+                       }
+               }
+
+               /* fixup markings for entries before imin */
+               for (i = 0; i < imin; ++i)
+                       tp[i].entry.mode |= S_IFXMIN_NEQ;       /* pi > p[imin] */
+
+
+
+               /* compare t vs p[imin] */
+               cmp = tree_entry_pathcmp(&t, &tp[imin]);
+
+               /* t = p[imin] */
+               if (cmp == 0) {
+                       /* are either pi > p[imin] or diff(t,pi) != ø ? */
+                       if (!DIFF_OPT_TST(opt, FIND_COPIES_HARDER)) {
+                               for (i = 0; i < nparent; ++i) {
+                                       /* p[i] > p[imin] */
+                                       if (tp[i].entry.mode & S_IFXMIN_NEQ)
+                                               continue;
+
+                                       /* diff(t,pi) != ø */
+                                       if (hashcmp(t.entry.sha1, tp[i].entry.sha1) ||
+                                           (t.entry.mode != tp[i].entry.mode))
+                                               continue;
+
+                                       goto skip_emit_t_tp;
+                               }
+                       }
+
+                       /* D += {δ(t,pi) if pi=p[imin];  "+a" if pi > p[imin]} */
+                       p = emit_path(p, base, opt, nparent,
+                                       &t, tp, imin);
+
+               skip_emit_t_tp:
+                       /* t↓,  ∀ pi=p[imin]  pi↓ */
+                       update_tree_entry(&t);
+                       update_tp_entries(tp, nparent);
+               }
+
+               /* t < p[imin] */
+               else if (cmp < 0) {
+                       /* D += "+t" */
+                       p = emit_path(p, base, opt, nparent,
+                                       &t, /*tp=*/NULL, -1);
+
+                       /* t↓ */
+                       update_tree_entry(&t);
                }
-               switch (compare_tree_entry(t1, t2, &base, opt)) {
-               case -1:
-                       update_tree_entry(t1);
-                       continue;
-               case 0:
-                       update_tree_entry(t1);
-                       /* Fallthrough */
-               case 1:
-                       update_tree_entry(t2);
-                       continue;
+
+               /* t > p[imin] */
+               else {
+                       /* ∀i pi=p[imin] -> D += "-p[imin]" */
+                       if (!DIFF_OPT_TST(opt, FIND_COPIES_HARDER)) {
+                               for (i = 0; i < nparent; ++i)
+                                       if (tp[i].entry.mode & S_IFXMIN_NEQ)
+                                               goto skip_emit_tp;
+                       }
+
+                       p = emit_path(p, base, opt, nparent,
+                                       /*t=*/NULL, tp, imin);
+
+               skip_emit_tp:
+                       /* ∀ pi=p[imin]  pi↓ */
+                       update_tp_entries(tp, nparent);
                }
-               die("git diff-tree: internal error");
        }
 
-       strbuf_release(&base);
-       return 0;
+       free(ttree);
+       for (i = nparent-1; i >= 0; i--)
+               free(tptree[i]);
+       xalloca_free(tptree);
+       xalloca_free(tp);
+
+       return p;
+}
+
+struct combine_diff_path *diff_tree_paths(
+       struct combine_diff_path *p, const unsigned char *sha1,
+       const unsigned char **parents_sha1, int nparent,
+       struct strbuf *base, struct diff_options *opt)
+{
+       p = ll_diff_tree_paths(p, sha1, parents_sha1, nparent, base, opt);
+
+       /*
+        * free pre-allocated last element, if any
+        * (see path_appendnew() for details about why)
+        */
+       if (p->next) {
+               free(p->next);
+               p->next = NULL;
+       }
+
+       return p;
 }
 
 /*
@@ -190,7 +567,7 @@ static inline int diff_might_be_rename(void)
                !DIFF_FILE_VALID(diff_queued_diff.queue[0]->one);
 }
 
-static void try_to_follow_renames(struct tree_desc *t1, struct tree_desc *t2, const char *base, struct diff_options *opt)
+static void try_to_follow_renames(const unsigned char *old, const unsigned char *new, struct strbuf *base, struct diff_options *opt)
 {
        struct diff_options diff_opts;
        struct diff_queue_struct *q = &diff_queued_diff;
@@ -228,7 +605,7 @@ static void try_to_follow_renames(struct tree_desc *t1, struct tree_desc *t2, co
        diff_opts.break_opt = opt->break_opt;
        diff_opts.rename_score = opt->rename_score;
        diff_setup_done(&diff_opts);
-       diff_tree(t1, t2, base, &diff_opts);
+       ll_diff_tree_sha1(old, new, base, &diff_opts);
        diffcore_std(&diff_opts);
        free_pathspec(&diff_opts.pathspec);
 
@@ -287,25 +664,40 @@ static void try_to_follow_renames(struct tree_desc *t1, struct tree_desc *t2, co
        q->nr = 1;
 }
 
-int diff_tree_sha1(const unsigned char *old, const unsigned char *new, const char *base, struct diff_options *opt)
+static int ll_diff_tree_sha1(const unsigned char *old, const unsigned char *new,
+                            struct strbuf *base, struct diff_options *opt)
 {
-       void *tree1, *tree2;
-       struct tree_desc t1, t2;
-       unsigned long size1, size2;
-       int retval;
+       struct combine_diff_path phead, *p;
+       pathchange_fn_t pathchange_old = opt->pathchange;
 
-       tree1 = fill_tree_descriptor(&t1, old);
-       tree2 = fill_tree_descriptor(&t2, new);
-       size1 = t1.size;
-       size2 = t2.size;
-       retval = diff_tree(&t1, &t2, base, opt);
-       if (!*base && DIFF_OPT_TST(opt, FOLLOW_RENAMES) && diff_might_be_rename()) {
-               init_tree_desc(&t1, tree1, size1);
-               init_tree_desc(&t2, tree2, size2);
-               try_to_follow_renames(&t1, &t2, base, opt);
+       phead.next = NULL;
+       opt->pathchange = emit_diff_first_parent_only;
+       diff_tree_paths(&phead, new, &old, 1, base, opt);
+
+       for (p = phead.next; p;) {
+               struct combine_diff_path *pprev = p;
+               p = p->next;
+               free(pprev);
        }
-       free(tree1);
-       free(tree2);
+
+       opt->pathchange = pathchange_old;
+       return 0;
+}
+
+int diff_tree_sha1(const unsigned char *old, const unsigned char *new, const char *base_str, struct diff_options *opt)
+{
+       struct strbuf base;
+       int retval;
+
+       strbuf_init(&base, PATH_MAX);
+       strbuf_addstr(&base, base_str);
+
+       retval = ll_diff_tree_sha1(old, new, &base, opt);
+       if (!*base_str && DIFF_OPT_TST(opt, FOLLOW_RENAMES) && diff_might_be_rename())
+               try_to_follow_renames(old, new, &base, opt);
+
+       strbuf_release(&base);
+
        return retval;
 }
 
index 0cc56368bd8ccef90ff643ce091cae25007eeee7..bc1bfb86003cb4133cc4ce3ce6423ce780ed7c84 100644 (file)
--- a/wrapper.c
+++ b/wrapper.c
@@ -174,6 +174,24 @@ ssize_t xwrite(int fd, const void *buf, size_t len)
        }
 }
 
+/*
+ * xpread() is the same as pread(), but it automatically restarts pread()
+ * operations with a recoverable error (EAGAIN and EINTR). xpread() DOES
+ * NOT GUARANTEE that "len" bytes is read even if the data is available.
+ */
+ssize_t xpread(int fd, void *buf, size_t len, off_t offset)
+{
+       ssize_t nr;
+       if (len > MAX_IO_SIZE)
+               len = MAX_IO_SIZE;
+       while (1) {
+               nr = pread(fd, buf, len, offset);
+               if ((nr < 0) && (errno == EAGAIN || errno == EINTR))
+                       continue;
+               return nr;
+       }
+}
+
 ssize_t read_in_full(int fd, void *buf, size_t count)
 {
        char *p = buf;
@@ -214,6 +232,26 @@ ssize_t write_in_full(int fd, const void *buf, size_t count)
        return total;
 }
 
+ssize_t pread_in_full(int fd, void *buf, size_t count, off_t offset)
+{
+       char *p = buf;
+       ssize_t total = 0;
+
+       while (count > 0) {
+               ssize_t loaded = xpread(fd, p, count, offset);
+               if (loaded < 0)
+                       return -1;
+               if (loaded == 0)
+                       return total;
+               count -= loaded;
+               p += loaded;
+               total += loaded;
+               offset += loaded;
+       }
+
+       return total;
+}
+
 int xdup(int fd)
 {
        int ret = dup(fd);