Merge branch 'dm/update-index-doc-fix' into maint-2.45

Doc fix.

* dm/update-index-doc-fix:
  documentation: git-update-index: add --show-index-version to synopsis
diff --git a/.cirrus.yml b/.cirrus.yml
index 4860beb..77346a4 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -1,7 +1,7 @@
 env:
   CIRRUS_CLONE_DEPTH: 1
 
-freebsd_12_task:
+freebsd_task:
   env:
     GIT_PROVE_OPTS: "--timer --jobs 10"
     GIT_TEST_OPTS: "--no-chain-lint --no-bin-wrappers"
@@ -9,7 +9,7 @@
     DEFAULT_TEST_TARGET: prove
     DEVELOPER: 1
   freebsd_instance:
-    image_family: freebsd-12-3
+    image_family: freebsd-13-2
     memory: 2G
   install_script:
     pkg install -y gettext gmake perl5
@@ -19,4 +19,4 @@
   build_script:
     - su git -c gmake
   test_script:
-    - su git -c 'gmake test'
+    - su git -c 'gmake DEFAULT_UNIT_TEST_TARGET=unit-tests-prove test unit-tests'
diff --git a/.editorconfig b/.editorconfig
index f9d8196..15d6cbe 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -4,7 +4,7 @@
 
 # The settings for C (*.c and *.h) files are mirrored in .clang-format.  Keep
 # them in sync.
-[*.{c,h,sh,perl,pl,pm,txt}]
+[{*.{c,h,sh,perl,pl,pm,txt},config.mak.*,Makefile}]
 indent_style = tab
 tab_width = 8
 
diff --git a/.github/workflows/check-whitespace.yml b/.github/workflows/check-whitespace.yml
index a58e2dc..a241a63 100644
--- a/.github/workflows/check-whitespace.yml
+++ b/.github/workflows/check-whitespace.yml
@@ -19,7 +19,7 @@
   check-whitespace:
     runs-on: ubuntu-latest
     steps:
-    - uses: actions/checkout@v3
+    - uses: actions/checkout@v4
       with:
         fetch-depth: 0
 
diff --git a/.github/workflows/coverity.yml b/.github/workflows/coverity.yml
index e5532d3..53cf12f 100644
--- a/.github/workflows/coverity.yml
+++ b/.github/workflows/coverity.yml
@@ -38,7 +38,7 @@
       COVERITY_LANGUAGE: cxx
       COVERITY_PLATFORM: overridden-below
     steps:
-      - uses: actions/checkout@v3
+      - uses: actions/checkout@v4
       - name: install minimal Git for Windows SDK
         if: contains(matrix.os, 'windows')
         uses: git-for-windows/setup-git-for-windows-sdk@v1
@@ -98,7 +98,7 @@
       # A cache miss will add ~30s to create, but a cache hit will save minutes.
       - name: restore the Coverity Build Tool
         id: cache
-        uses: actions/cache/restore@v3
+        uses: actions/cache/restore@v4
         with:
           path: ${{ runner.temp }}/cov-analysis
           key: cov-build-${{ env.COVERITY_LANGUAGE }}-${{ env.COVERITY_PLATFORM }}-${{ steps.lookup.outputs.hash }}
@@ -141,7 +141,7 @@
           esac
       - name: cache the Coverity Build Tool
         if: steps.cache.outputs.cache-hit != 'true'
-        uses: actions/cache/save@v3
+        uses: actions/cache/save@v4
         with:
           path: ${{ runner.temp }}/cov-analysis
           key: cov-build-${{ env.COVERITY_LANGUAGE }}-${{ env.COVERITY_PLATFORM }}-${{ steps.lookup.outputs.hash }}
diff --git a/.github/workflows/l10n.yml b/.github/workflows/l10n.yml
index 6c38496..e2c3dbd 100644
--- a/.github/workflows/l10n.yml
+++ b/.github/workflows/l10n.yml
@@ -63,9 +63,10 @@
             origin \
             ${{ github.ref }} \
             $args
-      - uses: actions/setup-go@v2
+      - uses: actions/setup-go@v5
         with:
           go-version: '>=1.16'
+          cache: false
       - name: Install git-po-helper
         run: go install github.com/git-l10n/git-po-helper@main
       - name: Install other dependencies
@@ -91,14 +92,13 @@
           cat git-po-helper.out
           exit $exit_code
       - name: Create comment in pull request for report
-        uses: mshick/add-pr-comment@v1
+        uses: mshick/add-pr-comment@v2
         if: >-
           always() &&
           github.event_name == 'pull_request_target' &&
           env.COMMENT_BODY != ''
         with:
           repo-token: ${{ secrets.GITHUB_TOKEN }}
-          repo-token-user-login: 'github-actions[bot]'
           message: >
             ${{ steps.check-commits.outcome == 'failure' && 'Errors and warnings' || 'Warnings' }}
             found by [git-po-helper](https://github.com/git-l10n/git-po-helper#readme) in workflow
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 9fdbd54..8922bd7 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -63,7 +63,7 @@
           echo "skip_concurrent=$skip_concurrent" >>$GITHUB_OUTPUT
       - name: skip if the commit or tree was already tested
         id: skip-if-redundant
-        uses: actions/github-script@v6
+        uses: actions/github-script@v7
         if: steps.check-ref.outputs.enabled == 'yes'
         with:
           github-token: ${{secrets.GITHUB_TOKEN}}
@@ -112,7 +112,7 @@
       group: windows-build-${{ github.ref }}
       cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }}
     steps:
-    - uses: actions/checkout@v3
+    - uses: actions/checkout@v4
     - uses: git-for-windows/setup-git-for-windows-sdk@v1
     - name: build
       shell: bash
@@ -123,7 +123,7 @@
     - name: zip up tracked files
       run: git archive -o artifacts/tracked.tar.gz HEAD
     - name: upload tracked files and build artifacts
-      uses: actions/upload-artifact@v3
+      uses: actions/upload-artifact@v4
       with:
         name: windows-artifacts
         path: artifacts
@@ -140,7 +140,7 @@
       cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }}
     steps:
     - name: download tracked files and build artifacts
-      uses: actions/download-artifact@v3
+      uses: actions/download-artifact@v4
       with:
         name: windows-artifacts
         path: ${{github.workspace}}
@@ -157,9 +157,9 @@
       run: ci/print-test-failures.sh
     - name: Upload failed tests' directories
       if: failure() && env.FAILED_TEST_ARTIFACTS != ''
-      uses: actions/upload-artifact@v3
+      uses: actions/upload-artifact@v4
       with:
-        name: failed-tests-windows
+        name: failed-tests-windows-${{ matrix.nr }}
         path: ${{env.FAILED_TEST_ARTIFACTS}}
   vs-build:
     name: win+VS build
@@ -173,10 +173,10 @@
       group: vs-build-${{ github.ref }}
       cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }}
     steps:
-    - uses: actions/checkout@v3
+    - uses: actions/checkout@v4
     - uses: git-for-windows/setup-git-for-windows-sdk@v1
     - name: initialize vcpkg
-      uses: actions/checkout@v3
+      uses: actions/checkout@v4
       with:
         repository: 'microsoft/vcpkg'
         path: 'compat/vcbuild/vcpkg'
@@ -212,7 +212,7 @@
     - name: zip up tracked files
       run: git archive -o artifacts/tracked.tar.gz HEAD
     - name: upload tracked files and build artifacts
-      uses: actions/upload-artifact@v3
+      uses: actions/upload-artifact@v4
       with:
         name: vs-artifacts
         path: artifacts
@@ -230,7 +230,7 @@
     steps:
     - uses: git-for-windows/setup-git-for-windows-sdk@v1
     - name: download tracked files and build artifacts
-      uses: actions/download-artifact@v3
+      uses: actions/download-artifact@v4
       with:
         name: vs-artifacts
         path: ${{github.workspace}}
@@ -248,9 +248,9 @@
       run: ci/print-test-failures.sh
     - name: Upload failed tests' directories
       if: failure() && env.FAILED_TEST_ARTIFACTS != ''
-      uses: actions/upload-artifact@v3
+      uses: actions/upload-artifact@v4
       with:
-        name: failed-tests-windows
+        name: failed-tests-windows-vs-${{ matrix.nr }}
         path: ${{env.FAILED_TEST_ARTIFACTS}}
   regular:
     name: ${{matrix.vector.jobname}} (${{matrix.vector.pool}})
@@ -266,6 +266,9 @@
           - jobname: linux-sha256
             cc: clang
             pool: ubuntu-latest
+          - jobname: linux-reftable
+            cc: clang
+            pool: ubuntu-latest
           - jobname: linux-gcc
             cc: gcc
             cc_package: gcc-8
@@ -277,9 +280,11 @@
           - jobname: osx-clang
             cc: clang
             pool: macos-13
+          - jobname: osx-reftable
+            cc: clang
+            pool: macos-13
           - jobname: osx-gcc
-            cc: gcc
-            cc_package: gcc-13
+            cc: gcc-13
             pool: macos-13
           - jobname: linux-gcc-default
             cc: gcc
@@ -287,6 +292,9 @@
           - jobname: linux-leaks
             cc: gcc
             pool: ubuntu-latest
+          - jobname: linux-reftable-leaks
+            cc: gcc
+            pool: ubuntu-latest
           - jobname: linux-asan-ubsan
             cc: clang
             pool: ubuntu-latest
@@ -297,7 +305,7 @@
       runs_on_pool: ${{matrix.vector.pool}}
     runs-on: ${{matrix.vector.pool}}
     steps:
-    - uses: actions/checkout@v3
+    - uses: actions/checkout@v4
     - run: ci/install-dependencies.sh
     - run: ci/run-build-and-tests.sh
     - name: print test failures
@@ -305,10 +313,21 @@
       run: ci/print-test-failures.sh
     - name: Upload failed tests' directories
       if: failure() && env.FAILED_TEST_ARTIFACTS != ''
-      uses: actions/upload-artifact@v3
+      uses: actions/upload-artifact@v4
       with:
         name: failed-tests-${{matrix.vector.jobname}}
         path: ${{env.FAILED_TEST_ARTIFACTS}}
+  fuzz-smoke-test:
+    name: fuzz smoke test
+    needs: ci-config
+    if: needs.ci-config.outputs.enabled == 'yes'
+    env:
+      CC: clang
+    runs-on: ubuntu-latest
+    steps:
+    - uses: actions/checkout@v4
+    - run: ci/install-dependencies.sh
+    - run: ci/run-build-and-minimal-fuzzers.sh
   dockerized:
     name: ${{matrix.vector.jobname}} (${{matrix.vector.image}})
     needs: ci-config
@@ -331,9 +350,9 @@
     runs-on: ubuntu-latest
     container: ${{matrix.vector.image}}
     steps:
-    - uses: actions/checkout@v3
+    - uses: actions/checkout@v4
       if: matrix.vector.jobname != 'linux32'
-    - uses: actions/checkout@v1
+    - uses: actions/checkout@v1 # cannot be upgraded because Node.js Actions aren't supported in this container
       if: matrix.vector.jobname == 'linux32'
     - run: ci/install-docker-dependencies.sh
     - run: ci/run-build-and-tests.sh
@@ -342,13 +361,13 @@
       run: ci/print-test-failures.sh
     - name: Upload failed tests' directories
       if: failure() && env.FAILED_TEST_ARTIFACTS != '' && matrix.vector.jobname != 'linux32'
-      uses: actions/upload-artifact@v3
+      uses: actions/upload-artifact@v4
       with:
         name: failed-tests-${{matrix.vector.jobname}}
         path: ${{env.FAILED_TEST_ARTIFACTS}}
     - name: Upload failed tests' directories
       if: failure() && env.FAILED_TEST_ARTIFACTS != '' && matrix.vector.jobname == 'linux32'
-      uses: actions/upload-artifact@v1
+      uses: actions/upload-artifact@v1 # cannot be upgraded because Node.js Actions aren't supported in this container
       with:
         name: failed-tests-${{matrix.vector.jobname}}
         path: ${{env.FAILED_TEST_ARTIFACTS}}
@@ -362,7 +381,7 @@
       group: static-analysis-${{ github.ref }}
       cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }}
     steps:
-    - uses: actions/checkout@v3
+    - uses: actions/checkout@v4
     - run: ci/install-dependencies.sh
     - run: ci/run-static-analysis.sh
     - run: ci/check-directional-formatting.bash
@@ -385,7 +404,7 @@
         artifact: sparse-20.04
     - name: Install the current `sparse` package
       run: sudo dpkg -i sparse-20.04/sparse_*.deb
-    - uses: actions/checkout@v3
+    - uses: actions/checkout@v4
     - name: Install other dependencies
       run: ci/install-dependencies.sh
     - run: make sparse
@@ -400,6 +419,6 @@
       jobname: Documentation
     runs-on: ubuntu-latest
     steps:
-    - uses: actions/checkout@v3
+    - uses: actions/checkout@v4
     - run: ci/install-dependencies.sh
     - run: ci/test-documentation.sh
diff --git a/.gitignore b/.gitignore
index 5e56e47..612c0f6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -135,6 +135,7 @@
 /git-remote-ext
 /git-repack
 /git-replace
+/git-replay
 /git-request-pull
 /git-rerere
 /git-reset
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index cd98bcb..c0fa2fe 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -7,7 +7,7 @@
     - if: $CI_COMMIT_TAG
     - if: $CI_COMMIT_REF_PROTECTED == "true"
 
-test:
+test:linux:
   image: $image
   before_script:
     - ./ci/install-docker-dependencies.sh
@@ -26,6 +26,9 @@
       - jobname: linux-sha256
         image: ubuntu:latest
         CC: clang
+      - jobname: linux-reftable
+        image: ubuntu:latest
+        CC: clang
       - jobname: linux-gcc
         image: ubuntu:20.04
         CC: gcc
@@ -40,6 +43,9 @@
       - jobname: linux-leaks
         image: ubuntu:latest
         CC: gcc
+      - jobname: linux-reftable-leaks
+        image: ubuntu:latest
+        CC: gcc
       - jobname: linux-asan-ubsan
         image: ubuntu:latest
         CC: clang
@@ -51,3 +57,48 @@
     paths:
       - t/failed-test-artifacts
     when: on_failure
+
+test:osx:
+  image: $image
+  tags:
+    - saas-macos-medium-m1
+  variables:
+    TEST_OUTPUT_DIRECTORY: "/Volumes/RAMDisk"
+  before_script:
+    # Create a 4GB RAM disk that we use to store test output on. This small hack
+    # significantly speeds up tests by more than a factor of 2 because the
+    # macOS runners use network-attached storage as disks, which is _really_
+    # slow with the many small writes that our tests do.
+    - sudo diskutil apfs create $(hdiutil attach -nomount ram://8192000) RAMDisk
+    - ./ci/install-dependencies.sh
+  script:
+    - ./ci/run-build-and-tests.sh
+  after_script:
+    - |
+      if test "$CI_JOB_STATUS" != 'success'
+      then
+        ./ci/print-test-failures.sh
+        mv "$TEST_OUTPUT_DIRECTORY"/failed-test-artifacts t/
+      fi
+  parallel:
+    matrix:
+      - jobname: osx-clang
+        image: macos-13-xcode-14
+        CC: clang
+      - jobname: osx-reftable
+        image: macos-13-xcode-14
+        CC: clang
+  artifacts:
+    paths:
+      - t/failed-test-artifacts
+    when: on_failure
+
+static-analysis:
+  image: ubuntu:22.04
+  variables:
+    jobname: StaticAnalysis
+  before_script:
+    - ./ci/install-docker-dependencies.sh
+  script:
+    - ./ci/run-static-analysis.sh
+    - ./ci/check-directional-formatting.bash
diff --git a/.mailmap b/.mailmap
index 82129be..18128a1 100644
--- a/.mailmap
+++ b/.mailmap
@@ -152,6 +152,7 @@
 Lars Doelle <lars.doelle@on-line.de>
 Lars Noschinski <lars@public.noschinski.de> <lars.noschinski@rwth-aachen.de>
 Li Hong <leehong@pku.edu.cn>
+Linus Arver <linus@ucla.edu> <linusa@google.com>
 Linus Torvalds <torvalds@linux-foundation.org> <torvalds@evo.osdl.org>
 Linus Torvalds <torvalds@linux-foundation.org> <torvalds@g5.osdl.org>
 Linus Torvalds <torvalds@linux-foundation.org> <torvalds@osdl.org>
diff --git a/Documentation/CodingGuidelines b/Documentation/CodingGuidelines
index 578587a..1d92b2d 100644
--- a/Documentation/CodingGuidelines
+++ b/Documentation/CodingGuidelines
@@ -188,6 +188,22 @@
    hopefully nobody starts using "local" before they are reimplemented
    in C ;-)
 
+ - Some versions of shell do not understand "export variable=value",
+   so we write "variable=value" and then "export variable" on two
+   separate lines.
+
+ - Some versions of dash have broken variable assignment when prefixed
+   with "local", "export", and "readonly", in that the value to be
+   assigned goes through field splitting at $IFS unless quoted.
+
+	(incorrect)
+	local variable=$value
+	local variable=$(command args)
+
+	(correct)
+	local variable="$value"
+	local variable="$(command args)"
+
  - Use octal escape sequences (e.g. "\302\242"), not hexadecimal (e.g.
    "\xc2\xa2") in printf format strings, since hexadecimal escape
    sequences are not portable.
@@ -446,12 +462,41 @@
    detail.
 
  - The first #include in C files, except in platform specific compat/
-   implementations and sha1dc/, must be either "git-compat-util.h" or
-   one of the approved headers that includes it first for you.  (The
-   approved headers currently include "builtin.h",
-   "t/helper/test-tool.h", "xdiff/xinclude.h", or
-   "reftable/system.h".)  You do not have to include more than one of
-   these.
+   implementations and sha1dc/, must be <git-compat-util.h>.  This
+   header file insulates other header files and source files from
+   platform differences, like which system header files must be
+   included in what order, and what C preprocessor feature macros must
+   be defined to trigger certain features we expect out of the system.
+   A collorary to this is that C files should not directly include
+   system header files themselves.
+
+   There are some exceptions, because certain group of files that
+   implement an API all have to include the same header file that
+   defines the API and it is convenient to include <git-compat-util.h>
+   there.  Namely:
+
+   - the implementation of the built-in commands in the "builtin/"
+     directory that include "builtin.h" for the cmd_foo() prototype
+     definition,
+
+   - the test helper programs in the "t/helper/" directory that include
+     "t/helper/test-tool.h" for the cmd__foo() prototype definition,
+
+   - the xdiff implementation in the "xdiff/" directory that includes
+     "xdiff/xinclude.h" for the xdiff machinery internals,
+
+   - the unit test programs in "t/unit-tests/" directory that include
+     "t/unit-tests/test-lib.h" that gives them the unit-tests
+     framework, and
+
+   - the source files that implement reftable in the "reftable/"
+     directory that include "reftable/system.h" for the reftable
+     internals,
+
+   are allowed to assume that they do not have to include
+   <git-compat-util.h> themselves, as it is included as the first
+   '#include' in these header files.  These headers must be the first
+   header file to be "#include"d in them, though.
 
  - A C file must directly include the header files that declare the
    functions and the types it uses, except for the functions and types
@@ -612,15 +657,15 @@
   - Prefer succinctness and matter-of-factly describing functionality
     in the abstract.  E.g.
 
-     --short:: Emit output in the short-format.
+     `--short`:: Emit output in the short-format.
 
     and avoid something like these overly verbose alternatives:
 
-     --short:: Use this to emit output in the short-format.
-     --short:: You can use this to get output in the short-format.
-     --short:: A user who prefers shorter output could....
-     --short:: Should a person and/or program want shorter output, he
-               she/they/it can...
+     `--short`:: Use this to emit output in the short-format.
+     `--short`:: You can use this to get output in the short-format.
+     `--short`:: A user who prefers shorter output could....
+     `--short`:: Should a person and/or program want shorter output, he
+                 she/they/it can...
 
     This practice often eliminates the need to involve human actors in
     your description, but it is a good practice regardless of the
@@ -630,12 +675,12 @@
     addressing the hypothetical user, and possibly "we" when
     discussing how the program might react to the user.  E.g.
 
-      You can use this option instead of --xyz, but we might remove
+      You can use this option instead of `--xyz`, but we might remove
       support for it in future versions.
 
     while keeping in mind that you can probably be less verbose, e.g.
 
-      Use this instead of --xyz. This option might be removed in future
+      Use this instead of `--xyz`. This option might be removed in future
       versions.
 
   - If you still need to refer to an example person that is
@@ -653,80 +698,12 @@
  The same general rule as for code applies -- imitate the existing
  conventions.
 
- A few commented examples follow to provide reference when writing or
- modifying command usage strings and synopsis sections in the manual
- pages:
 
- Placeholders are spelled in lowercase and enclosed in angle brackets:
-   <file>
-   --sort=<key>
-   --abbrev[=<n>]
+Markup:
 
- If a placeholder has multiple words, they are separated by dashes:
-   <new-branch-name>
-   --template=<template-directory>
-
- Possibility of multiple occurrences is indicated by three dots:
-   <file>...
-   (One or more of <file>.)
-
- Optional parts are enclosed in square brackets:
-   [<file>...]
-   (Zero or more of <file>.)
-
-   --exec-path[=<path>]
-   (Option with an optional argument.  Note that the "=" is inside the
-   brackets.)
-
-   [<patch>...]
-   (Zero or more of <patch>.  Note that the dots are inside, not
-   outside the brackets.)
-
- Multiple alternatives are indicated with vertical bars:
-   [-q | --quiet]
-   [--utf8 | --no-utf8]
-
- Use spacing around "|" token(s), but not immediately after opening or
- before closing a [] or () pair:
-   Do: [-q | --quiet]
-   Don't: [-q|--quiet]
-
- Don't use spacing around "|" tokens when they're used to separate the
- alternate arguments of an option:
-    Do: --track[=(direct|inherit)]
-    Don't: --track[=(direct | inherit)]
-
- Parentheses are used for grouping:
-   [(<rev> | <range>)...]
-   (Any number of either <rev> or <range>.  Parens are needed to make
-   it clear that "..." pertains to both <rev> and <range>.)
-
-   [(-p <parent>)...]
-   (Any number of option -p, each with one <parent> argument.)
-
-   git remote set-head <name> (-a | -d | <branch>)
-   (One and only one of "-a", "-d" or "<branch>" _must_ (no square
-   brackets) be provided.)
-
- And a somewhat more contrived example:
-   --diff-filter=[(A|C|D|M|R|T|U|X|B)...[*]]
-   Here "=" is outside the brackets, because "--diff-filter=" is a
-   valid usage.  "*" has its own pair of brackets, because it can
-   (optionally) be specified only when one or more of the letters is
-   also provided.
-
-  A note on notation:
-   Use 'git' (all lowercase) when talking about commands i.e. something
-   the user would type into a shell and use 'Git' (uppercase first letter)
-   when talking about the version control system and its properties.
-
- A few commented examples follow to provide reference when writing or
- modifying paragraphs or option/command explanations that contain options
- or commands:
-
- Literal examples (e.g. use of command-line options, command names,
+ Literal parts (e.g. use of command-line options, command names,
  branch names, URLs, pathnames (files and directories), configuration and
- environment variables) must be typeset in monospace (i.e. wrapped with
+ environment variables) must be typeset as verbatim (i.e. wrapped with
  backticks):
    `--pretty=oneline`
    `git rev-list`
@@ -735,6 +712,7 @@
    `.git/config`
    `GIT_DIR`
    `HEAD`
+   `umask`(2)
 
  An environment variable must be prefixed with "$" only when referring to its
  value and not when referring to the variable itself, in this case there is
@@ -751,6 +729,97 @@
    Incorrect:
       `\--pretty=oneline`
 
+ Placeholders are spelled in lowercase and enclosed in
+ angle brackets surrounded by underscores:
+   _<file>_
+   _<commit>_
+
+ If a placeholder has multiple words, they are separated by dashes:
+   _<new-branch-name>_
+   _<template-directory>_
+
+ A placeholder is not enclosed in backticks, as it is not a literal.
+
+ When needed, use a distinctive identifier for placeholders, usually
+ made of a qualification and a type:
+   _<git-dir>_
+   _<key-id>_
+
+ When literal and placeholders are mixed, each markup is applied for
+ each sub-entity. If they are stuck, a special markup, called
+ unconstrained formatting is required.
+ Unconstrained formating for placeholders is __<like-this>__
+ Unconstrained formatting for literal formatting is ++like this++
+   `--jobs` _<n>_
+   ++--sort=++__<key>__
+   __<directory>__++/.git++
+   ++remote.++__<name>__++.mirror++
+
+ caveat: ++ unconstrained format is not verbatim and may expand
+ content. Use Asciidoc escapes inside them.
+
+Synopsis Syntax
+
+ Syntax grammar is formatted neither as literal nor as placeholder.
+
+ A few commented examples follow to provide reference when writing or
+ modifying command usage strings and synopsis sections in the manual
+ pages:
+
+ Possibility of multiple occurrences is indicated by three dots:
+   _<file>_...
+   (One or more of <file>.)
+
+ Optional parts are enclosed in square brackets:
+   [_<file>_...]
+   (Zero or more of <file>.)
+
+   ++--exec-path++[++=++__<path>__]
+   (Option with an optional argument.  Note that the "=" is inside the
+   brackets.)
+
+   [_<patch>_...]
+   (Zero or more of <patch>.  Note that the dots are inside, not
+   outside the brackets.)
+
+ Multiple alternatives are indicated with vertical bars:
+   [`-q` | `--quiet`]
+   [`--utf8` | `--no-utf8`]
+
+ Use spacing around "|" token(s), but not immediately after opening or
+ before closing a [] or () pair:
+   Do: [`-q` | `--quiet`]
+   Don't: [`-q`|`--quiet`]
+
+ Don't use spacing around "|" tokens when they're used to separate the
+ alternate arguments of an option:
+    Do: ++--track++[++=++(`direct`|`inherit`)]`
+    Don't: ++--track++[++=++(`direct` | `inherit`)]
+
+ Parentheses are used for grouping:
+   [(_<rev>_ | _<range>_)...]
+   (Any number of either <rev> or <range>.  Parens are needed to make
+   it clear that "..." pertains to both <rev> and <range>.)
+
+   [(`-p` _<parent>_)...]
+   (Any number of option -p, each with one <parent> argument.)
+
+   `git remote set-head` _<name>_ (`-a` | `-d` | _<branch>_)
+   (One and only one of "-a", "-d" or "<branch>" _must_ (no square
+   brackets) be provided.)
+
+ And a somewhat more contrived example:
+   `--diff-filter=[(A|C|D|M|R|T|U|X|B)...[*]]`
+   Here "=" is outside the brackets, because "--diff-filter=" is a
+   valid usage.  "*" has its own pair of brackets, because it can
+   (optionally) be specified only when one or more of the letters is
+   also provided.
+
+  A note on notation:
+   Use 'git' (all lowercase) when talking about commands i.e. something
+   the user would type into a shell and use 'Git' (uppercase first letter)
+   when talking about the version control system and its properties.
+
  If some place in the documentation needs to typeset a command usage
  example with inline substitutions, it is fine to use +monospaced and
  inline substituted text+ instead of `monospaced literal text`, and with
diff --git a/Documentation/Makefile b/Documentation/Makefile
index b629176..3f2383a 100644
--- a/Documentation/Makefile
+++ b/Documentation/Makefile
@@ -122,6 +122,7 @@
 TECH_DOCS += technical/send-pack-pipeline
 TECH_DOCS += technical/shallow
 TECH_DOCS += technical/trivial-merge
+TECH_DOCS += technical/unit-tests
 SP_ARTICLES += $(TECH_DOCS)
 SP_ARTICLES += technical/api-index
 
diff --git a/Documentation/MyFirstObjectWalk.txt b/Documentation/MyFirstObjectWalk.txt
index c68cdb1..dec8afe 100644
--- a/Documentation/MyFirstObjectWalk.txt
+++ b/Documentation/MyFirstObjectWalk.txt
@@ -210,13 +210,14 @@
 
 ...
 
-static int git_walken_config(const char *var, const char *value, void *cb)
+static int git_walken_config(const char *var, const char *value,
+			     const struct config_context *ctx, void *cb)
 {
 	/*
 	 * For now, we don't have any custom configuration, so fall back to
 	 * the default config.
 	 */
-	return git_default_config(var, value, cb);
+	return git_default_config(var, value, ctx, cb);
 }
 ----
 
@@ -389,10 +390,11 @@
 First some setup. Add `grep_config()` to `git_walken_config()`:
 
 ----
-static int git_walken_config(const char *var, const char *value, void *cb)
+static int git_walken_config(const char *var, const char *value,
+			     const struct config_context *ctx, void *cb)
 {
-	grep_config(var, value, cb);
-	return git_default_config(var, value, cb);
+	grep_config(var, value, ctx, cb);
+	return git_default_config(var, value, ctx, cb);
 }
 ----
 
@@ -523,7 +525,7 @@
 
 We can base our work on an example. `git pack-objects` prepares all kinds of
 objects for packing into a bitmap or packfile. The work we are interested in
-resides in `builtins/pack-objects.c:get_object_list()`; examination of that
+resides in `builtin/pack-objects.c:get_object_list()`; examination of that
 function shows that the all-object walk is being performed by
 `traverse_commit_list()` or `traverse_commit_list_filtered()`. Those two
 functions reside in `list-objects.c`; examining the source shows that, despite
@@ -732,8 +734,8 @@
 	} else {
 		trace_printf(
 			_("Filtered object walk with filterspec 'tree:1'.\n"));
-		CALLOC_ARRAY(rev->filter, 1);
-		parse_list_objects_filter(rev->filter, "tree:1");
+
+		parse_list_objects_filter(&rev->filter, "tree:1");
 	}
 	traverse_commit_list(rev, walken_show_commit,
 			     walken_show_object, NULL);
@@ -752,10 +754,12 @@
 === Counting Omitted Objects
 
 We also have the capability to enumerate all objects which were omitted by a
-filter, like with `git log --filter=<spec> --filter-print-omitted`. Asking
-`traverse_commit_list_filtered()` to populate the `omitted` list means that our
-object walk does not perform any better than an unfiltered object walk; all
-reachable objects are walked in order to populate the list.
+filter, like with `git log --filter=<spec> --filter-print-omitted`. To do this,
+change `traverse_commit_list()` to `traverse_commit_list_filtered()`, which is
+able to populate an `omitted` list.  Asking for this list of filtered objects
+may cause performance degradations, however, because in this case, despite
+filtering objects, the possibly much larger set of all reachable objects must
+be processed in order to populate that list.
 
 First, add the `struct oidset` and related items we will use to iterate it:
 
@@ -776,8 +780,9 @@
 	...
 ----
 
-Modify the call to `traverse_commit_list_filtered()` to include your `omitted`
-object:
+Replace the call to `traverse_commit_list()` with
+`traverse_commit_list_filtered()` and pass a pointer to the `omitted` oidset
+defined and initialized above:
 
 ----
 	...
@@ -843,7 +848,7 @@
 With only that change, run again (but save yourself some scrollback):
 
 ----
-$ GIT_TRACE=1 ./bin-wrappers/git walken | head -n 10
+$ GIT_TRACE=1 ./bin-wrappers/git walken 2>&1 | head -n 10
 ----
 
 Take a look at the top commit with `git show` and the object ID you printed; it
@@ -871,7 +876,7 @@
 
 ----
 $ make
-$ GIT_TRACE=1 ./bin-wrappers git walken | tail -n 10
+$ GIT_TRACE=1 ./bin-wrappers/git walken 2>&1 | tail -n 10
 ----
 
 The last commit object given should have the same OID as the one we saw at the
diff --git a/Documentation/RelNotes/2.39.4.txt b/Documentation/RelNotes/2.39.4.txt
new file mode 100644
index 0000000..7f54521
--- /dev/null
+++ b/Documentation/RelNotes/2.39.4.txt
@@ -0,0 +1,79 @@
+Git v2.39.4 Release Notes
+=========================
+
+This addresses the security issues CVE-2024-32002, CVE-2024-32004,
+CVE-2024-32020 and CVE-2024-32021.
+
+This release also backports fixes necessary to let the CI builds pass
+successfully.
+
+Fixes since v2.39.3
+-------------------
+
+ * CVE-2024-32002:
+
+   Recursive clones on case-insensitive filesystems that support symbolic
+   links are susceptible to case confusion that can be exploited to
+   execute just-cloned code during the clone operation.
+
+ * CVE-2024-32004:
+
+   Repositories can be configured to execute arbitrary code during local
+   clones. To address this, the ownership checks introduced in v2.30.3
+   are now extended to cover cloning local repositories.
+
+ * CVE-2024-32020:
+
+   Local clones may end up hardlinking files into the target repository's
+   object database when source and target repository reside on the same
+   disk. If the source repository is owned by a different user, then
+   those hardlinked files may be rewritten at any point in time by the
+   untrusted user.
+
+ * CVE-2024-32021:
+
+   When cloning a local source repository that contains symlinks via the
+   filesystem, Git may create hardlinks to arbitrary user-readable files
+   on the same filesystem as the target repository in the objects/
+   directory.
+
+ * CVE-2024-32465:
+
+   It is supposed to be safe to clone untrusted repositories, even those
+   unpacked from zip archives or tarballs originating from untrusted
+   sources, but Git can be tricked to run arbitrary code as part of the
+   clone.
+
+ * Defense-in-depth: submodule: require the submodule path to contain
+   directories only.
+
+ * Defense-in-depth: clone: when symbolic links collide with directories, keep
+   the latter.
+
+ * Defense-in-depth: clone: prevent hooks from running during a clone.
+
+ * Defense-in-depth: core.hooksPath: add some protection while cloning.
+
+ * Defense-in-depth: fsck: warn about symlink pointing inside a gitdir.
+
+ * Various fix-ups on HTTP tests.
+
+ * Test update.
+
+ * HTTP Header redaction code has been adjusted for a newer version of
+   cURL library that shows its traces differently from earlier
+   versions.
+
+ * Fix was added to work around a regression in libcURL 8.7.0 (which has
+   already been fixed in their tip of the tree).
+
+ * Replace macos-12 used at GitHub CI with macos-13.
+
+ * ci(linux-asan/linux-ubsan): let's save some time
+
+ * Tests with LSan from time to time seem to emit harmless message that makes
+   our tests unnecessarily flakey; we work it around by filtering the
+   uninteresting output.
+
+ * Update GitHub Actions jobs to avoid warnings against using deprecated
+   version of Node.js.
diff --git a/Documentation/RelNotes/2.39.5.txt b/Documentation/RelNotes/2.39.5.txt
new file mode 100644
index 0000000..97c0185
--- /dev/null
+++ b/Documentation/RelNotes/2.39.5.txt
@@ -0,0 +1,26 @@
+Git v2.39.5 Release Notes
+=========================
+
+In preparing security fixes for four CVEs, we made overly aggressive
+"defense in depth" changes that broke legitimate use cases like 'git
+lfs' and 'git annex.'  This release is to revert these misguided, if
+well-intentioned, changes that were shipped in 2.39.4 and were not
+direct security fixes.
+
+Jeff King (5):
+      send-email: drop FakeTerm hack
+      send-email: avoid creating more than one Term::ReadLine object
+      ci: drop mention of BREW_INSTALL_PACKAGES variable
+      ci: avoid bare "gcc" for osx-gcc job
+      ci: stop installing "gcc-13" for osx-gcc
+
+Johannes Schindelin (6):
+      hook: plug a new memory leak
+      init: use the correct path of the templates directory again
+      Revert "core.hooksPath: add some protection while cloning"
+      tests: verify that `clone -c core.hooksPath=/dev/null` works again
+      clone: drop the protections where hooks aren't run
+      Revert "Add a helper function to compare file contents"
+
+Junio C Hamano (1):
+      Revert "fsck: warn about symlink pointing inside a gitdir"
diff --git a/Documentation/RelNotes/2.40.2.txt b/Documentation/RelNotes/2.40.2.txt
new file mode 100644
index 0000000..646a2cc
--- /dev/null
+++ b/Documentation/RelNotes/2.40.2.txt
@@ -0,0 +1,7 @@
+Git v2.40.2 Release Notes
+=========================
+
+This release merges up the fix that appears in v2.39.4 to address
+the security issues CVE-2024-32002, CVE-2024-32004, CVE-2024-32020,
+CVE-2024-32021 and CVE-2024-32465; see the release notes for that
+version for details.
diff --git a/Documentation/RelNotes/2.40.3.txt b/Documentation/RelNotes/2.40.3.txt
new file mode 100644
index 0000000..6ca088e
--- /dev/null
+++ b/Documentation/RelNotes/2.40.3.txt
@@ -0,0 +1,26 @@
+Git v2.40.3 Release Notes
+=========================
+
+In preparing security fixes for four CVEs, we made overly aggressive
+"defense in depth" changes that broke legitimate use cases like 'git
+lfs' and 'git annex.'  This release is to revert these misguided, if
+well-intentioned, changes that were shipped in 2.40.2 and were not
+direct security fixes.
+
+Jeff King (5):
+      send-email: drop FakeTerm hack
+      send-email: avoid creating more than one Term::ReadLine object
+      ci: drop mention of BREW_INSTALL_PACKAGES variable
+      ci: avoid bare "gcc" for osx-gcc job
+      ci: stop installing "gcc-13" for osx-gcc
+
+Johannes Schindelin (6):
+      hook: plug a new memory leak
+      init: use the correct path of the templates directory again
+      Revert "core.hooksPath: add some protection while cloning"
+      tests: verify that `clone -c core.hooksPath=/dev/null` works again
+      clone: drop the protections where hooks aren't run
+      Revert "Add a helper function to compare file contents"
+
+Junio C Hamano (1):
+      Revert "fsck: warn about symlink pointing inside a gitdir"
diff --git a/Documentation/RelNotes/2.41.1.txt b/Documentation/RelNotes/2.41.1.txt
new file mode 100644
index 0000000..9fb4c21
--- /dev/null
+++ b/Documentation/RelNotes/2.41.1.txt
@@ -0,0 +1,7 @@
+Git v2.41.1 Release Notes
+=========================
+
+This release merges up the fix that appears in v2.39.4 and v2.40.2
+to address the security issues CVE-2024-32002, CVE-2024-32004,
+CVE-2024-32020, CVE-2024-32021 and CVE-2024-32465; see the release
+notes for these versions for details.
diff --git a/Documentation/RelNotes/2.41.2.txt b/Documentation/RelNotes/2.41.2.txt
new file mode 100644
index 0000000..f94afde
--- /dev/null
+++ b/Documentation/RelNotes/2.41.2.txt
@@ -0,0 +1,26 @@
+Git v2.41.2 Release Notes
+=========================
+
+In preparing security fixes for four CVEs, we made overly aggressive
+"defense in depth" changes that broke legitimate use cases like 'git
+lfs' and 'git annex.'  This release is to revert these misguided, if
+well-intentioned, changes that were shipped in 2.41.1 and were not
+direct security fixes.
+
+Jeff King (5):
+      send-email: drop FakeTerm hack
+      send-email: avoid creating more than one Term::ReadLine object
+      ci: drop mention of BREW_INSTALL_PACKAGES variable
+      ci: avoid bare "gcc" for osx-gcc job
+      ci: stop installing "gcc-13" for osx-gcc
+
+Johannes Schindelin (6):
+      hook: plug a new memory leak
+      init: use the correct path of the templates directory again
+      Revert "core.hooksPath: add some protection while cloning"
+      tests: verify that `clone -c core.hooksPath=/dev/null` works again
+      clone: drop the protections where hooks aren't run
+      Revert "Add a helper function to compare file contents"
+
+Junio C Hamano (1):
+      Revert "fsck: warn about symlink pointing inside a gitdir"
diff --git a/Documentation/RelNotes/2.42.2.txt b/Documentation/RelNotes/2.42.2.txt
new file mode 100644
index 0000000..dbf761a
--- /dev/null
+++ b/Documentation/RelNotes/2.42.2.txt
@@ -0,0 +1,7 @@
+Git v2.42.2 Release Notes
+=========================
+
+This release merges up the fix that appears in v2.39.4, v2.40.2
+and v2.41.1 to address the security issues CVE-2024-32002,
+CVE-2024-32004, CVE-2024-32020, CVE-2024-32021 and CVE-2024-32465;
+see the release notes for these versions for details.
diff --git a/Documentation/RelNotes/2.42.3.txt b/Documentation/RelNotes/2.42.3.txt
new file mode 100644
index 0000000..bfe3ba5
--- /dev/null
+++ b/Documentation/RelNotes/2.42.3.txt
@@ -0,0 +1,26 @@
+Git v2.42.3 Release Notes
+=========================
+
+In preparing security fixes for four CVEs, we made overly aggressive
+"defense in depth" changes that broke legitimate use cases like 'git
+lfs' and 'git annex.'  This release is to revert these misguided, if
+well-intentioned, changes that were shipped in 2.42.2 and were not
+direct security fixes.
+
+Jeff King (5):
+      send-email: drop FakeTerm hack
+      send-email: avoid creating more than one Term::ReadLine object
+      ci: drop mention of BREW_INSTALL_PACKAGES variable
+      ci: avoid bare "gcc" for osx-gcc job
+      ci: stop installing "gcc-13" for osx-gcc
+
+Johannes Schindelin (6):
+      hook: plug a new memory leak
+      init: use the correct path of the templates directory again
+      Revert "core.hooksPath: add some protection while cloning"
+      tests: verify that `clone -c core.hooksPath=/dev/null` works again
+      clone: drop the protections where hooks aren't run
+      Revert "Add a helper function to compare file contents"
+
+Junio C Hamano (1):
+      Revert "fsck: warn about symlink pointing inside a gitdir"
diff --git a/Documentation/RelNotes/2.43.4.txt b/Documentation/RelNotes/2.43.4.txt
new file mode 100644
index 0000000..0a84251
--- /dev/null
+++ b/Documentation/RelNotes/2.43.4.txt
@@ -0,0 +1,7 @@
+Git v2.43.4 Release Notes
+=========================
+
+This release merges up the fix that appears in v2.39.4, v2.40.2,
+v2.41.1 and v2.42.2 to address the security issues CVE-2024-32002,
+CVE-2024-32004, CVE-2024-32020, CVE-2024-32021 and CVE-2024-32465;
+see the release notes for these versions for details.
diff --git a/Documentation/RelNotes/2.43.5.txt b/Documentation/RelNotes/2.43.5.txt
new file mode 100644
index 0000000..236b234
--- /dev/null
+++ b/Documentation/RelNotes/2.43.5.txt
@@ -0,0 +1,26 @@
+Git v2.43.5 Release Notes
+=========================
+
+In preparing security fixes for four CVEs, we made overly aggressive
+"defense in depth" changes that broke legitimate use cases like 'git
+lfs' and 'git annex.'  This release is to revert these misguided, if
+well-intentioned, changes that were shipped in 2.43.4 and were not
+direct security fixes.
+
+Jeff King (5):
+      send-email: drop FakeTerm hack
+      send-email: avoid creating more than one Term::ReadLine object
+      ci: drop mention of BREW_INSTALL_PACKAGES variable
+      ci: avoid bare "gcc" for osx-gcc job
+      ci: stop installing "gcc-13" for osx-gcc
+
+Johannes Schindelin (6):
+      hook: plug a new memory leak
+      init: use the correct path of the templates directory again
+      Revert "core.hooksPath: add some protection while cloning"
+      tests: verify that `clone -c core.hooksPath=/dev/null` works again
+      clone: drop the protections where hooks aren't run
+      Revert "Add a helper function to compare file contents"
+
+Junio C Hamano (1):
+      Revert "fsck: warn about symlink pointing inside a gitdir"
diff --git a/Documentation/RelNotes/2.44.0.txt b/Documentation/RelNotes/2.44.0.txt
new file mode 100644
index 0000000..14f9ce8
--- /dev/null
+++ b/Documentation/RelNotes/2.44.0.txt
@@ -0,0 +1,334 @@
+Git v2.44 Release Notes
+=======================
+
+Backward Compatibility Notes
+
+ * "git checkout -B <branch>" used to allow switching to a branch that
+   is in use on another worktree, but this was by mistake.  The users
+   need to use "--ignore-other-worktrees" option.
+
+
+UI, Workflows & Features
+
+ * "git add" and "git stash" learned to support the ":(attr:...)"
+   magic pathspec.
+
+ * "git rebase --autosquash" is now enabled for non-interactive rebase,
+   but it is still incompatible with the apply backend.
+
+ * Introduce "git replay", a tool meant on the server side without
+   working tree to recreate a history.
+
+ * "git merge-file" learned to take the "--diff-algorithm" option to
+   use algorithm different from the default "myers" diff.
+
+ * Command line completion (in contrib/) learned to complete path
+   arguments to the "add/set" subcommands of "git sparse-checkout"
+   better.
+
+ * "git checkout -B <branch> [<start-point>]" allowed a branch that is
+   in use in another worktree to be updated and checked out, which
+   might be a bit unexpected.  The rule has been tightened, which is a
+   breaking change.  "--ignore-other-worktrees" option is required to
+   unbreak you, if you are used to the current behaviour that "-B"
+   overrides the safety.
+
+ * The builtin_objectmode attribute is populated for each path
+   without adding anything in .gitattributes files, which would be
+   useful in magic pathspec, e.g., ":(attr:builtin_objectmode=100755)"
+   to limit to executables.
+
+ * "git fetch" learned to pay attention to "fetch.all" configuration
+   variable, which pretends as if "--all" was passed from the command
+   line when no remote parameter was given.
+
+ * In addition to (rather cryptic) Security Identifiers, show username
+   and domain in the error message when we barf on mismatch between
+   the Git directory and the current user on Windows.
+
+ * The error message given when "git branch -d branch" fails due to
+   commits unique to the branch has been split into an error and a new
+   conditional advice message.
+
+ * When given an existing but unreadable file as a configuration file,
+   gitweb behaved as if the file did not exist at all, but now it
+   errors out.  This is a change that may break backward compatibility.
+
+ * When $HOME/.gitconfig is missing but XDG config file is available, we
+   should write into the latter, not former.  "git gc" and "git
+   maintenance" wrote into a wrong "global config" file, which have
+   been corrected.
+
+ * Define "special ref" as a very narrow set that consists of
+   FETCH_HEAD and MERGE_HEAD, and clarify everything else that used to
+   be classified as such are actually just pseudorefs.
+
+ * All conditional "advice" messages show how to turn them off, which
+   becomes repetitive.  Setting advice.* configuration explicitly on
+   now omits the instruction part.
+
+ * The "disable repository discovery of a bare repository" check,
+   triggered by setting safe.bareRepository configuration variable to
+   'explicit', has been loosened to exclude the ".git/" directory inside
+   a non-bare repository from the check.  So you can do "cd .git &&
+   git cmd" to run a Git command that works on a bare repository without
+   explicitly specifying $GIT_DIR now.
+
+ * The completion script (in contrib/) learned more options that can
+   be used with "git log".
+
+ * The labels on conflict markers for the common ancestor, our version,
+   and the other version are available to custom 3-way merge driver
+   via %S, %X, and %Y placeholders.
+
+ * The write codepath for the reftable data learned to honor
+   core.fsync configuration.
+
+ * The "--fsck-objects" option of "git index-pack" now can take the
+   optional parameter to tweak severity of different fsck errors.
+
+ * The wincred credential backend has been taught to support oauth
+   refresh token the same way as credential-cache and
+   credential-libsecret backends.
+
+ * Command line completion support (in contrib/) has been
+   updated for "git bisect".
+
+ * "git branch" and friends learned to use the formatted text as
+   sorting key, not the underlying timestamp value, when the --sort
+   option is used with author or committer timestamp with a format
+   specifier (e.g., "--sort=creatordate:format:%H:%M:%S").
+
+ * The command line completion script (in contrib/) learned to
+   complete configuration variable names better.
+
+
+Performance, Internal Implementation, Development Support etc.
+
+ * Process to add some form of low-level unit tests has started.
+
+ * Add support for GitLab CI.
+
+ * "git for-each-ref --no-sort" still sorted the refs alphabetically
+   which paid non-trivial cost.  It has been redefined to show output
+   in an unspecified order, to allow certain optimizations to take
+   advantage of.
+
+ * Simplify API implementation to delete references by eliminating
+   duplication.
+
+ * Subject approxidate() and show_date() machinery to OSS-Fuzz.
+
+ * A new helper to let us pretend that we called lstat() when we know
+   our cache_entry is up-to-date via fsmonitor.
+
+ * The optimization based on fsmonitor in the "diff --cached"
+   codepath is resurrected with the "fake-lstat" introduced earlier.
+
+ * Test balloon to use C99 "bool" type from <stdbool.h> has been
+   added.
+
+ * "git clone" has been prepared to allow cloning a repository with
+   non-default hash function into a repository that uses the reftable
+   backend.
+
+ * Streaming spans of packfile data used to be done only from a
+   single, primary, pack in a repository with multiple packfiles.  It
+   has been extended to allow reuse from other packfiles, too.
+
+ * Comment updates to help developers not to attempt to modify
+   messages from plumbing commands that must stay constant.
+
+   It might make sense to reassess the plumbing needs every few years,
+   but that should be done as a separate effort.
+
+ * Move test-ctype helper to the unit-test framework.
+
+ * Instead of manually creating refs/ hierarchy on disk upon a
+   creation of a secondary worktree, which is only usable via the
+   files backend, use the refs API to populate it.
+
+ * CI for GitLab learned to drive macOS jobs.
+
+ * A few tests to "git commit -o <pathspec>" and "git commit -i
+   <pathspec>" has been added.
+
+ * Tests on ref API are moved around to prepare for reftable.
+
+ * The Makefile often had to say "-L$(path) -R$(path)" that repeats
+   the path to the same library directory for link time and runtime.
+   A Makefile template is used to reduce such repetition.
+
+ * The priority queue test has been migrated to the unit testing
+   framework.
+
+ * Setting `feature.experimental` opts the user into multi-pack reuse
+   experiment
+
+ * Squelch node.js 16 deprecation warnings from GitHub Actions CI
+   by updating actions/github-script and actions/checkout that use
+   node.js 20.
+
+ * The mechanism to report the filename in the source code, used by
+   the unit-test machinery, assumed that the compiler expanded __FILE__
+   to the path to the source given to the $(CC), but some compilers
+   give full path, breaking the output.  This has been corrected.
+
+
+Fixes since v2.43
+-----------------
+
+ * The way CI testing used "prove" could lead to running the test
+   suite twice needlessly, which has been corrected.
+
+ * Update ref-related tests.
+
+ * "git format-patch --encode-email-headers" ignored the option when
+   preparing the cover letter, which has been corrected.
+
+ * Newer versions of Getopt::Long started giving warnings against our
+   (ab)use of it in "git send-email".  Bump the minimum version
+   requirement for Perl to 5.8.1 (from September 2002) to allow
+   simplifying our implementation.
+
+ * Earlier we stopped relying on commit-graph that (still) records
+   information about commits that are lost from the object store,
+   which has negative performance implications.  The default has been
+   flipped to disable this pessimization.
+
+ * Stale URLs have been updated to their current counterparts (or
+   archive.org) and HTTP links are replaced with working HTTPS links.
+
+ * trace2 streams used to record the URLs that potentially embed
+   authentication material, which has been corrected.
+
+ * The sample pre-commit hook that tries to catch introduction of new
+   paths that use potentially non-portable characters did not notice
+   an existing path getting renamed to such a problematic path, when
+   rename detection was enabled.
+
+ * The command line parser for the "log" family of commands was too
+   loose when parsing certain numbers, e.g., silently ignoring the
+   extra 'q' in "git log -n 1q" without complaining, which has been
+   tightened up.
+
+ * "git $cmd --end-of-options --rev -- --path" for some $cmd failed
+   to interpret "--rev" as a rev, and "--path" as a path.  This was
+   fixed for many programs like "reset" and "checkout".
+
+ * "git bisect reset" has been taught to clean up state files and refs
+   even when BISECT_START file is gone.
+
+ * Some codepaths did not correctly parse configuration variables
+   specified with valueless "true", which has been corrected.
+
+ * Code clean-up for sanity checking of command line options for "git
+   show-ref".
+
+ * The code to parse the From e-mail header has been updated to avoid
+   recursion.
+
+ * "git fetch --atomic" issued an unnecessary empty error message,
+   which has been corrected.
+
+ * Command line completion script (in contrib/) learned to work better
+   with the reftable backend.
+
+ * "git status" is taught to show both the branch being bisected and
+   being rebased when both are in effect at the same time.
+
+ * "git archive --list extra garbage" silently ignored excess command
+   line parameters, which has been corrected.
+
+ * "git sparse-checkout set" added default patterns even when the
+   patterns are being fed from the standard input, which has been
+   corrected.
+
+ * "git sparse-checkout (add|set) --[no-]cone --end-of-options" did
+   not handle "--end-of-options" correctly after a recent update.
+
+ * Unlike other environment variables that took the usual
+   true/false/yes/no as well as 0/1, GIT_FLUSH only understood 0/1,
+   which has been corrected.
+
+ * Clearing in-core repository (happens during e.g., "git fetch
+   --recurse-submodules" with commit graph enabled) made in-core
+   commit object in an inconsistent state by discarding the necessary
+   data from commit-graph too early, which has been corrected.
+
+ * Update to a new feature recently added, "git show-ref --exists".
+
+ * oss-fuzz tests are built and run in CI.
+   (merge c4a9cf1df3 js/oss-fuzz-build-in-ci later to maint).
+
+ * Rename detection logic ignored the final line of a file if it is an
+   incomplete line.
+
+ * GitHub CI update.
+   (merge 0188b2c8e0 pb/ci-github-skip-logs-for-broken-tests later to maint).
+
+ * "git diff --no-rename A B" did not disable rename detection but did
+   not trigger an error from the command line parser.
+
+ * "git archive --remote=<remote>" learned to talk over the smart
+   http (aka stateless) transport.
+   (merge 176cd68634 jx/remote-archive-over-smart-http later to maint).
+
+ * Fetching via protocol v0 over Smart HTTP transport sometimes failed
+   to correctly auto-follow tags.
+   (merge fba732c462 jk/fetch-auto-tag-following-fix later to maint).
+
+ * The documentation for the --exclude-per-directory option marked it
+   as deprecated, which confused readers into thinking there may be a
+   plan to remove it in the future, which was not our intention.
+   (merge 0009542cab jc/ls-files-doc-update later to maint).
+
+ * "git diff --no-index file1 file2" segfaulted while invoking the
+   external diff driver, which has been corrected.
+
+ * Rewrite //-comments to /* comments */ in files whose comments
+   prevalently use the latter.
+
+ * Cirrus CI jobs started breaking because we specified version of
+   FreeBSD that is no longer available, which has been corrected.
+   (merge 81fffb66d3 cb/use-freebsd-13-2-at-cirrus-ci later to maint).
+
+ * A caller called index_file_exists() that takes a string expressed
+   as <ptr, length> with a wrong length, which has been corrected.
+   (merge 156e28b36d jh/sparse-index-expand-to-path-fix later to maint).
+
+ * A failed "git tag -s" did not necessarily result in an error
+   depending on the crypto backend, which has been corrected.
+
+ * "git stash" sometimes was silent even when it failed due to
+   unwritable index file, which has been corrected.
+
+ * "git show-ref --verify" did not show things like "CHERRY_PICK_HEAD",
+   which has been corrected.
+
+ * Recent conversion to allow more than 0/1 in GIT_FLUSH broke the
+   mechanism by flipping what yes/no means by mistake, which has been
+   corrected.
+
+ * The sequencer machinery does not use the ref API and instead
+   records names of certain objects it needs for its correct operation
+   in temporary files, which makes these objects susceptible to loss
+   by garbage collection.  These temporary files have been added as
+   starting points for reachability analysis to fix this.
+   (merge bc7f5db896 pw/gc-during-rebase later to maint).
+
+ * "git cherry-pick" invoked during "git rebase -i" session lost
+   the authorship information, which has been corrected.
+   (merge e4301f73ff vn/rebase-with-cherry-pick-authorship later to maint).
+
+ * The code paths that call repo_read_object_file() have been
+   tightened to react to errors.
+   (merge 568459bf5e js/check-null-from-read-object-file later to maint).
+
+ * Other code cleanup, docfix, build fix, etc.
+   (merge 5aea3955bc rj/clarify-branch-doc-m later to maint).
+   (merge 9cce3be2df bk/bisect-doc-fix later to maint).
+   (merge 8430b438f6 vd/fsck-submodule-url-test later to maint).
+   (merge 3cb4384683 jc/t0091-with-unknown-git later to maint).
+   (merge 020456cb74 rs/receive-pack-remove-find-header later to maint).
+   (merge bc47139f4f la/trailer-cleanups later to maint).
diff --git a/Documentation/RelNotes/2.44.1.txt b/Documentation/RelNotes/2.44.1.txt
new file mode 100644
index 0000000..b5135c3
--- /dev/null
+++ b/Documentation/RelNotes/2.44.1.txt
@@ -0,0 +1,8 @@
+Git v2.44.1 Release Notes
+=========================
+
+This release merges up the fix that appears in v2.39.4, v2.40.2,
+v2.41.1, v2.42.2 and v2.43.4 to address the security issues
+CVE-2024-32002, CVE-2024-32004, CVE-2024-32020, CVE-2024-32021
+and CVE-2024-32465; see the release notes for these versions
+for details.
diff --git a/Documentation/RelNotes/2.44.2.txt b/Documentation/RelNotes/2.44.2.txt
new file mode 100644
index 0000000..76700f0
--- /dev/null
+++ b/Documentation/RelNotes/2.44.2.txt
@@ -0,0 +1,26 @@
+Git v2.44.2 Release Notes
+=========================
+
+In preparing security fixes for four CVEs, we made overly aggressive
+"defense in depth" changes that broke legitimate use cases like 'git
+lfs' and 'git annex.'  This release is to revert these misguided, if
+well-intentioned, changes that were shipped in 2.44.1 and were not
+direct security fixes.
+
+Jeff King (5):
+      send-email: drop FakeTerm hack
+      send-email: avoid creating more than one Term::ReadLine object
+      ci: drop mention of BREW_INSTALL_PACKAGES variable
+      ci: avoid bare "gcc" for osx-gcc job
+      ci: stop installing "gcc-13" for osx-gcc
+
+Johannes Schindelin (6):
+      hook: plug a new memory leak
+      init: use the correct path of the templates directory again
+      Revert "core.hooksPath: add some protection while cloning"
+      tests: verify that `clone -c core.hooksPath=/dev/null` works again
+      clone: drop the protections where hooks aren't run
+      Revert "Add a helper function to compare file contents"
+
+Junio C Hamano (1):
+      Revert "fsck: warn about symlink pointing inside a gitdir"
diff --git a/Documentation/RelNotes/2.45.0.txt b/Documentation/RelNotes/2.45.0.txt
new file mode 100644
index 0000000..fec1936
--- /dev/null
+++ b/Documentation/RelNotes/2.45.0.txt
@@ -0,0 +1,476 @@
+Git v2.45 Release Notes
+=======================
+
+Backward Compatibility Notes
+
+UI, Workflows & Features
+
+ * Integrate the reftable code into the refs framework as a backend.
+   With "git init --ref-format=reftable", hopefully it would be a lot
+   more efficient to manage a repository with many references.
+
+ * "git checkout -p" and friends learned that that "@" is a synonym
+   for "HEAD".
+
+ * Variants of vimdiff learned to honor mergetool.<variant>.layout
+   settings.
+
+ * "git reflog" learned a "list" subcommand that enumerates known reflogs.
+
+ * When a merge conflicted at a submodule, merge-ort backend used to
+   unconditionally give a lengthy message to suggest how to resolve
+   it.  Now the message can be squelched as an advice message.
+
+ * "git for-each-ref" learned "--include-root-refs" option to show
+   even the stuff outside the 'refs/' hierarchy.
+
+ * "git rev-list --missing=print" has learned to optionally take
+   "--allow-missing-tips", which allows the objects at the starting
+   points to be missing.
+
+ * "git merge-tree" has learned that the three trees involved in the
+   3-way merge only need to be trees, not necessarily commits.
+
+ * "git log --merge" learned to pay attention to CHERRY_PICK_HEAD and
+   other kinds of *_HEAD pseudorefs.
+
+ * Platform specific tweaks for OS/390 has been added to
+   config.mak.uname.
+
+ * Users with safe.bareRepository=explicit can still work from within
+   $GIT_DIR of a seconary worktree (which resides at .git/worktrees/$name/)
+   of the primary worktree without explicitly specifying the $GIT_DIR
+   environment variable or the --git-dir=<path> option.
+
+ * The output format for dates "iso-strict" has been tweaked to show
+   a time in the Zulu timezone with "Z" suffix, instead of "+00:00".
+
+ * "git diff" and friends learned two extra configuration variables,
+   diff.srcPrefix and diff.dstPrefix.
+
+ * The status.showUntrackedFiles configuration variable had a name
+   that tempts users to set a Boolean value expressed in our usual
+   "false", "off", and "0", but it only took "no".  This has been
+   corrected so "true" and its synonyms are taken as "normal", while
+   "false" and its synonyms are taken as "no".
+
+ * Remove an ancient and not well maintained Hg-to-git migration
+   script from contrib/.
+
+ * Hints that suggest what to do after resolving conflicts can now be
+   squelched by disabling advice.mergeConflict.
+
+ * Allow git-cherry-pick(1) to automatically drop redundant commits via
+   a new `--empty` option, similar to the `--empty` options for
+   git-rebase(1) and git-am(1). Includes a soft deprecation of
+   `--keep-redundant-commits` as well as some related docs changes and
+   sequencer code cleanup.
+
+ * "git config" learned "--comment=<message>" option to leave a
+   comment immediately after the "variable = value" on the same line
+   in the configuration file.
+
+ * core.commentChar used to be limited to a single byte, but has been
+   updated to allow an arbitrary multi-byte sequence.
+
+ * "git add -p" and other "interactive hunk selection" UI has learned to
+   skip showing the hunk immediately after it has already been shown, and
+   an additional action to explicitly ask to reshow the current hunk.
+
+ * "git pack-refs" learned the "--auto" option, which defers the decision of
+   whether and how to pack to the ref backend. This is used by the reftable
+   backend to avoid repacking of an already-optimal ref database. The new mode
+   is triggered from "git gc --auto".
+
+ * "git add -u <pathspec>" and "git commit [-i] <pathspec>" did not
+   diagnose a pathspec element that did not match any files in certain
+   situations, unlike "git add <pathspec>" did.
+
+ * The userdiff patterns for C# has been updated.
+
+ * Git writes a "waiting for your editor" message on an incomplete
+   line after launching an editor, and then append another error
+   message on the same line if the editor errors out.  It now clears
+   the "waiting for..." line before giving the error message.
+
+ * The filename used for rejected hunks "git apply --reject" creates
+   was limited to PATH_MAX, which has been lifted.
+
+ * When "git bisect" reports the commit it determined to be the
+   culprit, we used to show it in a format that does not honor common
+   UI tweaks, like log.date and log.decorate.  The code has been
+   taught to use "git show" to follow more customizations.
+
+
+Performance, Internal Implementation, Development Support etc.
+
+ * The code to iterate over refs with the reftable backend has seen
+   some optimization.
+
+ * More tests that are marked as "ref-files only" have been updated to
+   improve test coverage of reftable backend.
+
+ * Some parts of command line completion script (in contrib/) have
+   been micro-optimized.
+
+ * The way placeholders are to be marked-up in documentation have been
+   specified; use "_<placeholder>_" to typeset the word inside a pair
+   of <angle-brackets> emphasized.
+
+ * "git --no-lazy-fetch cmd" allows to run "cmd" while disabling lazy
+   fetching of objects from the promisor remote, which may be handy
+   for debugging.
+
+ * The implementation in "git clean" that makes "-n" and "-i" ignore
+   clean.requireForce has been simplified, together with the
+   documentation.
+
+ * Uses of xwrite() helper have been audited and updated for better
+   error checking and simpler code.
+
+ * Some trace2 events that lacked def_param have learned to show it,
+   enriching the output.
+
+ * The parse-options code that deals with abbreviated long option
+   names have been cleaned up.
+
+ * The code in reftable backend that creates new table files works
+   better with the tempfile framework to avoid leaving cruft after a
+   failure.
+
+ * The reftable code has its own custom binary search function whose
+   comparison callback has an unusual interface, which caused the
+   binary search to degenerate into a linear search, which has been
+   corrected.
+
+ * The code to iterate over reflogs in the reftable has been optimized
+   to reduce memory allocation and deallocation.
+
+ * Work to support a repository that work with both SHA-1 and SHA-256
+   hash algorithms has started.
+
+ * A new fuzz target that exercises config parsing code has been
+   added.
+
+ * Fix the way recently added tests interpolate variables defined
+   outside them, and document the best practice to help future
+   developers.
+
+ * Introduce an experimental protocol for contributors to propose the
+   topic description to be used in the "What's cooking" report, the
+   merge commit message for the topic, and in the release notes and
+   document it in the SubmittingPatches document.
+
+ * The t/README file now gives a hint on running individual tests in
+   the "t/" directory with "make t<num>-*.sh t<num>-*.sh".
+   (merge 8d383806fc pb/test-scripts-are-build-targets later to maint).
+
+ * The "hint:" messages given by the advice mechanism, when given a
+   message with a blank line, left a line with trailing whitespace,
+   which has been cleansed.
+
+ * Documentation rules has been explicitly described how to mark-up
+   literal parts and a few manual pages have been updated as examples.
+
+ * The .editorconfig file has been taught that a Makefile uses HT
+   indentation.
+
+ * t-prio-queue test has been cleaned up by using C99 compound
+   literals; this is meant to also serve as a weather-balloon to smoke
+   out folks with compilers who have trouble compiling code that uses
+   the feature.
+
+ * Windows binary used to decide the use of unix-domain socket at
+   build time, but it learned to make the decision at runtime instead.
+
+ * The "shared repository" test in the t0610 reftable test failed
+   under restrictive umask setting (e.g. 007), which has been
+   corrected.
+
+ * Document and apply workaround for a buggy version of dash that
+   mishandles "local var=val" construct.
+
+ * The codepaths that reach date_mode_from_type() have been updated to
+   pass "struct date_mode" by value to make them thread safe.
+
+ * The strategy to compact multiple tables of reftables after many
+   operations accumulate many entries has been improved to avoid
+   accumulating too many tables uncollected.
+
+ * The code to iterate over reftable blocks has seen some optimization
+   to reduce memory allocation and deallocation.
+
+ * The way "git fast-import" handles paths described in its input has
+   been tightened up and more clearly documented.
+
+ * The cvsimport tests required that the platform understands
+   traditional timezone notations like CST6CDT, which has been
+   updated to work on those systems as long as they understand
+   POSIX notation with explicit tz transition dates.
+
+ * The code to format trailers have been cleaned up.
+
+
+Fixes since v2.44
+-----------------
+
+ * "git apply" on a filesystem without filemode support have learned
+   to take a hint from what is in the index for the path, even when
+   not working with the "--index" or "--cached" option, when checking
+   the executable bit match what is required by the preimage in the
+   patch.
+   (merge 45b625142d cp/apply-core-filemode later to maint).
+
+ * "git column" has been taught to reject negative padding value, as
+   it would lead to nonsense behaviour including division by zero.
+   (merge 76fb807faa kh/column-reject-negative-padding later to maint).
+
+ * "git am --help" now tells readers what actions are available in
+   "git am --whitespace=<action>", in addition to saying that the
+   option is passed through to the underlying "git apply".
+   (merge a171dac734 jc/am-whitespace-doc later to maint).
+
+ * "git tag --column" failed to check the exit status of its "git
+   column" invocation, which has been corrected.
+   (merge 92e66478fc rj/tag-column-fix later to maint).
+
+ * Credential helper based on libsecret (in contrib/) has been updated
+   to handle an empty password correctly.
+   (merge 8f1f2023b7 mh/libsecret-empty-password-fix later to maint).
+
+ * "git difftool --dir-diff" learned to honor the "--trust-exit-code"
+   option; it used to always exit with 0 and signalled success.
+   (merge eb84c8b6ce ps/difftool-dir-diff-exit-code later to maint).
+
+ * The code incorrectly attempted to use textconv cache when asked,
+   even when we are not running in a repository, which has been
+   corrected.
+   (merge affe355fe7 jk/textconv-cache-outside-repo-fix later to maint).
+
+ * Remove an empty file that shouldn't have been added in the first
+   place.
+   (merge 4f66942215 js/remove-cruft-files later to maint).
+
+ * The logic to access reflog entries by date and number had ugly
+   corner cases at the boundaries, which have been cleaned up.
+   (merge 5edd126720 jk/reflog-special-cases-fix later to maint).
+
+ * An error message from "git upload-pack", which responds to "git
+   fetch" requests, had a trailing NUL in it, which has been
+   corrected.
+   (merge 3f4c7a0805 sg/upload-pack-error-message-fix later to maint).
+
+ * Clarify wording in the CodingGuidelines that requires <git-compat-util.h>
+   to be the first header file.
+   (merge 4e89f0e07c jc/doc-compat-util later to maint).
+
+ * "git commit -v --cleanup=scissors" used to add the scissors line
+   twice in the log message buffer, which has been corrected.
+   (merge e90cc075cc jt/commit-redundant-scissors-fix later to maint).
+
+ * A custom remote helper no longer cannot access the newly created
+   repository during "git clone", which is a regression in Git 2.44.
+   This has been corrected.
+   (merge 199f44cb2e ps/remote-helper-repo-initialization-fix later to maint).
+
+ * Various parts of upload-pack have been updated to bound the resource
+   consumption relative to the size of the repository to protect from
+   abusive clients.
+   (merge 6cd05e768b jk/upload-pack-bounded-resources later to maint).
+
+ * The upload-pack program, when talking over v2, accepted the
+   packfile-uris protocol extension from the client, even if it did
+   not advertise the capability, which has been corrected.
+   (merge a922bfa3b5 jk/upload-pack-v2-capability-cleanup later to maint).
+
+ * Make sure failure return from merge_bases_many() is properly caught.
+   (merge 25fd20eb44 js/merge-base-with-missing-commit later to maint).
+
+ * FSMonitor client code was confused when FSEvents were given in a
+   different case on a case-insensitive filesystem, which has been
+   corrected.
+   (merge 29c139ce78 jh/fsmonitor-icase-corner-case-fix later to maint).
+
+ * The "core.commentChar" configuration variable only allows an ASCII
+   character, which was not clearly documented, which has been
+   corrected.
+   (merge fb7c556f58 kh/doc-commentchar-is-a-byte later to maint).
+
+ * With release 2.44 we got rid of all uses of test_i18ngrep and there
+   is no in-flight topic that adds a new use of it.  Make a call to
+   test_i18ngrep a hard failure, so that we can remove it at the end
+   of this release cycle.
+   (merge 381a83dfa3 jc/test-i18ngrep later to maint).
+
+ * The command line completion script (in contrib/) learned to
+   complete "git reflog" better.
+   (merge 1284f9cc11 rj/complete-reflog later to maint).
+
+ * The logic to complete the command line arguments to "git worktree"
+   subcommand (in contrib/) has been updated to correctly honor things
+   like "git -C dir" etc.
+   (merge 3574816d98 rj/complete-worktree-paths-fix later to maint).
+
+ * When git refuses to create a branch because the proposed branch
+   name is not a valid refname, an advice message is given to refer
+   the user to exact naming rules.
+   (merge 8fbd903e58 kh/branch-ref-syntax-advice later to maint).
+
+ * Code simplification by getting rid of code that sets an environment
+   variable that is no longer used.
+   (merge 72a8d3f027 pw/rebase-i-ignore-cherry-pick-help-environment later to maint).
+
+ * The code to find the effective end of log messages can fall into an
+   endless loop, which has been corrected.
+   (merge 2541cba2d6 fs/find-end-of-log-message-fix later to maint).
+
+ * Mark-up used in the documentation has been improved for
+   consistency.
+   (merge 45d5ed3e50 ja/doc-markup-fixes later to maint).
+
+ * The status.showUntrackedFiles configuration variable was
+   incorrectly documented to accept "false", which has been corrected.
+
+ * Leaks from "git restore" have been plugged.
+   (merge 2f64da0790 rj/restore-plug-leaks later to maint).
+
+ * "git bugreport --no-suffix" was not supported and instead
+   segfaulted, which has been corrected.
+   (merge b3b57c69da js/bugreport-no-suffix-fix later to maint).
+
+ * The documentation for "%(trailers[:options])" placeholder in the
+   "--pretty" option of commands in the "git log" family has been
+   updated.
+   (merge bff85a338c bl/doc-key-val-sep-fix later to maint).
+
+ * "git checkout --conflict=bad" reported a bad conflictStyle as if it
+   were given to a configuration variable; it has been corrected to
+   report that the command line option is bad.
+   (merge 5a99c1ac1a pw/checkout-conflict-errorfix later to maint).
+
+ * Code clean-up in the "git log" machinery that implements custom log
+   message formatting.
+   (merge 1c10b8e5b0 jk/pretty-subject-cleanup later to maint).
+
+ * "git config" corrupted literal HT characters written in the
+   configuration file as part of a value, which has been corrected.
+   (merge e6895c3f97 ds/config-internal-whitespace-fix later to maint).
+
+ * A unit test for reftable code tried to enumerate all files in a
+   directory after reftable operations and expected to see nothing but
+   the files it wanted to leave there, but was fooled by .nfs* cruft
+   files left, which has been corrected.
+   (merge 0068aa7946 ps/reftable-unit-test-nfs-workaround later to maint).
+
+ * The implementation and documentation of "object-format" option
+   exchange between the Git itself and its remote helpers did not
+   quite match, which has been corrected.
+
+ * The "--pretty=<shortHand>" option of the commands in the "git log"
+   family, defined as "[pretty] shortHand = <expansion>" should have
+   been looked up case insensitively, but was not, which has been
+   corrected.
+   (merge f999d5188b bl/pretty-shorthand-config-fix later to maint).
+
+ * "git apply" failed to extract the filename the patch applied to,
+   when the change was about an empty file created in or deleted from
+   a directory whose name ends with a SP, which has been corrected.
+   (merge 776ffd1a30 jc/apply-parse-diff-git-header-names-fix later to maint).
+
+ * Update a more recent tutorial doc.
+   (merge 95ab557b4b dg/myfirstobjectwalk-updates later to maint).
+
+ * The test script had an incomplete and ineffective attempt to avoid
+   clobbering the testing user's real crontab (and its equivalents),
+   which has been completed.
+   (merge 73cb87773b es/test-cron-safety later to maint).
+
+ * Use advice_if_enabled() API to rewrite a simple pattern to
+   call advise() after checking advice_enabled().
+   (merge 6412d01527 rj/use-adv-if-enabled later to maint).
+
+ * Another "set -u" fix for the bash prompt (in contrib/) script.
+   (merge d7805bc743 vs/complete-with-set-u-fix later to maint).
+
+ * "git checkout/switch --detach foo", after switching to the detached
+   HEAD state, gave the tracking information for the 'foo' branch,
+   which was pointless.
+
+ * "git apply" has been updated to lift the hardcoded pathname length
+   limit, which in turn allowed a mksnpath() function that is no
+   longer used.
+   (merge 708f7e0590 rs/apply-lift-path-length-limit later to maint).
+
+ * A file descriptor leak in an error codepath, used when "git apply
+   --reject" fails to create the *.rej file, has been corrected.
+   (merge 2b1f456adf rs/apply-reject-fd-leakfix later to maint).
+
+ * A config parser callback function fell through instead of returning
+   after recognising and processing a variable, wasting cycles, which
+   has been corrected.
+   (merge a816ccd642 ds/fetch-config-parse-microfix later to maint).
+
+ * Fix was added to work around a regression in libcURL 8.7.0 (which has
+   already been fixed in their tip of the tree).
+   (merge 92a209bf24 jk/libcurl-8.7-regression-workaround later to maint).
+
+ * The variable that holds the value read from the core.excludefile
+   configuration variable used to leak, which has been corrected.
+   (merge 0e0fefb29f jc/unleak-core-excludesfile later to maint).
+
+ * vreportf(), which is used by error() and friends, has been taught
+   to give the error message printf-format string when its vsnprintf()
+   call fails, instead of showing nothing useful to identify the
+   nature of the error.
+   (merge c63adab961 rs/usage-fallback-to-show-message-format later to maint).
+
+ * Adjust to an upcoming changes to GNU make that breaks our Makefiles.
+   (merge 227b8fd902 tb/make-indent-conditional-with-non-spaces later to maint).
+
+ * Git 2.44 introduced a regression that makes the updated code to
+   barf in repositories with multi-pack index written by older
+   versions of Git, which has been corrected.
+
+ * When .git/rr-cache/ rerere database gets corrupted or rerere is fed to
+   work on a file with conflicted hunks resolved incompletely, the rerere
+   machinery got confused and segfaulted, which has been corrected.
+   (merge 167395bb47 mr/rerere-crash-fix later to maint).
+
+ * The "receive-pack" program (which responds to "git push") was not
+   converted to run "git maintenance --auto" when other codepaths that
+   used to run "git gc --auto" were updated, which has been corrected.
+   (merge 7bf3057d9c ps/run-auto-maintenance-in-receive-pack later to maint).
+
+ * Other code cleanup, docfix, build fix, etc.
+   (merge f0e578c69c rs/use-xstrncmpz later to maint).
+   (merge 83e6eb7d7a ba/credential-test-clean-fix later to maint).
+   (merge 64562d784d jb/doc-interactive-singlekey-do-not-need-perl later to maint).
+   (merge c431a235e2 cp/t9146-use-test-path-helpers later to maint).
+   (merge 82d75402d5 ds/doc-send-email-capitalization later to maint).
+   (merge 41bff66e35 jc/doc-add-placeholder-fix later to maint).
+   (merge 6835f0efe9 jw/remote-doc-typofix later to maint).
+   (merge 244001aa20 hs/rebase-not-in-progress later to maint).
+   (merge 2ca6c07db2 jc/no-include-of-compat-util-from-headers later to maint).
+   (merge 87bd7fbb9c rs/fetch-simplify-with-starts-with later to maint).
+   (merge f39addd0d9 rs/name-rev-with-mempool later to maint).
+   (merge 9a97b43e03 rs/submodule-prefix-simplify later to maint).
+   (merge 40b8076462 ak/rebase-autosquash later to maint).
+   (merge 3223204456 eg/add-uflags later to maint).
+   (merge 5f78d52dce es/config-doc-sort-sections later to maint).
+   (merge 781fb7b4c2 as/option-names-in-messages later to maint).
+   (merge 51d41dc243 jk/doc-remote-helpers-markup-fix later to maint).
+   (merge e1aaf309db pb/ci-win-artifact-names-fix later to maint).
+   (merge ad538c61da jc/index-pack-fsck-levels later to maint).
+   (merge 67471bc704 ja/doc-formatting-fix later to maint).
+   (merge 86f9ce7dd6 bl/doc-config-fixes later to maint).
+   (merge 0d527842b7 az/grep-group-error-message-update later to maint).
+   (merge 7c43bdf07b rs/strbuf-expand-bad-format later to maint).
+   (merge 8b68b48d5c ds/typofix-core-config-doc later to maint).
+   (merge 39bb692152 rs/imap-send-use-xsnprintf later to maint).
+   (merge 8d320cec60 jc/t2104-style-fixes later to maint).
+   (merge b4454d5a7b pw/t3428-cleanup later to maint).
+   (merge 84a7c33a4b pf/commitish-committish later to maint).
+   (merge 8882ee9d68 la/mailmap-entry later to maint).
+   (merge 44bdba2fa6 rs/no-openssl-compilation-fix-on-macos later to maint).
+   (merge f412d72c19 yb/replay-doc-linkfix later to maint).
+   (merge 5da40be8d7 xx/rfc2822-date-format-in-doc later to maint).
diff --git a/Documentation/RelNotes/2.45.1.txt b/Documentation/RelNotes/2.45.1.txt
new file mode 100644
index 0000000..3b0d60c
--- /dev/null
+++ b/Documentation/RelNotes/2.45.1.txt
@@ -0,0 +1,8 @@
+Git v2.45.1 Release Notes
+=========================
+
+This release merges up the fix that appears in v2.39.4,
+v2.40.2, v2.41.1, v2.42.2, v2.43.4 and v2.44.1 to address the
+security issues CVE-2024-32002, CVE-2024-32004, CVE-2024-32020,
+CVE-2024-32021 and CVE-2024-32465; see the release notes for
+these versions for details.
diff --git a/Documentation/RelNotes/2.45.2.txt b/Documentation/RelNotes/2.45.2.txt
new file mode 100644
index 0000000..13429e6
--- /dev/null
+++ b/Documentation/RelNotes/2.45.2.txt
@@ -0,0 +1,26 @@
+Git v2.45.2 Release Notes
+=========================
+
+In preparing security fixes for four CVEs, we made overly aggressive
+"defense in depth" changes that broke legitimate use cases like 'git
+lfs' and 'git annex.'  This release is to revert these misguided, if
+well-intentioned, changes that were shipped in 2.45.1 and were not
+direct security fixes.
+
+Jeff King (5):
+      send-email: drop FakeTerm hack
+      send-email: avoid creating more than one Term::ReadLine object
+      ci: drop mention of BREW_INSTALL_PACKAGES variable
+      ci: avoid bare "gcc" for osx-gcc job
+      ci: stop installing "gcc-13" for osx-gcc
+
+Johannes Schindelin (6):
+      hook: plug a new memory leak
+      init: use the correct path of the templates directory again
+      Revert "core.hooksPath: add some protection while cloning"
+      tests: verify that `clone -c core.hooksPath=/dev/null` works again
+      clone: drop the protections where hooks aren't run
+      Revert "Add a helper function to compare file contents"
+
+Junio C Hamano (1):
+      Revert "fsck: warn about symlink pointing inside a gitdir"
diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches
index e734a3f..625bdd0 100644
--- a/Documentation/SubmittingPatches
+++ b/Documentation/SubmittingPatches
@@ -415,10 +415,12 @@
 your code.  For this reason, each patch should be submitted
 "inline" in a separate message.
 
-Multiple related patches should be grouped into their own e-mail
-thread to help readers find all parts of the series.  To that end,
-send them as replies to either an additional "cover letter" message
-(see below), the first patch, or the respective preceding patch.
+All subsequent versions of a patch series and other related patches should be
+grouped into their own e-mail thread to help readers find all parts of the
+series.  To that end, send them as replies to either an additional "cover
+letter" message (see below), the first patch, or the respective preceding patch.
+Here is a link:MyFirstContribution.html#v2-git-send-email[step-by-step guide] on
+how to submit updated versions of a patch series.
 
 If your log message (including your name on the
 `Signed-off-by` trailer) is not writable in ASCII, make sure that
@@ -459,6 +461,18 @@
 Git-notes and inserted automatically following the three-dash
 line via `git format-patch --notes`.
 
+[[the-topic-summary]]
+*This is EXPERIMENTAL*.
+
+When sending a topic, you can propose a one-paragraph summary that
+should appear in the "What's cooking" report when it is picked up to
+explain the topic.  If you choose to do so, please write a 2-5 line
+paragraph that will fit well in our release notes (see many bulleted
+entries in the Documentation/RelNotes/* files for examples), and make
+it the first paragraph of the cover letter.  For a single-patch
+series, use the space between the three-dash line and the diffstat, as
+described earlier.
+
 [[attachment]]
 Do not attach the patch as a MIME attachment, compressed or not.
 Do not let your e-mail client send quoted-printable.  Do not let
@@ -519,9 +533,9 @@
 Some parts of the system have dedicated maintainers with their own
 repositories.
 
-- `git-gui/` comes from git-gui project, maintained by Pratyush Yadav:
+- `git-gui/` comes from git-gui project, maintained by Johannes Sixt:
 
-	https://github.com/prati0100/git-gui.git
+        https://github.com/j6t/git-gui
 
 - `gitk-git/` comes from Paul Mackerras's gitk project:
 
@@ -536,6 +550,13 @@
 
 Patches to these parts should be based on their trees.
 
+- The "Git documentation translations" project, led by Jean-Noël
+  Avila, translates our documentation pages.  Their work products are
+  maintained separately from this project, not as part of our tree:
+
+	https://github.com/jnavila/git-manpages-l10n/
+
+
 [[patch-flow]]
 == An ideal patch flow
 
diff --git a/Documentation/config.txt b/Documentation/config.txt
index e3a74dd..70b448b 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -22,9 +22,10 @@
 Syntax
 ~~~~~~
 
-The syntax is fairly flexible and permissive; whitespaces are mostly
-ignored.  The '#' and ';' characters begin comments to the end of line,
-blank lines are ignored.
+The syntax is fairly flexible and permissive.  Whitespace characters,
+which in this context are the space character (SP) and the horizontal
+tabulation (HT), are mostly ignored.  The '#' and ';' characters begin
+comments to the end of line.  Blank lines are ignored.
 
 The file consists of sections and variables.  A section begins with
 the name of the section in square brackets and continues until the next
@@ -63,16 +64,17 @@
 The variable names are case-insensitive, allow only alphanumeric characters
 and `-`, and must start with an alphabetic character.
 
-A line that defines a value can be continued to the next line by
-ending it with a `\`; the backslash and the end-of-line are
-stripped.  Leading whitespaces after 'name =', the remainder of the
-line after the first comment character '#' or ';', and trailing
-whitespaces of the line are discarded unless they are enclosed in
-double quotes.  Internal whitespaces within the value are retained
-verbatim.
+Whitespace characters surrounding `name`, `=` and `value` are discarded.
+Internal whitespace characters within 'value' are retained verbatim.
+Comments starting with either `#` or `;` and extending to the end of line
+are discarded.  A line that defines a value can be continued to the next
+line by ending it with a backslash (`\`);  the backslash and the end-of-line
+characters are discarded.
 
-Inside double quotes, double quote `"` and backslash `\` characters
-must be escaped: use `\"` for `"` and `\\` for `\`.
+If `value` needs to contain leading or trailing whitespace characters,
+it must be enclosed in double quotation marks (`"`).  Inside double quotation
+marks, double quote (`"`) and backslash (`\`) characters must be escaped:
+use `\"` for `"` and `\\` for `\`.
 
 The following escape sequences (beside `\"` and `\\`) are recognized:
 `\n` for newline character (NL), `\t` for horizontal tabulation (HT, TAB)
@@ -369,20 +371,18 @@
 names do not conflict with those that are used by Git itself and
 other popular tools, and describe them in your documentation.
 
-include::config/advice.txt[]
-
-include::config/attr.txt[]
-
-include::config/core.txt[]
-
 include::config/add.txt[]
 
+include::config/advice.txt[]
+
 include::config/alias.txt[]
 
 include::config/am.txt[]
 
 include::config/apply.txt[]
 
+include::config/attr.txt[]
+
 include::config/blame.txt[]
 
 include::config/branch.txt[]
@@ -405,10 +405,12 @@
 
 include::config/commitgraph.txt[]
 
-include::config/credential.txt[]
-
 include::config/completion.txt[]
 
+include::config/core.txt[]
+
+include::config/credential.txt[]
+
 include::config/diff.txt[]
 
 include::config/difftool.txt[]
@@ -421,10 +423,10 @@
 
 include::config/fetch.txt[]
 
-include::config/format.txt[]
-
 include::config/filter.txt[]
 
+include::config/format.txt[]
+
 include::config/fsck.txt[]
 
 include::config/fsmonitor--daemon.txt[]
@@ -435,10 +437,10 @@
 
 include::config/gitweb.txt[]
 
-include::config/grep.txt[]
-
 include::config/gpg.txt[]
 
+include::config/grep.txt[]
+
 include::config/gui.txt[]
 
 include::config/guitool.txt[]
@@ -519,10 +521,10 @@
 
 include::config/ssh.txt[]
 
-include::config/status.txt[]
-
 include::config/stash.txt[]
 
+include::config/status.txt[]
+
 include::config/submodule.txt[]
 
 include::config/tag.txt[]
diff --git a/Documentation/config/advice.txt b/Documentation/config/advice.txt
index 4d7e5d8..0e35ae5 100644
--- a/Documentation/config/advice.txt
+++ b/Documentation/config/advice.txt
@@ -1,30 +1,65 @@
 advice.*::
 	These variables control various optional help messages designed to
-	aid new users. All 'advice.*' variables default to 'true', and you
-	can tell Git that you do not need help by setting these to 'false':
+	aid new users.  When left unconfigured, Git will give the message
+	alongside instructions on how to squelch it.  You can tell Git
+	that you do not need the help message by setting these to `false`:
 +
 --
+	addEmbeddedRepo::
+		Shown when the user accidentally adds one
+		git repo inside of another.
+	addEmptyPathspec::
+		Shown when the user runs `git add` without providing
+		the pathspec parameter.
+	addIgnoredFile::
+		Shown when the user attempts to add an ignored file to
+		the index.
+	amWorkDir::
+		Shown when linkgit:git-am[1] fails to apply a patch
+		file, to tell the user the location of the file.
 	ambiguousFetchRefspec::
-		Advice shown when a fetch refspec for multiple remotes maps to
+		Shown when a fetch refspec for multiple remotes maps to
 		the same remote-tracking branch namespace and causes branch
 		tracking set-up to fail.
+	checkoutAmbiguousRemoteBranchName::
+		Shown when the argument to
+		linkgit:git-checkout[1] and linkgit:git-switch[1]
+		ambiguously resolves to a
+		remote tracking branch on more than one remote in
+		situations where an unambiguous argument would have
+		otherwise caused a remote-tracking branch to be
+		checked out. See the `checkout.defaultRemote`
+		configuration variable for how to set a given remote
+		to be used by default in some situations where this
+		advice would be printed.
+	commitBeforeMerge::
+		Shown when linkgit:git-merge[1] refuses to
+		merge to avoid overwriting local changes.
+	detachedHead::
+		Shown when the user uses
+		linkgit:git-switch[1] or linkgit:git-checkout[1]
+		to move to the detached HEAD state, to tell the user how
+		to create a local branch after the fact.
+	diverging::
+		Shown when a fast-forward is not possible.
 	fetchShowForcedUpdates::
-		Advice shown when linkgit:git-fetch[1] takes a long time
+		Shown when linkgit:git-fetch[1] takes a long time
 		to calculate forced updates after ref updates, or to warn
 		that the check is disabled.
-	pushUpdateRejected::
-		Set this variable to 'false' if you want to disable
-		'pushNonFFCurrent', 'pushNonFFMatching', 'pushAlreadyExists',
-		'pushFetchFirst', 'pushNeedsForce', and 'pushRefNeedsUpdate'
-		simultaneously.
-	pushNonFFCurrent::
-		Advice shown when linkgit:git-push[1] fails due to a
-		non-fast-forward update to the current branch.
-	pushNonFFMatching::
-		Advice shown when you ran linkgit:git-push[1] and pushed
-		'matching refs' explicitly (i.e. you used ':', or
-		specified a refspec that isn't your current branch) and
-		it resulted in a non-fast-forward error.
+	forceDeleteBranch::
+		Shown when the user tries to delete a not fully merged
+		branch without the force option set.
+	ignoredHook::
+		Shown when a hook is ignored because the hook is not
+		set as executable.
+	implicitIdentity::
+		Shown when the user's information is guessed from the
+		system username and domain name, to tell the user how to
+		set their identity configuration.
+	mergeConflict::
+		Shown when various commands stop because of conflicts.
+	nestedTag::
+		Shown when a user attempts to recursively tag a tag object.
 	pushAlreadyExists::
 		Shown when linkgit:git-push[1] rejects an update that
 		does not qualify for fast-forwarding (e.g., a tag.)
@@ -37,17 +72,45 @@
 		tries to overwrite a remote ref that points at an
 		object that is not a commit-ish, or make the remote
 		ref point at an object that is not a commit-ish.
+	pushNonFFCurrent::
+		Shown when linkgit:git-push[1] fails due to a
+		non-fast-forward update to the current branch.
+	pushNonFFMatching::
+		Shown when the user ran linkgit:git-push[1] and pushed
+		"matching refs" explicitly (i.e. used `:`, or
+		specified a refspec that isn't the current branch) and
+		it resulted in a non-fast-forward error.
+	pushRefNeedsUpdate::
+		Shown when linkgit:git-push[1] rejects a forced update of
+		a branch when its remote-tracking ref has updates that we
+		do not have locally.
 	pushUnqualifiedRefname::
 		Shown when linkgit:git-push[1] gives up trying to
 		guess based on the source and destination refs what
 		remote ref namespace the source belongs in, but where
 		we can still suggest that the user push to either
-		refs/heads/* or refs/tags/* based on the type of the
+		`refs/heads/*` or `refs/tags/*` based on the type of the
 		source object.
-	pushRefNeedsUpdate::
-		Shown when linkgit:git-push[1] rejects a forced update of
-		a branch when its remote-tracking ref has updates that we
-		do not have locally.
+	pushUpdateRejected::
+		Set this variable to `false` if you want to disable
+		`pushNonFFCurrent`, `pushNonFFMatching`, `pushAlreadyExists`,
+		`pushFetchFirst`, `pushNeedsForce`, and `pushRefNeedsUpdate`
+		simultaneously.
+	refSyntax::
+		Shown when the user provides an illegal ref name, to
+		tell the user about the ref syntax documentation.
+	resetNoRefresh::
+		Shown when linkgit:git-reset[1] takes more than 2
+		seconds to refresh the index after reset, to tell the user
+		that they can use the `--no-refresh` option.
+	resolveConflict::
+		Shown by various commands when conflicts
+		prevent the operation from being performed.
+	rmHints::
+		Shown on failure in the output of linkgit:git-rm[1], to
+		give directions on how to proceed from the current state.
+	sequencerInUse::
+		Shown when a sequencer command is already in progress.
 	skippedCherryPicks::
 		Shown when linkgit:git-rebase[1] skips a commit that has already
 		been cherry-picked onto the upstream branch.
@@ -65,81 +128,30 @@
 		by linkgit:git-switch[1] or
 		linkgit:git-checkout[1] when switching branches.
 	statusUoption::
-		Advise to consider using the `-u` option to linkgit:git-status[1]
-		when the command takes more than 2 seconds to enumerate untracked
-		files.
-	commitBeforeMerge::
-		Advice shown when linkgit:git-merge[1] refuses to
-		merge to avoid overwriting local changes.
-	resetNoRefresh::
-		Advice to consider using the `--no-refresh` option to
-		linkgit:git-reset[1] when the command takes more than 2 seconds
-		to refresh the index after reset.
-	resolveConflict::
-		Advice shown by various commands when conflicts
-		prevent the operation from being performed.
-	sequencerInUse::
-		Advice shown when a sequencer command is already in progress.
-	implicitIdentity::
-		Advice on how to set your identity configuration when
-		your information is guessed from the system username and
-		domain name.
-	detachedHead::
-		Advice shown when you used
-		linkgit:git-switch[1] or linkgit:git-checkout[1]
-		to move to the detached HEAD state, to instruct how to
-		create a local branch after the fact.
-	suggestDetachingHead::
-		Advice shown when linkgit:git-switch[1] refuses to detach HEAD
-		without the explicit `--detach` option.
-	checkoutAmbiguousRemoteBranchName::
-		Advice shown when the argument to
-		linkgit:git-checkout[1] and linkgit:git-switch[1]
-		ambiguously resolves to a
-		remote tracking branch on more than one remote in
-		situations where an unambiguous argument would have
-		otherwise caused a remote-tracking branch to be
-		checked out. See the `checkout.defaultRemote`
-		configuration variable for how to set a given remote
-		to be used by default in some situations where this
-		advice would be printed.
-	amWorkDir::
-		Advice that shows the location of the patch file when
-		linkgit:git-am[1] fails to apply it.
-	rmHints::
-		In case of failure in the output of linkgit:git-rm[1],
-		show directions on how to proceed from the current state.
-	addEmbeddedRepo::
-		Advice on what to do when you've accidentally added one
-		git repo inside of another.
-	ignoredHook::
-		Advice shown if a hook is ignored because the hook is not
-		set as executable.
-	waitingForEditor::
-		Print a message to the terminal whenever Git is waiting for
-		editor input from the user.
-	nestedTag::
-		Advice shown if a user attempts to recursively tag a tag object.
+		Shown when linkgit:git-status[1] takes more than 2
+		seconds to enumerate untracked files, to tell the user that
+		they can use the `-u` option.
 	submoduleAlternateErrorStrategyDie::
-		Advice shown when a submodule.alternateErrorStrategy option
+		Shown when a submodule.alternateErrorStrategy option
 		configured to "die" causes a fatal error.
+	submoduleMergeConflict::
+		Advice shown when a non-trivial submodule merge conflict is
+		encountered.
 	submodulesNotUpdated::
-		Advice shown when a user runs a submodule command that fails
+		Shown when a user runs a submodule command that fails
 		because `git submodule update --init` was not run.
-	addIgnoredFile::
-		Advice shown if a user attempts to add an ignored file to
-		the index.
-	addEmptyPathspec::
-		Advice shown if a user runs the add command without providing
-		the pathspec parameter.
+	suggestDetachingHead::
+		Shown when linkgit:git-switch[1] refuses to detach HEAD
+		without the explicit `--detach` option.
 	updateSparsePath::
-		Advice shown when either linkgit:git-add[1] or linkgit:git-rm[1]
+		Shown when either linkgit:git-add[1] or linkgit:git-rm[1]
 		is asked to update index entries outside the current sparse
 		checkout.
-	diverging::
-		Advice shown when a fast-forward is not possible.
+	waitingForEditor::
+		Shown when Git is waiting for editor input. Relevant
+		when e.g. the editor is not launched inside the terminal.
 	worktreeAddOrphan::
-		Advice shown when a user tries to create a worktree from an
-		invalid reference, to instruct how to create a new unborn
+		Shown when the user tries to create a worktree from an
+		invalid reference, to tell the user how to create a new unborn
 		branch instead.
 --
diff --git a/Documentation/config/clean.txt b/Documentation/config/clean.txt
index f05b940..c0188ea 100644
--- a/Documentation/config/clean.txt
+++ b/Documentation/config/clean.txt
@@ -1,3 +1,3 @@
 clean.requireForce::
-	A boolean to make git-clean do nothing unless given -f,
-	-i, or -n.  Defaults to true.
+	A boolean to make git-clean refuse to delete files unless -f
+	is given. Defaults to true.
diff --git a/Documentation/config/clone.txt b/Documentation/config/clone.txt
index d037b57..0a10efd 100644
--- a/Documentation/config/clone.txt
+++ b/Documentation/config/clone.txt
@@ -1,13 +1,23 @@
-clone.defaultRemoteName::
+`clone.defaultRemoteName`::
 	The name of the remote to create when cloning a repository.  Defaults to
-	`origin`, and can be overridden by passing the `--origin` command-line
+	`origin`.
+ifdef::git-clone[]
+	It can be overridden by passing the `--origin` command-line
+	option.
+endif::[]
+ifndef::git-clone[]
+	It can be overridden by passing the `--origin` command-line
 	option to linkgit:git-clone[1].
+endif::[]
 
-clone.rejectShallow::
+`clone.rejectShallow`::
 	Reject cloning a repository if it is a shallow one; this can be overridden by
-	passing the `--reject-shallow` option on the command line. See linkgit:git-clone[1]
+	passing the `--reject-shallow` option on the command line.
+ifndef::git-clone[]
+	See linkgit:git-clone[1].
+endif::[]
 
-clone.filterSubmodules::
+`clone.filterSubmodules`::
 	If a partial clone filter is provided (see `--filter` in
 	linkgit:git-rev-list[1]) and `--recurse-submodules` is used, also apply
 	the filter to submodules.
diff --git a/Documentation/config/core.txt b/Documentation/config/core.txt
index 0e8c283..93d65e1 100644
--- a/Documentation/config/core.txt
+++ b/Documentation/config/core.txt
@@ -520,6 +520,7 @@
 	`GIT_EDITOR` is not set.  See linkgit:git-var[1].
 
 core.commentChar::
+core.commentString::
 	Commands such as `commit` and `tag` that let you edit
 	messages consider a line that begins with this character
 	commented, and removes them after the editor returns
@@ -527,6 +528,20 @@
 +
 If set to "auto", `git-commit` would select a character that is not
 the beginning character of any line in existing commit messages.
++
+Note that these two variables are aliases of each other, and in modern
+versions of Git you are free to use a string (e.g., `//` or `⁑⁕⁑`) with
+`commentChar`. Versions of Git prior to v2.45.0 will ignore
+`commentString` but will reject a value of `commentChar` that consists
+of more than a single ASCII byte. If you plan to use your config with
+older and newer versions of Git, you may want to specify both:
++
+    [core]
+    # single character for older versions
+    commentChar = "#"
+    # string for newer versions (which will override commentChar
+    # because it comes later in the file)
+    commentString = "//"
 
 core.filesRefLockTimeout::
 	The length of time, in milliseconds, to retry when trying to
@@ -688,7 +703,7 @@
 	will not overwrite existing objects.
 +
 On some file system/operating system combinations, this is unreliable.
-Set this config setting to 'rename' there; However, This will remove the
+Set this config setting to 'rename' there; however, this will remove the
 check that makes sure that existing object files will not get overwritten.
 
 core.notesRef::
diff --git a/Documentation/config/diff.txt b/Documentation/config/diff.txt
index bd5ae0c..5ce7b91 100644
--- a/Documentation/config/diff.txt
+++ b/Documentation/config/diff.txt
@@ -108,9 +108,15 @@
 `git diff --no-index a b`;;
 	compares two non-git things (1) and (2).
 
-diff.noprefix::
+diff.noPrefix::
 	If set, 'git diff' does not show any source or destination prefix.
 
+diff.srcPrefix::
+	If set, 'git diff' uses this source prefix. Defaults to "a/".
+
+diff.dstPrefix::
+	If set, 'git diff' uses this destination prefix. Defaults to "b/".
+
 diff.relative::
 	If set to 'true', 'git diff' does not show changes outside of the directory
 	and show pathnames relative to the current directory.
@@ -223,5 +229,5 @@
 
 diff.colorMovedWS::
 	When moved lines are colored using e.g. the `diff.colorMoved` setting,
-	this option controls the `<mode>` how spaces are treated
-	for details of valid modes see '--color-moved-ws' in linkgit:git-diff[1].
+	this option controls the `<mode>` how spaces are treated.
+	For details of valid modes see '--color-moved-ws' in linkgit:git-diff[1].
diff --git a/Documentation/config/extensions.txt b/Documentation/config/extensions.txt
index bccaec7..38dce3d 100644
--- a/Documentation/config/extensions.txt
+++ b/Documentation/config/extensions.txt
@@ -7,6 +7,29 @@
 linkgit:git-clone[1].  Trying to change it after initialization will not
 work and will produce hard-to-diagnose issues.
 
+extensions.compatObjectFormat::
+
+	Specify a compatitbility hash algorithm to use.  The acceptable values
+	are `sha1` and `sha256`.  The value specified must be different from the
+	value of extensions.objectFormat.  This allows client level
+	interoperability between git repositories whose objectFormat matches
+	this compatObjectFormat.  In particular when fully implemented the
+	pushes and pulls from a repository in whose objectFormat matches
+	compatObjectFormat.  As well as being able to use oids encoded in
+	compatObjectFormat in addition to oids encoded with objectFormat to
+	locally specify objects.
+
+extensions.refStorage::
+	Specify the ref storage format to use. The acceptable values are:
++
+include::../ref-storage-format.txt[]
++
+It is an error to specify this key unless `core.repositoryFormatVersion` is 1.
++
+Note that this setting should only be set by linkgit:git-init[1] or
+linkgit:git-clone[1]. Trying to change it after initialization will not
+work and will produce hard-to-diagnose issues.
+
 extensions.worktreeConfig::
 	If enabled, then worktrees will load config settings from the
 	`$GIT_DIR/config.worktree` file in addition to the
diff --git a/Documentation/config/feature.txt b/Documentation/config/feature.txt
index bf9546f..f061b64 100644
--- a/Documentation/config/feature.txt
+++ b/Documentation/config/feature.txt
@@ -17,6 +17,9 @@
 +
 * `pack.useBitmapBoundaryTraversal=true` may improve bitmap traversal times by
 walking fewer objects.
++
+* `pack.allowPackReuse=multi` may improve the time it takes to create a pack by
+reusing objects from multiple packs instead of just one.
 
 feature.manyFiles::
 	Enable config options that optimize for repos with many files in the
diff --git a/Documentation/config/fetch.txt b/Documentation/config/fetch.txt
index aea5b97..d7dc461 100644
--- a/Documentation/config/fetch.txt
+++ b/Documentation/config/fetch.txt
@@ -50,6 +50,12 @@
 	refs. See also `remote.<name>.pruneTags` and the PRUNING
 	section of linkgit:git-fetch[1].
 
+fetch.all::
+	If true, fetch will attempt to update all available remotes.
+	This behavior can be overridden by passing `--no-all` or by
+	explicitly specifying one or more remote(s) to fetch from.
+	Defaults to false.
+
 fetch.output::
 	Control how ref update status is printed. Valid values are
 	`full` and `compact`. Default value is `full`. See the
diff --git a/Documentation/config/grep.txt b/Documentation/config/grep.txt
index e521f20..10041f2 100644
--- a/Documentation/config/grep.txt
+++ b/Documentation/config/grep.txt
@@ -24,5 +24,5 @@
 	If set to true, enable `--full-name` option by default.
 
 grep.fallbackToNoIndex::
-	If set to true, fall back to git grep --no-index if git grep
+	If set to true, fall back to `git grep --no-index` if `git grep`
 	is executed outside of a git repository.  Defaults to false.
diff --git a/Documentation/config/init.txt b/Documentation/config/init.txt
index 79c79d6..af03acd 100644
--- a/Documentation/config/init.txt
+++ b/Documentation/config/init.txt
@@ -1,7 +1,10 @@
-init.templateDir::
-	Specify the directory from which templates will be copied.
-	(See the "TEMPLATE DIRECTORY" section of linkgit:git-init[1].)
+:see-git-init:
+ifndef::git-init[]
+:see-git-init: (See the "TEMPLATE DIRECTORY" section of linkgit:git-init[1].)
+endif::[]
 
-init.defaultBranch::
+`init.templateDir`::
+	Specify the directory from which templates will be copied. {see-git-init}
+`init.defaultBranch`::
 	Allows overriding the default branch name e.g. when initializing
 	a new repository.
diff --git a/Documentation/config/interactive.txt b/Documentation/config/interactive.txt
index a2d3c7e..5cc2655 100644
--- a/Documentation/config/interactive.txt
+++ b/Documentation/config/interactive.txt
@@ -4,9 +4,7 @@
 	Currently this is used by the `--patch` mode of
 	linkgit:git-add[1], linkgit:git-checkout[1],
 	linkgit:git-restore[1], linkgit:git-commit[1],
-	linkgit:git-reset[1], and linkgit:git-stash[1]. Note that this
-	setting is silently ignored if portable keystroke input
-	is not available; requires the Perl module Term::ReadKey.
+	linkgit:git-reset[1], and linkgit:git-stash[1].
 
 interactive.diffFilter::
 	When an interactive command (such as `git add --patch`) shows
diff --git a/Documentation/config/mergetool.txt b/Documentation/config/mergetool.txt
index 294f61e..00bf665 100644
--- a/Documentation/config/mergetool.txt
+++ b/Documentation/config/mergetool.txt
@@ -45,14 +45,21 @@
 	value of `false` avoids using `--auto-merge` altogether, and is the
 	default value.
 
-mergetool.vimdiff.layout::
-	The vimdiff backend uses this variable to control how its split
-	windows appear. Applies even if you are using Neovim (`nvim`) or
-	gVim (`gvim`) as the merge tool. See BACKEND SPECIFIC HINTS section
-ifndef::git-mergetool[]
-	in linkgit:git-mergetool[1].
+mergetool.<vimdiff variant>.layout::
+	Configure the split window layout for vimdiff's `<variant>`, which is any of `vimdiff`,
+	`nvimdiff`, `gvimdiff`.
+	Upon launching `git mergetool` with `--tool=<variant>` (or without `--tool`
+	if `merge.tool` is configured as `<variant>`), Git will consult
+	`mergetool.<variant>.layout` to determine the tool's layout. If the
+	variant-specific configuration is not available, `vimdiff`'s is used as
+	fallback.  If that too is not available, a default layout with 4 windows
+	will be used.  To configure the layout, see the `BACKEND SPECIFIC HINTS`
+ifdef::git-mergetool[]
+	section.
 endif::[]
-	for details.
+ifndef::git-mergetool[]
+	section in linkgit:git-mergetool[1].
+endif::[]
 
 mergetool.hideResolved::
 	During a merge, Git will automatically resolve as many conflicts as
diff --git a/Documentation/config/pack.txt b/Documentation/config/pack.txt
index f50df9d..da52737 100644
--- a/Documentation/config/pack.txt
+++ b/Documentation/config/pack.txt
@@ -28,11 +28,16 @@
 to linkgit:git-repack[1].
 
 pack.allowPackReuse::
-	When true, and when reachability bitmaps are enabled,
-	pack-objects will try to send parts of the bitmapped packfile
-	verbatim. This can reduce memory and CPU usage to serve fetches,
-	but might result in sending a slightly larger pack. Defaults to
-	true.
+	When true or "single", and when reachability bitmaps are
+	enabled, pack-objects will try to send parts of the bitmapped
+	packfile verbatim. When "multi", and when a multi-pack
+	reachability bitmap is available, pack-objects will try to send
+	parts of all packs in the MIDX.
++
+If only a single pack bitmap is available, and `pack.allowPackReuse`
+is set to "multi", reuse parts of just the bitmapped packfile. This
+can reduce memory and CPU usage to serve fetches, but might result in
+sending a slightly larger pack. Defaults to true.
 
 pack.island::
 	An extended regular expression configuring a set of delta
diff --git a/Documentation/config/rebase.txt b/Documentation/config/rebase.txt
index 7c57c5e..c6187ab 100644
--- a/Documentation/config/rebase.txt
+++ b/Documentation/config/rebase.txt
@@ -9,7 +9,9 @@
 	rebase. False by default.
 
 rebase.autoSquash::
-	If set to true enable `--autosquash` option by default.
+	If set to true, enable the `--autosquash` option of
+	linkgit:git-rebase[1] by default for interactive mode.
+	This can be overridden with the `--no-autosquash` option.
 
 rebase.autoStash::
 	When set to true, automatically create a temporary stash entry
diff --git a/Documentation/config/receive.txt b/Documentation/config/receive.txt
index c77e55b..36a1e6f 100644
--- a/Documentation/config/receive.txt
+++ b/Documentation/config/receive.txt
@@ -8,7 +8,7 @@
 	capability to its clients. False by default.
 
 receive.autogc::
-	By default, git-receive-pack will run "git-gc --auto" after
+	By default, git-receive-pack will run "git maintenance run --auto" after
 	receiving data from git-push and updating refs.  You can stop
 	it by setting this variable to false.
 
diff --git a/Documentation/config/sendemail.txt b/Documentation/config/sendemail.txt
index 7fc770e..6a869d6 100644
--- a/Documentation/config/sendemail.txt
+++ b/Documentation/config/sendemail.txt
@@ -8,7 +8,7 @@
 	See linkgit:git-send-email[1] for description.  Note that this
 	setting is not subject to the 'identity' mechanism.
 
-sendemail.smtpsslcertpath::
+sendemail.smtpSSLCertPath::
 	Path to ca-certificates (either a directory or a single file).
 	Set it to an empty string to disable certificate verification.
 
@@ -62,12 +62,12 @@
 sendemail.envelopeSender::
 sendemail.from::
 sendemail.headerCmd::
-sendemail.signedoffbycc::
+sendemail.signedOffByCc::
 sendemail.smtpPass::
-sendemail.suppresscc::
+sendemail.suppressCc::
 sendemail.suppressFrom::
 sendemail.to::
-sendemail.tocmd::
+sendemail.toCmd::
 sendemail.smtpDomain::
 sendemail.smtpServer::
 sendemail.smtpServerPort::
@@ -81,8 +81,8 @@
 	linkgit:git-send-email[1] command-line options. See its
 	documentation for details.
 
-sendemail.signedoffcc (deprecated)::
-	Deprecated alias for `sendemail.signedoffbycc`.
+sendemail.signedOffCc (deprecated)::
+	Deprecated alias for `sendemail.signedOffByCc`.
 
 sendemail.smtpBatchSize::
 	Number of messages to be sent per connection, after that a relogin
diff --git a/Documentation/config/status.txt b/Documentation/config/status.txt
index 2ff8237..8caf90f 100644
--- a/Documentation/config/status.txt
+++ b/Documentation/config/status.txt
@@ -57,6 +57,8 @@
 --
 +
 If this variable is not specified, it defaults to 'normal'.
+All usual spellings for Boolean value `true` are taken as `normal`
+and `false` as `no`.
 This variable can be overridden with the -u|--untracked-files option
 of linkgit:git-status[1] and linkgit:git-commit[1].
 
diff --git a/Documentation/config/transfer.txt b/Documentation/config/transfer.txt
index a9cbdb8..f1ce50f 100644
--- a/Documentation/config/transfer.txt
+++ b/Documentation/config/transfer.txt
@@ -121,3 +121,7 @@
 	information from the remote server (if advertised) and download
 	bundles before continuing the clone through the Git protocol.
 	Defaults to `false`.
+
+transfer.advertiseObjectInfo::
+	When `true`, the `object-info` capability is advertised by
+	servers. Defaults to false.
diff --git a/Documentation/date-formats.txt b/Documentation/date-formats.txt
index 67645ca..e24517c 100644
--- a/Documentation/date-formats.txt
+++ b/Documentation/date-formats.txt
@@ -11,7 +11,7 @@
 	For example CET (which is 1 hour ahead of UTC) is `+0100`.
 
 RFC 2822::
-	The standard email format as described by RFC 2822, for example
+	The standard date format as described by RFC 2822, for example
 	`Thu, 07 Apr 2005 22:13:13 +0200`.
 
 ISO 8601::
diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt
index 53ec3c9..0e94569 100644
--- a/Documentation/diff-options.txt
+++ b/Documentation/diff-options.txt
@@ -299,7 +299,7 @@
 	Synonym for --dirstat=cumulative
 
 --dirstat-by-file[=<param1,param2>...]::
-	Synonym for --dirstat=files,param1,param2...
+	Synonym for --dirstat=files,<param1>,<param2>...
 
 --summary::
 	Output a condensed summary of extended header information
@@ -865,8 +865,9 @@
 
 --default-prefix::
 	Use the default source and destination prefixes ("a/" and "b/").
-	This is usually the default already, but may be used to override
-	config such as `diff.noprefix`.
+	This overrides configuration variables such as `diff.noprefix`,
+	`diff.srcPrefix`, `diff.dstPrefix`, and `diff.mnemonicPrefix`
+	(see `git-config`(1)).
 
 --line-prefix=<prefix>::
 	Prepend an additional prefix to every line of output.
diff --git a/Documentation/fetch-options.txt b/Documentation/fetch-options.txt
index a1d6633..e22b217 100644
--- a/Documentation/fetch-options.txt
+++ b/Documentation/fetch-options.txt
@@ -1,5 +1,6 @@
---all::
-	Fetch all remotes.
+--[no-]all::
+	Fetch all remotes. This overrides the configuration variable
+	`fetch.all`.
 
 -a::
 --append::
@@ -201,7 +202,7 @@
 	destination of an explicit refspec; see `--prune`).
 
 ifndef::git-pull[]
---recurse-submodules[=yes|on-demand|no]::
+--recurse-submodules[=(yes|on-demand|no)]::
 	This option controls if and under what conditions new commits of
 	submodules should be fetched too. When recursing through submodules,
 	`git fetch` always attempts to fetch "changed" submodules, that is, a
diff --git a/Documentation/git-add.txt b/Documentation/git-add.txt
index 3d2e670..aceaa02 100644
--- a/Documentation/git-add.txt
+++ b/Documentation/git-add.txt
@@ -63,7 +63,7 @@
 	to ignore removed files; use `--no-all` option if you want
 	to add modified or new files but ignore removed ones.
 +
-For more details about the <pathspec> syntax, see the 'pathspec' entry
+For more details about the _<pathspec>_ syntax, see the 'pathspec' entry
 in linkgit:gitglossary[7].
 
 -n::
@@ -119,10 +119,10 @@
 -u::
 --update::
 	Update the index just where it already has an entry matching
-	<pathspec>.  This removes as well as modifies index entries to
+	_<pathspec>_.  This removes as well as modifies index entries to
 	match the working tree, but adds no new files.
 +
-If no <pathspec> is given when `-u` option is used, all
+If no _<pathspec>_ is given when `-u` option is used, all
 tracked files in the entire working tree are updated (old versions
 of Git used to limit the update to the current directory and its
 subdirectories).
@@ -131,11 +131,11 @@
 --all::
 --no-ignore-removal::
 	Update the index not only where the working tree has a file
-	matching <pathspec> but also where the index already has an
+	matching _<pathspec>_ but also where the index already has an
 	entry. This adds, modifies, and removes index entries to
 	match the working tree.
 +
-If no <pathspec> is given when `-A` option is used, all
+If no _<pathspec>_ is given when `-A` option is used, all
 files in the entire working tree are updated (old versions
 of Git used to limit the update to the current directory and its
 subdirectories).
@@ -145,11 +145,11 @@
 	Update the index by adding new files that are unknown to the
 	index and files modified in the working tree, but ignore
 	files that have been removed from the working tree.  This
-	option is a no-op when no <pathspec> is used.
+	option is a no-op when no _<pathspec>_ is used.
 +
 This option is primarily to help users who are used to older
-versions of Git, whose "git add <pathspec>..." was a synonym
-for "git add --no-all <pathspec>...", i.e. ignored removed files.
+versions of Git, whose "git add _<pathspec>_..." was a synonym
+for "git add --no-all _<pathspec>_...", i.e. ignored removed files.
 
 -N::
 --intent-to-add::
@@ -198,8 +198,8 @@
 	unchanged.
 
 --pathspec-from-file=<file>::
-	Pathspec is passed in `<file>` instead of commandline args. If
-	`<file>` is exactly `-` then standard input is used. Pathspec
+	Pathspec is passed in _<file>_ instead of commandline args. If
+	_<file>_ is exactly `-` then standard input is used. Pathspec
 	elements are separated by LF or CR/LF. Pathspec elements can be
 	quoted as explained for the configuration variable `core.quotePath`
 	(see linkgit:git-config[1]). See also `--pathspec-file-nul` and
@@ -348,6 +348,7 @@
        K - leave this hunk undecided, see previous hunk
        s - split the current hunk into smaller hunks
        e - manually edit the current hunk
+       p - print the current hunk
        ? - print help
 +
 After deciding the fate for all hunks, if there is any hunk
diff --git a/Documentation/git-am.txt b/Documentation/git-am.txt
index e080458..624a6e6 100644
--- a/Documentation/git-am.txt
+++ b/Documentation/git-am.txt
@@ -66,13 +66,19 @@
 --quoted-cr=<action>::
 	This flag will be passed down to 'git mailinfo' (see linkgit:git-mailinfo[1]).
 
---empty=(stop|drop|keep)::
-	By default, or when the option is set to 'stop', the command
-	errors out on an input e-mail message lacking a patch
-	and stops in the middle of the current am session. When this
-	option is set to 'drop', skip such an e-mail message instead.
-	When this option is set to 'keep', create an empty commit,
-	recording the contents of the e-mail message as its log.
+--empty=(drop|keep|stop)::
+	How to handle an e-mail message lacking a patch:
++
+--
+`drop`;;
+	The e-mail message will be skipped.
+`keep`;;
+	An empty commit will be created, with the contents of the e-mail
+	message as its log.
+`stop`;;
+	The command will fail, stopping in the middle of the current `am`
+	session. This is the default behavior.
+--
 
 -m::
 --message-id::
@@ -128,6 +134,9 @@
 	These flags are passed to the 'git apply' (see linkgit:git-apply[1])
 	program that applies
 	the patch.
++
+Valid <action> for the `--whitespace` option are:
+`nowarn`, `warn`, `fix`, `error`, and `error-all`.
 
 --patch-format::
 	By default the command will try to detect the patch format
diff --git a/Documentation/git-bisect.txt b/Documentation/git-bisect.txt
index a0e75a6..82f944d 100644
--- a/Documentation/git-bisect.txt
+++ b/Documentation/git-bisect.txt
@@ -17,7 +17,7 @@
 on the subcommand:
 
  git bisect start [--term-(bad|new)=<term-new> --term-(good|old)=<term-old>]
-		  [--no-checkout] [--first-parent] [<bad> [<good>...]] [--] [<paths>...]
+		  [--no-checkout] [--first-parent] [<bad> [<good>...]] [--] [<pathspec>...]
  git bisect (bad|new|<term-new>) [<rev>]
  git bisect (good|old|<term-old>) [<rev>...]
  git bisect terms [--term-(good|old) | --term-(bad|new)]
@@ -301,7 +301,7 @@
 
 You can further cut down the number of trials, if you know what part of
 the tree is involved in the problem you are tracking down, by specifying
-path parameters when issuing the `bisect start` command:
+pathspec parameters when issuing the `bisect start` command:
 
 ------------
 $ git bisect start -- arch/i386 include/asm-i386
diff --git a/Documentation/git-blame.txt b/Documentation/git-blame.txt
index 5720d04..b1d7fb5 100644
--- a/Documentation/git-blame.txt
+++ b/Documentation/git-blame.txt
@@ -210,7 +210,7 @@
 
 . Each blame entry always starts with a line of:
 
-	<40-byte hex sha1> <sourceline> <resultline> <num_lines>
+	<40-byte-hex-sha1> <sourceline> <resultline> <num-lines>
 +
 Line numbers count from 1.
 
diff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt
index 4395aa9..0b08442 100644
--- a/Documentation/git-branch.txt
+++ b/Documentation/git-branch.txt
@@ -312,7 +312,8 @@
 	option is omitted, the current HEAD will be used instead.
 
 <oldbranch>::
-	The name of an existing branch to rename.
+	The name of an existing branch.  If this option is omitted,
+	the name of the current branch will be used instead.
 
 <newbranch>::
 	The new name for an existing branch. The same restrictions as for
diff --git a/Documentation/git-bugreport.txt b/Documentation/git-bugreport.txt
index 392d9eb..112658b 100644
--- a/Documentation/git-bugreport.txt
+++ b/Documentation/git-bugreport.txt
@@ -8,7 +8,8 @@
 SYNOPSIS
 --------
 [verse]
-'git bugreport' [(-o | --output-directory) <path>] [(-s | --suffix) <format>]
+'git bugreport' [(-o | --output-directory) <path>]
+		[(-s | --suffix) <format> | --no-suffix]
 		[--diagnose[=<mode>]]
 
 DESCRIPTION
@@ -51,16 +52,19 @@
 
 -s <format>::
 --suffix <format>::
+--no-suffix::
 	Specify an alternate suffix for the bugreport name, to create a file
-	named 'git-bugreport-<formatted suffix>'. This should take the form of a
+	named 'git-bugreport-<formatted-suffix>'. This should take the form of a
 	strftime(3) format string; the current local time will be used.
+	`--no-suffix` disables the suffix and the file is just named
+	`git-bugreport` without any disambiguation measure.
 
 --no-diagnose::
 --diagnose[=<mode>]::
 	Create a zip archive of supplemental information about the user's
 	machine, Git client, and repository state. The archive is written to the
 	same output directory as the bug report and is named
-	'git-diagnostics-<formatted suffix>'.
+	'git-diagnostics-<formatted-suffix>'.
 +
 Without `mode` specified, the diagnostic archive will contain the default set of
 statistics reported by `git diagnose`. An optional `mode` value may be specified
diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt
index 26ad1a5..8bdfa54 100644
--- a/Documentation/git-checkout.txt
+++ b/Documentation/git-checkout.txt
@@ -63,7 +63,9 @@
 ------------
 +
 that is to say, the branch is not reset/created unless "git checkout" is
-successful.
+successful (e.g., when the branch is in use in another worktree, not
+just the current branch stays the same, but the branch is not reset to
+the start-point, either).
 
 'git checkout' --detach [<branch>]::
 'git checkout' [--detach] <commit>::
diff --git a/Documentation/git-cherry-pick.txt b/Documentation/git-cherry-pick.txt
index fdcad3d..81ace90 100644
--- a/Documentation/git-cherry-pick.txt
+++ b/Documentation/git-cherry-pick.txt
@@ -131,20 +131,36 @@
 	even without this option.  Note also, that use of this option only
 	keeps commits that were initially empty (i.e. the commit recorded the
 	same tree as its parent).  Commits which are made empty due to a
-	previous commit are dropped.  To force the inclusion of those commits
-	use `--keep-redundant-commits`.
+	previous commit will cause the cherry-pick to fail.  To force the
+	inclusion of those commits, use `--empty=keep`.
 
 --allow-empty-message::
 	By default, cherry-picking a commit with an empty message will fail.
 	This option overrides that behavior, allowing commits with empty
 	messages to be cherry picked.
 
+--empty=(drop|keep|stop)::
+	How to handle commits being cherry-picked that are redundant with
+	changes already in the current history.
++
+--
+`drop`;;
+	The commit will be dropped.
+`keep`;;
+	The commit will be kept. Implies `--allow-empty`.
+`stop`;;
+	The cherry-pick will stop when the commit is applied, allowing
+	you to examine the commit. This is the default behavior.
+--
++
+Note that `--empty=drop` and `--empty=stop` only specify how to handle a
+commit that was not initially empty, but rather became empty due to a previous
+commit. Commits that were initially empty will still cause the cherry-pick to
+fail unless one of `--empty=keep` or `--allow-empty` are specified.
++
+
 --keep-redundant-commits::
-	If a commit being cherry picked duplicates a commit already in the
-	current history, it will become empty.  By default these
-	redundant commits cause `cherry-pick` to stop so the user can
-	examine the commit. This option overrides that behavior and
-	creates an empty commit object.  Implies `--allow-empty`.
+	Deprecated synonym for `--empty=keep`.
 
 --strategy=<strategy>::
 	Use the given merge strategy.  Should only be used once.
diff --git a/Documentation/git-clean.txt b/Documentation/git-clean.txt
index 69331e3..fd17165 100644
--- a/Documentation/git-clean.txt
+++ b/Documentation/git-clean.txt
@@ -37,7 +37,7 @@
 --force::
 	If the Git configuration variable clean.requireForce is not set
 	to false, 'git clean' will refuse to delete files or directories
-	unless given -f or -i.  Git will refuse to modify untracked
+	unless given -f.  Git will refuse to modify untracked
 	nested git repositories (directories with a .git subdirectory)
 	unless a second -f is given.
 
@@ -45,10 +45,14 @@
 --interactive::
 	Show what would be done and clean files interactively. See
 	``Interactive mode'' for details.
+	Configuration variable `clean.requireForce` is ignored, as
+	this mode gives its own safety protection by going interactive.
 
 -n::
 --dry-run::
 	Don't actually remove anything, just show what would be done.
+	Configuration variable `clean.requireForce` is ignored, as
+	nothing will be deleted anyway.
 
 -q::
 --quiet::
diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt
index c37c4a3..5de18de 100644
--- a/Documentation/git-clone.txt
+++ b/Documentation/git-clone.txt
@@ -9,15 +9,15 @@
 SYNOPSIS
 --------
 [verse]
-'git clone' [--template=<template-directory>]
-	  [-l] [-s] [--no-hardlinks] [-q] [-n] [--bare] [--mirror]
-	  [-o <name>] [-b <name>] [-u <upload-pack>] [--reference <repository>]
-	  [--dissociate] [--separate-git-dir <git-dir>]
-	  [--depth <depth>] [--[no-]single-branch] [--no-tags]
-	  [--recurse-submodules[=<pathspec>]] [--[no-]shallow-submodules]
-	  [--[no-]remote-submodules] [--jobs <n>] [--sparse] [--[no-]reject-shallow]
-	  [--filter=<filter> [--also-filter-submodules]] [--] <repository>
-	  [<directory>]
+`git clone` [++--template=++__<template-directory>__]
+	  [`-l`] [`-s`] [`--no-hardlinks`] [`-q`] [`-n`] [`--bare`] [`--mirror`]
+	  [`-o` _<name>_] [`-b` _<name>_] [`-u` _<upload-pack>_] [`--reference` _<repository>_]
+	  [`--dissociate`] [`--separate-git-dir` _<git-dir>_]
+	  [`--depth` _<depth>_] [`--`[`no-`]`single-branch`] [`--no-tags`]
+	  [++--recurse-submodules++[++=++__<pathspec>__]] [`--`[`no-`]`shallow-submodules`]
+	  [`--`[`no-`]`remote-submodules`] [`--jobs` _<n>_] [`--sparse`] [`--`[`no-`]`reject-shallow`]
+	  [++--filter=++__<filter-spec>__] [`--also-filter-submodules`]] [`--`] _<repository>_
+	  [_<directory>_]
 
 DESCRIPTION
 -----------
@@ -31,7 +31,7 @@
 After the clone, a plain `git fetch` without arguments will update
 all the remote-tracking branches, and a `git pull` without
 arguments will in addition merge the remote master branch into the
-current master branch, if any (this is untrue when "--single-branch"
+current master branch, if any (this is untrue when `--single-branch`
 is given; see below).
 
 This default configuration is achieved by creating references to
@@ -42,12 +42,12 @@
 
 OPTIONS
 -------
--l::
---local::
+`-l`::
+`--local`::
 	When the repository to clone from is on a local machine,
 	this flag bypasses the normal "Git aware" transport
 	mechanism and clones the repository by making a copy of
-	HEAD and everything under objects and refs directories.
+	`HEAD` and everything under objects and refs directories.
 	The files under `.git/objects/` directory are hardlinked
 	to save space when possible.
 +
@@ -67,14 +67,14 @@
 source repository, similar to running `cp -r src dst` while modifying
 `src`.
 
---no-hardlinks::
+`--no-hardlinks`::
 	Force the cloning process from a repository on a local
 	filesystem to copy the files under the `.git/objects`
 	directory instead of using hardlinks. This may be desirable
 	if you are trying to make a back-up of your repository.
 
--s::
---shared::
+`-s`::
+`--shared`::
 	When the repository to clone is on the local machine,
 	instead of using hard links, automatically setup
 	`.git/objects/info/alternates` to share the objects
@@ -101,10 +101,10 @@
 its source repository, you can simply run `git repack -a` to copy all
 objects from the source repository into a pack in the cloned repository.
 
---reference[-if-able] <repository>::
-	If the reference repository is on the local machine,
+`--reference`[`-if-able`] _<repository>_::
+	If the reference _<repository>_ is on the local machine,
 	automatically setup `.git/objects/info/alternates` to
-	obtain objects from the reference repository.  Using
+	obtain objects from the reference _<repository>_.  Using
 	an already existing repository as an alternate will
 	require fewer objects to be copied from the repository
 	being cloned, reducing network and local storage costs.
@@ -115,7 +115,7 @@
 *NOTE*: see the NOTE for the `--shared` option, and also the
 `--dissociate` option.
 
---dissociate::
+`--dissociate`::
 	Borrow the objects from reference repositories specified
 	with the `--reference` options only to reduce network
 	transfer, and stop borrowing from them after a clone is made
@@ -126,43 +126,43 @@
 	same repository, and this option can be used to stop the
 	borrowing.
 
--q::
---quiet::
+`-q`::
+`--quiet`::
 	Operate quietly.  Progress is not reported to the standard
 	error stream.
 
--v::
---verbose::
+`-v`::
+`--verbose`::
 	Run verbosely. Does not affect the reporting of progress status
 	to the standard error stream.
 
---progress::
+`--progress`::
 	Progress status is reported on the standard error stream
 	by default when it is attached to a terminal, unless `--quiet`
 	is specified. This flag forces progress status even if the
 	standard error stream is not directed to a terminal.
 
---server-option=<option>::
+++--server-option=++__<option>__::
 	Transmit the given string to the server when communicating using
 	protocol version 2.  The given string must not contain a NUL or LF
 	character.  The server's handling of server options, including
 	unknown ones, is server-specific.
-	When multiple `--server-option=<option>` are given, they are all
+	When multiple ++--server-option=++__<option>__ are given, they are all
 	sent to the other side in the order listed on the command line.
 
--n::
---no-checkout::
+`-n`::
+`--no-checkout`::
 	No checkout of HEAD is performed after the clone is complete.
 
---[no-]reject-shallow::
+`--`[`no-`]`reject-shallow`::
 	Fail if the source repository is a shallow repository.
-	The 'clone.rejectShallow' configuration variable can be used to
+	The `clone.rejectShallow` configuration variable can be used to
 	specify the default.
 
---bare::
+`--bare`::
 	Make a 'bare' Git repository.  That is, instead of
-	creating `<directory>` and placing the administrative
-	files in `<directory>/.git`, make the `<directory>`
+	creating _<directory>_ and placing the administrative
+	files in _<directory>_`/.git`, make the _<directory>_
 	itself the `$GIT_DIR`. This obviously implies the `--no-checkout`
 	because there is nowhere to check out the working tree.
 	Also the branch heads at the remote are copied directly
@@ -171,28 +171,28 @@
 	used, neither remote-tracking branches nor the related
 	configuration variables are created.
 
---sparse::
+`--sparse`::
 	Employ a sparse-checkout, with only files in the toplevel
 	directory initially being present.  The
 	linkgit:git-sparse-checkout[1] command can be used to grow the
 	working directory as needed.
 
---filter=<filter-spec>::
+++--filter=++__<filter-spec>__::
 	Use the partial clone feature and request that the server sends
 	a subset of reachable objects according to a given object filter.
-	When using `--filter`, the supplied `<filter-spec>` is used for
+	When using `--filter`, the supplied _<filter-spec>_ is used for
 	the partial clone filter. For example, `--filter=blob:none` will
 	filter out all blobs (file contents) until needed by Git. Also,
-	`--filter=blob:limit=<size>` will filter out all blobs of size
-	at least `<size>`. For more details on filter specifications, see
+	++--filter=blob:limit=++__<size>__ will filter out all blobs of size
+	at least _<size>_. For more details on filter specifications, see
 	the `--filter` option in linkgit:git-rev-list[1].
 
---also-filter-submodules::
+`--also-filter-submodules`::
 	Also apply the partial clone filter to any submodules in the repository.
 	Requires `--filter` and `--recurse-submodules`. This can be turned on by
 	default by setting the `clone.filterSubmodules` config option.
 
---mirror::
+`--mirror`::
 	Set up a mirror of the source repository.  This implies `--bare`.
 	Compared to `--bare`, `--mirror` not only maps local branches of the
 	source to local branches of the target, it maps all refs (including
@@ -200,37 +200,37 @@
 	that all these refs are overwritten by a `git remote update` in the
 	target repository.
 
--o <name>::
---origin <name>::
+`-o` _<name>_::
+`--origin` _<name>_::
 	Instead of using the remote name `origin` to keep track of the upstream
-	repository, use `<name>`.  Overrides `clone.defaultRemoteName` from the
+	repository, use _<name>_.  Overrides `clone.defaultRemoteName` from the
 	config.
 
--b <name>::
---branch <name>::
+`-b` _<name>_::
+`--branch` _<name>_::
 	Instead of pointing the newly created HEAD to the branch pointed
-	to by the cloned repository's HEAD, point to `<name>` branch
+	to by the cloned repository's HEAD, point to _<name>_ branch
 	instead. In a non-bare repository, this is the branch that will
 	be checked out.
 	`--branch` can also take tags and detaches the HEAD at that commit
 	in the resulting repository.
 
--u <upload-pack>::
---upload-pack <upload-pack>::
+`-u` _<upload-pack>_::
+`--upload-pack` _<upload-pack>_::
 	When given, and the repository to clone from is accessed
 	via ssh, this specifies a non-default path for the command
 	run on the other end.
 
---template=<template-directory>::
+++--template=++__<template-directory>__::
 	Specify the directory from which templates will be used;
 	(See the "TEMPLATE DIRECTORY" section of linkgit:git-init[1].)
 
--c <key>=<value>::
---config <key>=<value>::
+`-c` __<key>__++=++__<value>__::
+`--config` __<key>__++=++__<value>__::
 	Set a configuration variable in the newly-created repository;
 	this takes effect immediately after the repository is
 	initialized, but before the remote history is fetched or any
-	files checked out.  The key is in the same format as expected by
+	files checked out.  The _<key>_ is in the same format as expected by
 	linkgit:git-config[1] (e.g., `core.eol=true`). If multiple
 	values are given for the same key, each value will be written to
 	the config file. This makes it safe, for example, to add
@@ -239,35 +239,35 @@
 Due to limitations of the current implementation, some configuration
 variables do not take effect until after the initial fetch and checkout.
 Configuration variables known to not take effect are:
-`remote.<name>.mirror` and `remote.<name>.tagOpt`.  Use the
+++remote.++__<name>__++.mirror++ and ++remote.++__<name>__++.tagOpt++.  Use the
 corresponding `--mirror` and `--no-tags` options instead.
 
---depth <depth>::
+`--depth` _<depth>_::
 	Create a 'shallow' clone with a history truncated to the
 	specified number of commits. Implies `--single-branch` unless
 	`--no-single-branch` is given to fetch the histories near the
 	tips of all branches. If you want to clone submodules shallowly,
 	also pass `--shallow-submodules`.
 
---shallow-since=<date>::
+++--shallow-since=++__<date>__::
 	Create a shallow clone with a history after the specified time.
 
---shallow-exclude=<revision>::
+++--shallow-exclude=++__<revision>__::
 	Create a shallow clone with a history, excluding commits
 	reachable from a specified remote branch or tag.  This option
 	can be specified multiple times.
 
---[no-]single-branch::
+`--`[`no-`]`single-branch`::
 	Clone only the history leading to the tip of a single branch,
 	either specified by the `--branch` option or the primary
 	branch remote's `HEAD` points at.
 	Further fetches into the resulting repository will only update the
 	remote-tracking branch for the branch this option was used for the
-	initial cloning.  If the HEAD at the remote did not point at any
+	initial cloning.  If the `HEAD` at the remote did not point at any
 	branch when `--single-branch` clone was made, no remote-tracking
 	branch is created.
 
---no-tags::
+`--no-tags`::
 	Don't clone any tags, and set
 	`remote.<remote>.tagOpt=--no-tags` in the config, ensuring
 	that future `git pull` and `git fetch` operations won't follow
@@ -279,9 +279,9 @@
 branch. This is useful e.g. to maintain minimal clones of the default
 branch of some repository for search indexing.
 
---recurse-submodules[=<pathspec>]::
+`--recurse-submodules`[`=`{empty}__<pathspec>__]::
 	After the clone is created, initialize and clone submodules
-	within based on the provided pathspec.  If no pathspec is
+	within based on the provided _<pathspec>_.  If no _=<pathspec>_ is
 	provided, all submodules are initialized and cloned.
 	This option can be given multiple times for pathspecs consisting
 	of multiple entries.  The resulting clone has `submodule.active` set to
@@ -295,42 +295,48 @@
 not have a worktree/checkout (i.e. if any of `--no-checkout`/`-n`, `--bare`,
 or `--mirror` is given)
 
---[no-]shallow-submodules::
+`--`[`no-`]`shallow-submodules`::
 	All submodules which are cloned will be shallow with a depth of 1.
 
---[no-]remote-submodules::
+`--`[`no-`]`remote-submodules`::
 	All submodules which are cloned will use the status of the submodule's
 	remote-tracking branch to update the submodule, rather than the
 	superproject's recorded SHA-1. Equivalent to passing `--remote` to
 	`git submodule update`.
 
---separate-git-dir=<git-dir>::
+`--separate-git-dir=`{empty}__<git-dir>__::
 	Instead of placing the cloned repository where it is supposed
 	to be, place the cloned repository at the specified directory,
 	then make a filesystem-agnostic Git symbolic link to there.
 	The result is Git repository can be separated from working
 	tree.
 
--j <n>::
---jobs <n>::
+`--ref-format=`{empty}__<ref-format>__::
+
+Specify the given ref storage format for the repository. The valid values are:
++
+include::ref-storage-format.txt[]
+
+`-j` _<n>_::
+`--jobs` _<n>_::
 	The number of submodules fetched at the same time.
 	Defaults to the `submodule.fetchJobs` option.
 
-<repository>::
-	The (possibly remote) repository to clone from.  See the
+_<repository>_::
+	The (possibly remote) _<repository>_ to clone from.  See the
 	<<URLS,GIT URLS>> section below for more information on specifying
 	repositories.
 
-<directory>::
+_<directory>_::
 	The name of a new directory to clone into.  The "humanish"
-	part of the source repository is used if no directory is
+	part of the source repository is used if no _<directory>_ is
 	explicitly given (`repo` for `/path/to/repo.git` and `foo`
 	for `host.xz:foo/.git`).  Cloning into an existing directory
 	is only allowed if the directory is empty.
 
---bundle-uri=<uri>::
+`--bundle-uri=`{empty}__<uri>__::
 	Before fetching from the remote, fetch a bundle from the given
-	`<uri>` and unbundle the data into the local repository. The refs
+	_<uri>_ and unbundle the data into the local repository. The refs
 	in the bundle will be stored under the hidden `refs/bundle/*`
 	namespace. This option is incompatible with `--depth`,
 	`--shallow-since`, and `--shallow-exclude`.
diff --git a/Documentation/git-commit-graph.txt b/Documentation/git-commit-graph.txt
index c8dbceb..903b168 100644
--- a/Documentation/git-commit-graph.txt
+++ b/Documentation/git-commit-graph.txt
@@ -13,7 +13,7 @@
 'git commit-graph write' [--object-dir <dir>] [--append]
 			[--split[=<strategy>]] [--reachable | --stdin-packs | --stdin-commits]
 			[--changed-paths] [--[no-]max-new-filters <n>] [--[no-]progress]
-			<split options>
+			<split-options>
 
 
 DESCRIPTION
diff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt
index a6cef5d..89ecfc6 100644
--- a/Documentation/git-commit.txt
+++ b/Documentation/git-commit.txt
@@ -347,6 +347,8 @@
 	- 'normal' - Shows untracked files and directories
 	- 'all'    - Also shows individual files in untracked directories.
 
+All usual spellings for Boolean value `true` are taken as `normal`
+and `false` as `no`.
 The default can be changed using the status.showUntrackedFiles
 configuration variable documented in linkgit:git-config[1].
 --
diff --git a/Documentation/git-config.txt b/Documentation/git-config.txt
index b1caac8..ac61113 100644
--- a/Documentation/git-config.txt
+++ b/Documentation/git-config.txt
@@ -9,9 +9,9 @@
 SYNOPSIS
 --------
 [verse]
-'git config' [<file-option>] [--type=<type>] [--fixed-value] [--show-origin] [--show-scope] [-z|--null] <name> [<value> [<value-pattern>]]
-'git config' [<file-option>] [--type=<type>] --add <name> <value>
-'git config' [<file-option>] [--type=<type>] [--fixed-value] --replace-all <name> <value> [<value-pattern>]
+'git config' [<file-option>] [--type=<type>] [--comment=<message>] [--fixed-value] [--show-origin] [--show-scope] [-z|--null] <name> [<value> [<value-pattern>]]
+'git config' [<file-option>] [--type=<type>] [--comment=<message>] --add <name> <value>
+'git config' [<file-option>] [--type=<type>] [--comment=<message>] [--fixed-value] --replace-all <name> <value> [<value-pattern>]
 'git config' [<file-option>] [--type=<type>] [--show-origin] [--show-scope] [-z|--null] [--fixed-value] --get <name> [<value-pattern>]
 'git config' [<file-option>] [--type=<type>] [--show-origin] [--show-scope] [-z|--null] [--fixed-value] --get-all <name> [<value-pattern>]
 'git config' [<file-option>] [--type=<type>] [--show-origin] [--show-scope] [-z|--null] [--fixed-value] [--name-only] --get-regexp <name-regex> [<value-pattern>]
@@ -87,6 +87,18 @@
 	values.  This is the same as providing '^$' as the `value-pattern`
 	in `--replace-all`.
 
+--comment <message>::
+	Append a comment at the end of new or modified lines.
+
+	If _<message>_ begins with one or more whitespaces followed
+	by "#", it is used as-is.  If it begins with "#", a space is
+	prepended before it is used.  Otherwise, a string " # " (a
+	space followed by a hash followed by a space) is prepended
+	to it.  And the resulting string is placed immediately after
+	the value defined for the variable.  The _<message>_ must
+	not contain linefeed characters (no multi-line comments are
+	permitted).
+
 --get::
 	Get the value for a given key (optionally filtered by a regex
 	matching the value). Returns error code 1 if the key was not
@@ -103,11 +115,11 @@
 	names are not.
 
 --get-urlmatch <name> <URL>::
-	When given a two-part name section.key, the value for
-	section.<URL>.key whose <URL> part matches the best to the
+	When given a two-part <name> as <section>.<key>, the value for
+	<section>.<URL>.<key> whose <URL> part matches the best to the
 	given URL is returned (if no such key exists, the value for
-	section.key is used as a fallback).  When given just the
-	section as name, do so for all the keys in the section and
+	<section>.<key> is used as a fallback).  When given just the
+	<section> as name, do so for all the keys in the section and
 	list them.  Returns error code 1 if no value is found.
 
 --global::
@@ -275,7 +287,8 @@
 -e::
 --edit::
 	Opens an editor to modify the specified config file; either
-	`--system`, `--global`, or repository (default).
+	`--system`, `--global`, `--local` (default), `--worktree`, or
+	`--file <config-file>`.
 
 --[no-]includes::
 	Respect `include.*` directives in config files when looking up
@@ -285,7 +298,7 @@
 
 --default <value>::
   When using `--get`, and the requested variable is not found, behave as if
-  <value> were the value assigned to the that variable.
+  <value> were the value assigned to that variable.
 
 CONFIGURATION
 -------------
diff --git a/Documentation/git-cvsserver.txt b/Documentation/git-cvsserver.txt
index cf4a5a2..4c475ef 100644
--- a/Documentation/git-cvsserver.txt
+++ b/Documentation/git-cvsserver.txt
@@ -197,7 +197,7 @@
 5. Clients should now be able to check out the project. Use the CVS 'module'
    name to indicate what Git 'head' you want to check out.  This also sets the
    name of your newly checked-out directory, unless you tell it otherwise with
-   `-d <dir_name>`.  For example, this checks out 'master' branch to the
+   `-d <dir-name>`.  For example, this checks out 'master' branch to the
    `project-master` directory:
 +
 ------
@@ -224,7 +224,7 @@
 that the database is up to date any time 'git-cvsserver' is executed).
 
 By default it uses SQLite databases in the Git directory, named
-`gitcvs.<module_name>.sqlite`. Note that the SQLite backend creates
+`gitcvs.<module-name>.sqlite`. Note that the SQLite backend creates
 temporary files in the same directory as the database file on
 write so it might not be enough to grant the users using
 'git-cvsserver' write access to the database file without granting
diff --git a/Documentation/git-daemon.txt b/Documentation/git-daemon.txt
index e064f91..ede7b93 100644
--- a/Documentation/git-daemon.txt
+++ b/Documentation/git-daemon.txt
@@ -18,7 +18,7 @@
 	     [--allow-override=<service>] [--forbid-override=<service>]
 	     [--access-hook=<path>] [--[no-]informative-errors]
 	     [--inetd |
-	      [--listen=<host_or_ipaddr>] [--port=<n>]
+	      [--listen=<host-or-ipaddr>] [--port=<n>]
 	      [--user=<user> [--group=<group>]]]
 	     [--log-destination=(stderr|syslog|none)]
 	     [<directory>...]
@@ -86,10 +86,10 @@
 	Incompatible with --detach, --port, --listen, --user and --group
 	options.
 
---listen=<host_or_ipaddr>::
+--listen=<host-or-ipaddr>::
 	Listen on a specific IP address or hostname.  IP addresses can
 	be either an IPv4 address or an IPv6 address if supported.  If IPv6
-	is not supported, then --listen=hostname is also not supported and
+	is not supported, then --listen=<hostname> is also not supported and
 	--listen must be given an IPv4 address.
 	Can be given more than once.
 	Incompatible with `--inetd` option.
@@ -141,8 +141,8 @@
 	specified with no parameter, a request to
 	git://host/{tilde}alice/foo is taken as a request to access
 	'foo' repository in the home directory of user `alice`.
-	If `--user-path=path` is specified, the same request is
-	taken as a request to access `path/foo` repository in
+	If `--user-path=<path>` is specified, the same request is
+	taken as a request to access `<path>/foo` repository in
 	the home directory of user `alice`.
 
 --verbose::
diff --git a/Documentation/git-diagnose.txt b/Documentation/git-diagnose.txt
index 3ec8cc7..0711959 100644
--- a/Documentation/git-diagnose.txt
+++ b/Documentation/git-diagnose.txt
@@ -45,7 +45,7 @@
 -s <format>::
 --suffix <format>::
 	Specify an alternate suffix for the diagnostics archive name, to create
-	a file named 'git-diagnostics-<formatted suffix>'. This should take the
+	a file named 'git-diagnostics-<formatted-suffix>'. This should take the
 	form of a strftime(3) format string; the current local time will be
 	used.
 
diff --git a/Documentation/git-difftool.txt b/Documentation/git-difftool.txt
index 50cb080..a616f8b 100644
--- a/Documentation/git-difftool.txt
+++ b/Documentation/git-difftool.txt
@@ -90,7 +90,7 @@
 --extcmd=<command>::
 	Specify a custom command for viewing diffs.
 	'git-difftool' ignores the configured defaults and runs
-	`$command $LOCAL $REMOTE` when this option is specified.
+	`<command> $LOCAL $REMOTE` when this option is specified.
 	Additionally, `$BASE` is set in the environment.
 
 -g::
@@ -105,7 +105,6 @@
 	`merge.tool` until a tool is found.
 
 --[no-]trust-exit-code::
-	'git-difftool' invokes a diff tool individually on each file.
 	Errors reported by the diff tool are ignored by default.
 	Use `--trust-exit-code` to make 'git-difftool' exit when an
 	invoked diff tool returns a non-zero exit code.
diff --git a/Documentation/git-fast-export.txt b/Documentation/git-fast-export.txt
index 4643ddb..752e4b9 100644
--- a/Documentation/git-fast-export.txt
+++ b/Documentation/git-fast-export.txt
@@ -48,7 +48,7 @@
 when encountering such a tag.  With 'drop' it will omit such tags from
 the output.  With 'rewrite', if the tagged object is a commit, it will
 rewrite the tag to tag an ancestor commit (via parent rewriting; see
-linkgit:git-rev-list[1])
+linkgit:git-rev-list[1]).
 
 -M::
 -C::
diff --git a/Documentation/git-fast-import.txt b/Documentation/git-fast-import.txt
index bd7b1e0..3d43515 100644
--- a/Documentation/git-fast-import.txt
+++ b/Documentation/git-fast-import.txt
@@ -303,7 +303,7 @@
 	with e.g. bogus timezone values.
 
 `rfc2822`::
-	This is the standard email format as described by RFC 2822.
+	This is the standard date format as described by RFC 2822.
 +
 An example value is ``Tue Feb 6 11:22:18 2007 -0500''.  The Git
 parser is accurate, but a little on the lenient side.  It is the
@@ -630,18 +630,28 @@
 In both formats `<path>` is the complete path of the file to be added
 (if not already existing) or modified (if already existing).
 
-A `<path>` string must use UNIX-style directory separators (forward
-slash `/`), may contain any byte other than `LF`, and must not
-start with double quote (`"`).
+A `<path>` can be written as unquoted bytes or a C-style quoted string.
 
-A path can use C-style string quoting; this is accepted in all cases
-and mandatory if the filename starts with double quote or contains
-`LF`. In C-style quoting, the complete name should be surrounded with
-double quotes, and any `LF`, backslash, or double quote characters
-must be escaped by preceding them with a backslash (e.g.,
-`"path/with\n, \\ and \" in it"`).
+When a `<path>` does not start with a double quote (`"`), it is an
+unquoted string and is parsed as literal bytes without any escape
+sequences. However, if the filename contains `LF` or starts with double
+quote, it cannot be represented as an unquoted string and must be
+quoted. Additionally, the source `<path>` in `filecopy` or `filerename`
+must be quoted if it contains SP.
 
-The value of `<path>` must be in canonical form. That is it must not:
+When a `<path>` starts with a double quote (`"`), it is a C-style quoted
+string, where the complete filename is enclosed in a pair of double
+quotes and escape sequences are used. Certain characters must be escaped
+by preceding them with a backslash: `LF` is written as `\n`, backslash
+as `\\`, and double quote as `\"`. Some characters may optionally be
+written with escape sequences: `\a` for bell, `\b` for backspace, `\f`
+for form feed, `\n` for line feed, `\r` for carriage return, `\t` for
+horizontal tab, and `\v` for vertical tab. Any byte can be written with
+3-digit octal codes (e.g., `\033`). All filenames can be represented as
+quoted strings.
+
+A `<path>` must use UNIX-style directory separators (forward slash `/`)
+and its value must be in canonical form. That is it must not:
 
 * contain an empty directory component (e.g. `foo//bar` is invalid),
 * end with a directory separator (e.g. `foo/` is invalid),
@@ -651,6 +661,7 @@
 
 The root of the tree can be represented by an empty string as `<path>`.
 
+`<path>` cannot contain NUL, either literally or escaped as `\000`.
 It is recommended that `<path>` always be encoded using UTF-8.
 
 `filedelete`
@@ -745,11 +756,11 @@
 
 `notemodify`
 ^^^^^^^^^^^^
-Included in a `commit` `<notes_ref>` command to add a new note
+Included in a `commit` `<notes-ref>` command to add a new note
 annotating a `<commit-ish>` or change this annotation contents.
 Internally it is similar to filemodify 100644 on `<commit-ish>`
 path (maybe split into subdirectories). It's not advised to
-use any other commands to write to the `<notes_ref>` tree except
+use any other commands to write to the `<notes-ref>` tree except
 `filedeleteall` to delete all existing notes in this tree.
 This command has two different means of specifying the content
 of the note.
diff --git a/Documentation/git-fetch.txt b/Documentation/git-fetch.txt
index f123139..50900a5 100644
--- a/Documentation/git-fetch.txt
+++ b/Documentation/git-fetch.txt
@@ -186,8 +186,8 @@
 ------------------------------------------------
 $ git fetch origin --prune --prune-tags
 $ git fetch origin --prune 'refs/tags/*:refs/tags/*'
-$ git fetch <url of origin> --prune --prune-tags
-$ git fetch <url of origin> --prune 'refs/tags/*:refs/tags/*'
+$ git fetch <url-of-origin> --prune --prune-tags
+$ git fetch <url-of-origin> --prune 'refs/tags/*:refs/tags/*'
 ------------------------------------------------
 
 OUTPUT
diff --git a/Documentation/git-filter-branch.txt b/Documentation/git-filter-branch.txt
index 62e482a..5a4f853 100644
--- a/Documentation/git-filter-branch.txt
+++ b/Documentation/git-filter-branch.txt
@@ -14,7 +14,7 @@
 	[--msg-filter <command>] [--commit-filter <command>]
 	[--tag-name-filter <command>] [--prune-empty]
 	[--original <namespace>] [-d <directory>] [-f | --force]
-	[--state-branch <branch>] [--] [<rev-list options>...]
+	[--state-branch <branch>] [--] [<rev-list-options>...]
 
 WARNING
 -------
@@ -32,7 +32,7 @@
 DESCRIPTION
 -----------
 Lets you rewrite Git revision history by rewriting the branches mentioned
-in the <rev-list options>, applying custom filters on each revision.
+in the <rev-list-options>, applying custom filters on each revision.
 Those filters can modify each tree (e.g. removing a file or running
 a perl rewrite on all files) or information about each commit.
 Otherwise, all information (including original commit times or merge
@@ -624,7 +624,7 @@
      real backup; it dereferences tags first.)
 
   ** Running git-filter-branch with either --tags or --all in your
-     <rev-list options>.  In order to retain annotated tags as
+     <rev-list-options>.  In order to retain annotated tags as
      annotated, you must use --tag-name-filter (and must not have
      restored from refs/original/ in a previously botched rewrite).
 
diff --git a/Documentation/git-for-each-ref.txt b/Documentation/git-for-each-ref.txt
index e86d570..c1dd12b 100644
--- a/Documentation/git-for-each-ref.txt
+++ b/Documentation/git-for-each-ref.txt
@@ -10,7 +10,7 @@
 [verse]
 'git for-each-ref' [--count=<count>] [--shell|--perl|--python|--tcl]
 		   [(--sort=<key>)...] [--format=<format>]
-		   [ --stdin | <pattern>... ]
+		   [--include-root-refs] [ --stdin | <pattern>... ]
 		   [--points-at=<object>]
 		   [--merged[=<object>]] [--no-merged[=<object>]]
 		   [--contains[=<object>]] [--no-contains[=<object>]]
@@ -51,17 +51,14 @@
 	key.
 
 --format=<format>::
-	A string that interpolates `%(fieldname)` from a ref being shown
-	and the object it points at.  If `fieldname`
-	is prefixed with an asterisk (`*`) and the ref points
-	at a tag object, use the value for the field in the object
-	which the tag object refers to (instead of the field in the tag object).
-	When unspecified, `<format>` defaults to
-	`%(objectname) SPC %(objecttype) TAB %(refname)`.
-	It also interpolates `%%` to `%`, and `%xx` where `xx`
-	are hex digits interpolates to character with hex code
-	`xx`; for example `%00` interpolates to `\0` (NUL),
-	`%09` to `\t` (TAB) and `%0a` to `\n` (LF).
+	A string that interpolates `%(fieldname)` from a ref being shown and
+	the object it points at. In addition, the string literal `%%`
+	renders as `%` and `%xx` - where `xx` are hex digits - renders as
+	the character with hex code `xx`. For example, `%00` interpolates to
+	`\0` (NUL), `%09` to `\t` (TAB), and `%0a` to `\n` (LF).
++
+When unspecified, `<format>` defaults to `%(objectname) SPC %(objecttype)
+TAB %(refname)`.
 
 --color[=<when>]::
 	Respect any colors specified in the `--format` option. The
@@ -108,6 +105,9 @@
 	any excluded pattern(s) are shown. Matching is done using the
 	same rules as `<pattern>` above.
 
+--include-root-refs::
+	List root refs (HEAD and pseudorefs) apart from regular refs.
+
 FIELD NAMES
 -----------
 
@@ -298,6 +298,10 @@
 from the `committer` or `tagger` fields depending on the object type.
 These are intended for working on a mix of annotated and lightweight tags.
 
+For tag objects, a `fieldname` prefixed with an asterisk (`*`) expands to
+the `fieldname` value of the peeled object, rather than that of the tag
+object itself.
+
 Fields that have name-email-date tuple as its value (`author`,
 `committer`, and `tagger`) can be suffixed with `name`, `email`,
 and `date` to extract the named component.  For email fields (`authoremail`,
@@ -358,9 +362,11 @@
 the object referred by the ref does not cause an error.  It
 returns an empty string instead.
 
-As a special case for the date-type fields, you may specify a format for
-the date by adding `:` followed by date format name (see the
-values the `--date` option to linkgit:git-rev-list[1] takes).
+As a special case for the date-type fields, you may specify a format for the
+date by adding `:` followed by date format name (see the values the `--date`
+option to linkgit:git-rev-list[1] takes). If this formatting is provided in
+a `--sort` key, references will be sorted according to the byte-value of the
+formatted string rather than the numeric value of the underlying timestamp.
 
 Some atoms like %(align) and %(if) always require a matching %(end).
 We call them "opening atoms" and sometimes denote them as %($open).
diff --git a/Documentation/git-for-each-repo.txt b/Documentation/git-for-each-repo.txt
index 94bd19d..abe3527 100644
--- a/Documentation/git-for-each-repo.txt
+++ b/Documentation/git-for-each-repo.txt
@@ -42,6 +42,15 @@
 as available. If `git for-each-repo` is run in a directory that is not a
 Git repository, then only the system and global config is used.
 
+--keep-going::
+	Continue with the remaining repositories if the command failed
+	on a repository. The exit code will still indicate that the
+	overall operation was not successful.
++
+Note that the exact exit code of the failing command is not passed
+through as the exit code of the `for-each-repo` command: If the command
+failed in any of the specified repositories, the overall exit code will
+be 1.
 
 SUBPROCESS BEHAVIOR
 -------------------
diff --git a/Documentation/git-format-patch.txt b/Documentation/git-format-patch.txt
index 414da6b..728bb38 100644
--- a/Documentation/git-format-patch.txt
+++ b/Documentation/git-format-patch.txt
@@ -17,10 +17,10 @@
 		   [--signature-file=<file>]
 		   [-n | --numbered | -N | --no-numbered]
 		   [--start-number <n>] [--numbered-files]
-		   [--in-reply-to=<message id>] [--suffix=.<sfx>]
+		   [--in-reply-to=<message-id>] [--suffix=.<sfx>]
 		   [--ignore-if-in-upstream] [--always]
 		   [--cover-from-description=<mode>]
-		   [--rfc] [--subject-prefix=<subject prefix>]
+		   [--rfc] [--subject-prefix=<subject-prefix>]
 		   [(--reroll-count|-v) <n>]
 		   [--to=<email>] [--cc=<email>]
 		   [--[no-]cover-letter] [--quiet]
@@ -30,8 +30,8 @@
 		   [--range-diff=<previous> [--creation-factor=<percent>]]
 		   [--filename-max-length=<n>]
 		   [--progress]
-		   [<common diff options>]
-		   [ <since> | <revision range> ]
+		   [<common-diff-options>]
+		   [ <since> | <revision-range> ]
 
 DESCRIPTION
 -----------
@@ -64,7 +64,7 @@
    to the tip of the current branch that are not in the history
    that leads to the <since> to be output.
 
-2. Generic <revision range> expression (see "SPECIFYING
+2. Generic <revision-range> expression (see "SPECIFYING
    REVISIONS" section in linkgit:gitrevisions[7]) means the
    commits in the specified range.
 
@@ -179,9 +179,9 @@
 itself.  If you want `git format-patch` to take care of threading, you
 will want to ensure that threading is disabled for `git send-email`.
 
---in-reply-to=<message id>::
+--in-reply-to=<message-id>::
 	Make the first mail (or all the mails with `--no-thread`) appear as a
-	reply to the given <message id>, which avoids breaking threads to
+	reply to the given <message-id>, which avoids breaking threads to
 	provide a new patch series.
 
 --ignore-if-in-upstream::
@@ -219,9 +219,9 @@
 	Use the contents of <file> instead of the branch's description
 	for generating the cover letter.
 
---subject-prefix=<subject prefix>::
+--subject-prefix=<subject-prefix>::
 	Instead of the standard '[PATCH]' prefix in the subject
-	line, instead use '[<subject prefix>]'. This can be used
+	line, instead use '[<subject-prefix>]'. This can be used
 	to name a patch series, and can be combined with the
 	`--numbered` option.
 +
@@ -403,7 +403,7 @@
 	`format.useAutoBase` configuration.
 
 --root::
-	Treat the revision argument as a <revision range>, even if it
+	Treat the revision argument as a <revision-range>, even if it
 	is just a single commit (that would normally be treated as a
 	<since>).  Note that root commits included in the specified
 	range are always formatted as creation patches, independently
diff --git a/Documentation/git-grep.txt b/Documentation/git-grep.txt
index 0d0103c..1e6d7b6 100644
--- a/Documentation/git-grep.txt
+++ b/Documentation/git-grep.txt
@@ -28,7 +28,7 @@
 	   [-f <file>] [-e] <pattern>
 	   [--and|--or|--not|(|)|-e <pattern>...]
 	   [--recurse-submodules] [--parent-basename <basename>]
-	   [ [--[no-]exclude-standard] [--cached | --no-index | --untracked] | <tree>...]
+	   [ [--[no-]exclude-standard] [--cached | --untracked | --no-index] | <tree>...]
 	   [--] [<pathspec>...]
 
 DESCRIPTION
@@ -45,13 +45,21 @@
 	Instead of searching tracked files in the working tree, search
 	blobs registered in the index file.
 
---no-index::
-	Search files in the current directory that is not managed by Git.
-
 --untracked::
 	In addition to searching in the tracked files in the working
 	tree, search also in untracked files.
 
+--no-index::
+	Search files in the current directory that is not managed by Git,
+	or by ignoring that the current directory is managed by Git.  This
+	is rather similar to running the regular `grep(1)` utility with its
+	`-r` option specified, but with some additional benefits, such as
+	using pathspec patterns to limit paths;  see the 'pathspec' entry
+	in linkgit:gitglossary[7] for more information.
++
+This option cannot be used together with `--cached` or `--untracked`.
+See also `grep.fallbackToNoIndex` in 'CONFIGURATION' below.
+
 --no-exclude-standard::
 	Also search in ignored files by not honoring the `.gitignore`
 	mechanism. Only useful with `--untracked`.
@@ -64,9 +72,9 @@
 --recurse-submodules::
 	Recursively search in each submodule that is active and
 	checked out in the repository.  When used in combination with the
-	<tree> option the prefix of all submodule output will be the name of
-	the parent project's <tree> object. This option has no effect
-	if `--no-index` is given.
+	_<tree>_ option the prefix of all submodule output will be the name of
+	the parent project's _<tree>_ object.  This option cannot be used together
+	with `--untracked`, and it has no effect if `--no-index` is specified.
 
 -a::
 --text::
@@ -178,7 +186,7 @@
 	Use \0 as the delimiter for pathnames in the output, and print
 	them verbatim. Without this option, pathnames with "unusual"
 	characters are quoted as explained for the configuration
-	variable core.quotePath (see linkgit:git-config[1]).
+	variable `core.quotePath` (see linkgit:git-config[1]).
 
 -o::
 --only-matching::
@@ -248,8 +256,8 @@
 	a non-zero status.
 
 --threads <num>::
-	Number of grep worker threads to use.
-	See `grep.threads` in 'CONFIGURATION' for more information.
+	Number of `grep` worker threads to use.  See 'NOTES ON THREADS'
+	and `grep.threads` in 'CONFIGURATION' for more information.
 
 -f <file>::
 	Read patterns from <file>, one per line.
@@ -332,13 +340,13 @@
 NOTES ON THREADS
 ----------------
 
-The `--threads` option (and the grep.threads configuration) will be ignored when
+The `--threads` option (and the `grep.threads` configuration) will be ignored when
 `--open-files-in-pager` is used, forcing a single-threaded execution.
 
 When grepping the object store (with `--cached` or giving tree objects), running
-with multiple threads might perform slower than single threaded if `--textconv`
-is given and there are too many text conversions. So if you experience low
-performance in this case, it might be desirable to use `--threads=1`.
+with multiple threads might perform slower than single-threaded if `--textconv`
+is given and there are too many text conversions.  Thus, if low performance is
+experienced in this case, it might be desirable to use `--threads=1`.
 
 CONFIGURATION
 -------------
diff --git a/Documentation/git-gui.txt b/Documentation/git-gui.txt
index e8f3ccb..f5b02ef 100644
--- a/Documentation/git-gui.txt
+++ b/Documentation/git-gui.txt
@@ -114,7 +114,7 @@
 
 The official repository of the 'git gui' project can be found at:
 
-  https://github.com/prati0100/git-gui.git/
+  https://github.com/j6t/git-gui
 
 GIT
 ---
diff --git a/Documentation/git-index-pack.txt b/Documentation/git-index-pack.txt
index 6486620..5a20dee 100644
--- a/Documentation/git-index-pack.txt
+++ b/Documentation/git-index-pack.txt
@@ -79,8 +79,13 @@
 	to force the version for the generated pack index, and to force
 	64-bit index entries on objects located above the given offset.
 
---strict::
-	Die, if the pack contains broken objects or links.
+--strict[=<msg-id>=<severity>...]::
+	Die, if the pack contains broken objects or links. An optional
+	comma-separated list of `<msg-id>=<severity>` can be passed to change
+	the severity of some possible issues, e.g.,
+	 `--strict="missingEmail=ignore,badTagName=error"`. See the entry for the
+	`fsck.<msg-id>` configuration options in linkgit:git-fsck[1] for more
+	information on the possible values of `<msg-id>` and `<severity>`.
 
 --progress-title::
 	For internal use only.
@@ -91,13 +96,18 @@
 --check-self-contained-and-connected::
 	Die if the pack contains broken links. For internal use only.
 
---fsck-objects::
-	For internal use only.
+--fsck-objects[=<msg-id>=<severity>...]::
+	Die if the pack contains broken objects, but unlike `--strict`, don't
+	choke on broken links. If the pack contains a tree pointing to a
+	.gitmodules blob that does not exist, prints the hash of that blob
+	(for the caller to check) after the hash that goes into the name of the
+	pack/idx file (see "Notes").
 +
-Die if the pack contains broken objects. If the pack contains a tree
-pointing to a .gitmodules blob that does not exist, prints the hash of
-that blob (for the caller to check) after the hash that goes into the
-name of the pack/idx file (see "Notes").
+An optional comma-separated list of `<msg-id>=<severity>` can be passed to
+change the severity of some possible issues, e.g.,
+`--fsck-objects="missingEmail=ignore,badTagName=ignore"`. See the entry for the
+`fsck.<msg-id>` configuration options in linkgit:git-fsck[1] for more
+information on the possible values of `<msg-id>` and `<severity>`.
 
 --threads=<n>::
 	Specifies the number of threads to spawn when resolving
diff --git a/Documentation/git-init.txt b/Documentation/git-init.txt
index 6f0d297..daff93b 100644
--- a/Documentation/git-init.txt
+++ b/Documentation/git-init.txt
@@ -9,10 +9,11 @@
 SYNOPSIS
 --------
 [verse]
-'git init' [-q | --quiet] [--bare] [--template=<template-directory>]
-	  [--separate-git-dir <git-dir>] [--object-format=<format>]
-	  [-b <branch-name> | --initial-branch=<branch-name>]
-	  [--shared[=<permissions>]] [<directory>]
+`git init` [`-q` | `--quiet`] [`--bare`] [++--template=++__<template-directory>__]
+	  [`--separate-git-dir` _<git-dir>_] [++--object-format=++__<format>__]
+	  [++--ref-format=++__<format>__]
+	  [`-b` _<branch-name>_ | ++--initial-branch=++__<branch-name>__]
+	  [++--shared++[++=++__<permissions>__]] [_<directory>_]
 
 
 DESCRIPTION
@@ -32,37 +33,43 @@
 are created underneath; otherwise, the default `$GIT_DIR/objects`
 directory is used.
 
-Running 'git init' in an existing repository is safe. It will not
+Running `git init` in an existing repository is safe. It will not
 overwrite things that are already there. The primary reason for
-rerunning 'git init' is to pick up newly added templates (or to move
-the repository to another place if --separate-git-dir is given).
+rerunning `git init` is to pick up newly added templates (or to move
+the repository to another place if `--separate-git-dir` is given).
 
 OPTIONS
 -------
 
--q::
---quiet::
+`-q`::
+`--quiet`::
 
 Only print error and warning messages; all other output will be suppressed.
 
---bare::
+`--bare`::
 
 Create a bare repository. If `GIT_DIR` environment is not set, it is set to the
 current working directory.
 
---object-format=<format>::
+++--object-format=++__<format>__::
 
-Specify the given object format (hash algorithm) for the repository.  The valid
-values are 'sha1' and (if enabled) 'sha256'.  'sha1' is the default.
+Specify the given object _<format>_ (hash algorithm) for the repository.  The valid
+values are `sha1` and (if enabled) `sha256`.  `sha1` is the default.
 +
 include::object-format-disclaimer.txt[]
 
---template=<template-directory>::
+++--ref-format=++__<format>__::
+
+Specify the given ref storage _<format>_ for the repository. The valid values are:
++
+include::ref-storage-format.txt[]
+
+++--template=++__<template-directory>__::
 
 Specify the directory from which templates will be used.  (See the "TEMPLATE
 DIRECTORY" section below.)
 
---separate-git-dir=<git-dir>::
+++--separate-git-dir=++__<git-dir>__::
 
 Instead of initializing the repository as a directory to either `$GIT_DIR` or
 `./.git/`, create a text file there containing the path to the actual
@@ -71,52 +78,56 @@
 +
 If this is a reinitialization, the repository will be moved to the specified path.
 
--b <branch-name>::
---initial-branch=<branch-name>::
+`-b` _<branch-name>_::
+++--initial-branch=++__<branch-name>__::
 
-Use the specified name for the initial branch in the newly created
+Use _<branch-name>_ for the initial branch in the newly created
 repository.  If not specified, fall back to the default name (currently
 `master`, but this is subject to change in the future; the name can be
 customized via the `init.defaultBranch` configuration variable).
 
---shared[=(false|true|umask|group|all|world|everybody|<perm>)]::
+++--shared++[++=++(`false`|`true`|`umask`|`group`|`all`|`world`|`everybody`|_<perm>_)]::
 
 Specify that the Git repository is to be shared amongst several users.  This
 allows users belonging to the same group to push into that
-repository.  When specified, the config variable "core.sharedRepository" is
+repository.  When specified, the config variable `core.sharedRepository` is
 set so that files and directories under `$GIT_DIR` are created with the
 requested permissions.  When not specified, Git will use permissions reported
-by umask(2).
+by `umask`(2).
 +
-The option can have the following values, defaulting to 'group' if no value
+The option can have the following values, defaulting to `group` if no value
 is given:
 +
 --
-'umask' (or 'false')::
+`umask`::
+`false`::
 
-Use permissions reported by umask(2). The default, when `--shared` is not
+Use permissions reported by `umask`(2). The default, when `--shared` is not
 specified.
 
-'group' (or 'true')::
+`group`::
+`true`::
 
-Make the repository group-writable, (and g+sx, since the git group may not be
+Make the repository group-writable, (and `g+sx`, since the git group may not be
 the primary group of all users). This is used to loosen the permissions of an
-otherwise safe umask(2) value. Note that the umask still applies to the other
-permission bits (e.g. if umask is '0022', using 'group' will not remove read
-privileges from other (non-group) users). See '0xxx' for how to exactly specify
+otherwise safe `umask`(2) value. Note that the umask still applies to the other
+permission bits (e.g. if umask is `0022`, using `group` will not remove read
+privileges from other (non-group) users). See `0xxx` for how to exactly specify
 the repository permissions.
 
-'all' (or 'world' or 'everybody')::
+`all`::
+`world`::
+`everybody`::
 
-Same as 'group', but make the repository readable by all users.
+Same as `group`, but make the repository readable by all users.
 
-'<perm>'::
+_<perm>_::
 
-'<perm>' is a 3-digit octal number prefixed with `0` and each file
-will have mode '<perm>'. '<perm>' will override users' umask(2)
-value (and not only loosen permissions as 'group' and 'all'
-do). '0640' will create a repository which is group-readable, but
-not group-writable or accessible to others. '0660' will create a repo
+_<perm>_ is a 3-digit octal number prefixed with `0` and each file
+will have mode _<perm>_. _<perm>_ will override users' `umask`(2)
+value (and not only loosen permissions as `group` and `all`
+do). `0640` will create a repository which is group-readable, but
+not group-writable or accessible to others. `0660` will create a repo
 that is readable and writable to the current user and group, but
 inaccessible to others (directories and executable files get their
 `x` bit from the `r` bit for corresponding classes of users).
@@ -126,7 +137,7 @@
 in shared repositories, so that you cannot force a non fast-forwarding push
 into it.
 
-If you provide a 'directory', the command is run inside it. If this directory
+If you provide a _<directory>_, the command is run inside it. If this directory
 does not exist, it will be created.
 
 TEMPLATE DIRECTORY
@@ -165,7 +176,7 @@
 $ git commit    <3>
 ----------------
 +
-<1> Create a /path/to/my/codebase/.git directory.
+<1> Create a `/path/to/my/codebase/.git` directory.
 <2> Add all existing files to the index.
 <3> Record the pristine state as the first commit in the history.
 
@@ -174,6 +185,8 @@
 
 include::includes/cmd-config-section-all.txt[]
 
+:git-init:
+
 include::config/init.txt[]
 
 GIT
diff --git a/Documentation/git-interpret-trailers.txt b/Documentation/git-interpret-trailers.txt
index 418265f..d9dfb75 100644
--- a/Documentation/git-interpret-trailers.txt
+++ b/Documentation/git-interpret-trailers.txt
@@ -9,7 +9,7 @@
 --------
 [verse]
 'git interpret-trailers' [--in-place] [--trim-empty]
-			[(--trailer (<key>|<keyAlias>)[(=|:)<value>])...]
+			[(--trailer (<key>|<key-alias>)[(=|:)<value>])...]
 			[--parse] [<file>...]
 
 DESCRIPTION
@@ -67,9 +67,9 @@
 This means that the trimmed <key> and <value> will be separated by
 `': '` (one colon followed by one space).
 
-For convenience, a <keyAlias> can be configured to make using `--trailer`
+For convenience, a <key-alias> can be configured to make using `--trailer`
 shorter to type on the command line. This can be configured using the
-'trailer.<keyAlias>.key' configuration variable. The <keyAlias> must be a prefix
+'trailer.<key-alias>.key' configuration variable. The <keyAlias> must be a prefix
 of the full <key> string, although case sensitivity does not matter. For
 example, if you have
 
diff --git a/Documentation/git-ls-files.txt b/Documentation/git-ls-files.txt
index f65a8cd..d08c7da 100644
--- a/Documentation/git-ls-files.txt
+++ b/Documentation/git-ls-files.txt
@@ -119,8 +119,10 @@
 
 --exclude-per-directory=<file>::
 	Read additional exclude patterns that apply only to the
-	directory and its subdirectories in <file>.  Deprecated; use
-	--exclude-standard instead.
+	directory and its subdirectories in <file>.  If you are
+	trying to emulate the way Porcelain commands work, using
+	the `--exclude-standard` option instead is easier and more
+	thorough.
 
 --exclude-standard::
 	Add the standard Git exclusions: .git/info/exclude, .gitignore
@@ -298,9 +300,8 @@
 flags --others or --ignored are specified.  linkgit:gitignore[5]
 specifies the format of exclude patterns.
 
-Generally, you should just use --exclude-standard, but for historical
-reasons the exclude patterns can be specified from the following
-places, in order:
+These exclude patterns can be specified from the following places,
+in order:
 
   1. The command-line flag --exclude=<pattern> specifies a
      single pattern.  Patterns are ordered in the same order
@@ -322,6 +323,18 @@
 by --exclude-per-directory is relative to the directory that the
 pattern file appears in.
 
+Generally, you should be able to use `--exclude-standard` when you
+want the exclude rules applied the same way as what Porcelain
+commands do.  To emulate what `--exclude-standard` specifies, you
+can give `--exclude-per-directory=.gitignore`, and then specify:
+
+  1. The file specified by the `core.excludesfile` configuration
+     variable, if exists, or the `$XDG_CONFIG_HOME/git/ignore` file.
+
+  2. The `$GIT_DIR/info/exclude` file.
+
+via the `--exclude-from=` option.
+
 SEE ALSO
 --------
 linkgit:git-read-tree[1], linkgit:gitignore[5]
diff --git a/Documentation/git-merge-file.txt b/Documentation/git-merge-file.txt
index 6a081ea..71915a0 100644
--- a/Documentation/git-merge-file.txt
+++ b/Documentation/git-merge-file.txt
@@ -92,6 +92,12 @@
 	Instead of leaving conflicts in the file, resolve conflicts
 	favouring our (or their or both) side of the lines.
 
+--diff-algorithm={patience|minimal|histogram|myers}::
+	Use a different diff algorithm while merging. The current default is "myers",
+	but selecting more recent algorithm such as "histogram" can help
+	avoid mismerges that occur due to unimportant matching lines
+	(such as braces from distinct functions). See also
+	linkgit:git-diff[1] `--diff-algorithm`.
 
 EXAMPLES
 --------
diff --git a/Documentation/git-merge-tree.txt b/Documentation/git-merge-tree.txt
index b50acac..84cb2ed 100644
--- a/Documentation/git-merge-tree.txt
+++ b/Documentation/git-merge-tree.txt
@@ -64,10 +64,18 @@
 	share no common history.  This flag can be given to override that
 	check and make the merge proceed anyway.
 
---merge-base=<commit>::
+--merge-base=<tree-ish>::
 	Instead of finding the merge-bases for <branch1> and <branch2>,
 	specify a merge-base for the merge, and specifying multiple bases is
 	currently not supported. This option is incompatible with `--stdin`.
++
+As the merge-base is provided directly, <branch1> and <branch2> do not need
+to specify commits; trees are enough.
+
+-X<option>::
+--strategy-option=<option>::
+	Pass the merge strategy-specific option through to the merge strategy.
+	See linkgit:git-merge[1] for details.
 
 [[OUTPUT]]
 OUTPUT
diff --git a/Documentation/git-mv.txt b/Documentation/git-mv.txt
index 7f991a3..dc1bf61 100644
--- a/Documentation/git-mv.txt
+++ b/Documentation/git-mv.txt
@@ -16,7 +16,7 @@
 Move or rename a file, directory, or symlink.
 
  git mv [-v] [-f] [-n] [-k] <source> <destination>
- git mv [-v] [-f] [-n] [-k] <source> ... <destination directory>
+ git mv [-v] [-f] [-n] [-k] <source> ... <destination-directory>
 
 In the first form, it renames <source>, which must exist and be either
 a file, symlink or directory, to <destination>.
diff --git a/Documentation/git-notes.txt b/Documentation/git-notes.txt
index f8310e5..c9221a6 100644
--- a/Documentation/git-notes.txt
+++ b/Documentation/git-notes.txt
@@ -56,7 +56,7 @@
 list::
 	List the notes object for a given object. If no object is
 	given, show a list of all note objects and the objects they
-	annotate (in the format "<note object> <annotated object>").
+	annotate (in the format "<note-object> <annotated-object>").
 	This is the default subcommand if no subcommand is given.
 
 add::
diff --git a/Documentation/git-pack-refs.txt b/Documentation/git-pack-refs.txt
index 284956a..2dcabaf 100644
--- a/Documentation/git-pack-refs.txt
+++ b/Documentation/git-pack-refs.txt
@@ -8,7 +8,7 @@
 SYNOPSIS
 --------
 [verse]
-'git pack-refs' [--all] [--no-prune] [--include <pattern>] [--exclude <pattern>]
+'git pack-refs' [--all] [--no-prune] [--auto] [--include <pattern>] [--exclude <pattern>]
 
 DESCRIPTION
 -----------
@@ -60,6 +60,19 @@
 The command usually removes loose refs under `$GIT_DIR/refs`
 hierarchy after packing them.  This option tells it not to.
 
+--auto::
+
+Pack refs as needed depending on the current state of the ref database. The
+behavior depends on the ref format used by the repository and may change in the
+future.
++
+	- "files": No special handling for `--auto` has been implemented.
++
+	- "reftable": Tables are compacted such that they form a geometric
+	  sequence. For two tables N and N+1, where N+1 is newer, this
+	  maintains the property that N is at least twice as big as N+1. Only
+	  tables that violate this property are compacted.
+
 --include <pattern>::
 
 Pack refs based on a `glob(7)` pattern. Repetitions of this option
diff --git a/Documentation/git-pull.txt b/Documentation/git-pull.txt
index 0e14f8b..b2ae496 100644
--- a/Documentation/git-pull.txt
+++ b/Documentation/git-pull.txt
@@ -87,7 +87,7 @@
 --verbose::
 	Pass --verbose to git-fetch and git-merge.
 
---[no-]recurse-submodules[=yes|on-demand|no]::
+--[no-]recurse-submodules[=(yes|on-demand|no)]::
 	This option controls if new commits of populated submodules should
 	be fetched, and if the working trees of active submodules should be
 	updated, too (see linkgit:git-fetch[1], linkgit:git-config[1] and
@@ -105,7 +105,7 @@
 include::merge-options.txt[]
 
 -r::
---rebase[=false|true|merges|interactive]::
+--rebase[=(false|true|merges|interactive)]::
 	When true, rebase the current branch on top of the upstream
 	branch after fetching. If there is a remote-tracking branch
 	corresponding to the upstream branch and the upstream branch
diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt
index af05708..74df345 100644
--- a/Documentation/git-rebase.txt
+++ b/Documentation/git-rebase.txt
@@ -12,7 +12,7 @@
 	[--onto <newbase> | --keep-base] [<upstream> [<branch>]]
 'git rebase' [-i | --interactive] [<options>] [--exec <cmd>] [--onto <newbase>]
 	--root [<branch>]
-'git rebase' (--continue | --skip | --abort | --quit | --edit-todo | --show-current-patch)
+'git rebase' (--continue|--skip|--abort|--quit|--edit-todo|--show-current-patch)
 
 DESCRIPTION
 -----------
@@ -289,17 +289,25 @@
 +
 See also INCOMPATIBLE OPTIONS below.
 
---empty=(drop|keep|ask)::
+--empty=(drop|keep|stop)::
 	How to handle commits that are not empty to start and are not
 	clean cherry-picks of any upstream commit, but which become
 	empty after rebasing (because they contain a subset of already
-	upstream changes).  With drop (the default), commits that
-	become empty are dropped.  With keep, such commits are kept.
-	With ask (implied by `--interactive`), the rebase will halt when
-	an empty commit is applied allowing you to choose whether to
-	drop it, edit files more, or just commit the empty changes.
-	Other options, like `--exec`, will use the default of drop unless
-	`-i`/`--interactive` is explicitly specified.
+	upstream changes):
++
+--
+`drop`;;
+	The commit will be dropped. This is the default behavior.
+`keep`;;
+	The commit will be kept. This option is implied when `--exec` is
+	specified unless `-i`/`--interactive` is also specified.
+`stop`;;
+`ask`;;
+	The rebase will halt when the commit is applied, allowing you to
+	choose whether to drop it, edit files more, or just commit the empty
+	changes. This option is implied when `-i`/`--interactive` is
+	specified. `ask` is a deprecated synonym of `stop`.
+--
 +
 Note that commits which start empty are kept (unless `--no-keep-empty`
 is specified), and commits which are clean cherry-picks (as determined
@@ -589,21 +597,27 @@
 
 --autosquash::
 --no-autosquash::
-	When the commit log message begins with "squash! ..." or "fixup! ..."
-	or "amend! ...", and there is already a commit in the todo list that
-	matches the same `...`, automatically modify the todo list of
-	`rebase -i`, so that the commit marked for squashing comes right after
-	the commit to be modified, and change the action of the moved commit
-	from `pick` to `squash` or `fixup` or `fixup -C` respectively. A commit
-	matches the `...` if the commit subject matches, or if the `...` refers
-	to the commit's hash. As a fall-back, partial matches of the commit
-	subject work, too. The recommended way to create fixup/amend/squash
-	commits is by using the `--fixup`, `--fixup=amend:` or `--fixup=reword:`
-	and `--squash` options respectively of linkgit:git-commit[1].
+	Automatically squash commits with specially formatted messages into
+	previous commits being rebased.  If a commit message starts with
+	"squash! ", "fixup! " or "amend! ", the remainder of the subject line
+	is taken as a commit specifier, which matches a previous commit if it
+	matches the subject line or the hash of that commit.  If no commit
+	matches fully, matches of the specifier with the start of commit
+	subjects are considered.
 +
-If the `--autosquash` option is enabled by default using the
-configuration variable `rebase.autoSquash`, this option can be
-used to override and disable this setting.
+In the rebase todo list, the actions of squash, fixup and amend commits are
+changed from `pick` to `squash`, `fixup` or `fixup -C`, respectively, and they
+are moved right after the commit they modify.  The `--interactive` option can
+be used to review and edit the todo list before proceeding.
++
+The recommended way to create commits with squash markers is by using the
+`--squash`, `--fixup`, `--fixup=amend:` or `--fixup=reword:` options of
+linkgit:git-commit[1], which take the target commit as an argument and
+automatically fill in the subject line of the new commit from that.
++
+Setting configuration variable `rebase.autoSquash` to true enables
+auto-squashing by default for interactive rebase.  The `--no-autosquash`
+option can be used to override that setting.
 +
 See also INCOMPATIBLE OPTIONS below.
 
@@ -698,7 +712,7 @@
 Similar to the apply backend, by default the merge backend drops
 commits that become empty unless `-i`/`--interactive` is specified (in
 which case it stops and asks the user what to do).  The merge backend
-also has an `--empty=(drop|keep|ask)` option for changing the behavior
+also has an `--empty=(drop|keep|stop)` option for changing the behavior
 of handling commits that become empty.
 
 Directory rename detection
diff --git a/Documentation/git-reflog.txt b/Documentation/git-reflog.txt
index ec64cbf..a929c52 100644
--- a/Documentation/git-reflog.txt
+++ b/Documentation/git-reflog.txt
@@ -10,6 +10,7 @@
 --------
 [verse]
 'git reflog' [show] [<log-options>] [<ref>]
+'git reflog list'
 'git reflog expire' [--expire=<time>] [--expire-unreachable=<time>]
 	[--rewrite] [--updateref] [--stale-fix]
 	[--dry-run | -n] [--verbose] [--all [--single-worktree] | <refs>...]
@@ -39,6 +40,8 @@
 `git reflog show` is an alias for `git log -g --abbrev-commit
 --pretty=oneline`; see linkgit:git-log[1] for more information.
 
+The "list" subcommand lists all refs which have a corresponding reflog.
+
 The "expire" subcommand prunes older reflog entries. Entries older
 than `expire` time, or entries older than `expire-unreachable` time
 and not reachable from the current tip, are removed from the reflog.
diff --git a/Documentation/git-remote.txt b/Documentation/git-remote.txt
index 1dec314..932a5c3 100644
--- a/Documentation/git-remote.txt
+++ b/Documentation/git-remote.txt
@@ -35,7 +35,7 @@
 -v::
 --verbose::
 	Be a little more verbose and show remote url after name.
-	For promisor remotes, also show which filter (`blob:none` etc.)
+	For promisor remotes, also show which filters (`blob:none` etc.)
 	are configured.
 	NOTE: This must be placed between `remote` and subcommand.
 
diff --git a/Documentation/git-replace.txt b/Documentation/git-replace.txt
index 4f25712..0a65460 100644
--- a/Documentation/git-replace.txt
+++ b/Documentation/git-replace.txt
@@ -114,11 +114,11 @@
 The following formats are available:
 
 * 'short':
-	<replaced sha1>
+	<replaced-sha1>
 * 'medium':
-	<replaced sha1> -> <replacement sha1>
+	<replaced-sha1> -> <replacement-sha1>
 * 'long':
-	<replaced sha1> (<replaced type>) -> <replacement sha1> (<replacement type>)
+	<replaced-sha1> (<replaced-type>) -> <replacement-sha1> (<replacement-type>)
 
 CREATING REPLACEMENT OBJECTS
 ----------------------------
diff --git a/Documentation/git-replay.txt b/Documentation/git-replay.txt
new file mode 100644
index 0000000..8f3300c
--- /dev/null
+++ b/Documentation/git-replay.txt
@@ -0,0 +1,127 @@
+git-replay(1)
+=============
+
+NAME
+----
+git-replay - EXPERIMENTAL: Replay commits on a new base, works with bare repos too
+
+
+SYNOPSIS
+--------
+[verse]
+(EXPERIMENTAL!) 'git replay' ([--contained] --onto <newbase> | --advance <branch>) <revision-range>...
+
+DESCRIPTION
+-----------
+
+Takes ranges of commits and replays them onto a new location. Leaves
+the working tree and the index untouched, and updates no references.
+The output of this command is meant to be used as input to
+`git update-ref --stdin`, which would update the relevant branches
+(see the OUTPUT section below).
+
+THIS COMMAND IS EXPERIMENTAL. THE BEHAVIOR MAY CHANGE.
+
+OPTIONS
+-------
+
+--onto <newbase>::
+	Starting point at which to create the new commits.  May be any
+	valid commit, and not just an existing branch name.
++
+When `--onto` is specified, the update-ref command(s) in the output will
+update the branch(es) in the revision range to point at the new
+commits, similar to the way how `git rebase --update-refs` updates
+multiple branches in the affected range.
+
+--advance <branch>::
+	Starting point at which to create the new commits; must be a
+	branch name.
++
+When `--advance` is specified, the update-ref command(s) in the output
+will update the branch passed as an argument to `--advance` to point at
+the new commits (in other words, this mimics a cherry-pick operation).
+
+<revision-range>::
+	Range of commits to replay. More than one <revision-range> can
+	be passed, but in `--advance <branch>` mode, they should have
+	a single tip, so that it's clear where <branch> should point
+	to. See "Specifying Ranges" in linkgit:git-rev-parse[1] and the
+	"Commit Limiting" options below.
+
+include::rev-list-options.txt[]
+
+OUTPUT
+------
+
+When there are no conflicts, the output of this command is usable as
+input to `git update-ref --stdin`.  It is of the form:
+
+	update refs/heads/branch1 ${NEW_branch1_HASH} ${OLD_branch1_HASH}
+	update refs/heads/branch2 ${NEW_branch2_HASH} ${OLD_branch2_HASH}
+	update refs/heads/branch3 ${NEW_branch3_HASH} ${OLD_branch3_HASH}
+
+where the number of refs updated depends on the arguments passed and
+the shape of the history being replayed.  When using `--advance`, the
+number of refs updated is always one, but for `--onto`, it can be one
+or more (rebasing multiple branches simultaneously is supported).
+
+EXIT STATUS
+-----------
+
+For a successful, non-conflicted replay, the exit status is 0.  When
+the replay has conflicts, the exit status is 1.  If the replay is not
+able to complete (or start) due to some kind of error, the exit status
+is something other than 0 or 1.
+
+EXAMPLES
+--------
+
+To simply rebase `mybranch` onto `target`:
+
+------------
+$ git replay --onto target origin/main..mybranch
+update refs/heads/mybranch ${NEW_mybranch_HASH} ${OLD_mybranch_HASH}
+------------
+
+To cherry-pick the commits from mybranch onto target:
+
+------------
+$ git replay --advance target origin/main..mybranch
+update refs/heads/target ${NEW_target_HASH} ${OLD_target_HASH}
+------------
+
+Note that the first two examples replay the exact same commits and on
+top of the exact same new base, they only differ in that the first
+provides instructions to make mybranch point at the new commits and
+the second provides instructions to make target point at them.
+
+What if you have a stack of branches, one depending upon another, and
+you'd really like to rebase the whole set?
+
+------------
+$ git replay --contained --onto origin/main origin/main..tipbranch
+update refs/heads/branch1 ${NEW_branch1_HASH} ${OLD_branch1_HASH}
+update refs/heads/branch2 ${NEW_branch2_HASH} ${OLD_branch2_HASH}
+update refs/heads/tipbranch ${NEW_tipbranch_HASH} ${OLD_tipbranch_HASH}
+------------
+
+When calling `git replay`, one does not need to specify a range of
+commits to replay using the syntax `A..B`; any range expression will
+do:
+
+------------
+$ git replay --onto origin/main ^base branch1 branch2 branch3
+update refs/heads/branch1 ${NEW_branch1_HASH} ${OLD_branch1_HASH}
+update refs/heads/branch2 ${NEW_branch2_HASH} ${OLD_branch2_HASH}
+update refs/heads/branch3 ${NEW_branch3_HASH} ${OLD_branch3_HASH}
+------------
+
+This will simultaneously rebase `branch1`, `branch2`, and `branch3`,
+all commits they have since `base`, playing them on top of
+`origin/main`. These three branches may have commits on top of `base`
+that they have in common, but that does not need to be the case.
+
+GIT
+---
+Part of the linkgit:git[1] suite
diff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt
index 912fab9..f9d5a35 100644
--- a/Documentation/git-rev-parse.txt
+++ b/Documentation/git-rev-parse.txt
@@ -9,7 +9,7 @@
 SYNOPSIS
 --------
 [verse]
-'git rev-parse' [<options>] <args>...
+'git rev-parse' [<options>] <arg>...
 
 DESCRIPTION
 -----------
@@ -130,7 +130,7 @@
 	'git diff-{asterisk}'). In contrast to the `--sq-quote` option,
 	the command input is still interpreted as usual.
 
---short[=length]::
+--short[=<length>]::
 	Same as `--verify` but shortens the object name to a unique
 	prefix with at least `length` characters. The minimum length
 	is 4, the default is the effective value of the `core.abbrev`
@@ -159,15 +159,27 @@
 	unfortunately named tag "master"), and shows them as full
 	refnames (e.g. "refs/heads/master").
 
+--output-object-format=(sha1|sha256|storage)::
+
+	Allow oids to be input from any object format that the current
+	repository supports.
+
+	Specifying "sha1" translates if necessary and returns a sha1 oid.
+
+	Specifying "sha256" translates if necessary and returns a sha256 oid.
+
+	Specifying "storage" translates if necessary and returns an oid in
+	encoded in the storage hash algorithm.
+
 Options for Objects
 ~~~~~~~~~~~~~~~~~~~
 
 --all::
 	Show all refs found in `refs/`.
 
---branches[=pattern]::
---tags[=pattern]::
---remotes[=pattern]::
+--branches[=<pattern>]::
+--tags[=<pattern>]::
+--remotes[=<pattern>]::
 	Show all branches, tags, or remote-tracking branches,
 	respectively (i.e., refs found in `refs/heads`,
 	`refs/tags`, or `refs/remotes`, respectively).
@@ -176,7 +188,7 @@
 shown.  If the pattern does not contain a globbing character (`?`,
 `*`, or `[`), it is turned into a prefix match by appending `/*`.
 
---glob=pattern::
+--glob=<pattern>::
 	Show all refs matching the shell glob pattern `pattern`. If
 	the pattern does not start with `refs/`, this is automatically
 	prepended.  If the pattern does not contain a globbing
@@ -197,7 +209,7 @@
 or `--all`. If a trailing '/{asterisk}' is intended, it must be given
 explicitly.
 
---exclude-hidden=[fetch|receive|uploadpack]::
+--exclude-hidden=(fetch|receive|uploadpack)::
 	Do not include refs that would be hidden by `git-fetch`,
 	`git-receive-pack` or `git-upload-pack` by consulting the appropriate
 	`fetch.hideRefs`, `receive.hideRefs` or `uploadpack.hideRefs`
@@ -307,21 +319,24 @@
 	input, multiple algorithms may be printed, space-separated.
 	If not specified, the default is "storage".
 
+--show-ref-format::
+	Show the reference storage format used for the repository.
+
 
 Other Options
 ~~~~~~~~~~~~~
 
---since=datestring::
---after=datestring::
+--since=<datestring>::
+--after=<datestring>::
 	Parse the date string, and output the corresponding
 	--max-age= parameter for 'git rev-list'.
 
---until=datestring::
---before=datestring::
+--until=<datestring>::
+--before=<datestring>::
 	Parse the date string, and output the corresponding
 	--min-age= parameter for 'git rev-list'.
 
-<args>...::
+<arg>...::
 	Flags and parameters to be parsed.
 
 
diff --git a/Documentation/git-revert.txt b/Documentation/git-revert.txt
index cbe0208..568925d 100644
--- a/Documentation/git-revert.txt
+++ b/Documentation/git-revert.txt
@@ -116,7 +116,7 @@
 
 --reference::
 	Instead of starting the body of the log message with "This
-	reverts <full object name of the commit being reverted>.",
+	reverts <full-object-name-of-the-commit-being-reverted>.",
 	refer to the commit using "--pretty=reference" format
 	(cf. linkgit:git-log[1]).  The `revert.reference`
 	configuration variable can be used to enable this option by
@@ -149,7 +149,7 @@
 _strongly_ recommended to explain why the original commit is being
 reverted.
 In addition, repeatedly reverting reverts will result in increasingly
-unwieldy subject lines, for example 'Reapply "Reapply "<original subject>""'.
+unwieldy subject lines, for example 'Reapply "Reapply "<original-subject>""'.
 Please consider rewording these to be shorter and more unique.
 
 CONFIGURATION
diff --git a/Documentation/git-send-email.txt b/Documentation/git-send-email.txt
index 30deb7f..c5d664f 100644
--- a/Documentation/git-send-email.txt
+++ b/Documentation/git-send-email.txt
@@ -9,8 +9,8 @@
 SYNOPSIS
 --------
 [verse]
-'git send-email' [<options>] <file|directory>...
-'git send-email' [<options>] <format-patch options>
+'git send-email' [<options>] (<file>|<directory>)...
+'git send-email' [<options>] <format-patch-options>
 'git send-email' --dump-aliases
 
 
@@ -138,7 +138,7 @@
 
 --compose-encoding=<encoding>::
 	Specify encoding of compose message. Default is the value of the
-	'sendemail.composeencoding'; if that is unspecified, UTF-8 is assumed.
+	'sendemail.composeEncoding'; if that is unspecified, UTF-8 is assumed.
 
 --transfer-encoding=(7bit|8bit|quoted-printable|base64|auto)::
 	Specify the transfer encoding to be used to send the message over SMTP.
@@ -174,7 +174,7 @@
 	Specify a command to run to send the email. The command should
 	be sendmail-like; specifically, it must support the `-i` option.
 	The command will be executed in the shell if necessary.  Default
-	is the value of `sendemail.sendmailcmd`.  If unspecified, and if
+	is the value of `sendemail.sendmailCmd`.  If unspecified, and if
 	--smtp-server is also unspecified, git-send-email will search
 	for `sendmail` in `/usr/sbin`, `/usr/lib` and $PATH.
 
@@ -269,7 +269,7 @@
 	certificates concatenated together: see verify(1) -CAfile and
 	-CApath for more information on these). Set it to an empty string
 	to disable certificate verification. Defaults to the value of the
-	`sendemail.smtpsslcertpath` configuration variable, if set, or the
+	`sendemail.smtpSSLCertPath` configuration variable, if set, or the
 	backing SSL library's compiled-in default otherwise (which should
 	be the best choice on most platforms).
 
@@ -278,7 +278,7 @@
 	if a username is not specified (with `--smtp-user` or `sendemail.smtpUser`),
 	then authentication is not attempted.
 
---smtp-debug=0|1::
+--smtp-debug=(0|1)::
 	Enable (1) or disable (0) debug output. If enabled, SMTP
 	commands and replies will be printed. Useful to debug TLS
 	connection and authentication problems.
@@ -301,7 +301,9 @@
 Automating
 ~~~~~~~~~~
 
---no-[to|cc|bcc]::
+--no-to::
+--no-cc::
+--no-bcc::
 	Clears any list of "To:", "Cc:", "Bcc:" addresses previously
 	set via config.
 
@@ -313,7 +315,7 @@
 	Specify a command to execute once per patch file which
 	should generate patch file specific "To:" entries.
 	Output of this command must be single email address per line.
-	Default is the value of 'sendemail.tocmd' configuration value.
+	Default is the value of 'sendemail.toCmd' configuration value.
 
 --cc-cmd=<command>::
 	Specify a command to execute once per patch file which
@@ -348,19 +350,19 @@
 
 --[no-]signed-off-by-cc::
 	If this is set, add emails found in the `Signed-off-by` trailer or Cc: lines to the
-	cc list. Default is the value of `sendemail.signedoffbycc` configuration
+	cc list. Default is the value of `sendemail.signedOffByCc` configuration
 	value; if that is unspecified, default to --signed-off-by-cc.
 
 --[no-]cc-cover::
 	If this is set, emails found in Cc: headers in the first patch of
 	the series (typically the cover letter) are added to the cc list
-	for each email set. Default is the value of 'sendemail.cccover'
+	for each email set. Default is the value of 'sendemail.ccCover'
 	configuration value; if that is unspecified, default to --no-cc-cover.
 
 --[no-]to-cover::
 	If this is set, emails found in To: headers in the first patch of
 	the series (typically the cover letter) are added to the to list
-	for each email set. Default is the value of 'sendemail.tocover'
+	for each email set. Default is the value of 'sendemail.toCover'
 	configuration value; if that is unspecified, default to --no-to-cover.
 
 --suppress-cc=<category>::
@@ -384,7 +386,7 @@
 - 'all' will suppress all auto cc values.
 --
 +
-Default is the value of `sendemail.suppresscc` configuration value; if
+Default is the value of `sendemail.suppressCc` configuration value; if
 that is unspecified, default to 'self' if --suppress-from is
 specified, as well as 'body' if --no-signed-off-cc is specified.
 
@@ -471,7 +473,7 @@
 	Instead of the normal operation, dump the shorthand alias names from
 	the configured alias file(s), one per line in alphabetical order. Note
 	that this only includes the alias name and not its expanded email addresses.
-	See 'sendemail.aliasesfile' for more information about aliases.
+	See 'sendemail.aliasesFile' for more information about aliases.
 
 
 CONFIGURATION
diff --git a/Documentation/git-status.txt b/Documentation/git-status.txt
index 10fecc5..9a37688 100644
--- a/Documentation/git-status.txt
+++ b/Documentation/git-status.txt
@@ -79,6 +79,8 @@
 `git update-index --untracked-cache` and `git update-index
 --split-index`), Otherwise you can use `no` to have `git status`
 return more quickly without showing untracked files.
+All usual spellings for Boolean value `true` are taken as `normal`
+and `false` as `no`.
 
 The default can be changed using the status.showUntrackedFiles
 configuration variable documented in linkgit:git-config[1].
@@ -309,7 +311,7 @@
 ------------------------------------------------------------
 # branch.oid <commit> | (initial)        Current commit.
 # branch.head <branch> | (detached)      Current branch.
-# branch.upstream <upstream_branch>      If upstream is set.
+# branch.upstream <upstream-branch>      If upstream is set.
 # branch.ab +<ahead> -<behind>           If upstream is set and
 					 the commit is present.
 ------------------------------------------------------------
@@ -472,7 +474,7 @@
 results, so it could be faster on subsequent runs.
 
 * The `--untracked-files=no` flag or the
-	`status.showUntrackedfiles=false` config (see above for both):
+	`status.showUntrackedFiles=no` config (see above for both):
 	indicate that `git status` should not report untracked
 	files. This is the fastest option. `git status` will not list
 	the untracked files, so you need to be careful to remember if
@@ -502,7 +504,7 @@
 	usually worth the additional size.
 
 * `core.untrackedCache=true` and `core.fsmonitor=true` or
-	`core.fsmonitor=<hook_command_pathname>` (see
+	`core.fsmonitor=<hook-command-pathname>` (see
 	linkgit:git-update-index[1]): enable both the untracked cache
 	and FSMonitor features and only search directories that have
 	been modified since the previous `git status` command.  This
diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt
index 6957306..ca0347a 100644
--- a/Documentation/git-submodule.txt
+++ b/Documentation/git-submodule.txt
@@ -136,7 +136,7 @@
 that use linkgit:git-rm[1] instead. See linkgit:gitsubmodules[7] for removal
 options.
 
-update [--init] [--remote] [-N|--no-fetch] [--[no-]recommend-shallow] [-f|--force] [--checkout|--rebase|--merge] [--reference <repository>] [--depth <depth>] [--recursive] [--jobs <n>] [--[no-]single-branch] [--filter <filter spec>] [--] [<path>...]::
+update [--init] [--remote] [-N|--no-fetch] [--[no-]recommend-shallow] [-f|--force] [--checkout|--rebase|--merge] [--reference <repository>] [--depth <depth>] [--recursive] [--jobs <n>] [--[no-]single-branch] [--filter <filter-spec>] [--] [<path>...]::
 +
 --
 Update the registered submodules to match what the superproject
@@ -185,7 +185,7 @@
 If `--recursive` is specified, this command will recurse into the
 registered submodules, and update any nested submodules within.
 
-If `--filter <filter spec>` is specified, the given partial clone filter will be
+If `--filter <filter-spec>` is specified, the given partial clone filter will be
 applied to the submodule. See linkgit:git-rev-list[1] for details on filter
 specifications.
 --
diff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt
index 4e92308..43c68c2 100644
--- a/Documentation/git-svn.txt
+++ b/Documentation/git-svn.txt
@@ -37,12 +37,12 @@
 	argument.  Normally this command initializes the current
 	directory.
 
--T<trunk_subdir>;;
---trunk=<trunk_subdir>;;
--t<tags_subdir>;;
---tags=<tags_subdir>;;
--b<branches_subdir>;;
---branches=<branches_subdir>;;
+-T<trunk-subdir>;;
+--trunk=<trunk-subdir>;;
+-t<tags-subdir>;;
+--tags=<tags-subdir>;;
+-b<branches-subdir>;;
+--branches=<branches-subdir>;;
 -s;;
 --stdlayout;;
 	These are optional command-line options for init.  Each of
@@ -726,9 +726,9 @@
 	when tracking a single URL.  The 'log' and 'dcommit' commands
 	no longer require this switch as an argument.
 
--R<remote name>::
---svn-remote <remote name>::
-	Specify the [svn-remote "<remote name>"] section to use,
+-R<remote-name>::
+--svn-remote <remote-name>::
+	Specify the [svn-remote "<remote-name>"] section to use,
 	this allows SVN multiple repositories to be tracked.
 	Default: "svn"
 
diff --git a/Documentation/git-switch.txt b/Documentation/git-switch.txt
index 3e23a82..f38e4c8 100644
--- a/Documentation/git-switch.txt
+++ b/Documentation/git-switch.txt
@@ -59,13 +59,18 @@
 -c <new-branch>::
 --create <new-branch>::
 	Create a new branch named `<new-branch>` starting at
-	`<start-point>` before switching to the branch. This is a
-	convenient shortcut for:
+	`<start-point>` before switching to the branch. This is the
+	transactional equivalent of
 +
 ------------
 $ git branch <new-branch>
 $ git switch <new-branch>
 ------------
++
+that is to say, the branch is not reset/created unless "git switch" is
+successful (e.g., when the branch is in use in another worktree, not
+just the current branch stays the same, but the branch is not reset to
+the start-point, either).
 
 -C <new-branch>::
 --force-create <new-branch>::
diff --git a/Documentation/git-tag.txt b/Documentation/git-tag.txt
index d42efb3..5fe519c 100644
--- a/Documentation/git-tag.txt
+++ b/Documentation/git-tag.txt
@@ -224,7 +224,7 @@
 
 -------------------------------------
 [user]
-    signingKey = <gpg-key_id>
+    signingKey = <gpg-key-id>
 -------------------------------------
 
 `pager.tag` is only respected when listing tags, i.e., when `-l` is
diff --git a/Documentation/git-update-ref.txt b/Documentation/git-update-ref.txt
index 0561808..374a2eb 100644
--- a/Documentation/git-update-ref.txt
+++ b/Documentation/git-update-ref.txt
@@ -8,21 +8,21 @@
 SYNOPSIS
 --------
 [verse]
-'git update-ref' [-m <reason>] [--no-deref] (-d <ref> [<oldvalue>] | [--create-reflog] <ref> <newvalue> [<oldvalue>] | --stdin [-z])
+'git update-ref' [-m <reason>] [--no-deref] (-d <ref> [<old-oid>] | [--create-reflog] <ref> <new-oid> [<old-oid>] | --stdin [-z])
 
 DESCRIPTION
 -----------
-Given two arguments, stores the <newvalue> in the <ref>, possibly
+Given two arguments, stores the <new-oid> in the <ref>, possibly
 dereferencing the symbolic refs.  E.g. `git update-ref HEAD
-<newvalue>` updates the current branch head to the new object.
+<new-oid>` updates the current branch head to the new object.
 
-Given three arguments, stores the <newvalue> in the <ref>,
+Given three arguments, stores the <new-oid> in the <ref>,
 possibly dereferencing the symbolic refs, after verifying that
-the current value of the <ref> matches <oldvalue>.
-E.g. `git update-ref refs/heads/master <newvalue> <oldvalue>`
-updates the master branch head to <newvalue> only if its current
-value is <oldvalue>.  You can specify 40 "0" or an empty string
-as <oldvalue> to make sure that the ref you are creating does
+the current value of the <ref> matches <old-oid>.
+E.g. `git update-ref refs/heads/master <new-oid> <old-oid>`
+updates the master branch head to <new-oid> only if its current
+value is <old-oid>.  You can specify 40 "0" or an empty string
+as <old-oid> to make sure that the ref you are creating does
 not exist.
 
 It also allows a "ref" file to be a symbolic pointer to another
@@ -56,15 +56,15 @@
 archive by creating a symlink tree).
 
 With `-d` flag, it deletes the named <ref> after verifying it
-still contains <oldvalue>.
+still contains <old-oid>.
 
 With `--stdin`, update-ref reads instructions from standard input and
 performs all modifications together.  Specify commands of the form:
 
-	update SP <ref> SP <newvalue> [SP <oldvalue>] LF
-	create SP <ref> SP <newvalue> LF
-	delete SP <ref> [SP <oldvalue>] LF
-	verify SP <ref> [SP <oldvalue>] LF
+	update SP <ref> SP <new-oid> [SP <old-oid>] LF
+	create SP <ref> SP <new-oid> LF
+	delete SP <ref> [SP <old-oid>] LF
+	verify SP <ref> [SP <old-oid>] LF
 	option SP <opt> LF
 	start LF
 	prepare LF
@@ -82,10 +82,10 @@
 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
-	delete SP <ref> NUL [<oldvalue>] NUL
-	verify SP <ref> NUL [<oldvalue>] NUL
+	update SP <ref> NUL <new-oid> NUL [<old-oid>] NUL
+	create SP <ref> NUL <new-oid> NUL
+	delete SP <ref> NUL [<old-oid>] NUL
+	verify SP <ref> NUL [<old-oid>] NUL
 	option SP <opt> NUL
 	start NUL
 	prepare NUL
@@ -100,22 +100,22 @@
 repeated <ref> produce an error.  Command meanings are:
 
 update::
-	Set <ref> to <newvalue> after verifying <oldvalue>, if given.
-	Specify a zero <newvalue> to ensure the ref does not exist
-	after the update and/or a zero <oldvalue> to make sure the
+	Set <ref> to <new-oid> after verifying <old-oid>, if given.
+	Specify a zero <new-oid> to ensure the ref does not exist
+	after the update and/or a zero <old-oid> to make sure the
 	ref does not exist before the update.
 
 create::
-	Create <ref> with <newvalue> after verifying it does not
-	exist.  The given <newvalue> may not be zero.
+	Create <ref> with <new-oid> after verifying it does not
+	exist.  The given <new-oid> may not be zero.
 
 delete::
-	Delete <ref> after verifying it exists with <oldvalue>, if
-	given.  If given, <oldvalue> may not be zero.
+	Delete <ref> after verifying it exists with <old-oid>, if
+	given.  If given, <old-oid> may not be zero.
 
 verify::
-	Verify <ref> against <oldvalue> but do not change it.  If
-	<oldvalue> is zero or missing, the ref must not exist.
+	Verify <ref> against <old-oid> but do not change it.  If
+	<old-oid> is zero or missing, the ref must not exist.
 
 option::
 	Modify the behavior of the next command naming a <ref>.
@@ -141,7 +141,7 @@
 	Abort the transaction, releasing all locks if the transaction is in
 	prepared state.
 
-If all <ref>s can be locked with matching <oldvalue>s
+If all <ref>s can be locked with matching <old-oid>s
 simultaneously, all modifications are performed.  Otherwise, no
 modifications are performed.  Note that while each individual
 <ref> is updated or deleted atomically, a concurrent reader may
@@ -161,7 +161,7 @@
 
 Where "oldsha1" is the 40 character hexadecimal value previously
 stored in <ref>, "newsha1" is the 40 character hexadecimal value of
-<newvalue> and "committer" is the committer's name, email address
+<new-oid> and "committer" is the committer's name, email address
 and date in the standard Git committer ident format.
 
 Optionally with -m:
diff --git a/Documentation/git-upload-pack.txt b/Documentation/git-upload-pack.txt
index 7ad60bc..516d163 100644
--- a/Documentation/git-upload-pack.txt
+++ b/Documentation/git-upload-pack.txt
@@ -55,6 +55,37 @@
 	admins may need to configure some transports to allow this
 	variable to be passed. See the discussion in linkgit:git[1].
 
+`GIT_NO_LAZY_FETCH`::
+	When cloning or fetching from a partial repository (i.e., one
+	itself cloned with `--filter`), the server-side `upload-pack`
+	may need to fetch extra objects from its upstream in order to
+	complete the request. By default, `upload-pack` will refuse to
+	perform such a lazy fetch, because `git fetch` may run arbitrary
+	commands specified in configuration and hooks of the source
+	repository (and `upload-pack` tries to be safe to run even in
+	untrusted `.git` directories).
++
+This is implemented by having `upload-pack` internally set the
+`GIT_NO_LAZY_FETCH` variable to `1`. If you want to override it
+(because you are fetching from a partial clone, and you are sure
+you trust it), you can explicitly set `GIT_NO_LAZY_FETCH` to
+`0`.
+
+SECURITY
+--------
+
+Most Git commands should not be run in an untrusted `.git` directory
+(see the section `SECURITY` in linkgit:git[1]). `upload-pack` tries to
+avoid any dangerous configuration options or hooks from the repository
+it's serving, making it safe to clone an untrusted directory and run
+commands on the resulting clone.
+
+For an extra level of safety, you may be able to run `upload-pack` as an
+alternate user. The details will be platform dependent, but on many
+systems you can run:
+
+    git clone --no-local --upload-pack='sudo -u nobody git-upload-pack' ...
+
 SEE ALSO
 --------
 linkgit:gitnamespaces[7]
diff --git a/Documentation/git.txt b/Documentation/git.txt
index 962887f..024a01d 100644
--- a/Documentation/git.txt
+++ b/Documentation/git.txt
@@ -174,8 +174,17 @@
 	directory.
 
 --no-replace-objects::
-	Do not use replacement refs to replace Git objects. See
-	linkgit:git-replace[1] for more information.
+	Do not use replacement refs to replace Git objects.
+	This is equivalent to exporting the `GIT_NO_REPLACE_OBJECTS`
+	environment variable with any value.
+	See linkgit:git-replace[1] for more information.
+
+--no-lazy-fetch::
+	Do not fetch missing objects from the promisor remote on
+	demand.  Useful together with `git cat-file -e <object>` to
+	see if the object is locally available.
+	This is equivalent to setting the `GIT_NO_LAZY_FETCH`
+	environment variable to `1`.
 
 --literal-pathspecs::
 	Treat pathspecs literally (i.e. no globbing, no pathspec magic).
@@ -202,7 +211,7 @@
 	Do not perform optional operations that require locks. This is
 	equivalent to setting the `GIT_OPTIONAL_LOCKS` to `0`.
 
---list-cmds=group[,group...]::
+--list-cmds=<group>[,<group>...]::
 	List commands by group. This is an internal/experimental
 	option and may change or be removed in the future. Supported
 	groups are: builtins, parseopt (builtin commands that use
@@ -556,6 +565,11 @@
 	is always used. The default is "sha1".
 	See `--object-format` in linkgit:git-init[1].
 
+`GIT_DEFAULT_REF_FORMAT`::
+	If this variable is set, the default reference backend format for new
+	repositories will be set to this value. The default is "files".
+	See `--ref-format` in linkgit:git-init[1].
+
 Git Commits
 ~~~~~~~~~~~
 `GIT_AUTHOR_NAME`::
@@ -837,7 +851,7 @@
 collisions).
 +
 In addition, if the variable is set to
-`af_unix:[<socket_type>:]<absolute-pathname>`, Git will try
+`af_unix:[<socket-type>:]<absolute-pathname>`, Git will try
 to open the path as a Unix Domain Socket.  The socket type
 can be either `stream` or `dgram`.
 +
@@ -867,6 +881,10 @@
 	header and packfile URIs. Set this Boolean environment variable to false to prevent this
 	redaction.
 
+`GIT_NO_REPLACE_OBJECTS`::
+	Setting and exporting this environment variable tells Git to
+	ignore replacement refs and do not replace Git objects.
+
 `GIT_LITERAL_PATHSPECS`::
 	Setting this Boolean environment variable to true will cause Git to treat all
 	pathspecs literally, rather than as glob patterns. For example,
@@ -888,6 +906,11 @@
 	Setting this Boolean environment variable to true will cause Git to treat all
 	pathspecs as case-insensitive.
 
+`GIT_NO_LAZY_FETCH`::
+	Setting this Boolean environment variable to true tells Git
+	not to lazily fetch missing objects from the promisor remote
+	on demand.
+
 `GIT_REFLOG_ACTION`::
 	When a ref is updated, reflog entries are created to keep
 	track of the reason why the ref was updated (which is
@@ -937,7 +960,7 @@
 `GIT_PROTOCOL`::
 	For internal use only.  Used in handshaking the wire protocol.
 	Contains a colon ':' separated list of keys with optional values
-	'key[=value]'.  Presence of unknown keys and values must be
+	'<key>[=<value>]'.  Presence of unknown keys and values must be
 	ignored.
 +
 Note that servers may need to be configured to allow this variable to
@@ -1044,6 +1067,37 @@
 for a given pathname.  These stages are used to hold the various
 unmerged version of a file when a merge is in progress.
 
+SECURITY
+--------
+
+Some configuration options and hook files may cause Git to run arbitrary
+shell commands. Because configuration and hooks are not copied using
+`git clone`, it is generally safe to clone remote repositories with
+untrusted content, inspect them with `git log`, and so on.
+
+However, it is not safe to run Git commands in a `.git` directory (or
+the working tree that surrounds it) when that `.git` directory itself
+comes from an untrusted source. The commands in its config and hooks
+are executed in the usual way.
+
+By default, Git will refuse to run when the repository is owned by
+someone other than the user running the command. See the entry for
+`safe.directory` in linkgit:git-config[1]. While this can help protect
+you in a multi-user environment, note that you can also acquire
+untrusted repositories that are owned by you (for example, if you
+extract a zip file or tarball from an untrusted source). In such cases,
+you'd need to "sanitize" the untrusted repository first.
+
+If you have an untrusted `.git` directory, you should first clone it
+with `git clone --no-local` to obtain a clean copy. Git does restrict
+the set of options and hooks that will be run by `upload-pack`, which
+handles the server side of a clone or fetch, but beware that the
+surface area for attack against `upload-pack` is large, so this does
+carry some risk. The safest thing is to serve the repository as an
+unprivileged user (either via linkgit:git-daemon[1], ssh, or using
+other tools to change user ids). See the discussion in the `SECURITY`
+section of linkgit:git-upload-pack[1].
+
 FURTHER DOCUMENTATION
 ---------------------
 
diff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt
index 8c1793c..4338d02 100644
--- a/Documentation/gitattributes.txt
+++ b/Documentation/gitattributes.txt
@@ -100,6 +100,21 @@
 the name of the attribute prefixed with an exclamation point `!`.
 
 
+RESERVED BUILTIN_* ATTRIBUTES
+-----------------------------
+
+builtin_* is a reserved namespace for builtin attribute values. Any
+user defined attributes under this namespace will be ignored and
+trigger a warning.
+
+`builtin_objectmode`
+~~~~~~~~~~~~~~~~~~~~
+This attribute is for filtering files by their file bit modes (40000,
+120000, 160000, 100755, 100644). e.g. ':(attr:builtin_objectmode=160000)'.
+You may also check these values with `git check-attr builtin_objectmode -- <file>`.
+If the object is not in the index `git check-attr --cached` will return unspecified.
+
+
 EFFECTS
 -------
 
@@ -1122,11 +1137,11 @@
 name.
 
 The `merge.*.driver` variable's value is used to construct a
-command to run to merge ancestor's version (`%O`), current
+command to run to common ancestor's version (`%O`), current
 version (`%A`) and the other branches' version (`%B`).  These
 three tokens are replaced with the names of temporary files that
 hold the contents of these versions when the command line is
-built. Additionally, %L will be replaced with the conflict marker
+built. Additionally, `%L` will be replaced with the conflict marker
 size (see below).
 
 The merge driver is expected to leave the result of the merge in
@@ -1144,8 +1159,9 @@
 internal merge and the final merge.
 
 The merge driver can learn the pathname in which the merged result
-will be stored via placeholder `%P`.
-
+will be stored via placeholder `%P`. The conflict labels to be used
+for the common ancestor, local head and other head can be passed by
+using '%S', '%X' and '%Y` respectively.
 
 `conflict-marker-size`
 ^^^^^^^^^^^^^^^^^^^^^^
diff --git a/Documentation/gitcli.txt b/Documentation/gitcli.txt
index e5fac94..7c70932 100644
--- a/Documentation/gitcli.txt
+++ b/Documentation/gitcli.txt
@@ -81,9 +81,6 @@
 Here are the rules regarding the "flags" that you should follow when you are
 scripting Git:
 
- * It's preferred to use the non-dashed form of Git commands, which means that
-   you should prefer `git foo` to `git-foo`.
-
  * Splitting short options to separate words (prefer `git foo -a -b`
    to `git foo -ab`, the latter may not even work).
 
diff --git a/Documentation/gitdiffcore.txt b/Documentation/gitdiffcore.txt
index 3cda2e0..642c512 100644
--- a/Documentation/gitdiffcore.txt
+++ b/Documentation/gitdiffcore.txt
@@ -245,20 +245,20 @@
 
 This transformation limits the set of filepairs to those that change
 specified strings between the preimage and the postimage in a certain
-way.  -S<block of text> and -G<regular expression> options are used to
+way.  -S<block-of-text> and -G<regular-expression> options are used to
 specify different ways these strings are sought.
 
-"-S<block of text>" detects filepairs whose preimage and postimage
+"-S<block-of-text>" detects filepairs whose preimage and postimage
 have different number of occurrences of the specified block of text.
 By definition, it will not detect in-file moves.  Also, when a
 changeset moves a file wholesale without affecting the interesting
 string, diffcore-rename kicks in as usual, and `-S` omits the filepair
 (since the number of occurrences of that string didn't change in that
 rename-detected filepair).  When used with `--pickaxe-regex`, treat
-the <block of text> as an extended POSIX regular expression to match,
+the <block-of-text> as an extended POSIX regular expression to match,
 instead of a literal string.
 
-"-G<regular expression>" (mnemonic: grep) detects filepairs whose
+"-G<regular-expression>" (mnemonic: grep) detects filepairs whose
 textual diff has an added or a deleted line that matches the given
 regular expression.  This means that it will detect in-file (or what
 rename-detection considers the same file) moves, which is noise.  The
diff --git a/Documentation/gitformat-index.txt b/Documentation/gitformat-index.txt
index 0773e5c..145cace 100644
--- a/Documentation/gitformat-index.txt
+++ b/Documentation/gitformat-index.txt
@@ -386,8 +386,8 @@
 	long, "REUC" extension that is M-bytes long, followed by "EOIE",
 	then the hash would be:
 
-	Hash("TREE" + <binary representation of N> +
-		"REUC" + <binary representation of M>)
+	Hash("TREE" + <binary-representation-of-N> +
+		"REUC" + <binary-representation-of-M>)
 
 == Index Entry Offset Table
 
diff --git a/Documentation/gitformat-pack.txt b/Documentation/gitformat-pack.txt
index 9fcb29a..d6ae229 100644
--- a/Documentation/gitformat-pack.txt
+++ b/Documentation/gitformat-pack.txt
@@ -396,6 +396,15 @@
 	    is padded at the end with between 0 and 3 NUL bytes to make the
 	    chunk size a multiple of 4 bytes.
 
+	Bitmapped Packfiles (ID: {'B', 'T', 'M', 'P'})
+	    Stores a table of two 4-byte unsigned integers in network order.
+	    Each table entry corresponds to a single pack (in the order that
+	    they appear above in the `PNAM` chunk). The values for each table
+	    entry are as follows:
+	    - The first bit position (in pseudo-pack order, see below) to
+	      contain an object from that pack.
+	    - The number of bits whose objects are selected from that pack.
+
 	OID Fanout (ID: {'O', 'I', 'D', 'F'})
 	    The ith entry, F[i], stores the number of OIDs with first
 	    byte at most i. Thus F[255] stores the total
@@ -509,6 +518,73 @@
 The MIDX's reverse index is stored in the optional 'RIDX' chunk within
 the MIDX itself.
 
+=== `BTMP` chunk
+
+The Bitmapped Packfiles (`BTMP`) chunk encodes additional information
+about the objects in the multi-pack index's reachability bitmap. Recall
+that objects from the MIDX are arranged in "pseudo-pack" order (see
+above) for reachability bitmaps.
+
+From the example above, suppose we have packs "a", "b", and "c", with
+10, 15, and 20 objects, respectively. In pseudo-pack order, those would
+be arranged as follows:
+
+    |a,0|a,1|...|a,9|b,0|b,1|...|b,14|c,0|c,1|...|c,19|
+
+When working with single-pack bitmaps (or, equivalently, multi-pack
+reachability bitmaps with a preferred pack), linkgit:git-pack-objects[1]
+performs ``verbatim'' reuse, attempting to reuse chunks of the bitmapped
+or preferred packfile instead of adding objects to the packing list.
+
+When a chunk of bytes is reused from an existing pack, any objects
+contained therein do not need to be added to the packing list, saving
+memory and CPU time. But a chunk from an existing packfile can only be
+reused when the following conditions are met:
+
+  - The chunk contains only objects which were requested by the caller
+    (i.e. does not contain any objects which the caller didn't ask for
+    explicitly or implicitly).
+
+  - All objects stored in non-thin packs as offset- or reference-deltas
+    also include their base object in the resulting pack.
+
+The `BTMP` chunk encodes the necessary information in order to implement
+multi-pack reuse over a set of packfiles as described above.
+Specifically, the `BTMP` chunk encodes three pieces of information (all
+32-bit unsigned integers in network byte-order) for each packfile `p`
+that is stored in the MIDX, as follows:
+
+`bitmap_pos`:: The first bit position (in pseudo-pack order) in the
+  multi-pack index's reachability bitmap occupied by an object from `p`.
+
+`bitmap_nr`:: The number of bit positions (including the one at
+  `bitmap_pos`) that encode objects from that pack `p`.
+
+For example, the `BTMP` chunk corresponding to the above example (with
+packs ``a'', ``b'', and ``c'') would look like:
+
+[cols="1,2,2"]
+|===
+| |`bitmap_pos` |`bitmap_nr`
+
+|packfile ``a''
+|`0`
+|`10`
+
+|packfile ``b''
+|`10`
+|`15`
+
+|packfile ``c''
+|`25`
+|`20`
+|===
+
+With this information in place, we can treat each packfile as
+individually reusable in the same fashion as verbatim pack reuse is
+performed on individual packs prior to the implementation of the `BTMP`
+chunk.
+
 == cruft packs
 
 The cruft packs feature offer an alternative to Git's traditional mechanism of
diff --git a/Documentation/githooks.txt b/Documentation/githooks.txt
index 883982e..ee9b92c 100644
--- a/Documentation/githooks.txt
+++ b/Documentation/githooks.txt
@@ -243,7 +243,7 @@
 Information about what is to be pushed is provided on the hook's standard
 input with lines of the form:
 
-  <local ref> SP <local object name> SP <remote ref> SP <remote object name> LF
+  <local-ref> SP <local-object-name> SP <remote-ref> SP <remote-object-name> LF
 
 For instance, if the command +git push origin master:foreign+ were run the
 hook would receive a line like the following:
@@ -251,9 +251,9 @@
   refs/heads/master 67890 refs/heads/foreign 12345
 
 although the full object name would be supplied.  If the foreign ref does not
-yet exist the `<remote object name>` will be the all-zeroes object name.  If a
-ref is to be deleted, the `<local ref>` will be supplied as `(delete)` and the
-`<local object name>` will be the all-zeroes object name.  If the local commit
+yet exist the `<remote-object-name>` will be the all-zeroes object name.  If a
+ref is to be deleted, the `<local-ref>` will be supplied as `(delete)` and the
+`<local-object-name>` will be the all-zeroes object name.  If the local commit
 was specified by something other than a name which could be expanded (such as
 `HEAD~`, or an object name) it will be supplied as it was originally given.
 
@@ -275,12 +275,12 @@
 arguments, but for each ref to be updated it receives on standard
 input a line of the format:
 
-  <old-value> SP <new-value> SP <ref-name> LF
+  <old-oid> SP <new-oid> SP <ref-name> LF
 
-where `<old-value>` is the old object name stored in the ref,
-`<new-value>` is the new object name to be stored in the ref and
+where `<old-oid>` is the old object name stored in the ref,
+`<new-oid>` is the new object name to be stored in the ref and
 `<ref-name>` is the full name of the ref.
-When creating a new ref, `<old-value>` is the all-zeroes object name.
+When creating a new ref, `<old-oid>` is the all-zeroes object name.
 
 If the hook exits with non-zero status, none of the refs will be
 updated. If the hook exits with zero, updating of individual refs can
@@ -503,13 +503,13 @@
 For each reference update that was added to the transaction, the hook
 receives on standard input a line of the format:
 
-  <old-value> SP <new-value> SP <ref-name> LF
+  <old-oid> SP <new-oid> SP <ref-name> LF
 
-where `<old-value>` is the old object name passed into the reference
-transaction, `<new-value>` is the new object name to be stored in the
+where `<old-oid>` is the old object name passed into the reference
+transaction, `<new-oid>` is the new object name to be stored in the
 ref and `<ref-name>` is the full name of the ref. When force updating
 the reference regardless of its current value or when the reference is
-to be created anew, `<old-value>` is the all-zeroes object name. To
+to be created anew, `<old-oid>` is the all-zeroes object name. To
 distinguish these cases, you can inspect the current value of
 `<ref-name>` via `git rev-parse`.
 
diff --git a/Documentation/gitk.txt b/Documentation/gitk.txt
index c2213bb..35b3996 100644
--- a/Documentation/gitk.txt
+++ b/Documentation/gitk.txt
@@ -8,7 +8,7 @@
 SYNOPSIS
 --------
 [verse]
-'gitk' [<options>] [<revision range>] [--] [<path>...]
+'gitk' [<options>] [<revision-range>] [--] [<path>...]
 
 DESCRIPTION
 -----------
@@ -124,7 +124,7 @@
 	range to show.  The command is expected to print on its
 	standard output a list of additional revisions to be shown,
 	one per line.  Use this instead of explicitly specifying a
-	'<revision range>' if the set of commits to show may vary
+	'<revision-range>' if the set of commits to show may vary
 	between refreshes.
 
 --select-commit=<ref>::
diff --git a/Documentation/gitprotocol-capabilities.txt b/Documentation/gitprotocol-capabilities.txt
index d6c6eff..2cf7735 100644
--- a/Documentation/gitprotocol-capabilities.txt
+++ b/Documentation/gitprotocol-capabilities.txt
@@ -378,7 +378,7 @@
 or partial fetch and request that the server omit various objects
 from the packfile.
 
-session-id=<session id>
+session-id=<session-id>
 -----------------------
 
 The server may advertise a session ID that can be used to identify this process
diff --git a/Documentation/gitprotocol-http.txt b/Documentation/gitprotocol-http.txt
index 836b349..ec40a55 100644
--- a/Documentation/gitprotocol-http.txt
+++ b/Documentation/gitprotocol-http.txt
@@ -391,14 +391,14 @@
 
 C: Send one `$GIT_URL/git-upload-pack` request:
 
-   C: 0032want <want #1>...............................
-   C: 0032want <want #2>...............................
+   C: 0032want <want-#1>...............................
+   C: 0032want <want-#2>...............................
    ....
-   C: 0032have <common #1>.............................
-   C: 0032have <common #2>.............................
+   C: 0032have <common-#1>.............................
+   C: 0032have <common-#2>.............................
    ....
-   C: 0032have <have #1>...............................
-   C: 0032have <have #2>...............................
+   C: 0032have <have-#1>...............................
+   C: 0032have <have-#2>...............................
    ....
    C: 0000
 
@@ -512,7 +512,7 @@
 the id obtained through ref discovery as old_id.
 
   update_request  =  command_list
-		     "PACK" <binary data>
+		     "PACK" <binary-data>
 
   command_list    =  PKT-LINE(command NUL cap_list LF)
 		     *(command_pkt)
diff --git a/Documentation/gitprotocol-v2.txt b/Documentation/gitprotocol-v2.txt
index 8c1e7c6..414bc62 100644
--- a/Documentation/gitprotocol-v2.txt
+++ b/Documentation/gitprotocol-v2.txt
@@ -199,7 +199,7 @@
 
 Additional features not supported in the base command will be advertised
 as the value of the command in the capability advertisement in the form
-of a space separated list of features: "<command>=<feature 1> <feature 2>"
+of a space separated list of features: "<command>=<feature-1> <feature-2>"
 
 ls-refs takes in the following arguments:
 
@@ -245,7 +245,7 @@
 
 Additional features not supported in the base command will be advertised
 as the value of the command in the capability advertisement in the form
-of a space separated list of features: "<command>=<feature 1> <feature 2>"
+of a space separated list of features: "<command>=<feature-1> <feature-2>"
 
 A `fetch` request can take the following arguments:
 
@@ -346,7 +346,8 @@
     want-ref <ref>
 	Indicates to the server that the client wants to retrieve a
 	particular ref, where <ref> is the full name of a ref on the
-	server.
+	server.  It is a protocol error to send want-ref for the
+	same ref more than once.
 
 If the 'sideband-all' feature is advertised, the following argument can be
 included in the client's request:
@@ -361,9 +362,10 @@
 If the 'packfile-uris' feature is advertised, the following argument
 can be included in the client's request as well as the potential
 addition of the 'packfile-uris' section in the server's response as
-explained below.
+explained below. Note that at most one `packfile-uris` line can be sent
+to the server.
 
-    packfile-uris <comma-separated list of protocols>
+    packfile-uris <comma-separated-list-of-protocols>
 	Indicates to the server that the client is willing to receive
 	URIs of any of the given protocols in place of objects in the
 	sent packfile. Before performing the connectivity check, the
@@ -534,7 +536,7 @@
 only handle SHA-1.  If the client would like to use a hash algorithm other than
 SHA-1, it should specify its object-format string.
 
-session-id=<session id>
+session-id=<session-id>
 ~~~~~~~~~~~~~~~~~~~~~~~
 
 The server may advertise a session ID that can be used to identify this process
diff --git a/Documentation/gitremote-helpers.txt b/Documentation/gitremote-helpers.txt
index ed8da42..d0be008 100644
--- a/Documentation/gitremote-helpers.txt
+++ b/Documentation/gitremote-helpers.txt
@@ -479,14 +479,14 @@
 'option depth' <depth>::
 	Deepens the history of a shallow repository.
 
-'option deepen-since <timestamp>::
+'option deepen-since' <timestamp>::
 	Deepens the history of a shallow repository based on time.
 
-'option deepen-not <ref>::
+'option deepen-not' <ref>::
 	Deepens the history of a shallow repository excluding ref.
 	Multiple options add up.
 
-'option deepen-relative {'true'|'false'}::
+'option deepen-relative' {'true'|'false'}::
 	Deepens the history of a shallow repository relative to
 	current boundary. Only valid when used with "option depth".
 
@@ -526,7 +526,7 @@
 'option pushcert' {'true'|'false'}::
 	GPG sign pushes.
 
-'option push-option <string>::
+'option push-option' <string>::
 	Transmit <string> as a push option. As the push option
 	must not contain LF or NUL characters, the string is not encoded.
 
@@ -542,13 +542,10 @@
 	transaction.  If successful, all refs will be updated, or none will.  If the
 	remote side does not support this capability, the push will fail.
 
-'option object-format' {'true'|algorithm}::
-	If 'true', indicate that the caller wants hash algorithm information
+'option object-format true'::
+	Indicate that the caller wants hash algorithm information
 	to be passed back from the remote.  This mode is used when fetching
 	refs.
-+
-If set to an algorithm, indicate that the caller wants to interact with
-the remote side using that algorithm.
 
 SEE ALSO
 --------
diff --git a/Documentation/gitsubmodules.txt b/Documentation/gitsubmodules.txt
index 8400d59..f7b5a25 100644
--- a/Documentation/gitsubmodules.txt
+++ b/Documentation/gitsubmodules.txt
@@ -151,7 +151,7 @@
 is not affected. This can be undone using `git submodule init`.
 
  * Deleted submodule: A submodule can be deleted by running
-`git rm <submodule path> && git commit`. This can be undone
+`git rm <submodule-path> && git commit`. This can be undone
 using `git revert`.
 +
 The deletion removes the superproject's tracking data, which are
@@ -229,7 +229,7 @@
   git submodule add <URL> <path>
 
   # Occasionally update the submodule to a new version:
-  git -C <path> checkout <new version>
+  git -C <path> checkout <new-version>
   git add <path>
   git commit -m "update submodule to new version"
 
diff --git a/Documentation/gitweb.conf.txt b/Documentation/gitweb.conf.txt
index 59fc1d2..8598358 100644
--- a/Documentation/gitweb.conf.txt
+++ b/Documentation/gitweb.conf.txt
@@ -343,7 +343,7 @@
 	Label for the "home link" at the top of all pages, leading to `$home_link`
 	(usually the main gitweb page, which contains the projects list).  It is
 	used as the first component of gitweb's "breadcrumb trail":
-	`<home link> / <project> / <action>`.  Can be set at build time using
+	`<home-link> / <project> / <action>`.  Can be set at build time using
 	the `GITWEB_HOME_LINK_STR` variable.  By default it is set to "projects",
 	as this link leads to the list of projects.  Another popular choice is to
 	set it to the name of site.  Note that it is treated as raw HTML so it
@@ -604,9 +604,9 @@
 Each `%feature` hash element is a hash reference and has the following
 structure:
 ----------------------------------------------------------------------
-"<feature_name>" => {
-	"sub" => <feature-sub (subroutine)>,
-	"override" => <allow-override (boolean)>,
+"<feature-name>" => {
+	"sub" => <feature-sub-(subroutine)>,
+	"override" => <allow-override-(boolean)>,
 	"default" => [ <options>... ]
 },
 ----------------------------------------------------------------------
@@ -614,7 +614,7 @@
 features the structure of appropriate `%feature` hash element has a simpler
 form:
 ----------------------------------------------------------------------
-"<feature_name>" => {
+"<feature-name>" => {
 	"override" => 0,
 	"default" => [ <options>... ]
 },
diff --git a/Documentation/gitweb.txt b/Documentation/gitweb.txt
index ddd4a0f..56d24a3 100644
--- a/Documentation/gitweb.txt
+++ b/Documentation/gitweb.txt
@@ -305,7 +305,7 @@
 looks like this:
 
 -----------------------------------------------------------------------
-.../gitweb.cgi/<repo>/<action>/<revision_from>:/<path_from>..<revision_to>:/<path_to>?<arguments>
+.../gitweb.cgi/<repo>/<action>/<revision-from>:/<path-from>..<revision-to>:/<path-to>?<arguments>
 -----------------------------------------------------------------------
 
 
diff --git a/Documentation/glossary-content.txt b/Documentation/glossary-content.txt
index f7d98c1..d71b199 100644
--- a/Documentation/glossary-content.txt
+++ b/Documentation/glossary-content.txt
@@ -638,6 +638,20 @@
 	An <<def_object,object>> used to temporarily store the contents of a
 	<<def_dirty,dirty>> working directory and the index for future reuse.
 
+[[def_special_ref]]special ref::
+	A ref that has different semantics than normal refs. These refs can be
+	accessed via normal Git commands but may not behave the same as a
+	normal ref in some cases.
++
+The following special refs are known to Git:
+
+ - "`FETCH_HEAD`" is written by linkgit:git-fetch[1] or linkgit:git-pull[1]. It
+   may refer to multiple object IDs. Each object ID is annotated with metadata
+   indicating where it was fetched from and its fetch status.
+
+ - "`MERGE_HEAD`" is written by linkgit:git-merge[1] when resolving merge
+   conflicts. It contains all commit IDs which are being merged.
+
 [[def_submodule]]submodule::
 	A <<def_repository,repository>> that holds the history of a
 	separate project inside another repository (the latter of
diff --git a/Documentation/howto/update-hook-example.txt b/Documentation/howto/update-hook-example.txt
index 151ee84..4e727de 100644
--- a/Documentation/howto/update-hook-example.txt
+++ b/Documentation/howto/update-hook-example.txt
@@ -100,7 +100,7 @@
 
 if test -f "$allowed_users_file"
 then
-  rc=$(cat $allowed_users_file | grep -v '^#' | grep -v '^$' |
+  rc=$(grep -Ev '^(#|$)' $allowed_users_file |
     while read heads user_patterns
     do
       # does this rule apply to us?
@@ -138,7 +138,7 @@
 
 if test -f "$allowed_groups_file"
 then
-  rc=$(cat $allowed_groups_file | grep -v '^#' | grep -v '^$' |
+  rc=$(grep -Ev '^(#|$)' $allowed_groups_file |
     while read heads group_patterns
     do
       # does this rule apply to us?
diff --git a/Documentation/mergetools/vimdiff.txt b/Documentation/mergetools/vimdiff.txt
index d1a4c46..befa86d 100644
--- a/Documentation/mergetools/vimdiff.txt
+++ b/Documentation/mergetools/vimdiff.txt
@@ -177,7 +177,8 @@
 
 When using these variants, in order to specify a custom layout you will have to
 set configuration variables `mergetool.gvimdiff.layout` and
-`mergetool.nvimdiff.layout` instead of `mergetool.vimdiff.layout`
+`mergetool.nvimdiff.layout` instead of `mergetool.vimdiff.layout` (though the
+latter will be used as fallback if the variant-specific one is not set).
 
 In addition, for backwards compatibility with previous Git versions, you can
 also append `1`, `2` or `3` to either `vimdiff` or any of the variants (ex:
diff --git a/Documentation/pretty-formats.txt b/Documentation/pretty-formats.txt
index d38b4ab..8ee940b 100644
--- a/Documentation/pretty-formats.txt
+++ b/Documentation/pretty-formats.txt
@@ -316,9 +316,8 @@
    `Reviewed-by`.
 ** 'only[=<bool>]': select whether non-trailer lines from the trailer
    block should be included.
-** 'separator=<sep>': specify a separator inserted between trailer
-   lines. When this option is not given each trailer line is
-   terminated with a line feed character. The string <sep> may contain
+** 'separator=<sep>': specify the separator inserted between trailer
+   lines. Defaults to a line feed character. The string <sep> may contain
    the literal formatting codes described above. To use comma as
    separator one must use `%x2C` as it would otherwise be parsed as
    next option. E.g., `%(trailers:key=Ticket,separator=%x2C )`
@@ -329,10 +328,9 @@
    `%(trailers:only,unfold=true)` unfolds and shows all trailer lines.
 ** 'keyonly[=<bool>]': only show the key part of the trailer.
 ** 'valueonly[=<bool>]': only show the value part of the trailer.
-** 'key_value_separator=<sep>': specify a separator inserted between
-   trailer lines. When this option is not given each trailer key-value
-   pair is separated by ": ". Otherwise it shares the same semantics
-   as 'separator=<sep>' above.
+** 'key_value_separator=<sep>': specify the separator inserted between
+   the key and value of each trailer. Defaults to ": ". Otherwise it
+   shares the same semantics as 'separator=<sep>' above.
 
 NOTE: Some placeholders may depend on other options given to the
 revision traversal engine. For example, the `%g*` reflog options will
diff --git a/Documentation/ref-storage-format.txt b/Documentation/ref-storage-format.txt
new file mode 100644
index 0000000..14fff8a
--- /dev/null
+++ b/Documentation/ref-storage-format.txt
@@ -0,0 +1,3 @@
+* `files` for loose files with packed-refs. This is the default.
+* `reftable` for the reftable format. This format is experimental and its
+  internals are subject to change.
diff --git a/Documentation/rev-list-options.txt b/Documentation/rev-list-options.txt
index a583b52..00ccf68 100644
--- a/Documentation/rev-list-options.txt
+++ b/Documentation/rev-list-options.txt
@@ -316,12 +316,12 @@
 With `--pretty` format other than `oneline` and `reference` (for obvious reasons),
 this causes the output to have two extra lines of information
 taken from the reflog.  The reflog designator in the output may be shown
-as `ref@{Nth}` (where `Nth` is the reverse-chronological index in the
-reflog) or as `ref@{timestamp}` (with the timestamp for that entry),
+as `ref@{<Nth>}` (where _<Nth>_ is the reverse-chronological index in the
+reflog) or as `ref@{<timestamp>}` (with the _<timestamp>_ for that entry),
 depending on a few rules:
 +
 --
-1. If the starting point is specified as `ref@{Nth}`, show the index
+1. If the starting point is specified as `ref@{<Nth>}`, show the index
    format.
 +
 2. If the starting point was specified as `ref@{now}`, show the
@@ -341,8 +341,11 @@
 Under `--pretty=reference`, this information will not be shown at all.
 
 --merge::
-	After a failed merge, show refs that touch files having a
-	conflict and don't exist on all heads to merge.
+	Show commits touching conflicted paths in the range `HEAD...<other>`,
+	where `<other>` is the first existing pseudoref in `MERGE_HEAD`,
+	`CHERRY_PICK_HEAD`, `REVERT_HEAD` or `REBASE_HEAD`. Only works
+	when the index has unmerged entries. This option can be used to show
+	relevant commits when resolving conflicts from a 3-way merge.
 
 --boundary::
 	Output excluded boundary commits. Boundary commits are
@@ -1019,6 +1022,10 @@
 +
 The form '--missing=print' is like 'allow-any', but will also print a
 list of the missing objects.  Object IDs are prefixed with a ``?'' character.
++
+If some tips passed to the traversal are missing, they will be
+considered as missing too, and the traversal will ignore them. In case
+we cannot get their Object ID though, an error will be raised.
 
 --exclude-promisor-objects::
 	(For internal use only.)  Prefilter object traversal at
diff --git a/Documentation/technical/repository-version.txt b/Documentation/technical/repository-version.txt
index 045a767..4728142 100644
--- a/Documentation/technical/repository-version.txt
+++ b/Documentation/technical/repository-version.txt
@@ -100,3 +100,9 @@
 multiple working directory mode, "config" file is shared while
 "config.worktree" is per-working directory (i.e., it's in
 GIT_COMMON_DIR/worktrees/<id>/config.worktree)
+
+==== `refStorage`
+
+Specifies the file format for the ref database. The valid values are
+`files` (loose references with a packed-refs file) and `reftable` (see
+Documentation/technical/reftable.txt).
diff --git a/Documentation/technical/unit-tests.txt b/Documentation/technical/unit-tests.txt
new file mode 100644
index 0000000..206037f
--- /dev/null
+++ b/Documentation/technical/unit-tests.txt
@@ -0,0 +1,240 @@
+= Unit Testing
+
+In our current testing environment, we spend a significant amount of effort
+crafting end-to-end tests for error conditions that could easily be captured by
+unit tests (or we simply forgo some hard-to-setup and rare error conditions).
+Unit tests additionally provide stability to the codebase and can simplify
+debugging through isolation. Writing unit tests in pure C, rather than with our
+current shell/test-tool helper setup, simplifies test setup, simplifies passing
+data around (no shell-isms required), and reduces testing runtime by not
+spawning a separate process for every test invocation.
+
+We believe that a large body of unit tests, living alongside the existing test
+suite, will improve code quality for the Git project.
+
+== Definitions
+
+For the purposes of this document, we'll use *test framework* to refer to
+projects that support writing test cases and running tests within the context
+of a single executable. *Test harness* will refer to projects that manage
+running multiple executables (each of which may contain multiple test cases) and
+aggregating their results.
+
+In reality, these terms are not strictly defined, and many of the projects
+discussed below contain features from both categories.
+
+For now, we will evaluate projects solely on their framework features. Since we
+are relying on having TAP output (see below), we can assume that any framework
+can be made to work with a harness that we can choose later.
+
+
+== Summary
+
+We believe the best way forward is to implement a custom TAP framework for the
+Git project. We use a version of the framework originally proposed in
+https://lore.kernel.org/git/c902a166-98ce-afba-93f2-ea6027557176@gmail.com/[1].
+
+See the <<framework-selection,Framework Selection>> section below for the
+rationale behind this decision.
+
+
+== Choosing a test harness
+
+During upstream discussion, it was occasionally noted that `prove` provides many
+convenient features, such as scheduling slower tests first, or re-running
+previously failed tests.
+
+While we already support the use of `prove` as a test harness for the shell
+tests, it is not strictly required. The t/Makefile allows running shell tests
+directly (though with interleaved output if parallelism is enabled). Git
+developers who wish to use `prove` as a more advanced harness can do so by
+setting DEFAULT_TEST_TARGET=prove in their config.mak.
+
+We will follow a similar approach for unit tests: by default the test
+executables will be run directly from the t/Makefile, but `prove` can be
+configured with DEFAULT_UNIT_TEST_TARGET=prove.
+
+
+[[framework-selection]]
+== Framework selection
+
+There are a variety of features we can use to rank the candidate frameworks, and
+those features have different priorities:
+
+* Critical features: we probably won't consider a framework without these
+** Can we legally / easily use the project?
+*** <<license,License>>
+*** <<vendorable-or-ubiquitous,Vendorable or ubiquitous>>
+*** <<maintainable-extensible,Maintainable / extensible>>
+*** <<major-platform-support,Major platform support>>
+** Does the project support our bare-minimum needs?
+*** <<tap-support,TAP support>>
+*** <<diagnostic-output,Diagnostic output>>
+*** <<runtime-skippable-tests,Runtime-skippable tests>>
+* Nice-to-have features:
+** <<parallel-execution,Parallel execution>>
+** <<mock-support,Mock support>>
+** <<signal-error-handling,Signal & error-handling>>
+* Tie-breaker stats
+** <<project-kloc,Project KLOC>>
+** <<adoption,Adoption>>
+
+[[license]]
+=== License
+
+We must be able to legally use the framework in connection with Git. As Git is
+licensed only under GPLv2, we must eliminate any LGPLv3, GPLv3, or Apache 2.0
+projects.
+
+[[vendorable-or-ubiquitous]]
+=== Vendorable or ubiquitous
+
+We want to avoid forcing Git developers to install new tools just to run unit
+tests. Any prospective frameworks and harnesses must either be vendorable
+(meaning, we can copy their source directly into Git's repository), or so
+ubiquitous that it is reasonable to expect that most developers will have the
+tools installed already.
+
+[[maintainable-extensible]]
+=== Maintainable / extensible
+
+It is unlikely that any pre-existing project perfectly fits our needs, so any
+project we select will need to be actively maintained and open to accepting
+changes. Alternatively, assuming we are vendoring the source into our repo, it
+must be simple enough that Git developers can feel comfortable making changes as
+needed to our version.
+
+In the comparison table below, "True" means that the framework seems to have
+active developers, that it is simple enough that Git developers can make changes
+to it, and that the project seems open to accepting external contributions (or
+that it is vendorable). "Partial" means that at least one of the above
+conditions holds.
+
+[[major-platform-support]]
+=== Major platform support
+
+At a bare minimum, unit-testing must work on Linux, MacOS, and Windows.
+
+In the comparison table below, "True" means that it works on all three major
+platforms with no issues. "Partial" means that there may be annoyances on one or
+more platforms, but it is still usable in principle.
+
+[[tap-support]]
+=== TAP support
+
+The https://testanything.org/[Test Anything Protocol] is a text-based interface
+that allows tests to communicate with a test harness. It is already used by
+Git's integration test suite. Supporting TAP output is a mandatory feature for
+any prospective test framework.
+
+In the comparison table below, "True" means this is natively supported.
+"Partial" means TAP output must be generated by post-processing the native
+output.
+
+Frameworks that do not have at least Partial support will not be evaluated
+further.
+
+[[diagnostic-output]]
+=== Diagnostic output
+
+When a test case fails, the framework must generate enough diagnostic output to
+help developers find the appropriate test case in source code in order to debug
+the failure.
+
+[[runtime-skippable-tests]]
+=== Runtime-skippable tests
+
+Test authors may wish to skip certain test cases based on runtime circumstances,
+so the framework should support this.
+
+[[parallel-execution]]
+=== Parallel execution
+
+Ideally, we will build up a significant collection of unit test cases, most
+likely split across multiple executables. It will be necessary to run these
+tests in parallel to enable fast develop-test-debug cycles.
+
+In the comparison table below, "True" means that individual test cases within a
+single test executable can be run in parallel. We assume that executable-level
+parallelism can be handled by the test harness.
+
+[[mock-support]]
+=== Mock support
+
+Unit test authors may wish to test code that interacts with objects that may be
+inconvenient to handle in a test (e.g. interacting with a network service).
+Mocking allows test authors to provide a fake implementation of these objects
+for more convenient tests.
+
+[[signal-error-handling]]
+=== Signal & error handling
+
+The test framework should fail gracefully when test cases are themselves buggy
+or when they are interrupted by signals during runtime.
+
+[[project-kloc]]
+=== Project KLOC
+
+The size of the project, in thousands of lines of code as measured by
+https://dwheeler.com/sloccount/[sloccount] (rounded up to the next multiple of
+1,000). As a tie-breaker, we probably prefer a project with fewer LOC.
+
+[[adoption]]
+=== Adoption
+
+As a tie-breaker, we prefer a more widely-used project. We use the number of
+GitHub / GitLab stars to estimate this.
+
+
+=== Comparison
+
+:true: [lime-background]#True#
+:false: [red-background]#False#
+:partial: [yellow-background]#Partial#
+
+:gpl: [lime-background]#GPL v2#
+:isc: [lime-background]#ISC#
+:mit: [lime-background]#MIT#
+:expat: [lime-background]#Expat#
+:lgpl: [lime-background]#LGPL v2.1#
+
+:custom-impl: https://lore.kernel.org/git/c902a166-98ce-afba-93f2-ea6027557176@gmail.com/[Custom Git impl.]
+:greatest: https://github.com/silentbicycle/greatest[Greatest]
+:criterion: https://github.com/Snaipe/Criterion[Criterion]
+:c-tap: https://github.com/rra/c-tap-harness/[C TAP]
+:check: https://libcheck.github.io/check/[Check]
+
+[format="csv",options="header",width="33%",subs="specialcharacters,attributes,quotes,macros"]
+|=====
+Framework,"<<license,License>>","<<vendorable-or-ubiquitous,Vendorable or ubiquitous>>","<<maintainable-extensible,Maintainable / extensible>>","<<major-platform-support,Major platform support>>","<<tap-support,TAP support>>","<<diagnostic-output,Diagnostic output>>","<<runtime--skippable-tests,Runtime- skippable tests>>","<<parallel-execution,Parallel execution>>","<<mock-support,Mock support>>","<<signal-error-handling,Signal & error handling>>","<<project-kloc,Project KLOC>>","<<adoption,Adoption>>"
+{custom-impl},{gpl},{true},{true},{true},{true},{true},{true},{false},{false},{false},1,0
+{greatest},{isc},{true},{partial},{true},{partial},{true},{true},{false},{false},{false},3,1400
+{criterion},{mit},{false},{partial},{true},{true},{true},{true},{true},{false},{true},19,1800
+{c-tap},{expat},{true},{partial},{partial},{true},{false},{true},{false},{false},{false},4,33
+{check},{lgpl},{false},{partial},{true},{true},{true},{false},{false},{false},{true},17,973
+|=====
+
+=== Additional framework candidates
+
+Several suggested frameworks have been eliminated from consideration:
+
+* Incompatible licenses:
+** https://github.com/zorgnax/libtap[libtap] (LGPL v3)
+** https://cmocka.org/[cmocka] (Apache 2.0)
+* Missing source: https://www.kindahl.net/mytap/doc/index.html[MyTap]
+* No TAP support:
+** https://nemequ.github.io/munit/[µnit]
+** https://github.com/google/cmockery[cmockery]
+** https://github.com/lpabon/cmockery2[cmockery2]
+** https://github.com/ThrowTheSwitch/Unity[Unity]
+** https://github.com/siu/minunit[minunit]
+** https://cunit.sourceforge.net/[CUnit]
+
+
+== Milestones
+
+* Add useful tests of library-like code
+* Integrate with
+  https://lore.kernel.org/git/20230502211454.1673000-1-calvinwan@google.com/[stdlib
+  work]
+* Run alongside regular `make test` target
diff --git a/Documentation/trace2-target-values.txt b/Documentation/trace2-target-values.txt
index 3985b6d..06f1953 100644
--- a/Documentation/trace2-target-values.txt
+++ b/Documentation/trace2-target-values.txt
@@ -5,7 +5,7 @@
 * `<absolute-pathname>` - Writes to the file in append mode. If the target
 already exists and is a directory, the traces will be written to files (one
 per process) underneath the given directory.
-* `af_unix:[<socket_type>:]<absolute-pathname>` - Write to a
+* `af_unix:[<socket-type>:]<absolute-pathname>` - Write to a
 Unix DomainSocket (on platforms that support them).  Socket
 type can be either `stream` or `dgram`; if omitted Git will
 try both.
diff --git a/Documentation/urls.txt b/Documentation/urls.txt
index 4e79c15..7cec85a 100644
--- a/Documentation/urls.txt
+++ b/Documentation/urls.txt
@@ -15,14 +15,14 @@
 
 The following syntaxes may be used with them:
 
-- ssh://{startsb}user@{endsb}host.xz{startsb}:port{endsb}/path/to/repo.git/
-- git://host.xz{startsb}:port{endsb}/path/to/repo.git/
-- http{startsb}s{endsb}://host.xz{startsb}:port{endsb}/path/to/repo.git/
-- ftp{startsb}s{endsb}://host.xz{startsb}:port{endsb}/path/to/repo.git/
+- ++ssh://++{startsb}__<user>__++@++{endsb}__<host>__{startsb}++:++__<port>__{endsb}++/++__<path-to-git-repo>__
+- ++git://++__<host>__{startsb}:__<port>__{endsb}++/++__<path-to-git-repo>__
+- ++http++{startsb}++s++{endsb}++://++__<host>__{startsb}++:++__<port>__{endsb}++/++__<path-to-git-repo>__
+- ++ftp++{startsb}++s++{endsb}++://++__<host>__{startsb}++:++__<port>__{endsb}++/++__<path-to-git-repo>__
 
 An alternative scp-like syntax may also be used with the ssh protocol:
 
-- {startsb}user@{endsb}host.xz:path/to/repo.git/
+- {startsb}__<user>__++@++{endsb}__<host>__++:/++__<path-to-git-repo>__
 
 This syntax is only recognized if there are no slashes before the
 first colon. This helps differentiate a local path that contains a
@@ -30,40 +30,40 @@
 absolute path or `./foo:bar` to avoid being misinterpreted as an ssh
 url.
 
-The ssh and git protocols additionally support ~username expansion:
+The ssh and git protocols additionally support ++~++__<username>__ expansion:
 
-- ssh://{startsb}user@{endsb}host.xz{startsb}:port{endsb}/~{startsb}user{endsb}/path/to/repo.git/
-- git://host.xz{startsb}:port{endsb}/~{startsb}user{endsb}/path/to/repo.git/
-- {startsb}user@{endsb}host.xz:/~{startsb}user{endsb}/path/to/repo.git/
+- ++ssh://++{startsb}__<user>__++@++{endsb}__<host>__{startsb}++:++__<port>__{endsb}++/~++__<user>__++/++__<path-to-git-repo>__
+- ++git://++__<host>__{startsb}++:++__<port>__{endsb}++/~++__<user>__++/++__<path-to-git-repo>__
+- {startsb}__<user>__++@++{endsb}__<host>__++:~++__<user>__++/++__<path-to-git-repo>__
 
 For local repositories, also supported by Git natively, the following
 syntaxes may be used:
 
-- /path/to/repo.git/
-- \file:///path/to/repo.git/
+- `/path/to/repo.git/`
+- ++file:///path/to/repo.git/++
 
 ifndef::git-clone[]
 These two syntaxes are mostly equivalent, except when cloning, when
-the former implies --local option. See linkgit:git-clone[1] for
+the former implies `--local` option. See linkgit:git-clone[1] for
 details.
 endif::git-clone[]
 
 ifdef::git-clone[]
 These two syntaxes are mostly equivalent, except the former implies
---local option.
+`--local` option.
 endif::git-clone[]
 
-'git clone', 'git fetch' and 'git pull', but not 'git push', will also
+`git clone`, `git fetch` and `git pull`, but not `git push`, will also
 accept a suitable bundle file. See linkgit:git-bundle[1].
 
 When Git doesn't know how to handle a certain transport protocol, it
-attempts to use the 'remote-<transport>' remote helper, if one
+attempts to use the `remote-`{empty}__<transport>__ remote helper, if one
 exists. To explicitly request a remote helper, the following syntax
 may be used:
 
-- <transport>::<address>
+- _<transport>_::__<address>__
 
-where <address> may be a path, a server and path, or an arbitrary
+where _<address>_ may be a path, a server and path, or an arbitrary
 URL-like string recognized by the specific remote helper being
 invoked. See linkgit:gitremote-helpers[7] for details.
 
@@ -72,10 +72,11 @@
 use will be rewritten into URLs that work), you can create a
 configuration section of the form:
 
-------------
-	[url "<actual url base>"]
-		insteadOf = <other url base>
-------------
+[verse]
+--
+	[url "__<actual-url-base>__"]
+		insteadOf = _<other-url-base>_
+--
 
 For example, with this:
 
@@ -91,10 +92,11 @@
 If you want to rewrite URLs for push only, you can create a
 configuration section of the form:
 
-------------
-	[url "<actual url base>"]
-		pushInsteadOf = <other url base>
-------------
+[verse]
+--
+	[url "__<actual-url-base>__"]
+		pushInsteadOf = _<other-url-base>_
+--
 
 For example, with this:
 
diff --git a/Documentation/user-manual.txt b/Documentation/user-manual.txt
index 5d32ff2..90a4189 100644
--- a/Documentation/user-manual.txt
+++ b/Documentation/user-manual.txt
@@ -4093,15 +4093,46 @@
 about the data in the object.  It's worth noting that the SHA-1 hash
 that is used to name the object is the hash of the original data
 plus this header, so `sha1sum` 'file' does not match the object name
-for 'file'.
+for 'file' (the earliest versions of Git hashed slightly differently
+but the conclusion is still the same).
+
+The following is a short example that demonstrates how these hashes
+can be generated manually:
+
+Let's assume a small text file with some simple content:
+
+-------------------------------------------------
+$ echo "Hello world" >hello.txt
+-------------------------------------------------
+
+We can now manually generate the hash Git would use for this file:
+
+- The object we want the hash for is of type "blob" and its size is
+  12 bytes.
+
+- Prepend the object header to the file content and feed this to
+  `sha1sum`:
+
+-------------------------------------------------
+$ { printf "blob 12\0"; cat hello.txt; } | sha1sum
+802992c4220de19a90767f3000a79a31b98d0df7  -
+-------------------------------------------------
+
+This manually constructed hash can be verified using `git hash-object`
+which of course hides the addition of the header:
+
+-------------------------------------------------
+$ git hash-object hello.txt
+802992c4220de19a90767f3000a79a31b98d0df7
+-------------------------------------------------
 
 As a result, the general consistency of an object can always be tested
 independently of the contents or the type of the object: all objects can
 be validated by verifying that (a) their hashes match the content of the
 file and (b) the object successfully inflates to a stream of bytes that
 forms a sequence of
-`<ascii type without space> + <space> + <ascii decimal size> +
-<byte\0> + <binary object data>`.
+`<ascii-type-without-space> + <space> + <ascii-decimal-size> +
+<byte\0> + <binary-object-data>`.
 
 The structured objects can further have their structure and
 connectivity to other objects verified. This is generally done with
@@ -4123,7 +4154,8 @@
 ----------------------------------------------------
 
 The initial revision lays the foundation for almost everything Git has
-today, but is small enough to read in one sitting.
+today (even though details may differ in a few places), but is small
+enough to read in one sitting.
 
 Note that terminology has changed since that revision.  For example, the
 README in that revision uses the word "changeset" to describe what we
diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN
index 698e8dc..eb53b0e 100755
--- a/GIT-VERSION-GEN
+++ b/GIT-VERSION-GEN
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 GVF=GIT-VERSION-FILE
-DEF_VER=v2.43.3
+DEF_VER=v2.45.2
 
 LF='
 '
@@ -11,7 +11,7 @@
 if test -f version
 then
 	VN=$(cat version) || VN="$DEF_VER"
-elif test -d ${GIT_DIR:-.git} -o -f .git &&
+elif { test -d "${GIT_DIR:-.git}" || test -f .git; } &&
 	VN=$(git describe --match "v[0-9]*" HEAD 2>/dev/null) &&
 	case "$VN" in
 	*$LF*) (exit 1) ;;
diff --git a/INSTALL b/INSTALL
index c6fb240..2a46d04 100644
--- a/INSTALL
+++ b/INSTALL
@@ -139,7 +139,7 @@
 	  not need that functionality, use NO_CURL to build without
 	  it.
 
-	  Git requires version "7.19.5" or later of "libcurl" to build
+	  Git requires version "7.21.3" or later of "libcurl" to build
 	  without NO_CURL. This version requirement may be bumped in
 	  the future.
 
diff --git a/Makefile b/Makefile
index 1618ee2..1e31acc 100644
--- a/Makefile
+++ b/Makefile
@@ -682,6 +682,9 @@
 TEST_OBJS =
 TEST_PROGRAMS_NEED_X =
 THIRD_PARTY_SOURCES =
+UNIT_TEST_PROGRAMS =
+UNIT_TEST_DIR = t/unit-tests
+UNIT_TEST_BIN = $(UNIT_TEST_DIR)/bin
 
 # Having this variable in your environment would break pipelines because
 # you cause "cd" to echo its destination to stdout.  It can also take
@@ -749,7 +752,13 @@
 
 ETAGS_TARGET = TAGS
 
+# If you add a new fuzzer, please also make sure to run it in
+# ci/run-build-and-minimal-fuzzers.sh so that we make sure it still links and
+# runs in the future.
+FUZZ_OBJS += oss-fuzz/dummy-cmd-main.o
 FUZZ_OBJS += oss-fuzz/fuzz-commit-graph.o
+FUZZ_OBJS += oss-fuzz/fuzz-config.o
+FUZZ_OBJS += oss-fuzz/fuzz-date.o
 FUZZ_OBJS += oss-fuzz/fuzz-pack-headers.o
 FUZZ_OBJS += oss-fuzz/fuzz-pack-idx.o
 .PHONY: fuzz-objs
@@ -758,7 +767,7 @@
 # Always build fuzz objects even if not testing, to prevent bit-rot.
 all:: $(FUZZ_OBJS)
 
-FUZZ_PROGRAMS += $(patsubst %.o,%,$(FUZZ_OBJS))
+FUZZ_PROGRAMS += $(patsubst %.o,%,$(filter-out %dummy-cmd-main.o,$(FUZZ_OBJS)))
 
 # Empty...
 EXTRA_PROGRAMS =
@@ -788,8 +797,8 @@
 TEST_BUILTINS_OBJS += test-config.o
 TEST_BUILTINS_OBJS += test-crontab.o
 TEST_BUILTINS_OBJS += test-csprng.o
-TEST_BUILTINS_OBJS += test-ctype.o
 TEST_BUILTINS_OBJS += test-date.o
+TEST_BUILTINS_OBJS += test-delete-gpgsig.o
 TEST_BUILTINS_OBJS += test-delta.o
 TEST_BUILTINS_OBJS += test-dir-iterator.o
 TEST_BUILTINS_OBJS += test-drop-caches.o
@@ -799,7 +808,6 @@
 TEST_BUILTINS_OBJS += test-dump-untracked-cache.o
 TEST_BUILTINS_OBJS += test-env-helper.o
 TEST_BUILTINS_OBJS += test-example-decorate.o
-TEST_BUILTINS_OBJS += test-fast-rebase.o
 TEST_BUILTINS_OBJS += test-find-pack.o
 TEST_BUILTINS_OBJS += test-fsmonitor-client.o
 TEST_BUILTINS_OBJS += test-genrandom.o
@@ -825,7 +833,6 @@
 TEST_BUILTINS_OBJS += test-path-utils.o
 TEST_BUILTINS_OBJS += test-pcre2-config.o
 TEST_BUILTINS_OBJS += test-pkt-line.o
-TEST_BUILTINS_OBJS += test-prio-queue.o
 TEST_BUILTINS_OBJS += test-proc-receive.o
 TEST_BUILTINS_OBJS += test-progress.o
 TEST_BUILTINS_OBJS += test-reach.o
@@ -1055,6 +1062,7 @@
 LIB_OBJS += list-objects.o
 LIB_OBJS += lockfile.o
 LIB_OBJS += log-tree.o
+LIB_OBJS += loose.o
 LIB_OBJS += ls-refs.o
 LIB_OBJS += mailinfo.o
 LIB_OBJS += mailmap.o
@@ -1067,6 +1075,7 @@
 LIB_OBJS += merge-recursive.o
 LIB_OBJS += merge.o
 LIB_OBJS += midx.o
+LIB_OBJS += midx-write.o
 LIB_OBJS += name-hash.o
 LIB_OBJS += negotiator/default.o
 LIB_OBJS += negotiator/noop.o
@@ -1075,6 +1084,7 @@
 LIB_OBJS += notes-merge.o
 LIB_OBJS += notes-utils.o
 LIB_OBJS += notes.o
+LIB_OBJS += object-file-convert.o
 LIB_OBJS += object-file.o
 LIB_OBJS += object-name.o
 LIB_OBJS += object.o
@@ -1121,6 +1131,7 @@
 LIB_OBJS += refs.o
 LIB_OBJS += refs/debug.o
 LIB_OBJS += refs/files-backend.o
+LIB_OBJS += refs/reftable-backend.o
 LIB_OBJS += refs/iterator.o
 LIB_OBJS += refs/packed-backend.o
 LIB_OBJS += refs/ref-cache.o
@@ -1290,6 +1301,7 @@
 BUILTIN_OBJS += builtin/remote.o
 BUILTIN_OBJS += builtin/repack.o
 BUILTIN_OBJS += builtin/replace.o
+BUILTIN_OBJS += builtin/replay.o
 BUILTIN_OBJS += builtin/rerere.o
 BUILTIN_OBJS += builtin/reset.o
 BUILTIN_OBJS += builtin/rev-list.o
@@ -1335,6 +1347,15 @@
 THIRD_PARTY_SOURCES += sha1collisiondetection/%
 THIRD_PARTY_SOURCES += sha1dc/%
 
+UNIT_TEST_PROGRAMS += t-basic
+UNIT_TEST_PROGRAMS += t-mem-pool
+UNIT_TEST_PROGRAMS += t-strbuf
+UNIT_TEST_PROGRAMS += t-ctype
+UNIT_TEST_PROGRAMS += t-prio-queue
+UNIT_TEST_PROGS = $(patsubst %,$(UNIT_TEST_BIN)/%$X,$(UNIT_TEST_PROGRAMS))
+UNIT_TEST_OBJS = $(patsubst %,$(UNIT_TEST_DIR)/%.o,$(UNIT_TEST_PROGRAMS))
+UNIT_TEST_OBJS += $(UNIT_TEST_DIR)/test-lib.o
+
 # xdiff and reftable libs may in turn depend on what is in libgit.a
 GITLIBS = common-main.o $(LIB_FILE) $(XDIFF_LIB) $(REFTABLE_LIB) $(LIB_FILE)
 EXTLIBS =
@@ -1537,23 +1558,23 @@
 endif
 
 ifeq ($(uname_S),Darwin)
-	ifndef NO_FINK
-		ifeq ($(shell test -d /sw/lib && echo y),y)
+        ifndef NO_FINK
+                ifeq ($(shell test -d /sw/lib && echo y),y)
 			BASIC_CFLAGS += -I/sw/include
 			BASIC_LDFLAGS += -L/sw/lib
-		endif
-	endif
-	ifndef NO_DARWIN_PORTS
-		ifeq ($(shell test -d /opt/local/lib && echo y),y)
+                endif
+        endif
+        ifndef NO_DARWIN_PORTS
+                ifeq ($(shell test -d /opt/local/lib && echo y),y)
 			BASIC_CFLAGS += -I/opt/local/include
 			BASIC_LDFLAGS += -L/opt/local/lib
-		endif
-	endif
-	ifndef NO_APPLE_COMMON_CRYPTO
+                endif
+        endif
+        ifndef NO_APPLE_COMMON_CRYPTO
 		NO_OPENSSL = YesPlease
 		APPLE_COMMON_CRYPTO = YesPlease
 		COMPAT_CFLAGS += -DAPPLE_COMMON_CRYPTO
-	endif
+        endif
 	PTHREAD_LIBS =
 endif
 
@@ -1575,7 +1596,7 @@
 
 ifdef LIBPCREDIR
 	BASIC_CFLAGS += -I$(LIBPCREDIR)/include
-	EXTLIBS += -L$(LIBPCREDIR)/$(lib) $(CC_LD_DYNPATH)$(LIBPCREDIR)/$(lib)
+	EXTLIBS += $(call libpath_template,$(LIBPCREDIR)/$(lib))
 endif
 
 ifdef HAVE_ALLOCA_H
@@ -1592,23 +1613,23 @@
 	REMOTE_CURL_NAMES =
 	EXCLUDED_PROGRAMS += git-http-fetch git-http-push
 else
-	ifdef CURLDIR
+        ifdef CURLDIR
 		# Try "-Wl,-rpath=$(CURLDIR)/$(lib)" in such a case.
 		CURL_CFLAGS = -I$(CURLDIR)/include
-		CURL_LIBCURL = -L$(CURLDIR)/$(lib) $(CC_LD_DYNPATH)$(CURLDIR)/$(lib)
-	else
+		CURL_LIBCURL = $(call libpath_template,$(CURLDIR)/$(lib))
+        else
 		CURL_CFLAGS =
 		CURL_LIBCURL =
-	endif
+        endif
 
-	ifndef CURL_LDFLAGS
+        ifndef CURL_LDFLAGS
 		CURL_LDFLAGS = $(eval CURL_LDFLAGS := $$(shell $$(CURL_CONFIG) --libs))$(CURL_LDFLAGS)
-	endif
+        endif
 	CURL_LIBCURL += $(CURL_LDFLAGS)
 
-	ifndef CURL_CFLAGS
+        ifndef CURL_CFLAGS
 		CURL_CFLAGS = $(eval CURL_CFLAGS := $$(shell $$(CURL_CONFIG) --cflags))$(CURL_CFLAGS)
-	endif
+        endif
 	BASIC_CFLAGS += $(CURL_CFLAGS)
 
 	REMOTE_CURL_PRIMARY = git-remote-http$X
@@ -1616,49 +1637,49 @@
 	REMOTE_CURL_NAMES = $(REMOTE_CURL_PRIMARY) $(REMOTE_CURL_ALIASES)
 	PROGRAM_OBJS += http-fetch.o
 	PROGRAMS += $(REMOTE_CURL_NAMES)
-	ifndef NO_EXPAT
+        ifndef NO_EXPAT
 		PROGRAM_OBJS += http-push.o
-	endif
+        endif
 	curl_check := $(shell (echo 072200; $(CURL_CONFIG) --vernum | sed -e '/^70[BC]/s/^/0/') 2>/dev/null | sort -r | sed -ne 2p)
-	ifeq "$(curl_check)" "072200"
+        ifeq "$(curl_check)" "072200"
 		USE_CURL_FOR_IMAP_SEND = YesPlease
-	endif
-	ifdef USE_CURL_FOR_IMAP_SEND
+        endif
+        ifdef USE_CURL_FOR_IMAP_SEND
 		BASIC_CFLAGS += -DUSE_CURL_FOR_IMAP_SEND
 		IMAP_SEND_BUILDDEPS = http.o
 		IMAP_SEND_LDFLAGS += $(CURL_LIBCURL)
-	endif
-	ifndef NO_EXPAT
-		ifdef EXPATDIR
+        endif
+        ifndef NO_EXPAT
+                ifdef EXPATDIR
 			BASIC_CFLAGS += -I$(EXPATDIR)/include
-			EXPAT_LIBEXPAT = -L$(EXPATDIR)/$(lib) $(CC_LD_DYNPATH)$(EXPATDIR)/$(lib) -lexpat
-		else
+			EXPAT_LIBEXPAT = $(call libpath_template,$(EXPATDIR)/$(lib)) -lexpat
+                else
 			EXPAT_LIBEXPAT = -lexpat
-		endif
-		ifdef EXPAT_NEEDS_XMLPARSE_H
+                endif
+                ifdef EXPAT_NEEDS_XMLPARSE_H
 			BASIC_CFLAGS += -DEXPAT_NEEDS_XMLPARSE_H
-		endif
-	endif
+                endif
+        endif
 endif
 IMAP_SEND_LDFLAGS += $(OPENSSL_LINK) $(OPENSSL_LIBSSL) $(LIB_4_CRYPTO)
 
 ifdef ZLIB_PATH
 	BASIC_CFLAGS += -I$(ZLIB_PATH)/include
-	EXTLIBS += -L$(ZLIB_PATH)/$(lib) $(CC_LD_DYNPATH)$(ZLIB_PATH)/$(lib)
+	EXTLIBS += $(call libpath_template,$(ZLIB_PATH)/$(lib))
 endif
 EXTLIBS += -lz
 
 ifndef NO_OPENSSL
 	OPENSSL_LIBSSL = -lssl
-	ifdef OPENSSLDIR
+        ifdef OPENSSLDIR
 		BASIC_CFLAGS += -I$(OPENSSLDIR)/include
-		OPENSSL_LINK = -L$(OPENSSLDIR)/$(lib) $(CC_LD_DYNPATH)$(OPENSSLDIR)/$(lib)
-	else
+		OPENSSL_LINK = $(call libpath_template,$(OPENSSLDIR)/$(lib))
+        else
 		OPENSSL_LINK =
-	endif
-	ifdef NEEDS_CRYPTO_WITH_SSL
+        endif
+        ifdef NEEDS_CRYPTO_WITH_SSL
 		OPENSSL_LIBSSL += -lcrypto
-	endif
+        endif
 else
 	BASIC_CFLAGS += -DNO_OPENSSL
 	OPENSSL_LIBSSL =
@@ -1676,18 +1697,18 @@
 endif
 endif
 ifndef NO_ICONV
-	ifdef NEEDS_LIBICONV
-		ifdef ICONVDIR
+        ifdef NEEDS_LIBICONV
+                ifdef ICONVDIR
 			BASIC_CFLAGS += -I$(ICONVDIR)/include
-			ICONV_LINK = -L$(ICONVDIR)/$(lib) $(CC_LD_DYNPATH)$(ICONVDIR)/$(lib)
-		else
+			ICONV_LINK = $(call libpath_template,$(ICONVDIR)/$(lib))
+                else
 			ICONV_LINK =
-		endif
-		ifdef NEEDS_LIBINTL_BEFORE_LIBICONV
+                endif
+                ifdef NEEDS_LIBINTL_BEFORE_LIBICONV
 			ICONV_LINK += -lintl
-		endif
+                endif
 		EXTLIBS += $(ICONV_LINK) -liconv
-	endif
+        endif
 endif
 ifdef ICONV_OMITS_BOM
 	BASIC_CFLAGS += -DICONV_OMITS_BOM
@@ -1808,10 +1829,10 @@
 	COMPAT_CFLAGS += -DNO_MMAP
 	COMPAT_OBJS += compat/mmap.o
 else
-	ifdef USE_WIN32_MMAP
+        ifdef USE_WIN32_MMAP
 		COMPAT_CFLAGS += -DUSE_WIN32_MMAP
 		COMPAT_OBJS += compat/win32mmap.o
-	endif
+        endif
 endif
 ifdef MMAP_PREVENTS_DELETE
 	BASIC_CFLAGS += -DMMAP_PREVENTS_DELETE
@@ -1936,11 +1957,11 @@
 	BASIC_CFLAGS += -DSHA1_DC
 	LIB_OBJS += sha1dc_git.o
 ifdef DC_SHA1_EXTERNAL
-	ifdef DC_SHA1_SUBMODULE
-		ifneq ($(DC_SHA1_SUBMODULE),auto)
+        ifdef DC_SHA1_SUBMODULE
+                ifneq ($(DC_SHA1_SUBMODULE),auto)
 $(error Only set DC_SHA1_EXTERNAL or DC_SHA1_SUBMODULE, not both)
-		endif
-	endif
+                endif
+        endif
 	BASIC_CFLAGS += -DDC_SHA1_EXTERNAL
 	EXTLIBS += -lsha1detectcoll
 else
@@ -2342,7 +2363,7 @@
 
 all:: $(ALL_COMMANDS_TO_INSTALL) $(SCRIPT_LIB) $(OTHER_PROGRAMS) GIT-BUILD-OPTIONS
 ifneq (,$X)
-	$(QUIET_BUILT_IN)$(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_COMMANDS_TO_INSTALL) $(OTHER_PROGRAMS))), test -d '$p' -o '$p' -ef '$p$X' || $(RM) '$p';)
+	$(QUIET_BUILT_IN)$(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_COMMANDS_TO_INSTALL) $(OTHER_PROGRAMS))), if test ! -d '$p' && test ! '$p' -ef '$p$X'; then $(RM) '$p'; fi;)
 endif
 
 all::
@@ -2676,6 +2697,7 @@
 OBJECTS += $(XDIFF_OBJS)
 OBJECTS += $(FUZZ_OBJS)
 OBJECTS += $(REFTABLE_OBJS) $(REFTABLE_TEST_OBJS)
+OBJECTS += $(UNIT_TEST_OBJS)
 
 ifndef NO_CURL
 	OBJECTS += http.o http-walker.o remote-curl.o
@@ -3178,7 +3200,7 @@
 
 test_bindir_programs := $(patsubst %,bin-wrappers/%,$(BINDIR_PROGRAMS_NEED_X) $(BINDIR_PROGRAMS_NO_X) $(TEST_PROGRAMS_NEED_X))
 
-all:: $(TEST_PROGRAMS) $(test_bindir_programs)
+all:: $(TEST_PROGRAMS) $(test_bindir_programs) $(UNIT_TEST_PROGS)
 
 bin-wrappers/%: wrap-for-bin.sh
 	$(call mkdir_p_parent_template)
@@ -3604,12 +3626,12 @@
 .PHONY: rpm
 
 ifneq ($(INCLUDE_DLLS_IN_ARTIFACTS),)
-OTHER_PROGRAMS += $(shell echo *.dll t/helper/*.dll)
+OTHER_PROGRAMS += $(shell echo *.dll t/helper/*.dll t/unit-tests/bin/*.dll)
 endif
 
 artifacts-tar:: $(ALL_COMMANDS_TO_INSTALL) $(SCRIPT_LIB) $(OTHER_PROGRAMS) \
 		GIT-BUILD-OPTIONS $(TEST_PROGRAMS) $(test_bindir_programs) \
-		$(MOFILES)
+		$(UNIT_TEST_PROGS) $(MOFILES)
 	$(QUIET_SUBDIR0)templates $(QUIET_SUBDIR1) \
 		SHELL_PATH='$(SHELL_PATH_SQ)' PERL_PATH='$(PERL_PATH_SQ)'
 	test -n "$(ARTIFACTS_DIRECTORY)"
@@ -3664,7 +3686,7 @@
 	$(RM) contrib/coccinelle/*.cocci.patch
 
 clean: profile-clean coverage-clean cocciclean
-	$(RM) -r .build
+	$(RM) -r .build $(UNIT_TEST_BIN)
 	$(RM) po/git.pot po/git-core.pot
 	$(RM) git.res
 	$(RM) $(OBJECTS)
@@ -3838,15 +3860,26 @@
 #
 # make CC=clang CXX=clang++ \
 #      CFLAGS="-fsanitize=fuzzer-no-link,address" \
-#      LIB_FUZZING_ENGINE="-fsanitize=fuzzer" \
+#      LIB_FUZZING_ENGINE="-fsanitize=fuzzer,address" \
 #      fuzz-all
 #
-FUZZ_CXXFLAGS ?= $(CFLAGS)
+FUZZ_CXXFLAGS ?= $(ALL_CFLAGS)
 
 .PHONY: fuzz-all
 
-$(FUZZ_PROGRAMS): all
-	$(QUIET_LINK)$(CXX) $(FUZZ_CXXFLAGS) $(LIB_OBJS) $(BUILTIN_OBJS) \
-		$(XDIFF_OBJS) $(EXTLIBS) git.o $@.o $(LIB_FUZZING_ENGINE) -o $@
+$(FUZZ_PROGRAMS): %: %.o oss-fuzz/dummy-cmd-main.o $(GITLIBS) GIT-LDFLAGS
+	$(QUIET_LINK)$(CXX) $(FUZZ_CXXFLAGS) -o $@ $(ALL_LDFLAGS) \
+		-Wl,--allow-multiple-definition \
+		$(filter %.o,$^) $(filter %.a,$^) $(LIBS) $(LIB_FUZZING_ENGINE)
 
 fuzz-all: $(FUZZ_PROGRAMS)
+
+$(UNIT_TEST_PROGS): $(UNIT_TEST_BIN)/%$X: $(UNIT_TEST_DIR)/%.o $(UNIT_TEST_DIR)/test-lib.o $(GITLIBS) GIT-LDFLAGS
+	$(call mkdir_p_parent_template)
+	$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) \
+		$(filter %.o,$^) $(filter %.a,$^) $(LIBS)
+
+.PHONY: build-unit-tests unit-tests
+build-unit-tests: $(UNIT_TEST_PROGS)
+unit-tests: $(UNIT_TEST_PROGS)
+	$(MAKE) -C t/ unit-tests
diff --git a/RelNotes b/RelNotes
index 9879230..2079120 120000
--- a/RelNotes
+++ b/RelNotes
@@ -1 +1 @@
-Documentation/RelNotes/2.43.3.txt
\ No newline at end of file
+Documentation/RelNotes/2.45.2.txt
\ No newline at end of file
diff --git a/add-interactive.c b/add-interactive.c
index 6bf87e7..e17602b 100644
--- a/add-interactive.c
+++ b/add-interactive.c
@@ -865,6 +865,7 @@ static int get_untracked_files(struct repository *r,
 	}
 
 	strbuf_release(&buf);
+	dir_clear(&dir);
 	return 0;
 }
 
diff --git a/add-patch.c b/add-patch.c
index 79eda16..0997d4a 100644
--- a/add-patch.c
+++ b/add-patch.c
@@ -1105,26 +1105,26 @@ static int edit_hunk_manually(struct add_p_state *s, struct hunk *hunk)
 	size_t i;
 
 	strbuf_reset(&s->buf);
-	strbuf_commented_addf(&s->buf, comment_line_char,
+	strbuf_commented_addf(&s->buf, comment_line_str,
 			      _("Manual hunk edit mode -- see bottom for "
 				"a quick guide.\n"));
 	render_hunk(s, hunk, 0, 0, &s->buf);
-	strbuf_commented_addf(&s->buf, comment_line_char,
+	strbuf_commented_addf(&s->buf, comment_line_str,
 			      _("---\n"
 				"To remove '%c' lines, make them ' ' lines "
 				"(context).\n"
 				"To remove '%c' lines, delete them.\n"
-				"Lines starting with %c will be removed.\n"),
+				"Lines starting with %s will be removed.\n"),
 			      s->mode->is_reverse ? '+' : '-',
 			      s->mode->is_reverse ? '-' : '+',
-			      comment_line_char);
-	strbuf_commented_addf(&s->buf, comment_line_char, "%s",
+			      comment_line_str);
+	strbuf_commented_addf(&s->buf, comment_line_str, "%s",
 			      _(s->mode->edit_hunk_hint));
 	/*
 	 * TRANSLATORS: 'it' refers to the patch mentioned in the previous
 	 * messages.
 	 */
-	strbuf_commented_addf(&s->buf, comment_line_char,
+	strbuf_commented_addf(&s->buf, comment_line_str,
 			      _("If it does not apply cleanly, you will be "
 				"given an opportunity to\n"
 				"edit again.  If all lines of the hunk are "
@@ -1139,7 +1139,7 @@ static int edit_hunk_manually(struct add_p_state *s, struct hunk *hunk)
 	for (i = 0; i < s->buf.len; ) {
 		size_t next = find_next_line(&s->buf, i);
 
-		if (s->buf.buf[i] != comment_line_char)
+		if (!starts_with(s->buf.buf + i, comment_line_str))
 			strbuf_add(&s->plain, s->buf.buf + i, next - i);
 		i = next;
 	}
@@ -1388,13 +1388,14 @@ N_("j - leave this hunk undecided, see next undecided hunk\n"
    "/ - search for a hunk matching the given regex\n"
    "s - split the current hunk into smaller hunks\n"
    "e - manually edit the current hunk\n"
+   "p - print the current hunk\n"
    "? - print help\n");
 
 static int patch_update_file(struct add_p_state *s,
 			     struct file_diff *file_diff)
 {
 	size_t hunk_index = 0;
-	ssize_t i, undecided_previous, undecided_next;
+	ssize_t i, undecided_previous, undecided_next, rendered_hunk_index = -1;
 	struct hunk *hunk;
 	char ch;
 	struct child_process cp = CHILD_PROCESS_INIT;
@@ -1447,8 +1448,11 @@ static int patch_update_file(struct add_p_state *s,
 
 		strbuf_reset(&s->buf);
 		if (file_diff->hunk_nr) {
-			render_hunk(s, hunk, 0, colored, &s->buf);
-			fputs(s->buf.buf, stdout);
+			if (rendered_hunk_index != hunk_index) {
+				render_hunk(s, hunk, 0, colored, &s->buf);
+				fputs(s->buf.buf, stdout);
+				rendered_hunk_index = hunk_index;
+			}
 
 			strbuf_reset(&s->buf);
 			if (undecided_previous >= 0) {
@@ -1480,6 +1484,7 @@ static int patch_update_file(struct add_p_state *s,
 				permitted |= ALLOW_EDIT;
 				strbuf_addstr(&s->buf, ",e");
 			}
+			strbuf_addstr(&s->buf, ",p");
 		}
 		if (file_diff->deleted)
 			prompt_mode_type = PROMPT_DELETION;
@@ -1641,16 +1646,19 @@ static int patch_update_file(struct add_p_state *s,
 				err(s, _("No hunk matches the given pattern"));
 				break;
 			}
+			regfree(&regex);
 			hunk_index = i;
 		} else if (s->answer.buf[0] == 's') {
 			size_t splittable_into = hunk->splittable_into;
-			if (!(permitted & ALLOW_SPLIT))
+			if (!(permitted & ALLOW_SPLIT)) {
 				err(s, _("Sorry, cannot split this hunk"));
-			else if (!split_hunk(s, file_diff,
-					     hunk - file_diff->hunk))
+			} else if (!split_hunk(s, file_diff,
+					     hunk - file_diff->hunk)) {
 				color_fprintf_ln(stdout, s->s.header_color,
 						 _("Split into %d hunks."),
 						 (int)splittable_into);
+				rendered_hunk_index = -1;
+			}
 		} else if (s->answer.buf[0] == 'e') {
 			if (!(permitted & ALLOW_EDIT))
 				err(s, _("Sorry, cannot edit this hunk"));
@@ -1658,6 +1666,8 @@ static int patch_update_file(struct add_p_state *s,
 				hunk->use = USE_HUNK;
 				goto soft_increment;
 			}
+		} else if (s->answer.buf[0] == 'p') {
+			rendered_hunk_index = -1;
 		} else {
 			const char *p = _(help_patch_remainder), *eol = p;
 
@@ -1729,14 +1739,6 @@ int run_add_p(struct repository *r, enum add_p_mode mode,
 	if (mode == ADD_P_STASH)
 		s.mode = &patch_mode_stash;
 	else if (mode == ADD_P_RESET) {
-		/*
-		 * NEEDSWORK: Instead of comparing to the literal "HEAD",
-		 * compare the commit objects instead so that other ways of
-		 * saying the same thing (such as "@") are also handled
-		 * appropriately.
-		 *
-		 * This applies to the cases below too.
-		 */
 		if (!revision || !strcmp(revision, "HEAD"))
 			s.mode = &patch_mode_reset_head;
 		else
diff --git a/advice.c b/advice.c
index 50c7944..7511119 100644
--- a/advice.c
+++ b/advice.c
@@ -33,52 +33,59 @@ static const char *advise_get_color(enum color_advice ix)
 	return "";
 }
 
+enum advice_level {
+	ADVICE_LEVEL_NONE = 0,
+	ADVICE_LEVEL_DISABLED,
+	ADVICE_LEVEL_ENABLED,
+};
+
 static struct {
 	const char *key;
-	int enabled;
+	enum advice_level level;
 } advice_setting[] = {
-	[ADVICE_ADD_EMBEDDED_REPO]			= { "addEmbeddedRepo", 1 },
-	[ADVICE_ADD_EMPTY_PATHSPEC]			= { "addEmptyPathspec", 1 },
-	[ADVICE_ADD_IGNORED_FILE]			= { "addIgnoredFile", 1 },
-	[ADVICE_AM_WORK_DIR] 				= { "amWorkDir", 1 },
-	[ADVICE_AMBIGUOUS_FETCH_REFSPEC]		= { "ambiguousFetchRefspec", 1 },
-	[ADVICE_CHECKOUT_AMBIGUOUS_REMOTE_BRANCH_NAME] 	= { "checkoutAmbiguousRemoteBranchName", 1 },
-	[ADVICE_COMMIT_BEFORE_MERGE]			= { "commitBeforeMerge", 1 },
-	[ADVICE_DETACHED_HEAD]				= { "detachedHead", 1 },
-	[ADVICE_SUGGEST_DETACHING_HEAD]			= { "suggestDetachingHead", 1 },
-	[ADVICE_DIVERGING]				= { "diverging", 1 },
-	[ADVICE_FETCH_SHOW_FORCED_UPDATES]		= { "fetchShowForcedUpdates", 1 },
-	[ADVICE_GRAFT_FILE_DEPRECATED]			= { "graftFileDeprecated", 1 },
-	[ADVICE_IGNORED_HOOK]				= { "ignoredHook", 1 },
-	[ADVICE_IMPLICIT_IDENTITY]			= { "implicitIdentity", 1 },
-	[ADVICE_NESTED_TAG]				= { "nestedTag", 1 },
-	[ADVICE_OBJECT_NAME_WARNING]			= { "objectNameWarning", 1 },
-	[ADVICE_PUSH_ALREADY_EXISTS]			= { "pushAlreadyExists", 1 },
-	[ADVICE_PUSH_FETCH_FIRST]			= { "pushFetchFirst", 1 },
-	[ADVICE_PUSH_NEEDS_FORCE]			= { "pushNeedsForce", 1 },
-	[ADVICE_PUSH_REF_NEEDS_UPDATE]			= { "pushRefNeedsUpdate", 1 },
-
-	/* make this an alias for backward compatibility */
-	[ADVICE_PUSH_UPDATE_REJECTED_ALIAS]		= { "pushNonFastForward", 1 },
-
-	[ADVICE_PUSH_NON_FF_CURRENT]			= { "pushNonFFCurrent", 1 },
-	[ADVICE_PUSH_NON_FF_MATCHING]			= { "pushNonFFMatching", 1 },
-	[ADVICE_PUSH_UNQUALIFIED_REF_NAME]		= { "pushUnqualifiedRefName", 1 },
-	[ADVICE_PUSH_UPDATE_REJECTED]			= { "pushUpdateRejected", 1 },
-	[ADVICE_RESET_NO_REFRESH_WARNING]		= { "resetNoRefresh", 1 },
-	[ADVICE_RESOLVE_CONFLICT]			= { "resolveConflict", 1 },
-	[ADVICE_RM_HINTS]				= { "rmHints", 1 },
-	[ADVICE_SEQUENCER_IN_USE]			= { "sequencerInUse", 1 },
-	[ADVICE_SET_UPSTREAM_FAILURE]			= { "setUpstreamFailure", 1 },
-	[ADVICE_SKIPPED_CHERRY_PICKS]			= { "skippedCherryPicks", 1 },
-	[ADVICE_STATUS_AHEAD_BEHIND_WARNING]		= { "statusAheadBehindWarning", 1 },
-	[ADVICE_STATUS_HINTS]				= { "statusHints", 1 },
-	[ADVICE_STATUS_U_OPTION]			= { "statusUoption", 1 },
-	[ADVICE_SUBMODULE_ALTERNATE_ERROR_STRATEGY_DIE] = { "submoduleAlternateErrorStrategyDie", 1 },
-	[ADVICE_SUBMODULES_NOT_UPDATED] 		= { "submodulesNotUpdated", 1 },
-	[ADVICE_UPDATE_SPARSE_PATH]			= { "updateSparsePath", 1 },
-	[ADVICE_WAITING_FOR_EDITOR]			= { "waitingForEditor", 1 },
-	[ADVICE_WORKTREE_ADD_ORPHAN]			= { "worktreeAddOrphan", 1 },
+	[ADVICE_ADD_EMBEDDED_REPO]			= { "addEmbeddedRepo" },
+	[ADVICE_ADD_EMPTY_PATHSPEC]			= { "addEmptyPathspec" },
+	[ADVICE_ADD_IGNORED_FILE]			= { "addIgnoredFile" },
+	[ADVICE_AMBIGUOUS_FETCH_REFSPEC]		= { "ambiguousFetchRefspec" },
+	[ADVICE_AM_WORK_DIR] 				= { "amWorkDir" },
+	[ADVICE_CHECKOUT_AMBIGUOUS_REMOTE_BRANCH_NAME] 	= { "checkoutAmbiguousRemoteBranchName" },
+	[ADVICE_COMMIT_BEFORE_MERGE]			= { "commitBeforeMerge" },
+	[ADVICE_DETACHED_HEAD]				= { "detachedHead" },
+	[ADVICE_DIVERGING]				= { "diverging" },
+	[ADVICE_FETCH_SHOW_FORCED_UPDATES]		= { "fetchShowForcedUpdates" },
+	[ADVICE_FORCE_DELETE_BRANCH]			= { "forceDeleteBranch" },
+	[ADVICE_GRAFT_FILE_DEPRECATED]			= { "graftFileDeprecated" },
+	[ADVICE_IGNORED_HOOK]				= { "ignoredHook" },
+	[ADVICE_IMPLICIT_IDENTITY]			= { "implicitIdentity" },
+	[ADVICE_MERGE_CONFLICT]				= { "mergeConflict" },
+	[ADVICE_NESTED_TAG]				= { "nestedTag" },
+	[ADVICE_OBJECT_NAME_WARNING]			= { "objectNameWarning" },
+	[ADVICE_PUSH_ALREADY_EXISTS]			= { "pushAlreadyExists" },
+	[ADVICE_PUSH_FETCH_FIRST]			= { "pushFetchFirst" },
+	[ADVICE_PUSH_NEEDS_FORCE]			= { "pushNeedsForce" },
+	[ADVICE_PUSH_NON_FF_CURRENT]			= { "pushNonFFCurrent" },
+	[ADVICE_PUSH_NON_FF_MATCHING]			= { "pushNonFFMatching" },
+	[ADVICE_PUSH_REF_NEEDS_UPDATE]			= { "pushRefNeedsUpdate" },
+	[ADVICE_PUSH_UNQUALIFIED_REF_NAME]		= { "pushUnqualifiedRefName" },
+	[ADVICE_PUSH_UPDATE_REJECTED]			= { "pushUpdateRejected" },
+	[ADVICE_PUSH_UPDATE_REJECTED_ALIAS]		= { "pushNonFastForward" }, /* backwards compatibility */
+	[ADVICE_REF_SYNTAX]				= { "refSyntax" },
+	[ADVICE_RESET_NO_REFRESH_WARNING]		= { "resetNoRefresh" },
+	[ADVICE_RESOLVE_CONFLICT]			= { "resolveConflict" },
+	[ADVICE_RM_HINTS]				= { "rmHints" },
+	[ADVICE_SEQUENCER_IN_USE]			= { "sequencerInUse" },
+	[ADVICE_SET_UPSTREAM_FAILURE]			= { "setUpstreamFailure" },
+	[ADVICE_SKIPPED_CHERRY_PICKS]			= { "skippedCherryPicks" },
+	[ADVICE_STATUS_AHEAD_BEHIND_WARNING]		= { "statusAheadBehindWarning" },
+	[ADVICE_STATUS_HINTS]				= { "statusHints" },
+	[ADVICE_STATUS_U_OPTION]			= { "statusUoption" },
+	[ADVICE_SUBMODULES_NOT_UPDATED] 		= { "submodulesNotUpdated" },
+	[ADVICE_SUBMODULE_ALTERNATE_ERROR_STRATEGY_DIE] = { "submoduleAlternateErrorStrategyDie" },
+	[ADVICE_SUBMODULE_MERGE_CONFLICT]               = { "submoduleMergeConflict" },
+	[ADVICE_SUGGEST_DETACHING_HEAD]			= { "suggestDetachingHead" },
+	[ADVICE_UPDATE_SPARSE_PATH]			= { "updateSparsePath" },
+	[ADVICE_WAITING_FOR_EDITOR]			= { "waitingForEditor" },
+	[ADVICE_WORKTREE_ADD_ORPHAN]			= { "worktreeAddOrphan" },
 };
 
 static const char turn_off_instructions[] =
@@ -98,8 +105,9 @@ static void vadvise(const char *advice, int display_instructions,
 
 	for (cp = buf.buf; *cp; cp = np) {
 		np = strchrnul(cp, '\n');
-		fprintf(stderr,	_("%shint: %.*s%s\n"),
+		fprintf(stderr,	_("%shint:%s%.*s%s\n"),
 			advise_get_color(ADVICE_COLOR_HINT),
+			(np == cp) ? "" : " ",
 			(int)(np - cp), cp,
 			advise_get_color(ADVICE_COLOR_RESET));
 		if (*np)
@@ -118,13 +126,13 @@ void advise(const char *advice, ...)
 
 int advice_enabled(enum advice_type type)
 {
-	switch(type) {
-	case ADVICE_PUSH_UPDATE_REJECTED:
-		return advice_setting[ADVICE_PUSH_UPDATE_REJECTED].enabled &&
-		       advice_setting[ADVICE_PUSH_UPDATE_REJECTED_ALIAS].enabled;
-	default:
-		return advice_setting[type].enabled;
-	}
+	int enabled = advice_setting[type].level != ADVICE_LEVEL_DISABLED;
+
+	if (type == ADVICE_PUSH_UPDATE_REJECTED)
+		return enabled &&
+		       advice_enabled(ADVICE_PUSH_UPDATE_REJECTED_ALIAS);
+
+	return enabled;
 }
 
 void advise_if_enabled(enum advice_type type, const char *advice, ...)
@@ -135,7 +143,8 @@ void advise_if_enabled(enum advice_type type, const char *advice, ...)
 		return;
 
 	va_start(params, advice);
-	vadvise(advice, 1, advice_setting[type].key, params);
+	vadvise(advice, !advice_setting[type].level, advice_setting[type].key,
+		params);
 	va_end(params);
 }
 
@@ -164,7 +173,9 @@ int git_default_advice_config(const char *var, const char *value)
 	for (i = 0; i < ARRAY_SIZE(advice_setting); i++) {
 		if (strcasecmp(k, advice_setting[i].key))
 			continue;
-		advice_setting[i].enabled = git_config_bool(var, value);
+		advice_setting[i].level = git_config_bool(var, value)
+					  ? ADVICE_LEVEL_ENABLED
+					  : ADVICE_LEVEL_DISABLED;
 		return 0;
 	}
 
diff --git a/advice.h b/advice.h
index 2affbe1..c8d29f9 100644
--- a/advice.h
+++ b/advice.h
@@ -10,21 +10,22 @@ struct string_list;
  * Add the new config variable to Documentation/config/advice.txt.
  * Call advise_if_enabled to print your advice.
  */
- enum advice_type {
+enum advice_type {
 	ADVICE_ADD_EMBEDDED_REPO,
 	ADVICE_ADD_EMPTY_PATHSPEC,
 	ADVICE_ADD_IGNORED_FILE,
-	ADVICE_AM_WORK_DIR,
 	ADVICE_AMBIGUOUS_FETCH_REFSPEC,
+	ADVICE_AM_WORK_DIR,
 	ADVICE_CHECKOUT_AMBIGUOUS_REMOTE_BRANCH_NAME,
 	ADVICE_COMMIT_BEFORE_MERGE,
 	ADVICE_DETACHED_HEAD,
 	ADVICE_DIVERGING,
-	ADVICE_SUGGEST_DETACHING_HEAD,
 	ADVICE_FETCH_SHOW_FORCED_UPDATES,
+	ADVICE_FORCE_DELETE_BRANCH,
 	ADVICE_GRAFT_FILE_DEPRECATED,
 	ADVICE_IGNORED_HOOK,
 	ADVICE_IMPLICIT_IDENTITY,
+	ADVICE_MERGE_CONFLICT,
 	ADVICE_NESTED_TAG,
 	ADVICE_OBJECT_NAME_WARNING,
 	ADVICE_PUSH_ALREADY_EXISTS,
@@ -32,23 +33,26 @@ struct string_list;
 	ADVICE_PUSH_NEEDS_FORCE,
 	ADVICE_PUSH_NON_FF_CURRENT,
 	ADVICE_PUSH_NON_FF_MATCHING,
-	ADVICE_PUSH_UNQUALIFIED_REF_NAME,
-	ADVICE_PUSH_UPDATE_REJECTED_ALIAS,
-	ADVICE_PUSH_UPDATE_REJECTED,
 	ADVICE_PUSH_REF_NEEDS_UPDATE,
+	ADVICE_PUSH_UNQUALIFIED_REF_NAME,
+	ADVICE_PUSH_UPDATE_REJECTED,
+	ADVICE_PUSH_UPDATE_REJECTED_ALIAS,
+	ADVICE_REF_SYNTAX,
 	ADVICE_RESET_NO_REFRESH_WARNING,
 	ADVICE_RESOLVE_CONFLICT,
 	ADVICE_RM_HINTS,
 	ADVICE_SEQUENCER_IN_USE,
 	ADVICE_SET_UPSTREAM_FAILURE,
+	ADVICE_SKIPPED_CHERRY_PICKS,
 	ADVICE_STATUS_AHEAD_BEHIND_WARNING,
 	ADVICE_STATUS_HINTS,
 	ADVICE_STATUS_U_OPTION,
-	ADVICE_SUBMODULE_ALTERNATE_ERROR_STRATEGY_DIE,
 	ADVICE_SUBMODULES_NOT_UPDATED,
+	ADVICE_SUBMODULE_ALTERNATE_ERROR_STRATEGY_DIE,
+	ADVICE_SUBMODULE_MERGE_CONFLICT,
+	ADVICE_SUGGEST_DETACHING_HEAD,
 	ADVICE_UPDATE_SPARSE_PATH,
 	ADVICE_WAITING_FOR_EDITOR,
-	ADVICE_SKIPPED_CHERRY_PICKS,
 	ADVICE_WORKTREE_ADD_ORPHAN,
 };
 
diff --git a/apply.c b/apply.c
index 7608e33..901b67e 100644
--- a/apply.c
+++ b/apply.c
@@ -77,7 +77,8 @@ static int parse_whitespace_option(struct apply_state *state, const char *option
 		return 0;
 	}
 	/*
-	 * Please update $__git_whitespacelist in git-completion.bash
+	 * Please update $__git_whitespacelist in git-completion.bash,
+	 * Documentation/git-apply.txt, and Documentation/git-am.txt
 	 * when you add new options.
 	 */
 	return error(_("unrecognized whitespace option '%s'"), option);
@@ -1291,8 +1292,15 @@ static char *git_header_name(int p_value,
 				return NULL; /* no postimage name */
 			second = skip_tree_prefix(p_value, name + len + 1,
 						  line_len - (len + 1));
+			/*
+			 * If we are at the SP at the end of a directory,
+			 * skip_tree_prefix() may return NULL as that makes
+			 * it appears as if we have an absolute path.
+			 * Keep going to find another SP.
+			 */
 			if (!second)
-				return NULL;
+				continue;
+
 			/*
 			 * Does len bytes starting at "name" and "second"
 			 * (that are separated by one HT or SP we just
@@ -2219,7 +2227,8 @@ static void reverse_patches(struct patch *p)
 		struct fragment *frag = p->fragments;
 
 		SWAP(p->new_name, p->old_name);
-		SWAP(p->new_mode, p->old_mode);
+		if (p->new_mode)
+			SWAP(p->new_mode, p->old_mode);
 		SWAP(p->is_new, p->is_delete);
 		SWAP(p->lines_added, p->lines_deleted);
 		SWAP(p->old_oid_prefix, p->new_oid_prefix);
@@ -3703,8 +3712,10 @@ static int apply_data(struct apply_state *state, struct patch *patch,
 			fprintf(stderr, _("Falling back to direct application...\n"));
 
 		/* Note: with --reject, apply_fragments() returns 0 */
-		if (patch->direct_to_threeway || apply_fragments(state, &image, patch) < 0)
+		if (patch->direct_to_threeway || apply_fragments(state, &image, patch) < 0) {
+			clear_image(&image);
 			return -1;
+		}
 	}
 	patch->result = image.buf;
 	patch->resultsize = image.len;
@@ -3777,8 +3788,17 @@ static int check_preimage(struct apply_state *state,
 		return error_errno("%s", old_name);
 	}
 
-	if (!state->cached && !previous)
-		st_mode = ce_mode_from_stat(*ce, st->st_mode);
+	if (!state->cached && !previous) {
+		if (*ce && !(*ce)->ce_mode)
+			BUG("ce_mode == 0 for path '%s'", old_name);
+
+		if (trust_executable_bit)
+			st_mode = ce_mode_from_stat(*ce, st->st_mode);
+		else if (*ce)
+			st_mode = (*ce)->ce_mode;
+		else
+			st_mode = patch->old_mode;
+	}
 
 	if (patch->is_new < 0)
 		patch->is_new = 0;
@@ -4430,6 +4450,7 @@ static int create_one_file(struct apply_state *state,
 			   const char *buf,
 			   unsigned long size)
 {
+	char *newpath = NULL;
 	int res;
 
 	if (state->cached)
@@ -4491,24 +4512,26 @@ static int create_one_file(struct apply_state *state,
 		unsigned int nr = getpid();
 
 		for (;;) {
-			char newpath[PATH_MAX];
-			mksnpath(newpath, sizeof(newpath), "%s~%u", path, nr);
+			newpath = mkpathdup("%s~%u", path, nr);
 			res = try_create_file(state, newpath, mode, buf, size);
 			if (res < 0)
-				return -1;
+				goto out;
 			if (!res) {
 				if (!rename(newpath, path))
-					return 0;
+					goto out;
 				unlink_or_warn(newpath);
 				break;
 			}
 			if (errno != EEXIST)
 				break;
 			++nr;
+			FREE_AND_NULL(newpath);
 		}
 	}
-	return error_errno(_("unable to write file '%s' mode %o"),
-			   path, mode);
+	res = error_errno(_("unable to write file '%s' mode %o"), path, mode);
+out:
+	free(newpath);
+	return res;
 }
 
 static int add_conflicted_stages_file(struct apply_state *state,
@@ -4591,7 +4614,7 @@ static int write_out_one_result(struct apply_state *state,
 static int write_out_one_reject(struct apply_state *state, struct patch *patch)
 {
 	FILE *rej;
-	char namebuf[PATH_MAX];
+	char *namebuf;
 	struct fragment *frag;
 	int fd, cnt = 0;
 	struct strbuf sb = STRBUF_INIT;
@@ -4624,28 +4647,30 @@ static int write_out_one_reject(struct apply_state *state, struct patch *patch)
 		say_patch_name(stderr, sb.buf, patch);
 	strbuf_release(&sb);
 
-	cnt = strlen(patch->new_name);
-	if (ARRAY_SIZE(namebuf) <= cnt + 5) {
-		cnt = ARRAY_SIZE(namebuf) - 5;
-		warning(_("truncating .rej filename to %.*s.rej"),
-			cnt - 1, patch->new_name);
-	}
-	memcpy(namebuf, patch->new_name, cnt);
-	memcpy(namebuf + cnt, ".rej", 5);
+	namebuf = xstrfmt("%s.rej", patch->new_name);
 
 	fd = open(namebuf, O_CREAT | O_EXCL | O_WRONLY, 0666);
 	if (fd < 0) {
-		if (errno != EEXIST)
-			return error_errno(_("cannot open %s"), namebuf);
-		if (unlink(namebuf))
-			return error_errno(_("cannot unlink '%s'"), namebuf);
+		if (errno != EEXIST) {
+			error_errno(_("cannot open %s"), namebuf);
+			goto error;
+		}
+		if (unlink(namebuf)) {
+			error_errno(_("cannot unlink '%s'"), namebuf);
+			goto error;
+		}
 		fd = open(namebuf, O_CREAT | O_EXCL | O_WRONLY, 0666);
-		if (fd < 0)
-			return error_errno(_("cannot open %s"), namebuf);
+		if (fd < 0) {
+			error_errno(_("cannot open %s"), namebuf);
+			goto error;
+		}
 	}
 	rej = fdopen(fd, "w");
-	if (!rej)
-		return error_errno(_("cannot open %s"), namebuf);
+	if (!rej) {
+		error_errno(_("cannot open %s"), namebuf);
+		close(fd);
+		goto error;
+	}
 
 	/* Normal git tools never deal with .rej, so do not pretend
 	 * this is a git patch by saying --git or giving extended
@@ -4669,6 +4694,8 @@ static int write_out_one_reject(struct apply_state *state, struct patch *patch)
 			fputc('\n', rej);
 	}
 	fclose(rej);
+error:
+	free(namebuf);
 	return -1;
 }
 
diff --git a/archive-tar.c b/archive-tar.c
index f2a0ed7..8ae3012 100644
--- a/archive-tar.c
+++ b/archive-tar.c
@@ -365,7 +365,7 @@ static struct archiver *find_tar_filter(const char *name, size_t len)
 	int i;
 	for (i = 0; i < nr_tar_filters; i++) {
 		struct archiver *ar = tar_filters[i];
-		if (!strncmp(ar->name, name, len) && !ar->name[len])
+		if (!xstrncmpz(ar->name, name, len))
 			return ar;
 	}
 	return NULL;
diff --git a/archive.c b/archive.c
index a6730be..5287fcd 100644
--- a/archive.c
+++ b/archive.c
@@ -339,7 +339,8 @@ int write_archive_entries(struct archiver_args *args,
 		opts.src_index = args->repo->index;
 		opts.dst_index = args->repo->index;
 		opts.fn = oneway_merge;
-		init_tree_desc(&t, args->tree->buffer, args->tree->size);
+		init_tree_desc(&t, &args->tree->object.oid,
+			       args->tree->buffer, args->tree->size);
 		if (unpack_trees(1, &t, &opts))
 			return -1;
 		git_attr_set_direction(GIT_ATTR_INDEX);
diff --git a/attr.c b/attr.c
index e62876d..33473bd 100644
--- a/attr.c
+++ b/attr.c
@@ -17,6 +17,7 @@
 #include "utf8.h"
 #include "quote.h"
 #include "read-cache-ll.h"
+#include "refs.h"
 #include "revision.h"
 #include "object-store-ll.h"
 #include "setup.h"
@@ -183,6 +184,15 @@ static void all_attrs_init(struct attr_hashmap *map, struct attr_check *check)
 	}
 }
 
+/*
+ * Atribute name cannot begin with "builtin_" which
+ * is a reserved namespace for built in attributes values.
+ */
+static int attr_name_reserved(const char *name)
+{
+	return starts_with(name, "builtin_");
+}
+
 static int attr_name_valid(const char *name, size_t namelen)
 {
 	/*
@@ -315,7 +325,7 @@ static const char *parse_attr(const char *src, int lineno, const char *cp,
 			cp++;
 			len--;
 		}
-		if (!attr_name_valid(cp, len)) {
+		if (!attr_name_valid(cp, len) || attr_name_reserved(cp)) {
 			report_invalid_attr(cp, len, src, lineno);
 			return NULL;
 		}
@@ -379,7 +389,7 @@ static struct match_attr *parse_attr_line(const char *line, const char *src,
 		name += strlen(ATTRIBUTE_MACRO_PREFIX);
 		name += strspn(name, blank);
 		namelen = strcspn(name, blank);
-		if (!attr_name_valid(name, namelen)) {
+		if (!attr_name_valid(name, namelen) || attr_name_reserved(name)) {
 			report_invalid_attr(name, namelen, src, lineno);
 			goto fail_return;
 		}
@@ -755,8 +765,8 @@ static struct attr_stack *read_attr_from_file(const char *path, unsigned flags)
 	return res;
 }
 
-static struct attr_stack *read_attr_from_buf(char *buf, const char *path,
-					     unsigned flags)
+static struct attr_stack *read_attr_from_buf(char *buf, size_t length,
+					     const char *path, unsigned flags)
 {
 	struct attr_stack *res;
 	char *sp;
@@ -764,6 +774,11 @@ static struct attr_stack *read_attr_from_buf(char *buf, const char *path,
 
 	if (!buf)
 		return NULL;
+	if (length >= ATTR_MAX_FILE_SIZE) {
+		warning(_("ignoring overly large gitattributes blob '%s'"), path);
+		free(buf);
+		return NULL;
+	}
 
 	CALLOC_ARRAY(res, 1);
 	for (sp = buf; *sp;) {
@@ -803,7 +818,7 @@ static struct attr_stack *read_attr_from_blob(struct index_state *istate,
 		return NULL;
 	}
 
-	return read_attr_from_buf(buf, path, flags);
+	return read_attr_from_buf(buf, sz, path, flags);
 }
 
 static struct attr_stack *read_attr_from_index(struct index_state *istate,
@@ -850,13 +865,7 @@ static struct attr_stack *read_attr_from_index(struct index_state *istate,
 		stack = read_attr_from_blob(istate, &istate->cache[sparse_dir_pos]->oid, relative_path, flags);
 	} else {
 		buf = read_blob_data_from_index(istate, path, &size);
-		if (!buf)
-			return NULL;
-		if (size >= ATTR_MAX_FILE_SIZE) {
-			warning(_("ignoring overly large gitattributes blob '%s'"), path);
-			return NULL;
-		}
-		stack = read_attr_from_buf(buf, path, flags);
+		stack = read_attr_from_buf(buf, size, path, flags);
 	}
 	return stack;
 }
@@ -1213,13 +1222,6 @@ static void compute_default_attr_source(struct object_id *attr_source)
 		ignore_bad_attr_tree = 1;
 	}
 
-	if (!default_attr_source_tree_object_name &&
-	    startup_info->have_repository &&
-	    is_bare_repository()) {
-		default_attr_source_tree_object_name = "HEAD";
-		ignore_bad_attr_tree = 1;
-	}
-
 	if (!default_attr_source_tree_object_name || !is_null_oid(attr_source))
 		return;
 
@@ -1240,6 +1242,85 @@ static struct object_id *default_attr_source(void)
 	return &attr_source;
 }
 
+static const char *interned_mode_string(unsigned int mode)
+{
+	static struct {
+		unsigned int val;
+		char str[7];
+	} mode_string[] = {
+		{ .val = 0040000 },
+		{ .val = 0100644 },
+		{ .val = 0100755 },
+		{ .val = 0120000 },
+		{ .val = 0160000 },
+	};
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(mode_string); i++) {
+		if (mode_string[i].val != mode)
+			continue;
+		if (!*mode_string[i].str)
+			snprintf(mode_string[i].str, sizeof(mode_string[i].str),
+				 "%06o", mode);
+		return mode_string[i].str;
+	}
+	BUG("Unsupported mode 0%o", mode);
+}
+
+static const char *builtin_object_mode_attr(struct index_state *istate, const char *path)
+{
+	unsigned int mode;
+
+	if (direction == GIT_ATTR_CHECKIN) {
+		struct object_id oid;
+		struct stat st;
+		if (lstat(path, &st))
+			die_errno(_("unable to stat '%s'"), path);
+		mode = canon_mode(st.st_mode);
+		if (S_ISDIR(mode)) {
+			/*
+			 *`path` is either a directory or it is a submodule,
+			 * in which case it is already indexed as submodule
+			 * or it does not exist in the index yet and we need to
+			 * check if we can resolve to a ref.
+			*/
+			int pos = index_name_pos(istate, path, strlen(path));
+			if (pos >= 0) {
+				 if (S_ISGITLINK(istate->cache[pos]->ce_mode))
+					 mode = istate->cache[pos]->ce_mode;
+			} else if (resolve_gitlink_ref(path, "HEAD", &oid) == 0) {
+				mode = S_IFGITLINK;
+			}
+		}
+	} else {
+		/*
+		 * For GIT_ATTR_CHECKOUT and GIT_ATTR_INDEX we only check
+		 * for mode in the index.
+		 */
+		int pos = index_name_pos(istate, path, strlen(path));
+		if (pos >= 0)
+			mode = istate->cache[pos]->ce_mode;
+		else
+			return ATTR__UNSET;
+	}
+
+	return interned_mode_string(mode);
+}
+
+
+static const char *compute_builtin_attr(struct index_state *istate,
+					  const char *path,
+					  const struct git_attr *attr) {
+	static const struct git_attr *object_mode_attr;
+
+	if (!object_mode_attr)
+		object_mode_attr = git_attr("builtin_objectmode");
+
+	if (attr == object_mode_attr)
+		return builtin_object_mode_attr(istate, path);
+	return ATTR__UNSET;
+}
+
 void git_check_attr(struct index_state *istate,
 		    const char *path,
 		    struct attr_check *check)
@@ -1253,7 +1334,7 @@ void git_check_attr(struct index_state *istate,
 		unsigned int n = check->items[i].attr->attr_nr;
 		const char *value = check->all_attrs[n].value;
 		if (value == ATTR__UNKNOWN)
-			value = ATTR__UNSET;
+			value = compute_builtin_attr(istate, path, check->all_attrs[n].attr);
 		check->items[i].value = value;
 	}
 }
diff --git a/bisect.c b/bisect.c
index 8487f8c..29aae87 100644
--- a/bisect.c
+++ b/bisect.c
@@ -158,6 +158,9 @@ static void show_list(const char *debug, int counted, int nr,
 		const char *subject_start;
 		int subject_len;
 
+		if (!buf)
+			die(_("unable to read %s"), oid_to_hex(&commit->object.oid));
+
 		fprintf(stderr, "%c%c%c ",
 			(commit_flags & TREESAME) ? ' ' : 'T',
 			(commit_flags & UNINTERESTING) ? 'U' : ' ',
@@ -470,7 +473,6 @@ static int read_bisect_refs(void)
 }
 
 static GIT_PATH_FUNC(git_path_bisect_names, "BISECT_NAMES")
-static GIT_PATH_FUNC(git_path_bisect_expected_rev, "BISECT_EXPECTED_REV")
 static GIT_PATH_FUNC(git_path_bisect_ancestors_ok, "BISECT_ANCESTORS_OK")
 static GIT_PATH_FUNC(git_path_bisect_run, "BISECT_RUN")
 static GIT_PATH_FUNC(git_path_bisect_start, "BISECT_START")
@@ -706,26 +708,10 @@ static enum bisect_error error_if_skipped_commits(struct commit_list *tried,
 
 static int is_expected_rev(const struct object_id *oid)
 {
-	const char *filename = git_path_bisect_expected_rev();
-	struct stat st;
-	struct strbuf str = STRBUF_INIT;
-	FILE *fp;
-	int res = 0;
-
-	if (stat(filename, &st) || !S_ISREG(st.st_mode))
+	struct object_id expected_oid;
+	if (read_ref("BISECT_EXPECTED_REV", &expected_oid))
 		return 0;
-
-	fp = fopen_or_warn(filename, "r");
-	if (!fp)
-		return 0;
-
-	if (strbuf_getline_lf(&str, fp) != EOF)
-		res = !strcmp(str.buf, oid_to_hex(oid));
-
-	strbuf_release(&str);
-	fclose(fp);
-
-	return res;
+	return oideq(oid, &expected_oid);
 }
 
 enum bisect_error bisect_checkout(const struct object_id *bisect_rev,
@@ -850,10 +836,11 @@ static void handle_skipped_merge_base(const struct object_id *mb)
 static enum bisect_error check_merge_bases(int rev_nr, struct commit **rev, int no_checkout)
 {
 	enum bisect_error res = BISECT_OK;
-	struct commit_list *result;
+	struct commit_list *result = NULL;
 
-	result = repo_get_merge_bases_many(the_repository, rev[0], rev_nr - 1,
-					   rev + 1);
+	if (repo_get_merge_bases_many(the_repository, rev[0], rev_nr - 1,
+				      rev + 1, &result) < 0)
+		exit(128);
 
 	for (; result; result = result->next) {
 		const struct object_id *mb = &result->item->object.oid;
@@ -959,23 +946,32 @@ static enum bisect_error check_good_are_ancestors_of_bad(struct repository *r,
 }
 
 /*
- * This does "git diff-tree --pretty COMMIT" without one fork+exec.
+ * Display a commit summary to the user.
  */
-static void show_diff_tree(struct repository *r,
-			   const char *prefix,
-			   struct commit *commit)
+static void show_commit(struct commit *commit)
 {
-	const char *argv[] = {
-		"diff-tree", "--pretty", "--stat", "--summary", "--cc", NULL
-	};
-	struct rev_info opt;
+	struct child_process show = CHILD_PROCESS_INIT;
 
-	git_config(git_diff_ui_config, NULL);
-	repo_init_revisions(r, &opt, prefix);
-
-	setup_revisions(ARRAY_SIZE(argv) - 1, argv, &opt, NULL);
-	log_tree_commit(&opt, commit);
-	release_revisions(&opt);
+	/*
+	 * Call git show with --no-pager, as it would otherwise
+	 * paginate the "git show" output only, not the output
+	 * from bisect_next_all(); this can be fixed by moving
+	 * it into a --format parameter, but that would override
+	 * the user's default options for "git show", which we
+	 * are trying to honour.
+	 */
+	strvec_pushl(&show.args,
+		     "--no-pager",
+		     "show",
+		     "--stat",
+		     "--summary",
+		     "--no-abbrev-commit",
+		     "--diff-merges=first-parent",
+		     oid_to_hex(&commit->object.oid), NULL);
+	show.git_cmd = 1;
+	if (run_command(&show))
+		die(_("unable to start 'show' for object '%s'"),
+		    oid_to_hex(&commit->object.oid));
 }
 
 /*
@@ -1092,7 +1088,7 @@ enum bisect_error bisect_next_all(struct repository *r, const char *prefix)
 		printf("%s is the first %s commit\n", oid_to_hex(bisect_rev),
 			term_bad);
 
-		show_diff_tree(r, prefix, revs.commits->item);
+		show_commit(revs.commits->item);
 		/*
 		 * This means the bisection process succeeded.
 		 * Using BISECT_INTERNAL_SUCCESS_1ST_BAD_FOUND (-10)
@@ -1184,10 +1180,10 @@ int bisect_clean_state(void)
 	struct string_list refs_for_removal = STRING_LIST_INIT_NODUP;
 	for_each_ref_in("refs/bisect", mark_for_removal, (void *) &refs_for_removal);
 	string_list_append(&refs_for_removal, xstrdup("BISECT_HEAD"));
+	string_list_append(&refs_for_removal, xstrdup("BISECT_EXPECTED_REV"));
 	result = delete_refs("bisect: remove", &refs_for_removal, REF_NO_DEREF);
 	refs_for_removal.strdup_strings = 1;
 	string_list_clear(&refs_for_removal, 0);
-	unlink_or_warn(git_path_bisect_expected_rev());
 	unlink_or_warn(git_path_bisect_ancestors_ok());
 	unlink_or_warn(git_path_bisect_log());
 	unlink_or_warn(git_path_bisect_names());
diff --git a/branch.c b/branch.c
index 534594f..e4a738f 100644
--- a/branch.c
+++ b/branch.c
@@ -370,8 +370,12 @@ int read_branch_desc(struct strbuf *buf, const char *branch_name)
  */
 int validate_branchname(const char *name, struct strbuf *ref)
 {
-	if (strbuf_check_branch_ref(ref, name))
-		die(_("'%s' is not a valid branch name"), name);
+	if (strbuf_check_branch_ref(ref, name)) {
+		int code = die_message(_("'%s' is not a valid branch name"), name);
+		advise_if_enabled(ADVICE_REF_SYNTAX,
+				  _("See `man git check-ref-format`"));
+		exit(code);
+	}
 
 	return ref_exists(ref->buf);
 }
@@ -734,7 +738,7 @@ static int submodule_create_branch(struct repository *r,
 }
 
 void create_branches_recursively(struct repository *r, const char *name,
-				 const char *start_commitish,
+				 const char *start_committish,
 				 const char *tracking_name, int force,
 				 int reflog, int quiet, enum branch_track track,
 				 int dry_run)
@@ -744,8 +748,8 @@ void create_branches_recursively(struct repository *r, const char *name,
 	struct object_id super_oid;
 	struct submodule_entry_list submodule_entry_list;
 
-	/* Perform dwim on start_commitish to get super_oid and branch_point. */
-	dwim_branch_start(r, start_commitish, BRANCH_TRACK_NEVER,
+	/* Perform dwim on start_committish to get super_oid and branch_point. */
+	dwim_branch_start(r, start_committish, BRANCH_TRACK_NEVER,
 			  &branch_point, &super_oid);
 
 	/*
@@ -768,7 +772,7 @@ void create_branches_recursively(struct repository *r, const char *name,
 				submodule_entry_list.entries[i].submodule->name);
 			if (advice_enabled(ADVICE_SUBMODULES_NOT_UPDATED))
 				advise(_("You may try updating the submodules using 'git checkout --no-recurse-submodules %s && git submodule update --init'"),
-				       start_commitish);
+				       start_committish);
 			exit(code);
 		}
 
@@ -783,7 +787,7 @@ void create_branches_recursively(struct repository *r, const char *name,
 			    name);
 	}
 
-	create_branch(r, name, start_commitish, force, 0, reflog, quiet,
+	create_branch(r, name, start_committish, force, 0, reflog, quiet,
 		      BRANCH_TRACK_NEVER, dry_run);
 	if (dry_run)
 		return;
@@ -817,8 +821,9 @@ void remove_merge_branch_state(struct repository *r)
 	unlink(git_path_merge_rr(r));
 	unlink(git_path_merge_msg(r));
 	unlink(git_path_merge_mode(r));
-	unlink(git_path_auto_merge(r));
-	save_autostash(git_path_merge_autostash(r));
+	refs_delete_ref(get_main_ref_store(r), "", "AUTO_MERGE",
+			NULL, REF_NO_DEREF);
+	save_autostash_ref(r, "MERGE_AUTOSTASH");
 }
 
 void remove_branch_state(struct repository *r, int verbose)
diff --git a/branch.h b/branch.h
index 30c01ae..ec2f35f 100644
--- a/branch.h
+++ b/branch.h
@@ -78,26 +78,26 @@ void create_branch(struct repository *r,
  * those of create_branch() except for start_name, which is represented
  * by two different parameters:
  *
- * - start_commitish is the commit-ish, in repository r, that determines
+ * - start_committish is the commit-ish, in repository r, that determines
  *   which commits the branches will point to. The superproject branch
- *   will point to the commit of start_commitish and the submodule
- *   branches will point to the gitlink commit oids in start_commitish's
+ *   will point to the commit of start_committish and the submodule
+ *   branches will point to the gitlink commit oids in start_committish's
  *   tree.
  *
  * - tracking_name is the name of the ref, in repository r, that will be
  *   used to set up tracking information. This value is propagated to
  *   all submodules, which will evaluate the ref using their own ref
- *   stores. If NULL, this defaults to start_commitish.
+ *   stores. If NULL, this defaults to start_committish.
  *
- * When this function is called on the superproject, start_commitish
+ * When this function is called on the superproject, start_committish
  * can be any user-provided ref and tracking_name can be NULL (similar
  * to create_branches()). But when recursing through submodules,
- * start_commitish is the plain gitlink commit oid. Since the oid cannot
+ * start_committish is the plain gitlink commit oid. Since the oid cannot
  * be used for tracking information, tracking_name is propagated and
  * used for tracking instead.
  */
 void create_branches_recursively(struct repository *r, const char *name,
-				 const char *start_commitish,
+				 const char *start_committish,
 				 const char *tracking_name, int force,
 				 int reflog, int quiet, enum branch_track track,
 				 int dry_run);
diff --git a/builtin.h b/builtin.h
index d560baa..2828063 100644
--- a/builtin.h
+++ b/builtin.h
@@ -211,6 +211,7 @@ int cmd_remote(int argc, const char **argv, const char *prefix);
 int cmd_remote_ext(int argc, const char **argv, const char *prefix);
 int cmd_remote_fd(int argc, const char **argv, const char *prefix);
 int cmd_repack(int argc, const char **argv, const char *prefix);
+int cmd_replay(int argc, const char **argv, const char *prefix);
 int cmd_rerere(int argc, const char **argv, const char *prefix);
 int cmd_reset(int argc, const char **argv, const char *prefix);
 int cmd_restore(int argc, const char **argv, const char *prefix);
diff --git a/builtin/add.c b/builtin/add.c
index 2151c45..b7d3ff1 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -115,7 +115,7 @@ static int refresh(int verbose, const struct pathspec *pathspec)
 	int i, ret = 0;
 	char *skip_worktree_seen = NULL;
 	struct string_list only_match_skip_worktree = STRING_LIST_INIT_NODUP;
-	int flags = REFRESH_IGNORE_SKIP_WORKTREE |
+	unsigned int flags = REFRESH_IGNORE_SKIP_WORKTREE |
 		    (verbose ? REFRESH_IN_PORCELAIN : REFRESH_QUIET);
 
 	seen = xcalloc(pathspec->nr, 1);
@@ -150,7 +150,7 @@ static int refresh(int verbose, const struct pathspec *pathspec)
 int interactive_add(const char **argv, const char *prefix, int patch)
 {
 	struct pathspec pathspec;
-	int unused;
+	int unused, ret;
 
 	if (!git_config_get_bool("add.interactive.usebuiltin", &unused))
 		warning(_("the add.interactive.useBuiltin setting has been removed!\n"
@@ -163,9 +163,12 @@ int interactive_add(const char **argv, const char *prefix, int patch)
 		       prefix, argv);
 
 	if (patch)
-		return !!run_add_p(the_repository, ADD_P_ADD, NULL, &pathspec);
+		ret = !!run_add_p(the_repository, ADD_P_ADD, NULL, &pathspec);
 	else
-		return !!run_add_i(the_repository, &pathspec);
+		ret = !!run_add_i(the_repository, &pathspec);
+
+	clear_pathspec(&pathspec);
+	return ret;
 }
 
 static int edit_patch(int argc, const char **argv, const char *prefix)
@@ -310,9 +313,9 @@ static void check_embedded_repo(const char *path)
 	strbuf_strip_suffix(&name, "/");
 
 	warning(_("adding embedded git repository: %s"), name.buf);
-	if (!adviced_on_embedded_repo &&
-	    advice_enabled(ADVICE_ADD_EMBEDDED_REPO)) {
-		advise(embedded_advice, name.buf, name.buf);
+	if (!adviced_on_embedded_repo) {
+		advise_if_enabled(ADVICE_ADD_EMBEDDED_REPO,
+				  embedded_advice, name.buf, name.buf);
 		adviced_on_embedded_repo = 1;
 	}
 
@@ -328,10 +331,8 @@ static int add_files(struct dir_struct *dir, int flags)
 		fprintf(stderr, _(ignore_error));
 		for (i = 0; i < dir->ignored_nr; i++)
 			fprintf(stderr, "%s\n", dir->ignored[i]->name);
-		if (advice_enabled(ADVICE_ADD_IGNORED_FILE))
-			advise(_("Use -f if you really want to add them.\n"
-				"Turn this message off by running\n"
-				"\"git config advice.addIgnoredFile false\""));
+		advise_if_enabled(ADVICE_ADD_IGNORED_FILE,
+				  _("Use -f if you really want to add them."));
 		exit_status = 1;
 	}
 
@@ -370,6 +371,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
 	int add_new_files;
 	int require_pathspec;
 	char *seen = NULL;
+	char *ps_matched = NULL;
 	struct lock_file lock_file = LOCK_INIT;
 
 	git_config(add_config, NULL);
@@ -421,7 +423,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
 	 * Check the "pathspec '%s' did not match any files" block
 	 * below before enabling new magic.
 	 */
-	parse_pathspec(&pathspec, PATHSPEC_ATTR,
+	parse_pathspec(&pathspec, 0,
 		       PATHSPEC_PREFER_FULL |
 		       PATHSPEC_SYMLINK_LEADING_PATH,
 		       prefix, argv);
@@ -430,7 +432,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
 		if (pathspec.nr)
 			die(_("'%s' and pathspec arguments cannot be used together"), "--pathspec-from-file");
 
-		parse_pathspec_file(&pathspec, PATHSPEC_ATTR,
+		parse_pathspec_file(&pathspec, 0,
 				    PATHSPEC_PREFER_FULL |
 				    PATHSPEC_SYMLINK_LEADING_PATH,
 				    prefix, pathspec_from_file, pathspec_file_nul);
@@ -440,10 +442,8 @@ int cmd_add(int argc, const char **argv, const char *prefix)
 
 	if (require_pathspec && pathspec.nr == 0) {
 		fprintf(stderr, _("Nothing specified, nothing added.\n"));
-		if (advice_enabled(ADVICE_ADD_EMPTY_PATHSPEC))
-			advise( _("Maybe you wanted to say 'git add .'?\n"
-				"Turn this message off by running\n"
-				"\"git config advice.addEmptyPathspec false\""));
+		advise_if_enabled(ADVICE_ADD_EMPTY_PATHSPEC,
+				  _("Maybe you wanted to say 'git add .'?"));
 		return 0;
 	}
 
@@ -501,7 +501,8 @@ int cmd_add(int argc, const char **argv, const char *prefix)
 			       PATHSPEC_LITERAL |
 			       PATHSPEC_GLOB |
 			       PATHSPEC_ICASE |
-			       PATHSPEC_EXCLUDE);
+			       PATHSPEC_EXCLUDE |
+			       PATHSPEC_ATTR);
 
 		for (i = 0; i < pathspec.nr; i++) {
 			const char *path = pathspec.items[i].match;
@@ -548,12 +549,17 @@ int cmd_add(int argc, const char **argv, const char *prefix)
 
 	begin_odb_transaction();
 
+	ps_matched = xcalloc(pathspec.nr, 1);
 	if (add_renormalize)
 		exit_status |= renormalize_tracked_files(&pathspec, flags);
 	else
 		exit_status |= add_files_to_cache(the_repository, prefix,
-						  &pathspec, include_sparse,
-						  flags);
+						  &pathspec, ps_matched,
+						  include_sparse, flags);
+
+	if (take_worktree_changes && !add_renormalize && !ignore_add_errors &&
+	    report_path_error(ps_matched, &pathspec))
+		exit(128);
 
 	if (add_new_files)
 		exit_status |= add_files(&dir, flags);
@@ -567,6 +573,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
 			       COMMIT_LOCK | SKIP_IF_UNCHANGED))
 		die(_("unable to write new index file"));
 
+	free(ps_matched);
 	dir_clear(&dir);
 	clear_pathspec(&pathspec);
 	return exit_status;
diff --git a/builtin/am.c b/builtin/am.c
index d1990d7..022cae2 100644
--- a/builtin/am.c
+++ b/builtin/am.c
@@ -1150,19 +1150,23 @@ static const char *msgnum(const struct am_state *state)
 static void NORETURN die_user_resolve(const struct am_state *state)
 {
 	if (state->resolvemsg) {
-		printf_ln("%s", state->resolvemsg);
+		advise_if_enabled(ADVICE_MERGE_CONFLICT, "%s", state->resolvemsg);
 	} else {
 		const char *cmdline = state->interactive ? "git am -i" : "git am";
+		struct strbuf sb = STRBUF_INIT;
 
-		printf_ln(_("When you have resolved this problem, run \"%s --continue\"."), cmdline);
-		printf_ln(_("If you prefer to skip this patch, run \"%s --skip\" instead."), cmdline);
+		strbuf_addf(&sb, _("When you have resolved this problem, run \"%s --continue\".\n"), cmdline);
+		strbuf_addf(&sb, _("If you prefer to skip this patch, run \"%s --skip\" instead.\n"), cmdline);
 
 		if (advice_enabled(ADVICE_AM_WORK_DIR) &&
 		    is_empty_or_missing_file(am_path(state, "patch")) &&
 		    !repo_index_has_changes(the_repository, NULL, NULL))
-			printf_ln(_("To record the empty patch as an empty commit, run \"%s --allow-empty\"."), cmdline);
+			strbuf_addf(&sb, _("To record the empty patch as an empty commit, run \"%s --allow-empty\".\n"), cmdline);
 
-		printf_ln(_("To restore the original branch and stop patching, run \"%s --abort\"."), cmdline);
+		strbuf_addf(&sb, _("To restore the original branch and stop patching, run \"%s --abort\"."), cmdline);
+
+		advise_if_enabled(ADVICE_MERGE_CONFLICT, "%s", sb.buf);
+		strbuf_release(&sb);
 	}
 
 	exit(128);
@@ -1286,7 +1290,7 @@ static int parse_mail(struct am_state *state, const char *mail)
 
 	strbuf_addstr(&msg, "\n\n");
 	strbuf_addbuf(&msg, &mi.log_message);
-	strbuf_stripspace(&msg, '\0');
+	strbuf_stripspace(&msg, NULL);
 
 	assert(!state->author_name);
 	state->author_name = strbuf_detach(&author_name, NULL);
@@ -1994,8 +1998,8 @@ static int fast_forward_to(struct tree *head, struct tree *remote, int reset)
 	opts.reset = reset ? UNPACK_RESET_PROTECT_UNTRACKED : 0;
 	opts.preserve_ignored = 0; /* FIXME: !overwrite_ignore */
 	opts.fn = twoway_merge;
-	init_tree_desc(&t[0], head->buffer, head->size);
-	init_tree_desc(&t[1], remote->buffer, remote->size);
+	init_tree_desc(&t[0], &head->object.oid, head->buffer, head->size);
+	init_tree_desc(&t[1], &remote->object.oid, remote->buffer, remote->size);
 
 	if (unpack_trees(2, t, &opts)) {
 		rollback_lock_file(&lock_file);
@@ -2029,7 +2033,7 @@ static int merge_tree(struct tree *tree)
 	opts.dst_index = &the_index;
 	opts.merge = 1;
 	opts.fn = oneway_merge;
-	init_tree_desc(&t[0], tree->buffer, tree->size);
+	init_tree_desc(&t[0], &tree->object.oid, tree->buffer, tree->size);
 
 	if (unpack_trees(1, t, &opts)) {
 		rollback_lock_file(&lock_file);
diff --git a/builtin/bisect.c b/builtin/bisect.c
index 032beaa..f69c3f7 100644
--- a/builtin/bisect.c
+++ b/builtin/bisect.c
@@ -16,7 +16,6 @@
 #include "revision.h"
 
 static GIT_PATH_FUNC(git_path_bisect_terms, "BISECT_TERMS")
-static GIT_PATH_FUNC(git_path_bisect_expected_rev, "BISECT_EXPECTED_REV")
 static GIT_PATH_FUNC(git_path_bisect_ancestors_ok, "BISECT_ANCESTORS_OK")
 static GIT_PATH_FUNC(git_path_bisect_start, "BISECT_START")
 static GIT_PATH_FUNC(git_path_bisect_log, "BISECT_LOG")
@@ -919,7 +918,6 @@ static enum bisect_error bisect_state(struct bisect_terms *terms, int argc,
 	const char *state;
 	int i, verify_expected = 1;
 	struct object_id oid, expected;
-	struct strbuf buf = STRBUF_INIT;
 	struct oid_array revs = OID_ARRAY_INIT;
 
 	if (!argc)
@@ -974,10 +972,8 @@ static enum bisect_error bisect_state(struct bisect_terms *terms, int argc,
 		oid_array_append(&revs, &commit->object.oid);
 	}
 
-	if (strbuf_read_file(&buf, git_path_bisect_expected_rev(), 0) < the_hash_algo->hexsz ||
-	    get_oid_hex(buf.buf, &expected) < 0)
+	if (read_ref("BISECT_EXPECTED_REV", &expected))
 		verify_expected = 0; /* Ignore invalid file contents */
-	strbuf_release(&buf);
 
 	for (i = 0; i < revs.nr; i++) {
 		if (bisect_write(state, oid_to_hex(&revs.oid[i]), terms, 0)) {
@@ -986,7 +982,7 @@ static enum bisect_error bisect_state(struct bisect_terms *terms, int argc,
 		}
 		if (verify_expected && !oideq(&revs.oid[i], &expected)) {
 			unlink_or_warn(git_path_bisect_ancestors_ok());
-			unlink_or_warn(git_path_bisect_expected_rev());
+			delete_ref(NULL, "BISECT_EXPECTED_REV", NULL, REF_NO_DEREF);
 			verify_expected = 0;
 		}
 	}
diff --git a/builtin/blame.c b/builtin/blame.c
index db1f56d..9aa7468 100644
--- a/builtin/blame.c
+++ b/builtin/blame.c
@@ -316,7 +316,7 @@ static const char *format_time(timestamp_t time, const char *tz_str,
 		size_t time_width;
 		int tz;
 		tz = atoi(tz_str);
-		time_str = show_date(time, tz, &blame_date_mode);
+		time_str = show_date(time, tz, blame_date_mode);
 		strbuf_addstr(&time_buf, time_str);
 		/*
 		 * Add space paddings to time_buf to display a fixed width
@@ -1029,7 +1029,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
 		blame_date_width = sizeof("Thu Oct 19 16:00:04 2006 -0700");
 		break;
 	case DATE_STRFTIME:
-		blame_date_width = strlen(show_date(0, 0, &blame_date_mode)) + 1; /* add the null */
+		blame_date_width = strlen(show_date(0, 0, blame_date_mode)) + 1; /* add the null */
 		break;
 	}
 	blame_date_width -= 1; /* strip the null */
diff --git a/builtin/branch.c b/builtin/branch.c
index 6e30d5e..dd3e3a7 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -24,6 +24,7 @@
 #include "ref-filter.h"
 #include "worktree.h"
 #include "help.h"
+#include "advice.h"
 #include "commit-reach.h"
 
 static const char * const builtin_branch_usage[] = {
@@ -42,7 +43,6 @@ static const char *head;
 static struct object_id head_oid;
 static int recurse_submodules = 0;
 static int submodule_propagate_branches = 0;
-static int omit_empty = 0;
 
 static int branch_use_color = -1;
 static char branch_colors[][COLOR_MAXLEN] = {
@@ -158,6 +158,8 @@ static int branch_merged(int kind, const char *name,
 
 	merged = reference_rev ? repo_in_merge_bases(the_repository, rev,
 						     reference_rev) : 0;
+	if (merged < 0)
+		exit(128);
 
 	/*
 	 * After the safety valve is fully redefined to "check with
@@ -166,9 +168,13 @@ static int branch_merged(int kind, const char *name,
 	 * any of the following code, but during the transition period,
 	 * a gentle reminder is in order.
 	 */
-	if ((head_rev != reference_rev) &&
-	    (head_rev ? repo_in_merge_bases(the_repository, rev, head_rev) : 0) != merged) {
-		if (merged)
+	if (head_rev != reference_rev) {
+		int expect = head_rev ? repo_in_merge_bases(the_repository, rev, head_rev) : 0;
+		if (expect < 0)
+			exit(128);
+		if (expect == merged)
+			; /* okay */
+		else if (merged)
 			warning(_("deleting branch '%s' that has been merged to\n"
 				"         '%s', but not yet merged to HEAD"),
 				name, reference_name);
@@ -191,9 +197,10 @@ static int check_branch_commit(const char *branchname, const char *refname,
 		return -1;
 	}
 	if (!force && !branch_merged(kinds, branchname, rev, head_rev)) {
-		error(_("the branch '%s' is not fully merged.\n"
-		      "If you are sure you want to delete it, "
-		      "run 'git branch -D %s'"), branchname, branchname);
+		error(_("the branch '%s' is not fully merged"), branchname);
+		advise_if_enabled(ADVICE_FORCE_DELETE_BRANCH,
+				  _("If you are sure you want to delete it, "
+				  "run 'git branch -D %s'"), branchname);
 		return -1;
 	}
 	return 0;
@@ -435,8 +442,6 @@ static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sortin
 {
 	int i;
 	struct ref_array array;
-	struct strbuf out = STRBUF_INIT;
-	struct strbuf err = STRBUF_INIT;
 	int maxwidth = 0;
 	const char *remote_prefix = "";
 	char *to_free = NULL;
@@ -466,24 +471,27 @@ static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sortin
 	filter_ahead_behind(the_repository, format, &array);
 	ref_array_sort(sorting, &array);
 
-	for (i = 0; i < array.nr; i++) {
-		strbuf_reset(&err);
-		strbuf_reset(&out);
-		if (format_ref_array_item(array.items[i], format, &out, &err))
-			die("%s", err.buf);
-		if (column_active(colopts)) {
-			assert(!filter->verbose && "--column and --verbose are incompatible");
-			 /* format to a string_list to let print_columns() do its job */
+	if (column_active(colopts)) {
+		struct strbuf out = STRBUF_INIT, err = STRBUF_INIT;
+
+		assert(!filter->verbose && "--column and --verbose are incompatible");
+
+		for (i = 0; i < array.nr; i++) {
+			strbuf_reset(&err);
+			strbuf_reset(&out);
+			if (format_ref_array_item(array.items[i], format, &out, &err))
+				die("%s", err.buf);
+
+			/* format to a string_list to let print_columns() do its job */
 			string_list_append(output, out.buf);
-		} else {
-			fwrite(out.buf, 1, out.len, stdout);
-			if (out.len || !omit_empty)
-				putchar('\n');
 		}
+
+		strbuf_release(&err);
+		strbuf_release(&out);
+	} else {
+		print_formatted_ref_array(&array, format);
 	}
 
-	strbuf_release(&err);
-	strbuf_release(&out);
 	ref_array_clear(&array);
 	free(to_free);
 }
@@ -574,8 +582,12 @@ static void copy_or_rename_branch(const char *oldname, const char *newname, int
 		 */
 		if (ref_exists(oldref.buf))
 			recovery = 1;
-		else
-			die(_("invalid branch name: '%s'"), oldname);
+		else {
+			int code = die_message(_("invalid branch name: '%s'"), oldname);
+			advise_if_enabled(ADVICE_REF_SYNTAX,
+					  _("See `man git check-ref-format`"));
+			exit(code);
+		}
 	}
 
 	for (int i = 0; worktrees[i]; i++) {
@@ -665,18 +677,18 @@ static int edit_branch_description(const char *branch_name)
 	exists = !read_branch_desc(&buf, branch_name);
 	if (!buf.len || buf.buf[buf.len-1] != '\n')
 		strbuf_addch(&buf, '\n');
-	strbuf_commented_addf(&buf, comment_line_char,
+	strbuf_commented_addf(&buf, comment_line_str,
 		    _("Please edit the description for the branch\n"
 		      "  %s\n"
-		      "Lines starting with '%c' will be stripped.\n"),
-		    branch_name, comment_line_char);
+		      "Lines starting with '%s' will be stripped.\n"),
+		    branch_name, comment_line_str);
 	write_file_buf(edit_description(), buf.buf, buf.len);
 	strbuf_reset(&buf);
 	if (launch_editor(edit_description(), &buf, NULL)) {
 		strbuf_release(&buf);
 		return -1;
 	}
-	strbuf_stripspace(&buf, comment_line_char);
+	strbuf_stripspace(&buf, comment_line_str);
 
 	strbuf_addf(&name, "branch.%s.description", branch_name);
 	if (buf.len || exists)
@@ -734,7 +746,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
 		OPT_BIT('D', NULL, &delete, N_("delete branch (even if not merged)"), 2),
 		OPT_BIT('m', "move", &rename, N_("move/rename a branch and its reflog"), 1),
 		OPT_BIT('M', NULL, &rename, N_("move/rename a branch, even if target exists"), 2),
-		OPT_BOOL(0, "omit-empty",  &omit_empty,
+		OPT_BOOL(0, "omit-empty",  &format.array_opts.omit_empty,
 			N_("do not output a newline after empty formatted refs")),
 		OPT_BIT('c', "copy", &copy, N_("copy a branch and its reflog"), 1),
 		OPT_BIT('C', NULL, &copy, N_("copy a branch, even if target exists"), 2),
@@ -764,7 +776,13 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
 	if (argc == 2 && !strcmp(argv[1], "-h"))
 		usage_with_options(builtin_branch_usage, options);
 
+	/*
+	 * Try to set sort keys from config. If config does not set any,
+	 * fall back on default (refname) sorting.
+	 */
 	git_config(git_branch_config, &sorting_options);
+	if (!sorting_options.nr)
+		string_list_append(&sorting_options, "refname");
 
 	track = git_branch_track;
 
diff --git a/builtin/bugreport.c b/builtin/bugreport.c
index 3106e56..25f860a 100644
--- a/builtin/bugreport.c
+++ b/builtin/bugreport.c
@@ -64,7 +64,8 @@ static void get_populated_hooks(struct strbuf *hook_info, int nongit)
 }
 
 static const char * const bugreport_usage[] = {
-	N_("git bugreport [(-o | --output-directory) <path>] [(-s | --suffix) <format>]\n"
+	N_("git bugreport [(-o | --output-directory) <path>]\n"
+	   "              [(-s | --suffix) <format> | --no-suffix]\n"
 	   "              [--diagnose[=<mode>]]"),
 	NULL
 };
@@ -138,8 +139,11 @@ int cmd_bugreport(int argc, const char **argv, const char *prefix)
 	strbuf_complete(&report_path, '/');
 	output_path_len = report_path.len;
 
-	strbuf_addstr(&report_path, "git-bugreport-");
-	strbuf_addftime(&report_path, option_suffix, localtime_r(&now, &tm), 0, 0);
+	strbuf_addstr(&report_path, "git-bugreport");
+	if (option_suffix) {
+		strbuf_addch(&report_path, '-');
+		strbuf_addftime(&report_path, option_suffix, localtime_r(&now, &tm), 0, 0);
+	}
 	strbuf_addstr(&report_path, ".txt");
 
 	switch (safe_create_leading_directories(report_path.buf)) {
diff --git a/builtin/cat-file.c b/builtin/cat-file.c
index 7d48993..0c948f4 100644
--- a/builtin/cat-file.c
+++ b/builtin/cat-file.c
@@ -106,7 +106,10 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
 	struct object_info oi = OBJECT_INFO_INIT;
 	struct strbuf sb = STRBUF_INIT;
 	unsigned flags = OBJECT_INFO_LOOKUP_REPLACE;
-	unsigned get_oid_flags = GET_OID_RECORD_PATH | GET_OID_ONLY_TO_DIE;
+	unsigned get_oid_flags =
+		GET_OID_RECORD_PATH |
+		GET_OID_ONLY_TO_DIE |
+		GET_OID_HASH_ANY;
 	const char *path = force_path;
 	const int opt_cw = (opt == 'c' || opt == 'w');
 	if (!path && opt_cw)
@@ -221,8 +224,13 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
 								     &type,
 								     &size);
 				const char *target;
+
+				if (!buffer)
+					die(_("unable to read %s"), oid_to_hex(&oid));
+
 				if (!skip_prefix(buffer, "object ", &target) ||
-				    get_oid_hex(target, &blob_oid))
+				    get_oid_hex_algop(target, &blob_oid,
+						      &hash_algos[oid.algo]))
 					die("%s not a valid tag", oid_to_hex(&oid));
 				free(buffer);
 			} else
@@ -306,8 +314,8 @@ static int is_atom(const char *atom, const char *s, int slen)
 	return alen == slen && !memcmp(atom, s, alen);
 }
 
-static void expand_atom(struct strbuf *sb, const char *atom, int len,
-			struct expand_data *data)
+static int expand_atom(struct strbuf *sb, const char *atom, int len,
+		       struct expand_data *data)
 {
 	if (is_atom("objectname", atom, len)) {
 		if (!data->mark_query)
@@ -339,7 +347,8 @@ static void expand_atom(struct strbuf *sb, const char *atom, int len,
 			strbuf_addstr(sb,
 				      oid_to_hex(&data->delta_base_oid));
 	} else
-		die("unknown format element: %.*s", len, atom);
+		return 0;
+	return 1;
 }
 
 static void expand_format(struct strbuf *sb, const char *start,
@@ -350,12 +359,11 @@ static void expand_format(struct strbuf *sb, const char *start,
 
 		if (skip_prefix(start, "%", &start) || *start != '(')
 			strbuf_addch(sb, '%');
-		else if (!(end = strchr(start + 1, ')')))
-			die("format element '%s' does not end in ')'", start);
-		else {
-			expand_atom(sb, start + 1, end - start - 1, data);
+		else if ((end = strchr(start + 1, ')')) &&
+			 expand_atom(sb, start + 1, end - start - 1, data))
 			start = end + 1;
-		}
+		else
+			strbuf_expand_bad_format(start, "cat-file");
 	}
 }
 
@@ -416,6 +424,8 @@ static void print_object_or_die(struct batch_options *opt, struct expand_data *d
 
 		contents = repo_read_object_file(the_repository, oid, &type,
 						 &size);
+		if (!contents)
+			die("object %s disappeared", oid_to_hex(oid));
 
 		if (use_mailmap) {
 			size_t s = size;
@@ -423,8 +433,6 @@ static void print_object_or_die(struct batch_options *opt, struct expand_data *d
 			size = cast_size_t_to_ulong(s);
 		}
 
-		if (!contents)
-			die("object %s disappeared", oid_to_hex(oid));
 		if (type != data->type)
 			die("object %s changed type!?", oid_to_hex(oid));
 		if (data->info.sizep && size != data->size && !use_mailmap)
@@ -481,6 +489,8 @@ static void batch_object_write(const char *obj_name,
 
 			buf = repo_read_object_file(the_repository, &data->oid, &data->type,
 						    &data->size);
+			if (!buf)
+				die(_("unable to read %s"), oid_to_hex(&data->oid));
 			buf = replace_idents_using_mailmap(buf, &s);
 			data->size = cast_size_t_to_ulong(s);
 
@@ -511,7 +521,9 @@ static void batch_one_object(const char *obj_name,
 			     struct expand_data *data)
 {
 	struct object_context ctx;
-	int flags = opt->follow_symlinks ? GET_OID_FOLLOW_SYMLINKS : 0;
+	int flags =
+		GET_OID_HASH_ANY |
+		(opt->follow_symlinks ? GET_OID_FOLLOW_SYMLINKS : 0);
 	enum get_oid_result result;
 
 	result = get_oid_with_context(the_repository, obj_name,
diff --git a/builtin/checkout.c b/builtin/checkout.c
index 3a7bfde..71e6036 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -91,7 +91,7 @@ struct checkout_opts {
 	int new_branch_log;
 	enum branch_track track;
 	struct diff_options diff_options;
-	char *conflict_style;
+	int conflict_style;
 
 	int branch_exists;
 	const char *prefix;
@@ -100,6 +100,8 @@ struct checkout_opts {
 	struct tree *source_tree;
 };
 
+#define CHECKOUT_OPTS_INIT { .conflict_style = -1, .merge = -1 }
+
 struct branch_info {
 	char *name; /* The short name used */
 	char *path; /* The full name of a real branch */
@@ -251,7 +253,8 @@ static int checkout_stage(int stage, const struct cache_entry *ce, int pos,
 }
 
 static int checkout_merged(int pos, const struct checkout *state,
-			   int *nr_checkouts, struct mem_pool *ce_mem_pool)
+			   int *nr_checkouts, struct mem_pool *ce_mem_pool,
+			   int conflict_style)
 {
 	struct cache_entry *ce = the_index.cache[pos];
 	const char *path = ce->name;
@@ -262,7 +265,7 @@ static int checkout_merged(int pos, const struct checkout *state,
 	mmbuffer_t result_buf;
 	struct object_id threeway[3];
 	unsigned mode = 0;
-	struct ll_merge_options ll_opts;
+	struct ll_merge_options ll_opts = LL_MERGE_OPTIONS_INIT;
 	int renormalize = 0;
 
 	memset(threeway, 0, sizeof(threeway));
@@ -284,9 +287,9 @@ static int checkout_merged(int pos, const struct checkout *state,
 	read_mmblob(&ours, &threeway[1]);
 	read_mmblob(&theirs, &threeway[2]);
 
-	memset(&ll_opts, 0, sizeof(ll_opts));
 	git_config_get_bool("merge.renormalize", &renormalize);
 	ll_opts.renormalize = renormalize;
+	ll_opts.conflict_style = conflict_style;
 	merge_status = ll_merge(&result_buf, path, &ancestor, "base",
 				&ours, "ours", &theirs, "theirs",
 				state->istate, &ll_opts);
@@ -417,7 +420,8 @@ static int checkout_worktree(const struct checkout_opts *opts,
 			else if (opts->merge)
 				errs |= checkout_merged(pos, &state,
 							&nr_unmerged,
-							&ce_mem_pool);
+							&ce_mem_pool,
+							opts->conflict_style);
 			pos = skip_same_name(ce, pos) - 1;
 		}
 	}
@@ -704,8 +708,9 @@ static int reset_tree(struct tree *tree, const struct checkout_opts *o,
 	init_checkout_metadata(&opts.meta, info->refname,
 			       info->commit ? &info->commit->object.oid : null_oid(),
 			       NULL);
-	parse_tree(tree);
-	init_tree_desc(&tree_desc, tree->buffer, tree->size);
+	if (parse_tree(tree) < 0)
+		return 128;
+	init_tree_desc(&tree_desc, &tree->object.oid, tree->buffer, tree->size);
 	switch (unpack_trees(1, &tree_desc, &opts)) {
 	case -2:
 		*writeout_error = 1;
@@ -783,9 +788,15 @@ static int merge_working_tree(const struct checkout_opts *opts,
 		if (new_branch_info->commit)
 			BUG("'switch --orphan' should never accept a commit as starting point");
 		new_tree = parse_tree_indirect(the_hash_algo->empty_tree);
-	} else
+		if (!new_tree)
+			BUG("unable to read empty tree");
+	} else {
 		new_tree = repo_get_commit_tree(the_repository,
 						new_branch_info->commit);
+		if (!new_tree)
+			return error(_("unable to read tree (%s)"),
+				     oid_to_hex(&new_branch_info->commit->object.oid));
+	}
 	if (opts->discard_changes) {
 		ret = reset_tree(new_tree, opts, 1, writeout_error, new_branch_info);
 		if (ret)
@@ -819,10 +830,13 @@ static int merge_working_tree(const struct checkout_opts *opts,
 			die(_("unable to parse commit %s"),
 				oid_to_hex(old_commit_oid));
 
-		init_tree_desc(&trees[0], tree->buffer, tree->size);
-		parse_tree(new_tree);
+		init_tree_desc(&trees[0], &tree->object.oid,
+			       tree->buffer, tree->size);
+		if (parse_tree(new_tree) < 0)
+			exit(128);
 		tree = new_tree;
-		init_tree_desc(&trees[1], tree->buffer, tree->size);
+		init_tree_desc(&trees[1], &tree->object.oid,
+			       tree->buffer, tree->size);
 
 		ret = unpack_trees(2, trees, &topts);
 		clear_unpack_trees_porcelain(&topts);
@@ -868,7 +882,8 @@ static int merge_working_tree(const struct checkout_opts *opts,
 			 * entries in the index.
 			 */
 
-			add_files_to_cache(the_repository, NULL, NULL, 0, 0);
+			add_files_to_cache(the_repository, NULL, NULL, NULL, 0,
+					   0);
 			init_merge_options(&o, the_repository);
 			o.verbosity = 0;
 			work = write_in_core_index_as_tree(the_repository);
@@ -887,6 +902,7 @@ static int merge_working_tree(const struct checkout_opts *opts,
 			}
 			o.branch1 = new_branch_info->name;
 			o.branch2 = "local";
+			o.conflict_style = opts->conflict_style;
 			ret = merge_trees(&o,
 					  new_tree,
 					  work,
@@ -1020,7 +1036,8 @@ static void update_refs_for_switch(const struct checkout_opts *opts,
 	remove_branch_state(the_repository, !opts->quiet);
 	strbuf_release(&msg);
 	if (!opts->quiet &&
-	    (new_branch_info->path || (!opts->force_detach && !strcmp(new_branch_info->name, "HEAD"))))
+	    !opts->force_detach &&
+	    (new_branch_info->path || !strcmp(new_branch_info->name, "HEAD")))
 		report_tracking(new_branch_info);
 }
 
@@ -1224,7 +1241,9 @@ static void setup_new_branch_info_and_source_tree(
 	struct tree **source_tree = &opts->source_tree;
 	struct object_id branch_rev;
 
-	new_branch_info->name = xstrdup(arg);
+	/* treat '@' as a shortcut for 'HEAD' */
+	new_branch_info->name = !strcmp(arg, "@") ? xstrdup("HEAD") :
+						    xstrdup(arg);
 	setup_branch_path(new_branch_info);
 
 	if (!check_refname_format(new_branch_info->path, 0) &&
@@ -1238,10 +1257,15 @@ static void setup_new_branch_info_and_source_tree(
 	if (!new_branch_info->commit) {
 		/* not a commit */
 		*source_tree = parse_tree_indirect(rev);
+		if (!*source_tree)
+			die(_("unable to read tree (%s)"), oid_to_hex(rev));
 	} else {
 		parse_commit_or_die(new_branch_info->commit);
 		*source_tree = repo_get_commit_tree(the_repository,
 						    new_branch_info->commit);
+		if (!*source_tree)
+			die(_("unable to read tree (%s)"),
+			    oid_to_hex(&new_branch_info->commit->object.oid));
 	}
 }
 
@@ -1515,6 +1539,26 @@ static void die_if_some_operation_in_progress(void)
 	wt_status_state_free_buffers(&state);
 }
 
+/*
+ * die if attempting to checkout an existing branch that is in use
+ * in another worktree, unless ignore-other-wortrees option is given.
+ * The check is bypassed when the branch is already the current one,
+ * as it will not make things any worse.
+ */
+static void die_if_switching_to_a_branch_in_use(struct checkout_opts *opts,
+						const char *full_ref)
+{
+	int flags;
+	char *head_ref;
+
+	if (opts->ignore_other_worktrees)
+		return;
+	head_ref = resolve_refdup("HEAD", 0, NULL, &flags);
+	if (head_ref && (!(flags & REF_ISSYMREF) || strcmp(head_ref, full_ref)))
+		die_if_checked_out(full_ref, 1);
+	free(head_ref);
+}
+
 static int checkout_branch(struct checkout_opts *opts,
 			   struct branch_info *new_branch_info)
 {
@@ -1575,14 +1619,15 @@ static int checkout_branch(struct checkout_opts *opts,
 	if (!opts->can_switch_when_in_progress)
 		die_if_some_operation_in_progress();
 
-	if (new_branch_info->path && !opts->force_detach && !opts->new_branch &&
-	    !opts->ignore_other_worktrees) {
-		int flag;
-		char *head_ref = resolve_refdup("HEAD", 0, NULL, &flag);
-		if (head_ref &&
-		    (!(flag & REF_ISSYMREF) || strcmp(head_ref, new_branch_info->path)))
-			die_if_checked_out(new_branch_info->path, 1);
-		free(head_ref);
+	/* "git checkout <branch>" */
+	if (new_branch_info->path && !opts->force_detach && !opts->new_branch)
+		die_if_switching_to_a_branch_in_use(opts, new_branch_info->path);
+
+	/* "git checkout -B <branch>" */
+	if (opts->new_branch_force) {
+		char *full_ref = xstrfmt("refs/heads/%s", opts->new_branch);
+		die_if_switching_to_a_branch_in_use(opts, full_ref);
+		free(full_ref);
 	}
 
 	if (!new_branch_info->commit && opts->new_branch) {
@@ -1596,6 +1641,24 @@ static int checkout_branch(struct checkout_opts *opts,
 	return switch_branches(opts, new_branch_info);
 }
 
+static int parse_opt_conflict(const struct option *o, const char *arg, int unset)
+{
+	struct checkout_opts *opts = o->value;
+
+	if (unset) {
+		opts->conflict_style = -1;
+		return 0;
+	}
+	opts->conflict_style = parse_conflict_style_name(arg);
+	if (opts->conflict_style < 0)
+		return error(_("unknown conflict style '%s'"), arg);
+	/* --conflict overrides a previous --no-merge */
+	if (!opts->merge)
+		opts->merge = -1;
+
+	return 0;
+}
+
 static struct option *add_common_options(struct checkout_opts *opts,
 					 struct option *prevopts)
 {
@@ -1606,8 +1669,9 @@ static struct option *add_common_options(struct checkout_opts *opts,
 			    PARSE_OPT_OPTARG, option_parse_recurse_submodules_worktree_updater),
 		OPT_BOOL(0, "progress", &opts->show_progress, N_("force progress reporting")),
 		OPT_BOOL('m', "merge", &opts->merge, N_("perform a 3-way merge with the new branch")),
-		OPT_STRING(0, "conflict", &opts->conflict_style, N_("style"),
-			   N_("conflict style (merge, diff3, or zdiff3)")),
+		OPT_CALLBACK(0, "conflict", opts, N_("style"),
+			     N_("conflict style (merge, diff3, or zdiff3)"),
+			     parse_opt_conflict),
 		OPT_END()
 	};
 	struct option *newopts = parse_options_concat(prevopts, options);
@@ -1666,10 +1730,11 @@ static char cb_option = 'b';
 
 static int checkout_main(int argc, const char **argv, const char *prefix,
 			 struct checkout_opts *opts, struct option *options,
-			 const char * const usagestr[],
-			 struct branch_info *new_branch_info)
+			 const char * const usagestr[])
 {
 	int parseopt_flags = 0;
+	struct branch_info new_branch_info = { 0 };
+	int ret;
 
 	opts->overwrite_ignore = 1;
 	opts->prefix = prefix;
@@ -1698,15 +1763,10 @@ static int checkout_main(int argc, const char **argv, const char *prefix,
 			opts->show_progress = isatty(2);
 	}
 
-	if (opts->conflict_style) {
-		struct key_value_info kvi = KVI_INIT;
-		struct config_context ctx = {
-			.kvi = &kvi,
-		};
-		opts->merge = 1; /* implied */
-		git_xmerge_config("merge.conflictstyle", opts->conflict_style,
-				  &ctx, NULL);
-	}
+	/* --conflicts implies --merge */
+	if (opts->merge == -1)
+		opts->merge = opts->conflict_style >= 0;
+
 	if (opts->force) {
 		opts->discard_changes = 1;
 		opts->ignore_unmerged_opt = "--force";
@@ -1785,7 +1845,7 @@ static int checkout_main(int argc, const char **argv, const char *prefix,
 			opts->track == BRANCH_TRACK_UNSPECIFIED &&
 			!opts->new_branch;
 		int n = parse_branchname_arg(argc, argv, dwim_ok,
-					     new_branch_info, opts, &rev);
+					     &new_branch_info, opts, &rev);
 		argv += n;
 		argc -= n;
 	} else if (!opts->accept_ref && opts->from_treeish) {
@@ -1794,7 +1854,7 @@ static int checkout_main(int argc, const char **argv, const char *prefix,
 		if (repo_get_oid_mb(the_repository, opts->from_treeish, &rev))
 			die(_("could not resolve %s"), opts->from_treeish);
 
-		setup_new_branch_info_and_source_tree(new_branch_info,
+		setup_new_branch_info_and_source_tree(&new_branch_info,
 						      opts, &rev,
 						      opts->from_treeish);
 
@@ -1814,7 +1874,7 @@ static int checkout_main(int argc, const char **argv, const char *prefix,
 		 * Try to give more helpful suggestion.
 		 * new_branch && argc > 1 will be caught later.
 		 */
-		if (opts->new_branch && argc == 1 && !new_branch_info->commit)
+		if (opts->new_branch && argc == 1 && !new_branch_info.commit)
 			die(_("'%s' is not a commit and a branch '%s' cannot be created from it"),
 				argv[0], opts->new_branch);
 
@@ -1864,14 +1924,21 @@ static int checkout_main(int argc, const char **argv, const char *prefix,
 	}
 
 	if (opts->patch_mode || opts->pathspec.nr)
-		return checkout_paths(opts, new_branch_info);
+		ret = checkout_paths(opts, &new_branch_info);
 	else
-		return checkout_branch(opts, new_branch_info);
+		ret = checkout_branch(opts, &new_branch_info);
+
+	branch_info_release(&new_branch_info);
+	clear_pathspec(&opts->pathspec);
+	free(opts->pathspec_from_file);
+	free(options);
+
+	return ret;
 }
 
 int cmd_checkout(int argc, const char **argv, const char *prefix)
 {
-	struct checkout_opts opts;
+	struct checkout_opts opts = CHECKOUT_OPTS_INIT;
 	struct option *options;
 	struct option checkout_options[] = {
 		OPT_STRING('b', NULL, &opts.new_branch, N_("branch"),
@@ -1884,10 +1951,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
 		OPT_BOOL(0, "overlay", &opts.overlay_mode, N_("use overlay mode (default)")),
 		OPT_END()
 	};
-	int ret;
-	struct branch_info new_branch_info = { 0 };
 
-	memset(&opts, 0, sizeof(opts));
 	opts.dwim_new_local_branch = 1;
 	opts.switch_branch_doing_nothing_is_ok = 1;
 	opts.only_merge_on_switching_branches = 0;
@@ -1915,18 +1979,13 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
 	options = add_common_switch_branch_options(&opts, options);
 	options = add_checkout_path_options(&opts, options);
 
-	ret = checkout_main(argc, argv, prefix, &opts,
-			    options, checkout_usage, &new_branch_info);
-	branch_info_release(&new_branch_info);
-	clear_pathspec(&opts.pathspec);
-	free(opts.pathspec_from_file);
-	FREE_AND_NULL(options);
-	return ret;
+	return checkout_main(argc, argv, prefix, &opts, options,
+			     checkout_usage);
 }
 
 int cmd_switch(int argc, const char **argv, const char *prefix)
 {
-	struct checkout_opts opts;
+	struct checkout_opts opts = CHECKOUT_OPTS_INIT;
 	struct option *options = NULL;
 	struct option switch_options[] = {
 		OPT_STRING('c', "create", &opts.new_branch, N_("branch"),
@@ -1939,10 +1998,7 @@ int cmd_switch(int argc, const char **argv, const char *prefix)
 			 N_("throw away local modifications")),
 		OPT_END()
 	};
-	int ret;
-	struct branch_info new_branch_info = { 0 };
 
-	memset(&opts, 0, sizeof(opts));
 	opts.dwim_new_local_branch = 1;
 	opts.accept_ref = 1;
 	opts.accept_pathspec = 0;
@@ -1959,16 +2015,13 @@ int cmd_switch(int argc, const char **argv, const char *prefix)
 
 	cb_option = 'c';
 
-	ret = checkout_main(argc, argv, prefix, &opts,
-			    options, switch_branch_usage, &new_branch_info);
-	branch_info_release(&new_branch_info);
-	FREE_AND_NULL(options);
-	return ret;
+	return checkout_main(argc, argv, prefix, &opts, options,
+			     switch_branch_usage);
 }
 
 int cmd_restore(int argc, const char **argv, const char *prefix)
 {
-	struct checkout_opts opts;
+	struct checkout_opts opts = CHECKOUT_OPTS_INIT;
 	struct option *options;
 	struct option restore_options[] = {
 		OPT_STRING('s', "source", &opts.from_treeish, "<tree-ish>",
@@ -1982,10 +2035,7 @@ int cmd_restore(int argc, const char **argv, const char *prefix)
 		OPT_BOOL(0, "overlay", &opts.overlay_mode, N_("use overlay mode")),
 		OPT_END()
 	};
-	int ret;
-	struct branch_info new_branch_info = { 0 };
 
-	memset(&opts, 0, sizeof(opts));
 	opts.accept_ref = 0;
 	opts.accept_pathspec = 1;
 	opts.empty_pathspec_ok = 0;
@@ -1998,9 +2048,6 @@ int cmd_restore(int argc, const char **argv, const char *prefix)
 	options = add_common_options(&opts, options);
 	options = add_checkout_path_options(&opts, options);
 
-	ret = checkout_main(argc, argv, prefix, &opts,
-			    options, restore_usage, &new_branch_info);
-	branch_info_release(&new_branch_info);
-	FREE_AND_NULL(options);
-	return ret;
+	return checkout_main(argc, argv, prefix, &opts, options,
+			     restore_usage);
 }
diff --git a/builtin/clean.c b/builtin/clean.c
index d90766c..29efe84 100644
--- a/builtin/clean.c
+++ b/builtin/clean.c
@@ -25,7 +25,7 @@
 #include "help.h"
 #include "prompt.h"
 
-static int force = -1; /* unset */
+static int require_force = -1; /* unset */
 static int interactive;
 static struct string_list del_list = STRING_LIST_INIT_DUP;
 static unsigned int colopts;
@@ -128,7 +128,7 @@ static int git_clean_config(const char *var, const char *value,
 	}
 
 	if (!strcmp(var, "clean.requireforce")) {
-		force = !git_config_bool(var, value);
+		require_force = git_config_bool(var, value);
 		return 0;
 	}
 
@@ -920,7 +920,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
 {
 	int i, res;
 	int dry_run = 0, remove_directories = 0, quiet = 0, ignored = 0;
-	int ignored_only = 0, config_set = 0, errors = 0, gone = 1;
+	int ignored_only = 0, force = 0, errors = 0, gone = 1;
 	int rm_flags = REMOVE_DIR_KEEP_NESTED_GIT;
 	struct strbuf abs_path = STRBUF_INIT;
 	struct dir_struct dir = DIR_INIT;
@@ -946,22 +946,12 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
 	};
 
 	git_config(git_clean_config, NULL);
-	if (force < 0)
-		force = 0;
-	else
-		config_set = 1;
 
 	argc = parse_options(argc, argv, prefix, options, builtin_clean_usage,
 			     0);
 
-	if (!interactive && !dry_run && !force) {
-		if (config_set)
-			die(_("clean.requireForce set to true and neither -i, -n, nor -f given; "
-				  "refusing to clean"));
-		else
-			die(_("clean.requireForce defaults to true and neither -i, -n, nor -f given;"
-				  " refusing to clean"));
-	}
+	if (require_force != 0 && !force && !interactive && !dry_run)
+		die(_("clean.requireForce is true and -f not given: refusing to clean"));
 
 	if (force > 1)
 		rm_flags = 0;
diff --git a/builtin/clone.c b/builtin/clone.c
index 315befa..5fbe39f 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -71,6 +71,7 @@ static char *remote_name = NULL;
 static char *option_branch = NULL;
 static struct string_list option_not = STRING_LIST_INIT_NODUP;
 static const char *real_git_dir;
+static const char *ref_format;
 static char *option_upload_pack = "git-upload-pack";
 static int option_verbosity;
 static int option_progress = -1;
@@ -115,7 +116,7 @@ static struct option builtin_clone_options[] = {
 	OPT_HIDDEN_BOOL(0, "naked", &option_bare,
 			N_("create a bare repository")),
 	OPT_BOOL(0, "mirror", &option_mirror,
-		 N_("create a mirror repository (implies bare)")),
+		 N_("create a mirror repository (implies --bare)")),
 	OPT_BOOL('l', "local", &option_local,
 		N_("to clone from a local repository")),
 	OPT_BOOL(0, "no-hardlinks", &option_no_hardlinks,
@@ -156,6 +157,8 @@ static struct option builtin_clone_options[] = {
 		    N_("any cloned submodules will be shallow")),
 	OPT_STRING(0, "separate-git-dir", &real_git_dir, N_("gitdir"),
 		   N_("separate git dir from working tree")),
+	OPT_STRING(0, "ref-format", &ref_format, N_("format"),
+		   N_("specify the reference format to use")),
 	OPT_STRING_LIST('c', "config", &option_config, N_("key=value"),
 			N_("set config inside the new repository")),
 	OPT_STRING_LIST(0, "server-option", &server_options,
@@ -326,7 +329,20 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest,
 	int src_len, dest_len;
 	struct dir_iterator *iter;
 	int iter_status;
-	struct strbuf realpath = STRBUF_INIT;
+
+	/*
+	 * Refuse copying directories by default which aren't owned by us. The
+	 * code that performs either the copying or hardlinking is not prepared
+	 * to handle various edge cases where an adversary may for example
+	 * racily swap out files for symlinks. This can cause us to
+	 * inadvertently use the wrong source file.
+	 *
+	 * Furthermore, even if we were prepared to handle such races safely,
+	 * creating hardlinks across user boundaries is an inherently unsafe
+	 * operation as the hardlinked files can be rewritten at will by the
+	 * potentially-untrusted user. We thus refuse to do so by default.
+	 */
+	die_upon_dubious_ownership(NULL, NULL, src_repo);
 
 	mkdir_if_missing(dest->buf, 0777);
 
@@ -374,9 +390,27 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest,
 		if (unlink(dest->buf) && errno != ENOENT)
 			die_errno(_("failed to unlink '%s'"), dest->buf);
 		if (!option_no_hardlinks) {
-			strbuf_realpath(&realpath, src->buf, 1);
-			if (!link(realpath.buf, dest->buf))
+			if (!link(src->buf, dest->buf)) {
+				struct stat st;
+
+				/*
+				 * Sanity-check whether the created hardlink
+				 * actually links to the expected file now. This
+				 * catches time-of-check-time-of-use bugs in
+				 * case the source file was meanwhile swapped.
+				 */
+				if (lstat(dest->buf, &st))
+					die(_("hardlink cannot be checked at '%s'"), dest->buf);
+				if (st.st_mode != iter->st.st_mode ||
+				    st.st_ino != iter->st.st_ino ||
+				    st.st_dev != iter->st.st_dev ||
+				    st.st_size != iter->st.st_size ||
+				    st.st_uid != iter->st.st_uid ||
+				    st.st_gid != iter->st.st_gid)
+					die(_("hardlink different from source at '%s'"), dest->buf);
+
 				continue;
+			}
 			if (option_local > 0)
 				die_errno(_("failed to create link '%s'"), dest->buf);
 			option_no_hardlinks = 1;
@@ -389,8 +423,6 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest,
 		strbuf_setlen(src, src_len);
 		die(_("failed to iterate over '%s'"), src->buf);
 	}
-
-	strbuf_release(&realpath);
 }
 
 static void clone_local(const char *src_repo, const char *dest_repo)
@@ -735,8 +767,9 @@ static int checkout(int submodule_progress, int filter_submodules)
 	tree = parse_tree_indirect(&oid);
 	if (!tree)
 		die(_("unable to parse commit %s"), oid_to_hex(&oid));
-	parse_tree(tree);
-	init_tree_desc(&t, tree->buffer, tree->size);
+	if (parse_tree(tree) < 0)
+		exit(128);
+	init_tree_desc(&t, &tree->object.oid, tree->buffer, tree->size);
 	if (unpack_trees(1, &t, &opts) < 0)
 		die(_("unable to checkout working tree"));
 
@@ -923,6 +956,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 	struct ref *mapped_refs = NULL;
 	const struct ref *ref;
 	struct strbuf key = STRBUF_INIT;
+	struct strbuf buf = STRBUF_INIT;
 	struct strbuf branch_top = STRBUF_INIT, reflog_msg = STRBUF_INIT;
 	struct transport *transport = NULL;
 	const char *src_ref_prefix = "refs/heads/";
@@ -931,6 +965,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 	int submodule_progress;
 	int filter_submodules = 0;
 	int hash_algo;
+	unsigned int ref_storage_format = REF_STORAGE_FORMAT_UNKNOWN;
 	const int do_not_override_repo_unix_permissions = -1;
 
 	struct transport_ls_refs_options transport_ls_refs_options =
@@ -956,6 +991,12 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 	if (option_single_branch == -1)
 		option_single_branch = deepen ? 1 : 0;
 
+	if (ref_format) {
+		ref_storage_format = ref_storage_format_by_name(ref_format);
+		if (ref_storage_format == REF_STORAGE_FORMAT_UNKNOWN)
+			die(_("unknown ref storage format '%s'"), ref_format);
+	}
+
 	if (option_mirror)
 		option_bare = 1;
 
@@ -1100,8 +1141,15 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 		}
 	}
 
-	init_db(git_dir, real_git_dir, option_template, GIT_HASH_UNKNOWN, NULL,
-		do_not_override_repo_unix_permissions, INIT_DB_QUIET);
+	/*
+	 * Initialize the repository, but skip initializing the reference
+	 * database. We do not yet know about the object format of the
+	 * repository, and reference backends may persist that information into
+	 * their on-disk data structures.
+	 */
+	init_db(git_dir, real_git_dir, option_template, GIT_HASH_UNKNOWN,
+		ref_storage_format, NULL,
+		do_not_override_repo_unix_permissions, INIT_DB_QUIET | INIT_DB_SKIP_REFDB);
 
 	if (real_git_dir) {
 		free((char *)git_dir);
@@ -1109,6 +1157,50 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 	}
 
 	/*
+	 * We have a chicken-and-egg situation between initializing the refdb
+	 * and spawning transport helpers:
+	 *
+	 *   - Initializing the refdb requires us to know about the object
+	 *     format. We thus have to spawn the transport helper to learn
+	 *     about it.
+	 *
+	 *   - The transport helper may want to access the Git repository. But
+	 *     because the refdb has not been initialized, we don't have "HEAD"
+	 *     or "refs/". Thus, the helper cannot find the Git repository.
+	 *
+	 * Ideally, we would have structured the helper protocol such that it's
+	 * mandatory for the helper to first announce its capabilities without
+	 * yet assuming a fully initialized repository. Like that, we could
+	 * have added a "lazy-refdb-init" capability that announces whether the
+	 * helper is ready to handle not-yet-initialized refdbs. If any helper
+	 * didn't support them, we would have fully initialized the refdb with
+	 * the SHA1 object format, but later on bailed out if we found out that
+	 * the remote repository used a different object format.
+	 *
+	 * But we didn't, and thus we use the following workaround to partially
+	 * initialize the repository's refdb such that it can be discovered by
+	 * Git commands. To do so, we:
+	 *
+	 *   - Create an invalid HEAD ref pointing at "refs/heads/.invalid".
+	 *
+	 *   - Create the "refs/" directory.
+	 *
+	 *   - Set up the ref storage format and repository version as
+	 *     required.
+	 *
+	 * This is sufficient for Git commands to discover the Git directory.
+	 */
+	initialize_repository_version(GIT_HASH_UNKNOWN,
+				      the_repository->ref_storage_format, 1);
+
+	strbuf_addf(&buf, "%s/HEAD", git_dir);
+	write_file(buf.buf, "ref: refs/heads/.invalid");
+
+	strbuf_reset(&buf);
+	strbuf_addf(&buf, "%s/refs", git_dir);
+	safe_create_dir(buf.buf, 1);
+
+	/*
 	 * additional config can be injected with -c, make sure it's included
 	 * after init_db, which clears the entire config environment.
 	 */
@@ -1188,10 +1280,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 	if (option_required_reference.nr || option_optional_reference.nr)
 		setup_reference();
 
-	if (option_sparse_checkout && git_sparse_checkout_init(dir))
-		return 1;
-
-	remote = remote_get(remote_name);
+	remote = remote_get_early(remote_name);
 
 	refspec_appendf(&remote->fetch, "+%s*:%s*", src_ref_prefix,
 			branch_top.buf);
@@ -1269,6 +1358,27 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 	if (transport->smart_options && !deepen && !filter_options.choice)
 		transport->smart_options->check_self_contained_and_connected = 1;
 
+	strvec_push(&transport_ls_refs_options.ref_prefixes, "HEAD");
+	refspec_ref_prefixes(&remote->fetch,
+			     &transport_ls_refs_options.ref_prefixes);
+	if (option_branch)
+		expand_ref_prefix(&transport_ls_refs_options.ref_prefixes,
+				  option_branch);
+	if (!option_no_tags)
+		strvec_push(&transport_ls_refs_options.ref_prefixes,
+			    "refs/tags/");
+
+	refs = transport_get_remote_refs(transport, &transport_ls_refs_options);
+
+	/*
+	 * Now that we know what algorithm the remote side is using, let's set
+	 * ours to the same thing.
+	 */
+	hash_algo = hash_algo_by_ptr(transport_get_hash_algo(transport));
+	initialize_repository_version(hash_algo, the_repository->ref_storage_format, 1);
+	repo_set_hash_algo(the_repository, hash_algo);
+	create_reference_database(the_repository->ref_storage_format, NULL, 1);
+
 	/*
 	 * Before fetching from the remote, download and install bundle
 	 * data from the --bundle-uri option.
@@ -1284,24 +1394,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 				bundle_uri);
 		else if (has_heuristic)
 			git_config_set_gently("fetch.bundleuri", bundle_uri);
-	}
-
-	strvec_push(&transport_ls_refs_options.ref_prefixes, "HEAD");
-	refspec_ref_prefixes(&remote->fetch,
-			     &transport_ls_refs_options.ref_prefixes);
-	if (option_branch)
-		expand_ref_prefix(&transport_ls_refs_options.ref_prefixes,
-				  option_branch);
-	if (!option_no_tags)
-		strvec_push(&transport_ls_refs_options.ref_prefixes,
-			    "refs/tags/");
-
-	refs = transport_get_remote_refs(transport, &transport_ls_refs_options);
-
-	if (refs)
-		mapped_refs = wanted_peer_refs(refs, &remote->fetch);
-
-	if (!bundle_uri) {
+	} else {
 		/*
 		* Populate transport->got_remote_bundle_uri and
 		* transport->bundle_uri. We might get nothing.
@@ -1322,13 +1415,8 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 		}
 	}
 
-		/*
-		 * Now that we know what algorithm the remote side is using,
-		 * let's set ours to the same thing.
-		 */
-	hash_algo = hash_algo_by_ptr(transport_get_hash_algo(transport));
-	initialize_repository_version(hash_algo, 1);
-	repo_set_hash_algo(the_repository, hash_algo);
+	if (refs)
+		mapped_refs = wanted_peer_refs(refs, &remote->fetch);
 
 	if (mapped_refs) {
 		/*
@@ -1431,12 +1519,16 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 		dissociate_from_references();
 	}
 
+	if (option_sparse_checkout && git_sparse_checkout_init(dir))
+		return 1;
+
 	junk_mode = JUNK_LEAVE_REPO;
 	err = checkout(submodule_progress, filter_submodules);
 
 	free(remote_name);
 	strbuf_release(&reflog_msg);
 	strbuf_release(&branch_top);
+	strbuf_release(&buf);
 	strbuf_release(&key);
 	free_refs(mapped_refs);
 	free_refs(remote_head_points_at);
@@ -1444,6 +1536,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 	free(dir);
 	free(path);
 	free(repo_to_free);
+	UNLEAK(repo);
 	junk_mode = JUNK_LEAVE_ALL;
 
 	transport_ls_refs_options_release(&transport_ls_refs_options);
diff --git a/builtin/column.c b/builtin/column.c
index e80218f..10ff7e0 100644
--- a/builtin/column.c
+++ b/builtin/column.c
@@ -45,6 +45,8 @@ int cmd_column(int argc, const char **argv, const char *prefix)
 	memset(&copts, 0, sizeof(copts));
 	copts.padding = 1;
 	argc = parse_options(argc, argv, prefix, options, builtin_column_usage, 0);
+	if (copts.padding < 0)
+		die(_("%s must be non-negative"), "--padding");
 	if (argc)
 		usage_with_options(builtin_column_usage, options);
 	if (real_command || command) {
diff --git a/builtin/commit-graph.c b/builtin/commit-graph.c
index 666ad57..7102ee9 100644
--- a/builtin/commit-graph.c
+++ b/builtin/commit-graph.c
@@ -21,7 +21,7 @@
 	N_("git commit-graph write [--object-dir <dir>] [--append]\n" \
 	   "                       [--split[=<strategy>]] [--reachable | --stdin-packs | --stdin-commits]\n" \
 	   "                       [--changed-paths] [--[no-]max-new-filters <n>] [--[no-]progress]\n" \
-	   "                       <split options>")
+	   "                       <split-options>")
 
 static const char * builtin_commit_graph_verify_usage[] = {
 	BUILTIN_COMMIT_GRAPH_VERIFY_USAGE,
diff --git a/builtin/commit.c b/builtin/commit.c
index 65196a2..6e14844 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -331,8 +331,9 @@ static void create_base_index(const struct commit *current_head)
 	tree = parse_tree_indirect(&current_head->object.oid);
 	if (!tree)
 		die(_("failed to unpack HEAD tree object"));
-	parse_tree(tree);
-	init_tree_desc(&t, tree->buffer, tree->size);
+	if (parse_tree(tree) < 0)
+		exit(128);
+	init_tree_desc(&t, &tree->object.oid, tree->buffer, tree->size);
 	if (unpack_trees(1, &t, &opts))
 		exit(128); /* We've already reported the error, finish dying */
 }
@@ -440,16 +441,21 @@ static const char *prepare_index(const char **argv, const char *prefix,
 	 * (B) on failure, rollback the real index.
 	 */
 	if (all || (also && pathspec.nr)) {
+		char *ps_matched = xcalloc(pathspec.nr, 1);
 		repo_hold_locked_index(the_repository, &index_lock,
 				       LOCK_DIE_ON_ERROR);
 		add_files_to_cache(the_repository, also ? prefix : NULL,
-				   &pathspec, 0, 0);
+				   &pathspec, ps_matched, 0, 0);
+		if (!all && report_path_error(ps_matched, &pathspec))
+			exit(128);
+
 		refresh_cache_or_die(refresh_flags);
 		cache_tree_update(&the_index, WRITE_TREE_SILENT);
 		if (write_locked_index(&the_index, &index_lock, 0))
 			die(_("unable to write new index file"));
 		commit_style = COMMIT_NORMAL;
 		ret = get_lock_file_path(&index_lock);
+		free(ps_matched);
 		goto out;
 	}
 
@@ -684,9 +690,10 @@ static void adjust_comment_line_char(const struct strbuf *sb)
 	char *candidate;
 	const char *p;
 
-	comment_line_char = candidates[0];
-	if (!memchr(sb->buf, comment_line_char, sb->len))
+	if (!memchr(sb->buf, candidates[0], sb->len)) {
+		comment_line_str = xstrfmt("%c", candidates[0]);
 		return;
+	}
 
 	p = sb->buf;
 	candidate = strchr(candidates, *p);
@@ -705,7 +712,7 @@ static void adjust_comment_line_char(const struct strbuf *sb)
 	if (!*p)
 		die(_("unable to select a comment character that is not used\n"
 		      "in the current commit message"));
-	comment_line_char = *p;
+	comment_line_str = xstrfmt("%c", *p);
 }
 
 static void prepare_amend_commit(struct commit *commit, struct strbuf *sb,
@@ -737,7 +744,6 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
 	const char *hook_arg2 = NULL;
 	int clean_message_contents = (cleanup_mode != COMMIT_MSG_CLEANUP_NONE);
 	int old_display_comment_prefix;
-	int merge_contains_scissors = 0;
 	int invoked_hook;
 
 	/* This checks and barfs if author is badly specified */
@@ -841,7 +847,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
 		    wt_status_locate_end(sb.buf + merge_msg_start,
 					 sb.len - merge_msg_start) <
 				sb.len - merge_msg_start)
-			merge_contains_scissors = 1;
+			s->added_cut_line = 1;
 	} else if (!stat(git_path_squash_msg(the_repository), &statbuf)) {
 		if (strbuf_read_file(&sb, git_path_squash_msg(the_repository), 0) < 0)
 			die_errno(_("could not read SQUASH_MSG"));
@@ -889,7 +895,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
 	s->hints = 0;
 
 	if (clean_message_contents)
-		strbuf_stripspace(&sb, '\0');
+		strbuf_stripspace(&sb, NULL);
 
 	if (signoff)
 		append_signoff(&sb, ignored_log_message_bytes(sb.buf, sb.len), 0);
@@ -909,24 +915,23 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
 		struct ident_split ci, ai;
 		const char *hint_cleanup_all = allow_empty_message ?
 			_("Please enter the commit message for your changes."
-			  " Lines starting\nwith '%c' will be ignored.\n") :
+			  " Lines starting\nwith '%s' will be ignored.\n") :
 			_("Please enter the commit message for your changes."
-			  " Lines starting\nwith '%c' will be ignored, and an empty"
+			  " Lines starting\nwith '%s' will be ignored, and an empty"
 			  " message aborts the commit.\n");
 		const char *hint_cleanup_space = allow_empty_message ?
 			_("Please enter the commit message for your changes."
 			  " Lines starting\n"
-			  "with '%c' will be kept; you may remove them"
+			  "with '%s' will be kept; you may remove them"
 			  " yourself if you want to.\n") :
 			_("Please enter the commit message for your changes."
 			  " Lines starting\n"
-			  "with '%c' will be kept; you may remove them"
+			  "with '%s' will be kept; you may remove them"
 			  " yourself if you want to.\n"
 			  "An empty message aborts the commit.\n");
 		if (whence != FROM_COMMIT) {
-			if (cleanup_mode == COMMIT_MSG_CLEANUP_SCISSORS &&
-				!merge_contains_scissors)
-				wt_status_add_cut_line(s->fp);
+			if (cleanup_mode == COMMIT_MSG_CLEANUP_SCISSORS)
+				wt_status_add_cut_line(s);
 			status_printf_ln(
 				s, GIT_COLOR_NORMAL,
 				whence == FROM_MERGE ?
@@ -944,12 +949,12 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
 
 		fprintf(s->fp, "\n");
 		if (cleanup_mode == COMMIT_MSG_CLEANUP_ALL)
-			status_printf(s, GIT_COLOR_NORMAL, hint_cleanup_all, comment_line_char);
+			status_printf(s, GIT_COLOR_NORMAL, hint_cleanup_all, comment_line_str);
 		else if (cleanup_mode == COMMIT_MSG_CLEANUP_SCISSORS) {
-			if (whence == FROM_COMMIT && !merge_contains_scissors)
-				wt_status_add_cut_line(s->fp);
+			if (whence == FROM_COMMIT)
+				wt_status_add_cut_line(s);
 		} else /* COMMIT_MSG_CLEANUP_SPACE, that is. */
-			status_printf(s, GIT_COLOR_NORMAL, hint_cleanup_space, comment_line_char);
+			status_printf(s, GIT_COLOR_NORMAL, hint_cleanup_space, comment_line_str);
 
 		/*
 		 * These should never fail because they come from our own
@@ -1158,22 +1163,45 @@ static void handle_ignored_arg(struct wt_status *s)
 		die(_("Invalid ignored mode '%s'"), ignored_arg);
 }
 
-static void handle_untracked_files_arg(struct wt_status *s)
+static enum untracked_status_type parse_untracked_setting_name(const char *u)
 {
-	if (!untracked_files_arg)
-		; /* default already initialized */
-	else if (!strcmp(untracked_files_arg, "no"))
-		s->show_untracked_files = SHOW_NO_UNTRACKED_FILES;
-	else if (!strcmp(untracked_files_arg, "normal"))
-		s->show_untracked_files = SHOW_NORMAL_UNTRACKED_FILES;
-	else if (!strcmp(untracked_files_arg, "all"))
-		s->show_untracked_files = SHOW_ALL_UNTRACKED_FILES;
 	/*
 	 * Please update $__git_untracked_file_modes in
 	 * git-completion.bash when you add new options
 	 */
+	switch (git_parse_maybe_bool(u)) {
+	case 0:
+		u = "no";
+		break;
+	case 1:
+		u = "normal";
+		break;
+	default:
+		break;
+	}
+
+	if (!strcmp(u, "no"))
+		return SHOW_NO_UNTRACKED_FILES;
+	else if (!strcmp(u, "normal"))
+		return SHOW_NORMAL_UNTRACKED_FILES;
+	else if (!strcmp(u, "all"))
+		return SHOW_ALL_UNTRACKED_FILES;
 	else
-		die(_("Invalid untracked files mode '%s'"), untracked_files_arg);
+		return SHOW_UNTRACKED_FILES_ERROR;
+}
+
+static void handle_untracked_files_arg(struct wt_status *s)
+{
+	enum untracked_status_type u;
+
+	if (!untracked_files_arg)
+		return; /* default already initialized */
+
+	u = parse_untracked_setting_name(untracked_files_arg);
+	if (u == SHOW_UNTRACKED_FILES_ERROR)
+		die(_("Invalid untracked files mode '%s'"),
+		    untracked_files_arg);
+	s->show_untracked_files = u;
 }
 
 static const char *read_commit_message(const char *name)
@@ -1456,16 +1484,12 @@ static int git_status_config(const char *k, const char *v,
 		return 0;
 	}
 	if (!strcmp(k, "status.showuntrackedfiles")) {
-		if (!v)
-			return config_error_nonbool(k);
-		else if (!strcmp(v, "no"))
-			s->show_untracked_files = SHOW_NO_UNTRACKED_FILES;
-		else if (!strcmp(v, "normal"))
-			s->show_untracked_files = SHOW_NORMAL_UNTRACKED_FILES;
-		else if (!strcmp(v, "all"))
-			s->show_untracked_files = SHOW_ALL_UNTRACKED_FILES;
-		else
+		enum untracked_status_type u;
+
+		u = parse_untracked_setting_name(v);
+		if (u == SHOW_UNTRACKED_FILES_ERROR)
 			return error(_("Invalid untracked files mode '%s'"), v);
+		s->show_untracked_files = u;
 		return 0;
 	}
 	if (!strcmp(k, "diff.renamelimit")) {
@@ -1877,7 +1901,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
 				     &oid, flags);
 	}
 
-	apply_autostash(git_path_merge_autostash(the_repository));
+	apply_autostash_ref(the_repository, "MERGE_AUTOSTASH");
 
 cleanup:
 	strbuf_release(&author_ident);
diff --git a/builtin/config.c b/builtin/config.c
index 11a4d4e..0015620 100644
--- a/builtin/config.c
+++ b/builtin/config.c
@@ -44,6 +44,7 @@ static struct config_options config_options;
 static int show_origin;
 static int show_scope;
 static int fixed_value;
+static const char *comment;
 
 #define ACTION_GET (1<<0)
 #define ACTION_GET_ALL (1<<1)
@@ -173,6 +174,7 @@ static struct option builtin_config_options[] = {
 	OPT_BOOL(0, "show-origin", &show_origin, N_("show origin of config (file, standard input, blob, command line)")),
 	OPT_BOOL(0, "show-scope", &show_scope, N_("show scope of config (worktree, local, global, system, command)")),
 	OPT_STRING(0, "default", &default_value, N_("value"), N_("with --get, use default value when missing entry")),
+	OPT_STRING(0, "comment", &comment, N_("value"), N_("human-readable comment string (# will be prepended as needed)")),
 	OPT_END(),
 };
 
@@ -708,10 +710,8 @@ int cmd_config(int argc, const char **argv, const char *prefix)
 	}
 
 	if (use_global_config) {
-		char *user_config, *xdg_config;
-
-		git_global_config(&user_config, &xdg_config);
-		if (!user_config)
+		given_config_source.file = git_global_config();
+		if (!given_config_source.file)
 			/*
 			 * It is unknown if HOME/.gitconfig exists, so
 			 * we do not know if we should write to XDG
@@ -719,19 +719,8 @@ int cmd_config(int argc, const char **argv, const char *prefix)
 			 * is set and points at a sane location.
 			 */
 			die(_("$HOME not set"));
-
 		given_config_source.scope = CONFIG_SCOPE_GLOBAL;
-
-		if (access_or_warn(user_config, R_OK, 0) &&
-		    xdg_config && !access_or_warn(xdg_config, R_OK, 0)) {
-			given_config_source.file = xdg_config;
-			free(user_config);
-		} else {
-			given_config_source.file = user_config;
-			free(xdg_config);
-		}
-	}
-	else if (use_system_config) {
+	} else if (use_system_config) {
 		given_config_source.file = git_system_config();
 		given_config_source.scope = CONFIG_SCOPE_SYSTEM;
 	} else if (use_local_config) {
@@ -760,7 +749,6 @@ int cmd_config(int argc, const char **argv, const char *prefix)
 		given_config_source.scope = CONFIG_SCOPE_COMMAND;
 	}
 
-
 	if (respect_includes_opt == -1)
 		config_options.respect_includes = !given_config_source.file;
 	else
@@ -811,6 +799,12 @@ int cmd_config(int argc, const char **argv, const char *prefix)
 		usage_builtin_config();
 	}
 
+	if (comment &&
+	    !(actions & (ACTION_ADD|ACTION_SET|ACTION_SET_ALL|ACTION_REPLACE_ALL))) {
+		error(_("--comment is only applicable to add/set/replace operations"));
+		usage_builtin_config();
+	}
+
 	/* check usage of --fixed-value */
 	if (fixed_value) {
 		int allowed_usage = 0;
@@ -847,6 +841,8 @@ int cmd_config(int argc, const char **argv, const char *prefix)
 		flags |= CONFIG_FLAGS_FIXED_VALUE;
 	}
 
+	comment = git_config_prepare_comment_string(comment);
+
 	if (actions & PAGING_ACTIONS)
 		setup_auto_pager("config", 1);
 
@@ -894,7 +890,7 @@ int cmd_config(int argc, const char **argv, const char *prefix)
 		check_write();
 		check_argc(argc, 2, 2);
 		value = normalize_value(argv[0], argv[1], &default_kvi);
-		ret = git_config_set_in_file_gently(given_config_source.file, argv[0], value);
+		ret = git_config_set_in_file_gently(given_config_source.file, argv[0], comment, value);
 		if (ret == CONFIG_NOTHING_SET)
 			error(_("cannot overwrite multiple values with a single value\n"
 			"       Use a regexp, --add or --replace-all to change %s."), argv[0]);
@@ -905,7 +901,7 @@ int cmd_config(int argc, const char **argv, const char *prefix)
 		value = normalize_value(argv[0], argv[1], &default_kvi);
 		ret = git_config_set_multivar_in_file_gently(given_config_source.file,
 							     argv[0], value, argv[2],
-							     flags);
+							     comment, flags);
 	}
 	else if (actions == ACTION_ADD) {
 		check_write();
@@ -914,7 +910,7 @@ int cmd_config(int argc, const char **argv, const char *prefix)
 		ret = git_config_set_multivar_in_file_gently(given_config_source.file,
 							     argv[0], value,
 							     CONFIG_REGEX_NONE,
-							     flags);
+							     comment, flags);
 	}
 	else if (actions == ACTION_REPLACE_ALL) {
 		check_write();
@@ -922,7 +918,7 @@ int cmd_config(int argc, const char **argv, const char *prefix)
 		value = normalize_value(argv[0], argv[1], &default_kvi);
 		ret = git_config_set_multivar_in_file_gently(given_config_source.file,
 							     argv[0], value, argv[2],
-							     flags | CONFIG_FLAGS_MULTI_REPLACE);
+							     comment, flags | CONFIG_FLAGS_MULTI_REPLACE);
 	}
 	else if (actions == ACTION_GET) {
 		check_argc(argc, 1, 2);
@@ -950,17 +946,17 @@ int cmd_config(int argc, const char **argv, const char *prefix)
 		if (argc == 2)
 			return git_config_set_multivar_in_file_gently(given_config_source.file,
 								      argv[0], NULL, argv[1],
-								      flags);
+								      NULL, flags);
 		else
 			return git_config_set_in_file_gently(given_config_source.file,
-							     argv[0], NULL);
+							     argv[0], NULL, NULL);
 	}
 	else if (actions == ACTION_UNSET_ALL) {
 		check_write();
 		check_argc(argc, 1, 2);
 		return git_config_set_multivar_in_file_gently(given_config_source.file,
 							      argv[0], NULL, argv[1],
-							      flags | CONFIG_FLAGS_MULTI_REPLACE);
+							      NULL, flags | CONFIG_FLAGS_MULTI_REPLACE);
 	}
 	else if (actions == ACTION_RENAME_SECTION) {
 		check_write();
diff --git a/builtin/credential-cache--daemon.c b/builtin/credential-cache--daemon.c
index 3a6a750..17f929d 100644
--- a/builtin/credential-cache--daemon.c
+++ b/builtin/credential-cache--daemon.c
@@ -294,6 +294,8 @@ int cmd_credential_cache_daemon(int argc, const char **argv, const char *prefix)
 	argc = parse_options(argc, argv, prefix, options, usage, 0);
 	socket_path = argv[0];
 
+	if (!have_unix_sockets())
+		die(_("credential-cache--daemon unavailable; no unix socket support"));
 	if (!socket_path)
 		usage_with_options(usage, options);
 
diff --git a/builtin/credential-cache.c b/builtin/credential-cache.c
index bba96d4..bef120b 100644
--- a/builtin/credential-cache.c
+++ b/builtin/credential-cache.c
@@ -149,6 +149,9 @@ int cmd_credential_cache(int argc, const char **argv, const char *prefix)
 		usage_with_options(usage, options);
 	op = argv[0];
 
+	if (!have_unix_sockets())
+		die(_("credential-cache unavailable; no unix socket support"));
+
 	if (!socket_path)
 		socket_path = get_socket_path();
 	if (!socket_path)
diff --git a/builtin/fast-export.c b/builtin/fast-export.c
index f18f080..4693d18 100644
--- a/builtin/fast-export.c
+++ b/builtin/fast-export.c
@@ -136,8 +136,7 @@ static int anonymized_entry_cmp(const void *cmp_data UNUSED,
 	a = container_of(eptr, const struct anonymized_entry, hash);
 	if (keydata) {
 		const struct anonymized_entry_key *key = keydata;
-		int equal = !strncmp(a->orig, key->orig, key->orig_len) &&
-			    !a->orig[key->orig_len];
+		int equal = !xstrncmpz(a->orig, key->orig, key->orig_len);
 		return !equal;
 	}
 
diff --git a/builtin/fast-import.c b/builtin/fast-import.c
index 92eda20..dc5a9d3 100644
--- a/builtin/fast-import.c
+++ b/builtin/fast-import.c
@@ -1236,20 +1236,6 @@ static void *gfi_unpack_entry(
 	return unpack_entry(the_repository, p, oe->idx.offset, &type, sizep);
 }
 
-static const char *get_mode(const char *str, uint16_t *modep)
-{
-	unsigned char c;
-	uint16_t mode = 0;
-
-	while ((c = *str++) != ' ') {
-		if (c < '0' || c > '7')
-			return NULL;
-		mode = (mode << 3) + (c - '0');
-	}
-	*modep = mode;
-	return str;
-}
-
 static void load_tree(struct tree_entry *root)
 {
 	struct object_id *oid = &root->versions[1].oid;
@@ -1287,7 +1273,7 @@ static void load_tree(struct tree_entry *root)
 		t->entries[t->entry_count++] = e;
 
 		e->tree = NULL;
-		c = get_mode(c, &e->versions[1].mode);
+		c = parse_mode(c, &e->versions[1].mode);
 		if (!c)
 			die("Corrupt mode in %s", oid_to_hex(oid));
 		e->versions[0].mode = e->versions[1].mode;
@@ -1625,6 +1611,7 @@ static int update_branch(struct branch *b)
 		oidclr(&old_oid);
 	if (!force_update && !is_null_oid(&old_oid)) {
 		struct commit *old_cmit, *new_cmit;
+		int ret;
 
 		old_cmit = lookup_commit_reference_gently(the_repository,
 							  &old_oid, 0);
@@ -1633,7 +1620,10 @@ static int update_branch(struct branch *b)
 		if (!old_cmit || !new_cmit)
 			return error("Branch %s is missing commits.", b->name);
 
-		if (!repo_in_merge_bases(the_repository, old_cmit, new_cmit)) {
+		ret = repo_in_merge_bases(the_repository, old_cmit, new_cmit);
+		if (ret < 0)
+			exit(128);
+		if (!ret) {
 			warning("Not updating %s"
 				" (new tip %s does not contain %s)",
 				b->name, oid_to_hex(&b->oid),
@@ -2220,7 +2210,7 @@ static int parse_mapped_oid_hex(const char *hex, struct object_id *oid, const ch
  *
  *   idnum ::= ':' bigint;
  *
- * Return the first character after the value in *endptr.
+ * Update *endptr to point to the first character after the value.
  *
  * Complain if the following character is not what is expected,
  * either a space or end of the string.
@@ -2253,8 +2243,8 @@ static uintmax_t parse_mark_ref_eol(const char *p)
 }
 
 /*
- * Parse the mark reference, demanding a trailing space.  Return a
- * pointer to the space.
+ * Parse the mark reference, demanding a trailing space. Update *p to
+ * point to the first character after the space.
  */
 static uintmax_t parse_mark_ref_space(const char **p)
 {
@@ -2268,15 +2258,67 @@ static uintmax_t parse_mark_ref_space(const char **p)
 	return mark;
 }
 
+/*
+ * Parse the path string into the strbuf. The path can either be quoted with
+ * escape sequences or unquoted without escape sequences. Unquoted strings may
+ * contain spaces only if `is_last_field` is nonzero; otherwise, it stops
+ * parsing at the first space.
+ */
+static void parse_path(struct strbuf *sb, const char *p, const char **endp,
+		int is_last_field, const char *field)
+{
+	if (*p == '"') {
+		if (unquote_c_style(sb, p, endp))
+			die("Invalid %s: %s", field, command_buf.buf);
+		if (strlen(sb->buf) != sb->len)
+			die("NUL in %s: %s", field, command_buf.buf);
+	} else {
+		/*
+		 * Unless we are parsing the last field of a line,
+		 * SP is the end of this field.
+		 */
+		*endp = is_last_field
+			? p + strlen(p)
+			: strchrnul(p, ' ');
+		strbuf_add(sb, p, *endp - p);
+	}
+}
+
+/*
+ * Parse the path string into the strbuf, and complain if this is not the end of
+ * the string. Unquoted strings may contain spaces.
+ */
+static void parse_path_eol(struct strbuf *sb, const char *p, const char *field)
+{
+	const char *end;
+
+	parse_path(sb, p, &end, 1, field);
+	if (*end)
+		die("Garbage after %s: %s", field, command_buf.buf);
+}
+
+/*
+ * Parse the path string into the strbuf, and ensure it is followed by a space.
+ * Unquoted strings may not contain spaces. Update *endp to point to the first
+ * character after the space.
+ */
+static void parse_path_space(struct strbuf *sb, const char *p,
+		const char **endp, const char *field)
+{
+	parse_path(sb, p, endp, 0, field);
+	if (**endp != ' ')
+		die("Missing space after %s: %s", field, command_buf.buf);
+	(*endp)++;
+}
+
 static void file_change_m(const char *p, struct branch *b)
 {
-	static struct strbuf uq = STRBUF_INIT;
-	const char *endp;
+	static struct strbuf path = STRBUF_INIT;
 	struct object_entry *oe;
 	struct object_id oid;
 	uint16_t mode, inline_data = 0;
 
-	p = get_mode(p, &mode);
+	p = parse_mode(p, &mode);
 	if (!p)
 		die("Corrupt mode: %s", command_buf.buf);
 	switch (mode) {
@@ -2308,16 +2350,12 @@ static void file_change_m(const char *p, struct branch *b)
 			die("Missing space after SHA1: %s", command_buf.buf);
 	}
 
-	strbuf_reset(&uq);
-	if (!unquote_c_style(&uq, p, &endp)) {
-		if (*endp)
-			die("Garbage after path in: %s", command_buf.buf);
-		p = uq.buf;
-	}
+	strbuf_reset(&path);
+	parse_path_eol(&path, p, "path");
 
 	/* Git does not track empty, non-toplevel directories. */
-	if (S_ISDIR(mode) && is_empty_tree_oid(&oid) && *p) {
-		tree_content_remove(&b->branch_tree, p, NULL, 0);
+	if (S_ISDIR(mode) && is_empty_tree_oid(&oid) && *path.buf) {
+		tree_content_remove(&b->branch_tree, path.buf, NULL, 0);
 		return;
 	}
 
@@ -2338,10 +2376,6 @@ static void file_change_m(const char *p, struct branch *b)
 		if (S_ISDIR(mode))
 			die("Directories cannot be specified 'inline': %s",
 				command_buf.buf);
-		if (p != uq.buf) {
-			strbuf_addstr(&uq, p);
-			p = uq.buf;
-		}
 		while (read_next_command() != EOF) {
 			const char *v;
 			if (skip_prefix(command_buf.buf, "cat-blob ", &v))
@@ -2367,74 +2401,48 @@ static void file_change_m(const char *p, struct branch *b)
 				command_buf.buf);
 	}
 
-	if (!*p) {
+	if (!*path.buf) {
 		tree_content_replace(&b->branch_tree, &oid, mode, NULL);
 		return;
 	}
-	tree_content_set(&b->branch_tree, p, &oid, mode, NULL);
+	tree_content_set(&b->branch_tree, path.buf, &oid, mode, NULL);
 }
 
 static void file_change_d(const char *p, struct branch *b)
 {
-	static struct strbuf uq = STRBUF_INIT;
-	const char *endp;
+	static struct strbuf path = STRBUF_INIT;
 
-	strbuf_reset(&uq);
-	if (!unquote_c_style(&uq, p, &endp)) {
-		if (*endp)
-			die("Garbage after path in: %s", command_buf.buf);
-		p = uq.buf;
-	}
-	tree_content_remove(&b->branch_tree, p, NULL, 1);
+	strbuf_reset(&path);
+	parse_path_eol(&path, p, "path");
+	tree_content_remove(&b->branch_tree, path.buf, NULL, 1);
 }
 
-static void file_change_cr(const char *s, struct branch *b, int rename)
+static void file_change_cr(const char *p, struct branch *b, int rename)
 {
-	const char *d;
-	static struct strbuf s_uq = STRBUF_INIT;
-	static struct strbuf d_uq = STRBUF_INIT;
-	const char *endp;
+	static struct strbuf source = STRBUF_INIT;
+	static struct strbuf dest = STRBUF_INIT;
 	struct tree_entry leaf;
 
-	strbuf_reset(&s_uq);
-	if (!unquote_c_style(&s_uq, s, &endp)) {
-		if (*endp != ' ')
-			die("Missing space after source: %s", command_buf.buf);
-	} else {
-		endp = strchr(s, ' ');
-		if (!endp)
-			die("Missing space after source: %s", command_buf.buf);
-		strbuf_add(&s_uq, s, endp - s);
-	}
-	s = s_uq.buf;
-
-	endp++;
-	if (!*endp)
-		die("Missing dest: %s", command_buf.buf);
-
-	d = endp;
-	strbuf_reset(&d_uq);
-	if (!unquote_c_style(&d_uq, d, &endp)) {
-		if (*endp)
-			die("Garbage after dest in: %s", command_buf.buf);
-		d = d_uq.buf;
-	}
+	strbuf_reset(&source);
+	parse_path_space(&source, p, &p, "source");
+	strbuf_reset(&dest);
+	parse_path_eol(&dest, p, "dest");
 
 	memset(&leaf, 0, sizeof(leaf));
 	if (rename)
-		tree_content_remove(&b->branch_tree, s, &leaf, 1);
+		tree_content_remove(&b->branch_tree, source.buf, &leaf, 1);
 	else
-		tree_content_get(&b->branch_tree, s, &leaf, 1);
+		tree_content_get(&b->branch_tree, source.buf, &leaf, 1);
 	if (!leaf.versions[1].mode)
-		die("Path %s not in branch", s);
-	if (!*d) {	/* C "path/to/subdir" "" */
+		die("Path %s not in branch", source.buf);
+	if (!*dest.buf) {	/* C "path/to/subdir" "" */
 		tree_content_replace(&b->branch_tree,
 			&leaf.versions[1].oid,
 			leaf.versions[1].mode,
 			leaf.tree);
 		return;
 	}
-	tree_content_set(&b->branch_tree, d,
+	tree_content_set(&b->branch_tree, dest.buf,
 		&leaf.versions[1].oid,
 		leaf.versions[1].mode,
 		leaf.tree);
@@ -2442,7 +2450,6 @@ static void file_change_cr(const char *s, struct branch *b, int rename)
 
 static void note_change_n(const char *p, struct branch *b, unsigned char *old_fanout)
 {
-	static struct strbuf uq = STRBUF_INIT;
 	struct object_entry *oe;
 	struct branch *s;
 	struct object_id oid, commit_oid;
@@ -2507,10 +2514,6 @@ static void note_change_n(const char *p, struct branch *b, unsigned char *old_fa
 		die("Invalid ref name or SHA1 expression: %s", p);
 
 	if (inline_data) {
-		if (p != uq.buf) {
-			strbuf_addstr(&uq, p);
-			p = uq.buf;
-		}
 		read_next_command();
 		parse_and_store_blob(&last_blob, &oid, 0);
 	} else if (oe) {
@@ -3162,6 +3165,7 @@ static void print_ls(int mode, const unsigned char *hash, const char *path)
 
 static void parse_ls(const char *p, struct branch *b)
 {
+	static struct strbuf path = STRBUF_INIT;
 	struct tree_entry *root = NULL;
 	struct tree_entry leaf = {NULL};
 
@@ -3178,17 +3182,9 @@ static void parse_ls(const char *p, struct branch *b)
 			root->versions[1].mode = S_IFDIR;
 		load_tree(root);
 	}
-	if (*p == '"') {
-		static struct strbuf uq = STRBUF_INIT;
-		const char *endp;
-		strbuf_reset(&uq);
-		if (unquote_c_style(&uq, p, &endp))
-			die("Invalid path: %s", command_buf.buf);
-		if (*endp)
-			die("Garbage after path in: %s", command_buf.buf);
-		p = uq.buf;
-	}
-	tree_content_get(root, p, &leaf, 1);
+	strbuf_reset(&path);
+	parse_path_eol(&path, p, "path");
+	tree_content_get(root, path.buf, &leaf, 1);
 	/*
 	 * A directory in preparation would have a sha1 of zero
 	 * until it is saved.  Save, for simplicity.
@@ -3196,7 +3192,7 @@ static void parse_ls(const char *p, struct branch *b)
 	if (S_ISDIR(leaf.versions[1].mode))
 		store_tree(&leaf);
 
-	print_ls(leaf.versions[1].mode, leaf.versions[1].oid.hash, p);
+	print_ls(leaf.versions[1].mode, leaf.versions[1].oid.hash, path.buf);
 	if (leaf.tree)
 		release_tree_content_recursive(leaf.tree);
 	if (!b || root != &b->branch_tree)
diff --git a/builtin/fetch.c b/builtin/fetch.c
index 119f1a7..5857d86 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -100,6 +100,7 @@ static struct string_list negotiation_tip = STRING_LIST_INIT_NODUP;
 
 struct fetch_config {
 	enum display_format display_format;
+	int all;
 	int prune;
 	int prune_tags;
 	int show_forced_updates;
@@ -113,6 +114,11 @@ static int git_fetch_config(const char *k, const char *v,
 {
 	struct fetch_config *fetch_config = cb;
 
+	if (!strcmp(k, "fetch.all")) {
+		fetch_config->all = git_config_bool(k, v);
+		return 0;
+	}
+
 	if (!strcmp(k, "fetch.prune")) {
 		fetch_config->prune = git_config_bool(k, v);
 		return 0;
@@ -132,6 +138,7 @@ static int git_fetch_config(const char *k, const char *v,
 		int r = git_config_bool(k, v) ?
 			RECURSE_SUBMODULES_ON : RECURSE_SUBMODULES_OFF;
 		fetch_config->recurse_submodules = r;
+		return 0;
 	}
 
 	if (!strcmp(k, "submodule.fetchjobs")) {
@@ -442,9 +449,8 @@ static void filter_prefetch_refspec(struct refspec *rs)
 			continue;
 		if (!rs->items[i].dst ||
 		    (rs->items[i].src &&
-		     !strncmp(rs->items[i].src,
-			      ref_namespace[NAMESPACE_TAGS].ref,
-			      strlen(ref_namespace[NAMESPACE_TAGS].ref)))) {
+		     starts_with(rs->items[i].src,
+				 ref_namespace[NAMESPACE_TAGS].ref))) {
 			int j;
 
 			free(rs->items[i].src);
@@ -976,6 +982,8 @@ static int update_local_ref(struct ref *ref,
 		uint64_t t_before = getnanotime();
 		fast_forward = repo_in_merge_bases(the_repository, current,
 						   updated);
+		if (fast_forward < 0)
+			exit(128);
 		forced_updates_ms += (getnanotime() - t_before) / 1000000;
 	} else {
 		fast_forward = 1;
@@ -2130,7 +2138,7 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
 	const char *bundle_uri;
 	struct string_list list = STRING_LIST_INIT_DUP;
 	struct remote *remote = NULL;
-	int all = 0, multiple = 0;
+	int all = -1, multiple = 0;
 	int result = 0;
 	int prune_tags_ok = 1;
 	int enable_auto_gc = 1;
@@ -2335,11 +2343,20 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
 	    fetch_bundle_uri(the_repository, bundle_uri, NULL))
 		warning(_("failed to fetch bundles from '%s'"), bundle_uri);
 
+	if (all < 0) {
+		/*
+		 * no --[no-]all given;
+		 * only use config option if no remote was explicitly specified
+		 */
+		all = (!argc) ? config.all : 0;
+	}
+
 	if (all) {
 		if (argc == 1)
 			die(_("fetch --all does not take a repository argument"));
 		else if (argc > 1)
 			die(_("fetch --all does not make sense with refspecs"));
+
 		(void) for_each_remote(get_one_remote_for_fetch, &list);
 
 		/* do not do fetch_multiple() of one */
diff --git a/builtin/for-each-ref.c b/builtin/for-each-ref.c
index b5bc700..919282e 100644
--- a/builtin/for-each-ref.c
+++ b/builtin/for-each-ref.c
@@ -18,16 +18,12 @@ static char const * const for_each_ref_usage[] = {
 
 int cmd_for_each_ref(int argc, const char **argv, const char *prefix)
 {
-	int i;
 	struct ref_sorting *sorting;
 	struct string_list sorting_options = STRING_LIST_INIT_DUP;
-	int maxcount = 0, icase = 0, omit_empty = 0;
-	struct ref_array array;
+	int icase = 0, include_root_refs = 0, from_stdin = 0;
 	struct ref_filter filter = REF_FILTER_INIT;
 	struct ref_format format = REF_FORMAT_INIT;
-	struct strbuf output = STRBUF_INIT;
-	struct strbuf err = STRBUF_INIT;
-	int from_stdin = 0;
+	unsigned int flags = FILTER_REFS_REGULAR;
 	struct strvec vec = STRVEC_INIT;
 
 	struct option opts[] = {
@@ -39,11 +35,11 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix)
 			N_("quote placeholders suitably for python"), QUOTE_PYTHON),
 		OPT_BIT(0 , "tcl",  &format.quote_style,
 			N_("quote placeholders suitably for Tcl"), QUOTE_TCL),
-		OPT_BOOL(0, "omit-empty",  &omit_empty,
+		OPT_BOOL(0, "omit-empty",  &format.array_opts.omit_empty,
 			N_("do not output a newline after empty formatted refs")),
 
 		OPT_GROUP(""),
-		OPT_INTEGER( 0 , "count", &maxcount, N_("show only <n> matched refs")),
+		OPT_INTEGER( 0 , "count", &format.array_opts.max_count, N_("show only <n> matched refs")),
 		OPT_STRING(  0 , "format", &format.format, N_("format"), N_("format to use for the output")),
 		OPT__COLOR(&format.use_color, N_("respect format colors")),
 		OPT_REF_FILTER_EXCLUDE(&filter),
@@ -57,18 +53,20 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix)
 		OPT_NO_CONTAINS(&filter.no_commit, N_("print only refs which don't contain the commit")),
 		OPT_BOOL(0, "ignore-case", &icase, N_("sorting and filtering are case insensitive")),
 		OPT_BOOL(0, "stdin", &from_stdin, N_("read reference patterns from stdin")),
+		OPT_BOOL(0, "include-root-refs", &include_root_refs, N_("also include HEAD ref and pseudorefs")),
 		OPT_END(),
 	};
 
-	memset(&array, 0, sizeof(array));
-
 	format.format = "%(objectname) %(objecttype)\t%(refname)";
 
 	git_config(git_default_config, NULL);
 
+	/* Set default (refname) sorting */
+	string_list_append(&sorting_options, "refname");
+
 	parse_options(argc, argv, prefix, opts, for_each_ref_usage, 0);
-	if (maxcount < 0) {
-		error("invalid --count argument: `%d'", maxcount);
+	if (format.array_opts.max_count < 0) {
+		error("invalid --count argument: `%d'", format.array_opts.max_count);
 		usage_with_options(for_each_ref_usage, opts);
 	}
 	if (HAS_MULTI_BITS(format.quote_style)) {
@@ -99,27 +97,12 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix)
 		filter.name_patterns = argv;
 	}
 
+	if (include_root_refs)
+		flags |= FILTER_REFS_ROOT_REFS;
+
 	filter.match_as_path = 1;
-	filter_refs(&array, &filter, FILTER_REFS_ALL);
-	filter_ahead_behind(the_repository, &format, &array);
+	filter_and_format_refs(&filter, flags, sorting, &format);
 
-	ref_array_sort(sorting, &array);
-
-	if (!maxcount || array.nr < maxcount)
-		maxcount = array.nr;
-	for (i = 0; i < maxcount; i++) {
-		strbuf_reset(&err);
-		strbuf_reset(&output);
-		if (format_ref_array_item(array.items[i], &format, &output, &err))
-			die("%s", err.buf);
-		fwrite(output.buf, 1, output.len, stdout);
-		if (output.len || !omit_empty)
-			putchar('\n');
-	}
-
-	strbuf_release(&err);
-	strbuf_release(&output);
-	ref_array_clear(&array);
 	ref_filter_clear(&filter);
 	ref_sorting_release(sorting);
 	strvec_clear(&vec);
diff --git a/builtin/for-each-repo.c b/builtin/for-each-repo.c
index 28186b3..c4fa41f 100644
--- a/builtin/for-each-repo.c
+++ b/builtin/for-each-repo.c
@@ -32,6 +32,7 @@ static int run_command_on_repo(const char *path, int argc, const char ** argv)
 int cmd_for_each_repo(int argc, const char **argv, const char *prefix)
 {
 	static const char *config_key = NULL;
+	int keep_going = 0;
 	int i, result = 0;
 	const struct string_list *values;
 	int err;
@@ -39,6 +40,8 @@ int cmd_for_each_repo(int argc, const char **argv, const char *prefix)
 	const struct option options[] = {
 		OPT_STRING(0, "config", &config_key, N_("config"),
 			   N_("config key storing a list of repository paths")),
+		OPT_BOOL(0, "keep-going", &keep_going,
+			 N_("keep going even if command fails in a repository")),
 		OPT_END()
 	};
 
@@ -55,8 +58,14 @@ int cmd_for_each_repo(int argc, const char **argv, const char *prefix)
 	else if (err)
 		return 0;
 
-	for (i = 0; !result && i < values->nr; i++)
-		result = run_command_on_repo(values->items[i].string, argc, argv);
+	for (i = 0; i < values->nr; i++) {
+		int ret = run_command_on_repo(values->items[i].string, argc, argv);
+		if (ret) {
+			if (!keep_going)
+					return ret;
+			result = 1;
+		}
+	}
 
 	return result;
 }
diff --git a/builtin/fsck.c b/builtin/fsck.c
index a7cf94f..f892487 100644
--- a/builtin/fsck.c
+++ b/builtin/fsck.c
@@ -509,9 +509,7 @@ static int fsck_handle_reflog_ent(struct object_id *ooid, struct object_id *noid
 	return 0;
 }
 
-static int fsck_handle_reflog(const char *logname,
-			      const struct object_id *oid UNUSED,
-			      int flag UNUSED, void *cb_data)
+static int fsck_handle_reflog(const char *logname, void *cb_data)
 {
 	struct strbuf refname = STRBUF_INIT;
 
diff --git a/builtin/gc.c b/builtin/gc.c
index 7c11d5e..d3b5ca9 100644
--- a/builtin/gc.c
+++ b/builtin/gc.c
@@ -180,13 +180,51 @@ static void gc_config(void)
 	git_config(git_default_config, NULL);
 }
 
-struct maintenance_run_opts;
+enum schedule_priority {
+	SCHEDULE_NONE = 0,
+	SCHEDULE_WEEKLY = 1,
+	SCHEDULE_DAILY = 2,
+	SCHEDULE_HOURLY = 3,
+};
+
+static enum schedule_priority parse_schedule(const char *value)
+{
+	if (!value)
+		return SCHEDULE_NONE;
+	if (!strcasecmp(value, "hourly"))
+		return SCHEDULE_HOURLY;
+	if (!strcasecmp(value, "daily"))
+		return SCHEDULE_DAILY;
+	if (!strcasecmp(value, "weekly"))
+		return SCHEDULE_WEEKLY;
+	return SCHEDULE_NONE;
+}
+
+struct maintenance_run_opts {
+	int auto_flag;
+	int quiet;
+	enum schedule_priority schedule;
+};
+
+static int pack_refs_condition(void)
+{
+	/*
+	 * The auto-repacking logic for refs is handled by the ref backends and
+	 * exposed via `git pack-refs --auto`. We thus always return truish
+	 * here and let the backend decide for us.
+	 */
+	return 1;
+}
+
 static int maintenance_task_pack_refs(MAYBE_UNUSED struct maintenance_run_opts *opts)
 {
 	struct child_process cmd = CHILD_PROCESS_INIT;
 
 	cmd.git_cmd = 1;
 	strvec_pushl(&cmd.args, "pack-refs", "--all", "--prune", NULL);
+	if (opts->auto_flag)
+		strvec_push(&cmd.args, "--auto");
+
 	return run_command(&cmd);
 }
 
@@ -547,7 +585,7 @@ static int report_last_gc_error(void)
 	return ret;
 }
 
-static void gc_before_repack(void)
+static void gc_before_repack(struct maintenance_run_opts *opts)
 {
 	/*
 	 * We may be called twice, as both the pre- and
@@ -558,7 +596,7 @@ static void gc_before_repack(void)
 	if (done++)
 		return;
 
-	if (pack_refs && maintenance_task_pack_refs(NULL))
+	if (pack_refs && maintenance_task_pack_refs(opts))
 		die(FAILED_RUN, "pack-refs");
 
 	if (prune_reflogs) {
@@ -574,7 +612,6 @@ static void gc_before_repack(void)
 int cmd_gc(int argc, const char **argv, const char *prefix)
 {
 	int aggressive = 0;
-	int auto_gc = 0;
 	int quiet = 0;
 	int force = 0;
 	const char *name;
@@ -583,6 +620,7 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
 	int keep_largest_pack = -1;
 	timestamp_t dummy;
 	struct child_process rerere_cmd = CHILD_PROCESS_INIT;
+	struct maintenance_run_opts opts = {0};
 
 	struct option builtin_gc_options[] = {
 		OPT__QUIET(&quiet, N_("suppress progress reporting")),
@@ -593,7 +631,7 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
 		OPT_MAGNITUDE(0, "max-cruft-size", &max_cruft_size,
 			      N_("with --cruft, limit the size of new cruft packs")),
 		OPT_BOOL(0, "aggressive", &aggressive, N_("be more thorough (increased runtime)")),
-		OPT_BOOL_F(0, "auto", &auto_gc, N_("enable auto-gc mode"),
+		OPT_BOOL_F(0, "auto", &opts.auto_flag, N_("enable auto-gc mode"),
 			   PARSE_OPT_NOCOMPLETE),
 		OPT_BOOL_F(0, "force", &force,
 			   N_("force running gc even if there may be another gc running"),
@@ -638,7 +676,7 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
 	if (quiet)
 		strvec_push(&repack, "-q");
 
-	if (auto_gc) {
+	if (opts.auto_flag) {
 		/*
 		 * Auto-gc should be least intrusive as possible.
 		 */
@@ -663,7 +701,7 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
 
 			if (lock_repo_for_gc(force, &pid))
 				return 0;
-			gc_before_repack(); /* dies on failure */
+			gc_before_repack(&opts); /* dies on failure */
 			delete_tempfile(&pidfile);
 
 			/*
@@ -688,7 +726,7 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
 
 	name = lock_repo_for_gc(force, &pid);
 	if (name) {
-		if (auto_gc)
+		if (opts.auto_flag)
 			return 0; /* be quiet on --auto */
 		die(_("gc is already running on machine '%s' pid %"PRIuMAX" (use --force if not)"),
 		    name, (uintmax_t)pid);
@@ -703,7 +741,7 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
 		atexit(process_log_file_at_exit);
 	}
 
-	gc_before_repack();
+	gc_before_repack(&opts);
 
 	if (!repository_format_precious_objects) {
 		struct child_process repack_cmd = CHILD_PROCESS_INIT;
@@ -758,7 +796,7 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
 					     !quiet && !daemonized ? COMMIT_GRAPH_WRITE_PROGRESS : 0,
 					     NULL);
 
-	if (auto_gc && too_many_loose_objects())
+	if (opts.auto_flag && too_many_loose_objects())
 		warning(_("There are too many unreachable loose objects; "
 			"run 'git prune' to remove them."));
 
@@ -773,26 +811,6 @@ static const char *const builtin_maintenance_run_usage[] = {
 	NULL
 };
 
-enum schedule_priority {
-	SCHEDULE_NONE = 0,
-	SCHEDULE_WEEKLY = 1,
-	SCHEDULE_DAILY = 2,
-	SCHEDULE_HOURLY = 3,
-};
-
-static enum schedule_priority parse_schedule(const char *value)
-{
-	if (!value)
-		return SCHEDULE_NONE;
-	if (!strcasecmp(value, "hourly"))
-		return SCHEDULE_HOURLY;
-	if (!strcasecmp(value, "daily"))
-		return SCHEDULE_DAILY;
-	if (!strcasecmp(value, "weekly"))
-		return SCHEDULE_WEEKLY;
-	return SCHEDULE_NONE;
-}
-
 static int maintenance_opt_schedule(const struct option *opt, const char *arg,
 				    int unset)
 {
@@ -809,12 +827,6 @@ static int maintenance_opt_schedule(const struct option *opt, const char *arg,
 	return 0;
 }
 
-struct maintenance_run_opts {
-	int auto_flag;
-	int quiet;
-	enum schedule_priority schedule;
-};
-
 /* Remember to update object flag allocation in object.h */
 #define SEEN		(1u<<0)
 
@@ -1296,7 +1308,7 @@ static struct maintenance_task tasks[] = {
 	[TASK_PACK_REFS] = {
 		"pack-refs",
 		maintenance_task_pack_refs,
-		NULL,
+		pack_refs_condition,
 	},
 };
 
@@ -1543,19 +1555,18 @@ static int maintenance_register(int argc, const char **argv, const char *prefix)
 
 	if (!found) {
 		int rc;
-		char *user_config = NULL, *xdg_config = NULL;
+		char *global_config_file = NULL;
 
 		if (!config_file) {
-			git_global_config(&user_config, &xdg_config);
-			config_file = user_config;
-			if (!user_config)
-				die(_("$HOME not set"));
+			global_config_file = git_global_config();
+			config_file = global_config_file;
 		}
+		if (!config_file)
+			die(_("$HOME not set"));
 		rc = git_config_set_multivar_in_file_gently(
 			config_file, "maintenance.repo", maintpath,
-			CONFIG_REGEX_NONE, 0);
-		free(user_config);
-		free(xdg_config);
+			CONFIG_REGEX_NONE, NULL, 0);
+		free(global_config_file);
 
 		if (rc)
 			die(_("unable to add '%s' value of '%s'"),
@@ -1612,18 +1623,18 @@ static int maintenance_unregister(int argc, const char **argv, const char *prefi
 
 	if (found) {
 		int rc;
-		char *user_config = NULL, *xdg_config = NULL;
+		char *global_config_file = NULL;
+
 		if (!config_file) {
-			git_global_config(&user_config, &xdg_config);
-			config_file = user_config;
-			if (!user_config)
-				die(_("$HOME not set"));
+			global_config_file = git_global_config();
+			config_file = global_config_file;
 		}
+		if (!config_file)
+			die(_("$HOME not set"));
 		rc = git_config_set_multivar_in_file_gently(
-			config_file, key, NULL, maintpath,
+			config_file, key, NULL, maintpath, NULL,
 			CONFIG_FLAGS_MULTI_REPLACE | CONFIG_FLAGS_FIXED_VALUE);
-		free(user_config);
-		free(xdg_config);
+		free(global_config_file);
 
 		if (rc &&
 		    (!force || rc == CONFIG_NOTHING_SET))
@@ -1859,6 +1870,7 @@ static int launchctl_schedule_plist(const char *exec_path, enum schedule_priorit
 		   "<string>%s/git</string>\n"
 		   "<string>--exec-path=%s</string>\n"
 		   "<string>for-each-repo</string>\n"
+		   "<string>--keep-going</string>\n"
 		   "<string>--config=maintenance.repo</string>\n"
 		   "<string>maintenance</string>\n"
 		   "<string>run</string>\n"
@@ -2101,7 +2113,7 @@ static int schtasks_schedule_task(const char *exec_path, enum schedule_priority
 	      "<Actions Context=\"Author\">\n"
 	      "<Exec>\n"
 	      "<Command>\"%s\\headless-git.exe\"</Command>\n"
-	      "<Arguments>--exec-path=\"%s\" for-each-repo --config=maintenance.repo maintenance run --schedule=%s</Arguments>\n"
+	      "<Arguments>--exec-path=\"%s\" for-each-repo --keep-going --config=maintenance.repo maintenance run --schedule=%s</Arguments>\n"
 	      "</Exec>\n"
 	      "</Actions>\n"
 	      "</Task>\n";
@@ -2246,7 +2258,7 @@ static int crontab_update_schedule(int run_maintenance, int fd)
 			"# replaced in the future by a Git command.\n\n");
 
 		strbuf_addf(&line_format,
-			    "%%d %%s * * %%s \"%s/git\" --exec-path=\"%s\" for-each-repo --config=maintenance.repo maintenance run --schedule=%%s\n",
+			    "%%d %%s * * %%s \"%s/git\" --exec-path=\"%s\" for-each-repo --keep-going --config=maintenance.repo maintenance run --schedule=%%s\n",
 			    exec_path, exec_path);
 		fprintf(cron_in, line_format.buf, minute, "1-23", "*", "hourly");
 		fprintf(cron_in, line_format.buf, minute, "0", "1-6", "daily");
@@ -2447,7 +2459,7 @@ static int systemd_timer_write_service_template(const char *exec_path)
 	       "\n"
 	       "[Service]\n"
 	       "Type=oneshot\n"
-	       "ExecStart=\"%s/git\" --exec-path=\"%s\" for-each-repo --config=maintenance.repo maintenance run --schedule=%%i\n"
+	       "ExecStart=\"%s/git\" --exec-path=\"%s\" for-each-repo --keep-going --config=maintenance.repo maintenance run --schedule=%%i\n"
 	       "LockPersonality=yes\n"
 	       "MemoryDenyWriteExecute=yes\n"
 	       "NoNewPrivileges=yes\n"
diff --git a/builtin/grep.c b/builtin/grep.c
index c8e33f9..5777ba8 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -527,7 +527,7 @@ static int grep_submodule(struct grep_opt *opt,
 		strbuf_addstr(&base, filename);
 		strbuf_addch(&base, '/');
 
-		init_tree_desc(&tree, data, size);
+		init_tree_desc(&tree, oid, data, size);
 		hit = grep_tree(&subopt, pathspec, &tree, &base, base.len,
 				object_type == OBJ_COMMIT);
 		strbuf_release(&base);
@@ -571,7 +571,9 @@ static int grep_cache(struct grep_opt *opt,
 
 			data = repo_read_object_file(the_repository, &ce->oid,
 						     &type, &size);
-			init_tree_desc(&tree, data, size);
+			if (!data)
+				die(_("unable to read tree %s"), oid_to_hex(&ce->oid));
+			init_tree_desc(&tree, &ce->oid, data, size);
 
 			hit |= grep_tree(opt, pathspec, &tree, &name, 0, 0);
 			strbuf_setlen(&name, name_base_len);
@@ -667,7 +669,7 @@ static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec,
 				    oid_to_hex(&entry.oid));
 
 			strbuf_addch(base, '/');
-			init_tree_desc(&sub, data, size);
+			init_tree_desc(&sub, &entry.oid, data, size);
 			hit |= grep_tree(opt, pathspec, &sub, base, tn_len,
 					 check_attr);
 			free(data);
@@ -711,7 +713,7 @@ static int grep_object(struct grep_opt *opt, const struct pathspec *pathspec,
 			strbuf_add(&base, name, len);
 			strbuf_addch(&base, ':');
 		}
-		init_tree_desc(&tree, data, size);
+		init_tree_desc(&tree, &obj->oid, data, size);
 		hit = grep_tree(opt, pathspec, &tree, &base, base.len,
 				obj->type == OBJ_COMMIT);
 		strbuf_release(&base);
diff --git a/builtin/index-pack.c b/builtin/index-pack.c
index 1ea87e0..856428f 100644
--- a/builtin/index-pack.c
+++ b/builtin/index-pack.c
@@ -24,7 +24,7 @@
 #include "setup.h"
 
 static const char index_pack_usage[] =
-"git index-pack [-v] [-o <index-file>] [--keep | --keep=<msg>] [--[no-]rev-index] [--verify] [--strict] (<pack-file> | --stdin [--fix-thin] [<pack-file>])";
+"git index-pack [-v] [-o <index-file>] [--keep | --keep=<msg>] [--[no-]rev-index] [--verify] [--strict[=<msg-id>=<severity>...]] [--fsck-objects[=<msg-id>=<severity>...]] (<pack-file> | --stdin [--fix-thin] [<pack-file>])";
 
 struct object_entry {
 	struct pack_idx_entry idx;
@@ -1524,14 +1524,12 @@ static void final(const char *final_pack_name, const char *curr_pack_name,
 	struct strbuf pack_name = STRBUF_INIT;
 	struct strbuf index_name = STRBUF_INIT;
 	struct strbuf rev_index_name = STRBUF_INIT;
-	int err;
 
 	if (!from_stdin) {
 		close(input_fd);
 	} else {
 		fsync_component_or_die(FSYNC_COMPONENT_PACK, output_fd, curr_pack_name);
-		err = close(output_fd);
-		if (err)
+		if (close(output_fd))
 			die_errno(_("error while closing pack file"));
 	}
 
@@ -1566,17 +1564,8 @@ static void final(const char *final_pack_name, const char *curr_pack_name,
 		write_or_die(1, buf.buf, buf.len);
 		strbuf_release(&buf);
 
-		/*
-		 * Let's just mimic git-unpack-objects here and write
-		 * the last part of the input buffer to stdout.
-		 */
-		while (input_len) {
-			err = xwrite(1, input_buffer + input_offset, input_len);
-			if (err <= 0)
-				break;
-			input_len -= err;
-			input_offset += err;
-		}
+		/* Write the last part of the buffer to stdout */
+		write_in_full(1, input_buffer + input_offset, input_len);
 	}
 
 	strbuf_release(&rev_index_name);
@@ -1785,8 +1774,9 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
 			} else if (!strcmp(arg, "--check-self-contained-and-connected")) {
 				strict = 1;
 				check_self_contained_and_connected = 1;
-			} else if (!strcmp(arg, "--fsck-objects")) {
+			} else if (skip_to_optional_arg(arg, "--fsck-objects", &arg)) {
 				do_fsck_object = 1;
+				fsck_set_msg_types(&fsck_options, arg);
 			} else if (!strcmp(arg, "--verify")) {
 				verify = 1;
 			} else if (!strcmp(arg, "--verify-stat")) {
diff --git a/builtin/init-db.c b/builtin/init-db.c
index b89814a..0170469 100644
--- a/builtin/init-db.c
+++ b/builtin/init-db.c
@@ -10,6 +10,8 @@
 #include "object-file.h"
 #include "parse-options.h"
 #include "path.h"
+#include "refs.h"
+#include "repository.h"
 #include "setup.h"
 #include "strbuf.h"
 
@@ -56,6 +58,7 @@ static int shared_callback(const struct option *opt, const char *arg, int unset)
 static const char *const init_db_usage[] = {
 	N_("git init [-q | --quiet] [--bare] [--template=<template-directory>]\n"
 	   "         [--separate-git-dir <git-dir>] [--object-format=<format>]\n"
+	   "         [--ref-format=<format>]\n"
 	   "         [-b <branch-name> | --initial-branch=<branch-name>]\n"
 	   "         [--shared[=<permissions>]] [<directory>]"),
 	NULL
@@ -75,8 +78,10 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
 	const char *template_dir = NULL;
 	unsigned int flags = 0;
 	const char *object_format = NULL;
+	const char *ref_format = NULL;
 	const char *initial_branch = NULL;
 	int hash_algo = GIT_HASH_UNKNOWN;
+	unsigned int ref_storage_format = REF_STORAGE_FORMAT_UNKNOWN;
 	int init_shared_repository = -1;
 	const struct option init_db_options[] = {
 		OPT_STRING(0, "template", &template_dir, N_("template-directory"),
@@ -94,6 +99,8 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
 			   N_("override the name of the initial branch")),
 		OPT_STRING(0, "object-format", &object_format, N_("hash"),
 			   N_("specify the hash algorithm to use")),
+		OPT_STRING(0, "ref-format", &ref_format, N_("format"),
+			   N_("specify the reference format to use")),
 		OPT_END()
 	};
 
@@ -157,6 +164,12 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
 			die(_("unknown hash algorithm '%s'"), object_format);
 	}
 
+	if (ref_format) {
+		ref_storage_format = ref_storage_format_by_name(ref_format);
+		if (ref_storage_format == REF_STORAGE_FORMAT_UNKNOWN)
+			die(_("unknown ref storage format '%s'"), ref_format);
+	}
+
 	if (init_shared_repository != -1)
 		set_shared_repository(init_shared_repository);
 
@@ -235,5 +248,6 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
 
 	flags |= INIT_DB_EXIST_OK;
 	return init_db(git_dir, real_git_dir, template_dir, hash_algo,
-		       initial_branch, init_shared_repository, flags);
+		       ref_storage_format, initial_branch,
+		       init_shared_repository, flags);
 }
diff --git a/builtin/interpret-trailers.c b/builtin/interpret-trailers.c
index 033bd15..8768bfe 100644
--- a/builtin/interpret-trailers.c
+++ b/builtin/interpret-trailers.c
@@ -9,12 +9,13 @@
 #include "gettext.h"
 #include "parse-options.h"
 #include "string-list.h"
+#include "tempfile.h"
 #include "trailer.h"
 #include "config.h"
 
 static const char * const git_interpret_trailers_usage[] = {
 	N_("git interpret-trailers [--in-place] [--trim-empty]\n"
-	   "                       [(--trailer (<key>|<keyAlias>)[(=|:)<value>])...]\n"
+	   "                       [(--trailer (<key>|<key-alias>)[(=|:)<value>])...]\n"
 	   "                       [--parse] [<file>...]"),
 	NULL
 };
@@ -91,6 +92,102 @@ static int parse_opt_parse(const struct option *opt, const char *arg,
 	return 0;
 }
 
+static struct tempfile *trailers_tempfile;
+
+static FILE *create_in_place_tempfile(const char *file)
+{
+	struct stat st;
+	struct strbuf filename_template = STRBUF_INIT;
+	const char *tail;
+	FILE *outfile;
+
+	if (stat(file, &st))
+		die_errno(_("could not stat %s"), file);
+	if (!S_ISREG(st.st_mode))
+		die(_("file %s is not a regular file"), file);
+	if (!(st.st_mode & S_IWUSR))
+		die(_("file %s is not writable by user"), file);
+
+	/* Create temporary file in the same directory as the original */
+	tail = strrchr(file, '/');
+	if (tail)
+		strbuf_add(&filename_template, file, tail - file + 1);
+	strbuf_addstr(&filename_template, "git-interpret-trailers-XXXXXX");
+
+	trailers_tempfile = xmks_tempfile_m(filename_template.buf, st.st_mode);
+	strbuf_release(&filename_template);
+	outfile = fdopen_tempfile(trailers_tempfile, "w");
+	if (!outfile)
+		die_errno(_("could not open temporary file"));
+
+	return outfile;
+}
+
+static void read_input_file(struct strbuf *sb, const char *file)
+{
+	if (file) {
+		if (strbuf_read_file(sb, file, 0) < 0)
+			die_errno(_("could not read input file '%s'"), file);
+	} else {
+		if (strbuf_read(sb, fileno(stdin), 0) < 0)
+			die_errno(_("could not read from stdin"));
+	}
+}
+
+static void interpret_trailers(const struct process_trailer_options *opts,
+			       struct list_head *new_trailer_head,
+			       const char *file)
+{
+	LIST_HEAD(head);
+	struct strbuf sb = STRBUF_INIT;
+	struct strbuf trailer_block = STRBUF_INIT;
+	struct trailer_info info;
+	FILE *outfile = stdout;
+
+	trailer_config_init();
+
+	read_input_file(&sb, file);
+
+	if (opts->in_place)
+		outfile = create_in_place_tempfile(file);
+
+	parse_trailers(opts, &info, sb.buf, &head);
+
+	/* Print the lines before the trailers */
+	if (!opts->only_trailers)
+		fwrite(sb.buf, 1, info.trailer_block_start, outfile);
+
+	if (!opts->only_trailers && !info.blank_line_before_trailer)
+		fprintf(outfile, "\n");
+
+
+	if (!opts->only_input) {
+		LIST_HEAD(config_head);
+		LIST_HEAD(arg_head);
+		parse_trailers_from_config(&config_head);
+		parse_trailers_from_command_line_args(&arg_head, new_trailer_head);
+		list_splice(&config_head, &arg_head);
+		process_trailers_lists(&head, &arg_head);
+	}
+
+	/* Print trailer block. */
+	format_trailers(opts, &head, &trailer_block);
+	free_trailers(&head);
+	fwrite(trailer_block.buf, 1, trailer_block.len, outfile);
+	strbuf_release(&trailer_block);
+
+	/* Print the lines after the trailers as is */
+	if (!opts->only_trailers)
+		fwrite(sb.buf + info.trailer_block_end, 1, sb.len - info.trailer_block_end, outfile);
+	trailer_info_release(&info);
+
+	if (opts->in_place)
+		if (rename_tempfile(&trailers_tempfile, file))
+			die_errno(_("could not rename temporary file to %s"), file);
+
+	strbuf_release(&sb);
+}
+
 int cmd_interpret_trailers(int argc, const char **argv, const char *prefix)
 {
 	struct process_trailer_options opts = PROCESS_TRAILER_OPTIONS_INIT;
@@ -132,11 +229,11 @@ int cmd_interpret_trailers(int argc, const char **argv, const char *prefix)
 	if (argc) {
 		int i;
 		for (i = 0; i < argc; i++)
-			process_trailers(argv[i], &opts, &trailers);
+			interpret_trailers(&opts, &trailers, argv[i]);
 	} else {
 		if (opts.in_place)
 			die(_("no input file given for in-place editing"));
-		process_trailers(NULL, &opts, &trailers);
+		interpret_trailers(&opts, &trailers, NULL);
 	}
 
 	new_trailers_clear(&trailers);
diff --git a/builtin/log.c b/builtin/log.c
index af6403c..c0a8bb9 100644
--- a/builtin/log.c
+++ b/builtin/log.c
@@ -1297,7 +1297,7 @@ static void prepare_cover_text(struct pretty_print_context *pp,
 		subject = subject_sb.buf;
 
 do_pp:
-	pp_title_line(pp, &subject, sb, encoding, need_8bit_cte);
+	pp_email_subject(pp, &subject, sb, encoding, need_8bit_cte);
 	pp_remainder(pp, &body, sb, 0);
 
 	strbuf_release(&description_sb);
@@ -1364,12 +1364,13 @@ static void make_cover_letter(struct rev_info *rev, int use_separate_file,
 	pp.fmt = CMIT_FMT_EMAIL;
 	pp.date_mode.type = DATE_RFC2822;
 	pp.rev = rev;
-	pp.print_email_subject = 1;
+	pp.encode_email_headers = rev->encode_email_headers;
 	pp_user_info(&pp, NULL, &sb, committer, encoding);
 	prepare_cover_text(&pp, description_file, branch_name, &sb,
 			   encoding, need_8bit_cte);
 	fprintf(rev->diffopt.file, "%s\n", sb.buf);
 
+	free(pp.after_subject);
 	strbuf_release(&sb);
 
 	shortlog_init(&log);
@@ -1624,7 +1625,7 @@ static struct commit *get_base_commit(const char *base_commit,
 {
 	struct commit *base = NULL;
 	struct commit **rev;
-	int i = 0, rev_nr = 0, auto_select, die_on_failure;
+	int i = 0, rev_nr = 0, auto_select, die_on_failure, ret;
 
 	switch (auto_base) {
 	case AUTO_BASE_NEVER:
@@ -1657,7 +1658,7 @@ static struct commit *get_base_commit(const char *base_commit,
 		struct branch *curr_branch = branch_get(NULL);
 		const char *upstream = branch_get_upstream(curr_branch, NULL);
 		if (upstream) {
-			struct commit_list *base_list;
+			struct commit_list *base_list = NULL;
 			struct commit *commit;
 			struct object_id oid;
 
@@ -1668,11 +1669,12 @@ static struct commit *get_base_commit(const char *base_commit,
 					return NULL;
 			}
 			commit = lookup_commit_or_die(&oid, "upstream base");
-			base_list = repo_get_merge_bases_many(the_repository,
-							      commit, total,
-							      list);
-			/* There should be one and only one merge base. */
-			if (!base_list || base_list->next) {
+			if (repo_get_merge_bases_many(the_repository,
+						      commit, total,
+						      list,
+						      &base_list) < 0 ||
+			    /* There should be one and only one merge base. */
+			    !base_list || base_list->next) {
 				if (die_on_failure) {
 					die(_("could not find exact merge base"));
 				} else {
@@ -1703,11 +1705,11 @@ static struct commit *get_base_commit(const char *base_commit,
 	 */
 	while (rev_nr > 1) {
 		for (i = 0; i < rev_nr / 2; i++) {
-			struct commit_list *merge_base;
-			merge_base = repo_get_merge_bases(the_repository,
-							  rev[2 * i],
-							  rev[2 * i + 1]);
-			if (!merge_base || merge_base->next) {
+			struct commit_list *merge_base = NULL;
+			if (repo_get_merge_bases(the_repository,
+						 rev[2 * i],
+						 rev[2 * i + 1], &merge_base) < 0 ||
+			    !merge_base || merge_base->next) {
 				if (die_on_failure) {
 					die(_("failed to find exact merge base"));
 				} else {
@@ -1724,7 +1726,10 @@ static struct commit *get_base_commit(const char *base_commit,
 		rev_nr = DIV_ROUND_UP(rev_nr, 2);
 	}
 
-	if (!repo_in_merge_bases(the_repository, base, rev[0])) {
+	ret = repo_in_merge_bases(the_repository, base, rev[0]);
+	if (ret < 0)
+		exit(128);
+	if (!ret) {
 		if (die_on_failure) {
 			die(_("base commit should be the ancestor of revision list"));
 		} else {
diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index 92f94e6..6eeb5cb 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -266,7 +266,6 @@ static void show_ce_fmt(struct repository *repo, const struct cache_entry *ce,
 	struct strbuf sb = STRBUF_INIT;
 
 	while (strbuf_expand_step(&sb, &format)) {
-		const char *end;
 		size_t len;
 		struct stat st;
 
@@ -274,12 +273,6 @@ static void show_ce_fmt(struct repository *repo, const struct cache_entry *ce,
 			strbuf_addch(&sb, '%');
 		else if ((len = strbuf_expand_literal(&sb, format)))
 			format += len;
-		else if (*format != '(')
-			die(_("bad ls-files format: element '%s' "
-			      "does not start with '('"), format);
-		else if (!(end = strchr(format + 1, ')')))
-			die(_("bad ls-files format: element '%s' "
-			      "does not end in ')'"), format);
 		else if (skip_prefix(format, "(objectmode)", &format))
 			strbuf_addf(&sb, "%06o", ce->ce_mode);
 		else if (skip_prefix(format, "(objectname)", &format))
@@ -308,8 +301,7 @@ static void show_ce_fmt(struct repository *repo, const struct cache_entry *ce,
 		else if (skip_prefix(format, "(path)", &format))
 			write_name_to_buf(&sb, fullname);
 		else
-			die(_("bad ls-files format: %%%.*s"),
-			    (int)(end - format + 1), format);
+			strbuf_expand_bad_format(format, "ls-files");
 	}
 	strbuf_addch(&sb, line_terminator);
 	fwrite(sb.buf, sb.len, 1, stdout);
diff --git a/builtin/ls-remote.c b/builtin/ls-remote.c
index 2975ea4..e8d65eb 100644
--- a/builtin/ls-remote.c
+++ b/builtin/ls-remote.c
@@ -57,6 +57,7 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)
 	struct transport *transport;
 	const struct ref *ref;
 	struct ref_array ref_array;
+	struct ref_sorting *sorting;
 	struct string_list sorting_options = STRING_LIST_INIT_DUP;
 
 	struct option options[] = {
@@ -140,13 +141,8 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)
 		item->symref = xstrdup_or_null(ref->symref);
 	}
 
-	if (sorting_options.nr) {
-		struct ref_sorting *sorting;
-
-		sorting = ref_sorting_options(&sorting_options);
-		ref_array_sort(sorting, &ref_array);
-		ref_sorting_release(sorting);
-	}
+	sorting = ref_sorting_options(&sorting_options);
+	ref_array_sort(sorting, &ref_array);
 
 	for (i = 0; i < ref_array.nr; i++) {
 		const struct ref_array_item *ref = ref_array.items[i];
@@ -156,6 +152,7 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)
 		status = 0; /* we found something */
 	}
 
+	ref_sorting_release(sorting);
 	ref_array_clear(&ref_array);
 	if (transport_disconnect(transport))
 		status = 1;
diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c
index e4a8913..7bf84b2 100644
--- a/builtin/ls-tree.c
+++ b/builtin/ls-tree.c
@@ -100,19 +100,12 @@ static int show_tree_fmt(const struct object_id *oid, struct strbuf *base,
 		return 0;
 
 	while (strbuf_expand_step(&sb, &format)) {
-		const char *end;
 		size_t len;
 
 		if (skip_prefix(format, "%", &format))
 			strbuf_addch(&sb, '%');
 		else if ((len = strbuf_expand_literal(&sb, format)))
 			format += len;
-		else if (*format != '(')
-			die(_("bad ls-tree format: element '%s' "
-			      "does not start with '('"), format);
-		else if (!(end = strchr(format + 1, ')')))
-			die(_("bad ls-tree format: element '%s' "
-			      "does not end in ')'"), format);
 		else if (skip_prefix(format, "(objectmode)", &format))
 			strbuf_addf(&sb, "%06o", mode);
 		else if (skip_prefix(format, "(objecttype)", &format))
@@ -135,8 +128,7 @@ static int show_tree_fmt(const struct object_id *oid, struct strbuf *base,
 			strbuf_setlen(base, baselen);
 			strbuf_release(&sbuf);
 		} else
-			die(_("bad ls-tree format: %%%.*s"),
-			    (int)(end - format + 1), format);
+			strbuf_expand_bad_format(format, "ls-tree");
 	}
 	strbuf_addch(&sb, options->null_termination ? '\0' : '\n');
 	fwrite(sb.buf, sb.len, 1, stdout);
@@ -375,6 +367,7 @@ int cmd_ls_tree(int argc, const char **argv, const char *prefix)
 		OPT_END()
 	};
 	struct ls_tree_cmdmode_to_fmt *m2f = ls_tree_cmdmode_format;
+	struct object_context obj_context;
 	int ret;
 
 	git_config(git_default_config, NULL);
@@ -406,7 +399,9 @@ int cmd_ls_tree(int argc, const char **argv, const char *prefix)
 			ls_tree_usage, ls_tree_options);
 	if (argc < 1)
 		usage_with_options(ls_tree_usage, ls_tree_options);
-	if (repo_get_oid(the_repository, argv[0], &oid))
+	if (get_oid_with_context(the_repository, argv[0],
+				 GET_OID_HASH_ANY, &oid,
+				 &obj_context))
 		die("Not a valid object name %s", argv[0]);
 
 	/*
diff --git a/builtin/merge-base.c b/builtin/merge-base.c
index d26e8fb..5a8e729 100644
--- a/builtin/merge-base.c
+++ b/builtin/merge-base.c
@@ -10,10 +10,13 @@
 
 static int show_merge_base(struct commit **rev, int rev_nr, int show_all)
 {
-	struct commit_list *result, *r;
+	struct commit_list *result = NULL, *r;
 
-	result = repo_get_merge_bases_many_dirty(the_repository, rev[0],
-						 rev_nr - 1, rev + 1);
+	if (repo_get_merge_bases_many_dirty(the_repository, rev[0],
+					    rev_nr - 1, rev + 1, &result) < 0) {
+		free_commit_list(result);
+		return -1;
+	}
 
 	if (!result)
 		return 1;
@@ -74,13 +77,17 @@ static int handle_independent(int count, const char **args)
 static int handle_octopus(int count, const char **args, int show_all)
 {
 	struct commit_list *revs = NULL;
-	struct commit_list *result, *rev;
+	struct commit_list *result = NULL, *rev;
 	int i;
 
 	for (i = count - 1; i >= 0; i--)
 		commit_list_insert(get_commit_reference(args[i]), &revs);
 
-	result = get_octopus_merge_bases(revs);
+	if (get_octopus_merge_bases(revs, &result) < 0) {
+		free_commit_list(revs);
+		free_commit_list(result);
+		return 128;
+	}
 	free_commit_list(revs);
 	reduce_heads_replace(&result);
 
@@ -100,12 +107,16 @@ static int handle_octopus(int count, const char **args, int show_all)
 static int handle_is_ancestor(int argc, const char **argv)
 {
 	struct commit *one, *two;
+	int ret;
 
 	if (argc != 2)
 		die("--is-ancestor takes exactly two commits");
 	one = get_commit_reference(argv[0]);
 	two = get_commit_reference(argv[1]);
-	if (repo_in_merge_bases(the_repository, one, two))
+	ret = repo_in_merge_bases(the_repository, one, two);
+	if (ret < 0)
+		exit(128);
+	if (ret)
 		return 0;
 	else
 		return 1;
diff --git a/builtin/merge-file.c b/builtin/merge-file.c
index 832c93d..1f98733 100644
--- a/builtin/merge-file.c
+++ b/builtin/merge-file.c
@@ -1,5 +1,6 @@
 #include "builtin.h"
 #include "abspath.h"
+#include "diff.h"
 #include "hex.h"
 #include "object-name.h"
 #include "object-store.h"
@@ -28,6 +29,30 @@ static int label_cb(const struct option *opt, const char *arg, int unset)
 	return 0;
 }
 
+static int set_diff_algorithm(xpparam_t *xpp,
+			      const char *alg)
+{
+	long diff_algorithm = parse_algorithm_value(alg);
+	if (diff_algorithm < 0)
+		return -1;
+	xpp->flags = (xpp->flags & ~XDF_DIFF_ALGORITHM_MASK) | diff_algorithm;
+	return 0;
+}
+
+static int diff_algorithm_cb(const struct option *opt,
+				const char *arg, int unset)
+{
+	xpparam_t *xpp = opt->value;
+
+	BUG_ON_OPT_NEG(unset);
+
+	if (set_diff_algorithm(xpp, arg))
+		return error(_("option diff-algorithm accepts \"myers\", "
+			       "\"minimal\", \"patience\" and \"histogram\""));
+
+	return 0;
+}
+
 int cmd_merge_file(int argc, const char **argv, const char *prefix)
 {
 	const char *names[3] = { 0 };
@@ -48,6 +73,9 @@ int cmd_merge_file(int argc, const char **argv, const char *prefix)
 			    XDL_MERGE_FAVOR_THEIRS),
 		OPT_SET_INT(0, "union", &xmp.favor, N_("for conflicts, use a union version"),
 			    XDL_MERGE_FAVOR_UNION),
+		OPT_CALLBACK_F(0, "diff-algorithm", &xmp.xpp, N_("<algorithm>"),
+			     N_("choose a diff algorithm"),
+			     PARSE_OPT_NONEG, diff_algorithm_cb),
 		OPT_INTEGER(0, "marker-size", &xmp.marker_size,
 			    N_("for conflicts, use this marker size")),
 		OPT__QUIET(&quiet, N_("do not warn about conflicts")),
diff --git a/builtin/merge-tree.c b/builtin/merge-tree.c
index 3bdec53..8bdb439 100644
--- a/builtin/merge-tree.c
+++ b/builtin/merge-tree.c
@@ -429,41 +429,56 @@ static int real_merge(struct merge_tree_options *o,
 	struct merge_options opt;
 
 	copy_merge_options(&opt, &o->merge_options);
-	parent1 = get_merge_parent(branch1);
-	if (!parent1)
-		help_unknown_ref(branch1, "merge-tree",
-				 _("not something we can merge"));
-
-	parent2 = get_merge_parent(branch2);
-	if (!parent2)
-		help_unknown_ref(branch2, "merge-tree",
-				 _("not something we can merge"));
-
 	opt.show_rename_progress = 0;
 
 	opt.branch1 = branch1;
 	opt.branch2 = branch2;
 
 	if (merge_base) {
-		struct commit *base_commit;
 		struct tree *base_tree, *parent1_tree, *parent2_tree;
 
-		base_commit = lookup_commit_reference_by_name(merge_base);
-		if (!base_commit)
-			die(_("could not lookup commit '%s'"), merge_base);
+		/*
+		 * We actually only need the trees because we already
+		 * have a merge base.
+		 */
+		struct object_id base_oid, head_oid, merge_oid;
+
+		if (repo_get_oid_treeish(the_repository, merge_base, &base_oid))
+			die(_("could not parse as tree '%s'"), merge_base);
+		base_tree = parse_tree_indirect(&base_oid);
+		if (!base_tree)
+			die(_("unable to read tree (%s)"), oid_to_hex(&base_oid));
+		if (repo_get_oid_treeish(the_repository, branch1, &head_oid))
+			die(_("could not parse as tree '%s'"), branch1);
+		parent1_tree = parse_tree_indirect(&head_oid);
+		if (!parent1_tree)
+			die(_("unable to read tree (%s)"), oid_to_hex(&head_oid));
+		if (repo_get_oid_treeish(the_repository, branch2, &merge_oid))
+			die(_("could not parse as tree '%s'"), branch2);
+		parent2_tree = parse_tree_indirect(&merge_oid);
+		if (!parent2_tree)
+			die(_("unable to read tree (%s)"), oid_to_hex(&merge_oid));
 
 		opt.ancestor = merge_base;
-		base_tree = repo_get_commit_tree(the_repository, base_commit);
-		parent1_tree = repo_get_commit_tree(the_repository, parent1);
-		parent2_tree = repo_get_commit_tree(the_repository, parent2);
 		merge_incore_nonrecursive(&opt, base_tree, parent1_tree, parent2_tree, &result);
 	} else {
+		parent1 = get_merge_parent(branch1);
+		if (!parent1)
+			help_unknown_ref(branch1, "merge-tree",
+					 _("not something we can merge"));
+
+		parent2 = get_merge_parent(branch2);
+		if (!parent2)
+			help_unknown_ref(branch2, "merge-tree",
+					 _("not something we can merge"));
+
 		/*
 		 * Get the merge bases, in reverse order; see comment above
 		 * merge_incore_recursive in merge-ort.h
 		 */
-		merge_bases = repo_get_merge_bases(the_repository, parent1,
-						   parent2);
+		if (repo_get_merge_bases(the_repository, parent1,
+					 parent2, &merge_bases) < 0)
+			exit(128);
 		if (!merge_bases && !o->allow_unrelated_histories)
 			die(_("refusing to merge unrelated histories"));
 		merge_bases = reverse_commit_list(merge_bases);
@@ -548,7 +563,7 @@ int cmd_merge_tree(int argc, const char **argv, const char *prefix)
 			   PARSE_OPT_NONEG),
 		OPT_STRING(0, "merge-base",
 			   &merge_base,
-			   N_("commit"),
+			   N_("tree-ish"),
 			   N_("specify a merge-base for the merge")),
 		OPT_STRVEC('X', "strategy-option", &xopts, N_("option=value"),
 			N_("option for selected merge strategy")),
diff --git a/builtin/merge.c b/builtin/merge.c
index ebbe050..6f4fec8 100644
--- a/builtin/merge.c
+++ b/builtin/merge.c
@@ -192,8 +192,7 @@ static struct strategy *get_strategy(const char *name)
 			int j, found = 0;
 			struct cmdname *ent = main_cmds.names[i];
 			for (j = 0; !found && j < ARRAY_SIZE(all_strategy); j++)
-				if (!strncmp(ent->name, all_strategy[j].name, ent->len)
-						&& !all_strategy[j].name[ent->len])
+				if (!xstrncmpz(all_strategy[j].name, ent->name, ent->len))
 					found = 1;
 			if (!found)
 				add_cmdname(&not_strategies, ent->name, ent->len);
@@ -476,7 +475,7 @@ static void finish(struct commit *head_commit,
 	run_hooks_l("post-merge", squash ? "1" : "0", NULL);
 
 	if (new_head)
-		apply_autostash(git_path_merge_autostash(the_repository));
+		apply_autostash_ref(the_repository, "MERGE_AUTOSTASH");
 	strbuf_release(&reflog_message);
 }
 
@@ -678,7 +677,8 @@ static int read_tree_trivial(struct object_id *common, struct object_id *head,
 	cache_tree_free(&the_index.cache_tree);
 	for (i = 0; i < nr_trees; i++) {
 		parse_tree(trees[i]);
-		init_tree_desc(t+i, trees[i]->buffer, trees[i]->size);
+		init_tree_desc(t+i, &trees[i]->object.oid,
+			       trees[i]->buffer, trees[i]->size);
 	}
 	if (unpack_trees(nr_trees, t, &opts))
 		return -1;
@@ -822,7 +822,7 @@ static const char scissors_editor_comment[] =
 N_("An empty message aborts the commit.\n");
 
 static const char no_scissors_editor_comment[] =
-N_("Lines starting with '%c' will be ignored, and an empty message aborts\n"
+N_("Lines starting with '%s' will be ignored, and an empty message aborts\n"
    "the commit.\n");
 
 static void write_merge_heads(struct commit_list *);
@@ -853,16 +853,16 @@ static void prepare_to_commit(struct commit_list *remoteheads)
 		strbuf_addch(&msg, '\n');
 		if (cleanup_mode == COMMIT_MSG_CLEANUP_SCISSORS) {
 			wt_status_append_cut_line(&msg);
-			strbuf_commented_addf(&msg, comment_line_char, "\n");
+			strbuf_commented_addf(&msg, comment_line_str, "\n");
 		}
-		strbuf_commented_addf(&msg, comment_line_char,
+		strbuf_commented_addf(&msg, comment_line_str,
 				      _(merge_editor_comment));
 		if (cleanup_mode == COMMIT_MSG_CLEANUP_SCISSORS)
-			strbuf_commented_addf(&msg, comment_line_char,
+			strbuf_commented_addf(&msg, comment_line_str,
 					      _(scissors_editor_comment));
 		else
-			strbuf_commented_addf(&msg, comment_line_char,
-				_(no_scissors_editor_comment), comment_line_char);
+			strbuf_commented_addf(&msg, comment_line_str,
+				_(no_scissors_editor_comment), comment_line_str);
 	}
 	if (signoff)
 		append_signoff(&msg, ignored_log_message_bytes(msg.buf, msg.len), 0);
@@ -1315,7 +1315,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
 	if (abort_current_merge) {
 		int nargc = 2;
 		const char *nargv[] = {"reset", "--merge", NULL};
-		struct strbuf stash_oid = STRBUF_INIT;
+		char stash_oid_hex[GIT_MAX_HEXSZ + 1];
+		struct object_id stash_oid = {0};
 
 		if (orig_argc != 2)
 			usage_msg_opt(_("--abort expects no arguments"),
@@ -1324,17 +1325,17 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
 		if (!file_exists(git_path_merge_head(the_repository)))
 			die(_("There is no merge to abort (MERGE_HEAD missing)."));
 
-		if (read_oneliner(&stash_oid, git_path_merge_autostash(the_repository),
-		    READ_ONELINER_SKIP_IF_EMPTY))
-			unlink(git_path_merge_autostash(the_repository));
+		if (!read_ref("MERGE_AUTOSTASH", &stash_oid))
+			delete_ref("", "MERGE_AUTOSTASH", &stash_oid, REF_NO_DEREF);
 
 		/* Invoke 'git reset --merge' */
 		ret = cmd_reset(nargc, nargv, prefix);
 
-		if (stash_oid.len)
-			apply_autostash_oid(stash_oid.buf);
+		if (!is_null_oid(&stash_oid)) {
+			oid_to_hex_r(stash_oid_hex, &stash_oid);
+			apply_autostash_oid(stash_oid_hex);
+		}
 
-		strbuf_release(&stash_oid);
 		goto done;
 	}
 
@@ -1513,13 +1514,20 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
 
 	if (!remoteheads)
 		; /* already up-to-date */
-	else if (!remoteheads->next)
-		common = repo_get_merge_bases(the_repository, head_commit,
-					      remoteheads->item);
-	else {
+	else if (!remoteheads->next) {
+		if (repo_get_merge_bases(the_repository, head_commit,
+					 remoteheads->item, &common) < 0) {
+			ret = 2;
+			goto done;
+		}
+	} else {
 		struct commit_list *list = remoteheads;
 		commit_list_insert(head_commit, &list);
-		common = get_octopus_merge_bases(list);
+		if (get_octopus_merge_bases(list, &common) < 0) {
+			free(list);
+			ret = 2;
+			goto done;
+		}
 		free(list);
 	}
 
@@ -1563,13 +1571,12 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
 		}
 
 		if (autostash)
-			create_autostash(the_repository,
-					 git_path_merge_autostash(the_repository));
+			create_autostash_ref(the_repository, "MERGE_AUTOSTASH");
 		if (checkout_fast_forward(the_repository,
 					  &head_commit->object.oid,
 					  &commit->object.oid,
 					  overwrite_ignore)) {
-			apply_autostash(git_path_merge_autostash(the_repository));
+			apply_autostash_ref(the_repository, "MERGE_AUTOSTASH");
 			ret = 1;
 			goto done;
 		}
@@ -1627,7 +1634,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
 		struct commit_list *j;
 
 		for (j = remoteheads; j; j = j->next) {
-			struct commit_list *common_one;
+			struct commit_list *common_one = NULL;
 			struct commit *common_item;
 
 			/*
@@ -1635,9 +1642,10 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
 			 * merge_bases again, otherwise "git merge HEAD^
 			 * HEAD^^" would be missed.
 			 */
-			common_one = repo_get_merge_bases(the_repository,
-							  head_commit,
-							  j->item);
+			if (repo_get_merge_bases(the_repository, head_commit,
+						 j->item, &common_one) < 0)
+				exit(128);
+
 			common_item = common_one->item;
 			free_commit_list(common_one);
 			if (!oideq(&common_item->object.oid, &j->item->object.oid)) {
@@ -1655,8 +1663,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
 		die_ff_impossible();
 
 	if (autostash)
-		create_autostash(the_repository,
-				 git_path_merge_autostash(the_repository));
+		create_autostash_ref(the_repository, "MERGE_AUTOSTASH");
 
 	/* We are going to make a new commit. */
 	git_committer_info(IDENT_STRICT);
@@ -1741,7 +1748,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
 		else
 			fprintf(stderr, _("Merge with strategy %s failed.\n"),
 				use_strategies[0]->name);
-		apply_autostash(git_path_merge_autostash(the_repository));
+		apply_autostash_ref(the_repository, "MERGE_AUTOSTASH");
 		ret = 2;
 		goto done;
 	} else if (best_strategy == wt_strategy)
diff --git a/builtin/multi-pack-index.c b/builtin/multi-pack-index.c
index a72aebe..8360932 100644
--- a/builtin/multi-pack-index.c
+++ b/builtin/multi-pack-index.c
@@ -8,6 +8,7 @@
 #include "strbuf.h"
 #include "trace2.h"
 #include "object-store-ll.h"
+#include "replace-object.h"
 
 #define BUILTIN_MIDX_WRITE_USAGE \
 	N_("git multi-pack-index [<options>] write [--preferred-pack=<pack>]" \
@@ -273,6 +274,8 @@ int cmd_multi_pack_index(int argc, const char **argv,
 	};
 	struct option *options = parse_options_concat(builtin_multi_pack_index_options, common_opts);
 
+	disable_replace_refs();
+
 	git_config(git_default_config, NULL);
 
 	if (the_repository &&
diff --git a/builtin/name-rev.c b/builtin/name-rev.c
index 2dd1807..ad9930c 100644
--- a/builtin/name-rev.c
+++ b/builtin/name-rev.c
@@ -15,6 +15,7 @@
 #include "commit-slab.h"
 #include "commit-graph.h"
 #include "wildmatch.h"
+#include "mem-pool.h"
 
 /*
  * One day.  See the 'name a rev shortly after epoch' test in t6120 when
@@ -155,30 +156,25 @@ static struct rev_name *create_or_update_name(struct commit *commit,
 	return name;
 }
 
-static char *get_parent_name(const struct rev_name *name, int parent_number)
+static char *get_parent_name(const struct rev_name *name, int parent_number,
+			     struct mem_pool *string_pool)
 {
-	struct strbuf sb = STRBUF_INIT;
 	size_t len;
 
 	strip_suffix(name->tip_name, "^0", &len);
 	if (name->generation > 0) {
-		strbuf_grow(&sb, len +
-			    1 + decimal_width(name->generation) +
-			    1 + decimal_width(parent_number));
-		strbuf_addf(&sb, "%.*s~%d^%d", (int)len, name->tip_name,
-			    name->generation, parent_number);
+		return mem_pool_strfmt(string_pool, "%.*s~%d^%d",
+				       (int)len, name->tip_name,
+				       name->generation, parent_number);
 	} else {
-		strbuf_grow(&sb, len +
-			    1 + decimal_width(parent_number));
-		strbuf_addf(&sb, "%.*s^%d", (int)len, name->tip_name,
-			    parent_number);
+		return mem_pool_strfmt(string_pool, "%.*s^%d",
+				       (int)len, name->tip_name, parent_number);
 	}
-	return strbuf_detach(&sb, NULL);
 }
 
 static void name_rev(struct commit *start_commit,
 		const char *tip_name, timestamp_t taggerdate,
-		int from_tag, int deref)
+		int from_tag, int deref, struct mem_pool *string_pool)
 {
 	struct prio_queue queue;
 	struct commit *commit;
@@ -195,9 +191,10 @@ static void name_rev(struct commit *start_commit,
 	if (!start_name)
 		return;
 	if (deref)
-		start_name->tip_name = xstrfmt("%s^0", tip_name);
+		start_name->tip_name = mem_pool_strfmt(string_pool, "%s^0",
+						       tip_name);
 	else
-		start_name->tip_name = xstrdup(tip_name);
+		start_name->tip_name = mem_pool_strdup(string_pool, tip_name);
 
 	memset(&queue, 0, sizeof(queue)); /* Use the prio_queue as LIFO */
 	prio_queue_put(&queue, start_commit);
@@ -235,7 +232,8 @@ static void name_rev(struct commit *start_commit,
 				if (parent_number > 1)
 					parent_name->tip_name =
 						get_parent_name(name,
-								parent_number);
+								parent_number,
+								string_pool);
 				else
 					parent_name->tip_name = name->tip_name;
 				ALLOC_GROW(parents_to_queue,
@@ -415,7 +413,7 @@ static int name_ref(const char *path, const struct object_id *oid,
 	return 0;
 }
 
-static void name_tips(void)
+static void name_tips(struct mem_pool *string_pool)
 {
 	int i;
 
@@ -428,7 +426,7 @@ static void name_tips(void)
 		struct tip_table_entry *e = &tip_table.table[i];
 		if (e->commit) {
 			name_rev(e->commit, e->refname, e->taggerdate,
-				 e->from_tag, e->deref);
+				 e->from_tag, e->deref, string_pool);
 		}
 	}
 }
@@ -561,6 +559,7 @@ static void name_rev_line(char *p, struct name_ref_data *data)
 
 int cmd_name_rev(int argc, const char **argv, const char *prefix)
 {
+	struct mem_pool string_pool;
 	struct object_array revs = OBJECT_ARRAY_INIT;
 	int all = 0, annotate_stdin = 0, transform_stdin = 0, allow_undefined = 1, always = 0, peel_tag = 0;
 	struct name_ref_data data = { 0, 0, STRING_LIST_INIT_NODUP, STRING_LIST_INIT_NODUP };
@@ -587,6 +586,7 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix)
 		OPT_END(),
 	};
 
+	mem_pool_init(&string_pool, 0);
 	init_commit_rev_name(&rev_names);
 	git_config(git_default_config, NULL);
 	argc = parse_options(argc, argv, prefix, opts, name_rev_usage, 0);
@@ -648,7 +648,7 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix)
 	adjust_cutoff_timestamp_for_slop();
 
 	for_each_ref(name_ref, &data);
-	name_tips();
+	name_tips(&string_pool);
 
 	if (annotate_stdin) {
 		struct strbuf sb = STRBUF_INIT;
@@ -676,6 +676,7 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix)
 				  always, allow_undefined, data.name_only);
 	}
 
+	UNLEAK(string_pool);
 	UNLEAK(revs);
 	return 0;
 }
diff --git a/builtin/notes.c b/builtin/notes.c
index e65cae0..cb01130 100644
--- a/builtin/notes.c
+++ b/builtin/notes.c
@@ -179,7 +179,7 @@ static void write_commented_object(int fd, const struct object_id *object)
 
 	if (strbuf_read(&buf, show.out, 0) < 0)
 		die_errno(_("could not read 'show' output"));
-	strbuf_add_commented_lines(&cbuf, buf.buf, buf.len, comment_line_char);
+	strbuf_add_commented_lines(&cbuf, buf.buf, buf.len, comment_line_str);
 	write_or_die(fd, cbuf.buf, cbuf.len);
 
 	strbuf_release(&cbuf);
@@ -207,10 +207,10 @@ static void prepare_note_data(const struct object_id *object, struct note_data *
 			copy_obj_to_fd(fd, old_note);
 
 		strbuf_addch(&buf, '\n');
-		strbuf_add_commented_lines(&buf, "\n", strlen("\n"), comment_line_char);
+		strbuf_add_commented_lines(&buf, "\n", strlen("\n"), comment_line_str);
 		strbuf_add_commented_lines(&buf, _(note_template), strlen(_(note_template)),
-					   comment_line_char);
-		strbuf_add_commented_lines(&buf, "\n", strlen("\n"), comment_line_char);
+					   comment_line_str);
+		strbuf_add_commented_lines(&buf, "\n", strlen("\n"), comment_line_str);
 		write_or_die(fd, buf.buf, buf.len);
 
 		write_commented_object(fd, object);
@@ -223,7 +223,7 @@ static void prepare_note_data(const struct object_id *object, struct note_data *
 			die(_("please supply the note contents using either -m or -F option"));
 		}
 		if (d->stripspace)
-			strbuf_stripspace(&d->buf, comment_line_char);
+			strbuf_stripspace(&d->buf, comment_line_str);
 	}
 }
 
@@ -264,7 +264,7 @@ static void concat_messages(struct note_data *d)
 		if ((d->stripspace == UNSPECIFIED &&
 		     d->messages[i]->stripspace == STRIPSPACE) ||
 		    d->stripspace == STRIPSPACE)
-			strbuf_stripspace(&d->buf, 0);
+			strbuf_stripspace(&d->buf, NULL);
 		strbuf_reset(&msg);
 	}
 	strbuf_release(&msg);
@@ -716,9 +716,11 @@ static int append_edit(int argc, const char **argv, const char *prefix)
 		struct strbuf buf = STRBUF_INIT;
 		char *prev_buf = repo_read_object_file(the_repository, note, &type, &size);
 
-		if (prev_buf && size)
+		if (!prev_buf)
+			die(_("unable to read %s"), oid_to_hex(note));
+		if (size)
 			strbuf_add(&buf, prev_buf, size);
-		if (d.buf.len && prev_buf && size)
+		if (d.buf.len && size)
 			append_separator(&buf);
 		strbuf_insert(&d.buf, 0, buf.buf, buf.len);
 
diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index 5c8bfe1..baf0090 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -218,13 +218,19 @@ static int thin;
 static int num_preferred_base;
 static struct progress *progress_state;
 
-static struct packed_git *reuse_packfile;
+static struct bitmapped_pack *reuse_packfiles;
+static size_t reuse_packfiles_nr;
+static size_t reuse_packfiles_used_nr;
 static uint32_t reuse_packfile_objects;
 static struct bitmap *reuse_packfile_bitmap;
 
 static int use_bitmap_index_default = 1;
 static int use_bitmap_index = -1;
-static int allow_pack_reuse = 1;
+static enum {
+	NO_PACK_REUSE = 0,
+	SINGLE_PACK_REUSE,
+	MULTI_PACK_REUSE,
+} allow_pack_reuse = SINGLE_PACK_REUSE;
 static enum {
 	WRITE_BITMAP_FALSE = 0,
 	WRITE_BITMAP_QUIET,
@@ -1010,7 +1016,9 @@ static off_t find_reused_offset(off_t where)
 	return reused_chunks[lo-1].difference;
 }
 
-static void write_reused_pack_one(size_t pos, struct hashfile *out,
+static void write_reused_pack_one(struct packed_git *reuse_packfile,
+				  size_t pos, struct hashfile *out,
+				  off_t pack_start,
 				  struct pack_window **w_curs)
 {
 	off_t offset, next, cur;
@@ -1020,7 +1028,8 @@ static void write_reused_pack_one(size_t pos, struct hashfile *out,
 	offset = pack_pos_to_offset(reuse_packfile, pos);
 	next = pack_pos_to_offset(reuse_packfile, pos + 1);
 
-	record_reused_object(offset, offset - hashfile_total(out));
+	record_reused_object(offset,
+			     offset - (hashfile_total(out) - pack_start));
 
 	cur = offset;
 	type = unpack_object_header(reuse_packfile, w_curs, &cur, &size);
@@ -1088,41 +1097,93 @@ static void write_reused_pack_one(size_t pos, struct hashfile *out,
 	copy_pack_data(out, reuse_packfile, w_curs, offset, next - offset);
 }
 
-static size_t write_reused_pack_verbatim(struct hashfile *out,
+static size_t write_reused_pack_verbatim(struct bitmapped_pack *reuse_packfile,
+					 struct hashfile *out,
+					 off_t pack_start,
 					 struct pack_window **w_curs)
 {
-	size_t pos = 0;
+	size_t pos = reuse_packfile->bitmap_pos;
+	size_t end;
 
-	while (pos < reuse_packfile_bitmap->word_alloc &&
-			reuse_packfile_bitmap->words[pos] == (eword_t)~0)
-		pos++;
+	if (pos % BITS_IN_EWORD) {
+		size_t word_pos = (pos / BITS_IN_EWORD);
+		size_t offset = pos % BITS_IN_EWORD;
+		size_t last;
+		eword_t word = reuse_packfile_bitmap->words[word_pos];
 
-	if (pos) {
-		off_t to_write;
+		if (offset + reuse_packfile->bitmap_nr < BITS_IN_EWORD)
+			last = offset + reuse_packfile->bitmap_nr;
+		else
+			last = BITS_IN_EWORD;
 
-		written = (pos * BITS_IN_EWORD);
-		to_write = pack_pos_to_offset(reuse_packfile, written)
-			- sizeof(struct pack_header);
+		for (; offset < last; offset++) {
+			if (word >> offset == 0)
+				return word_pos;
+			if (!bitmap_get(reuse_packfile_bitmap,
+					word_pos * BITS_IN_EWORD + offset))
+				return word_pos;
+		}
+
+		pos += BITS_IN_EWORD - (pos % BITS_IN_EWORD);
+	}
+
+	/*
+	 * Now we're going to copy as many whole eword_t's as possible.
+	 * "end" is the index of the last whole eword_t we copy, but
+	 * there may be additional bits to process. Those are handled
+	 * individually by write_reused_pack().
+	 *
+	 * Begin by advancing to the first word boundary in range of the
+	 * bit positions occupied by objects in "reuse_packfile". Then
+	 * pick the last word boundary in the same range. If we have at
+	 * least one word's worth of bits to process, continue on.
+	 */
+	end = reuse_packfile->bitmap_pos + reuse_packfile->bitmap_nr;
+	if (end % BITS_IN_EWORD)
+		end -= end % BITS_IN_EWORD;
+	if (pos >= end)
+		return reuse_packfile->bitmap_pos / BITS_IN_EWORD;
+
+	while (pos < end &&
+	       reuse_packfile_bitmap->words[pos / BITS_IN_EWORD] == (eword_t)~0)
+		pos += BITS_IN_EWORD;
+
+	if (pos > end)
+		pos = end;
+
+	if (reuse_packfile->bitmap_pos < pos) {
+		off_t pack_start_off = pack_pos_to_offset(reuse_packfile->p, 0);
+		off_t pack_end_off = pack_pos_to_offset(reuse_packfile->p,
+							pos - reuse_packfile->bitmap_pos);
+
+		written += pos - reuse_packfile->bitmap_pos;
 
 		/* We're recording one chunk, not one object. */
-		record_reused_object(sizeof(struct pack_header), 0);
+		record_reused_object(pack_start_off,
+				     pack_start_off - (hashfile_total(out) - pack_start));
 		hashflush(out);
-		copy_pack_data(out, reuse_packfile, w_curs,
-			sizeof(struct pack_header), to_write);
+		copy_pack_data(out, reuse_packfile->p, w_curs,
+			pack_start_off, pack_end_off - pack_start_off);
 
 		display_progress(progress_state, written);
 	}
-	return pos;
+	if (pos % BITS_IN_EWORD)
+		BUG("attempted to jump past a word boundary to %"PRIuMAX,
+		    (uintmax_t)pos);
+	return pos / BITS_IN_EWORD;
 }
 
-static void write_reused_pack(struct hashfile *f)
+static void write_reused_pack(struct bitmapped_pack *reuse_packfile,
+			      struct hashfile *f)
 {
-	size_t i = 0;
+	size_t i = reuse_packfile->bitmap_pos / BITS_IN_EWORD;
 	uint32_t offset;
+	off_t pack_start = hashfile_total(f) - sizeof(struct pack_header);
 	struct pack_window *w_curs = NULL;
 
 	if (allow_ofs_delta)
-		i = write_reused_pack_verbatim(f, &w_curs);
+		i = write_reused_pack_verbatim(reuse_packfile, f, pack_start,
+					       &w_curs);
 
 	for (; i < reuse_packfile_bitmap->word_alloc; ++i) {
 		eword_t word = reuse_packfile_bitmap->words[i];
@@ -1133,16 +1194,23 @@ static void write_reused_pack(struct hashfile *f)
 				break;
 
 			offset += ewah_bit_ctz64(word >> offset);
+			if (pos + offset < reuse_packfile->bitmap_pos)
+				continue;
+			if (pos + offset >= reuse_packfile->bitmap_pos + reuse_packfile->bitmap_nr)
+				goto done;
 			/*
 			 * Can use bit positions directly, even for MIDX
 			 * bitmaps. See comment in try_partial_reuse()
 			 * for why.
 			 */
-			write_reused_pack_one(pos + offset, f, &w_curs);
+			write_reused_pack_one(reuse_packfile->p,
+					      pos + offset - reuse_packfile->bitmap_pos,
+					      f, pack_start, &w_curs);
 			display_progress(progress_state, ++written);
 		}
 	}
 
+done:
 	unuse_pack(&w_curs);
 }
 
@@ -1194,9 +1262,14 @@ static void write_pack_file(void)
 
 		offset = write_pack_header(f, nr_remaining);
 
-		if (reuse_packfile) {
+		if (reuse_packfiles_nr) {
 			assert(pack_to_stdout);
-			write_reused_pack(f);
+			for (j = 0; j < reuse_packfiles_nr; j++) {
+				reused_chunks_nr = 0;
+				write_reused_pack(&reuse_packfiles[j], f);
+				if (reused_chunks_nr)
+					reuse_packfiles_used_nr++;
+			}
 			offset = hashfile_total(f);
 		}
 
@@ -1753,7 +1826,8 @@ static void add_pbase_object(struct tree_desc *tree,
 			tree = pbase_tree_get(&entry.oid);
 			if (!tree)
 				return;
-			init_tree_desc(&sub, tree->tree_data, tree->tree_size);
+			init_tree_desc(&sub, &tree->oid,
+				       tree->tree_data, tree->tree_size);
 
 			add_pbase_object(&sub, down, downlen, fullname);
 			pbase_tree_put(tree);
@@ -1813,7 +1887,8 @@ static void add_preferred_base_object(const char *name)
 		}
 		else {
 			struct tree_desc tree;
-			init_tree_desc(&tree, it->pcache.tree_data, it->pcache.tree_size);
+			init_tree_desc(&tree, &it->pcache.oid,
+				       it->pcache.tree_data, it->pcache.tree_size);
 			add_pbase_object(&tree, name, cmplen, name);
 		}
 	}
@@ -3172,7 +3247,19 @@ static int git_pack_config(const char *k, const char *v,
 		return 0;
 	}
 	if (!strcmp(k, "pack.allowpackreuse")) {
-		allow_pack_reuse = git_config_bool(k, v);
+		int res = git_parse_maybe_bool_text(v);
+		if (res < 0) {
+			if (!strcasecmp(v, "single"))
+				allow_pack_reuse = SINGLE_PACK_REUSE;
+			else if (!strcasecmp(v, "multi"))
+				allow_pack_reuse = MULTI_PACK_REUSE;
+			else
+				die(_("invalid pack.allowPackReuse value: '%s'"), v);
+		} else if (res) {
+			allow_pack_reuse = SINGLE_PACK_REUSE;
+		} else {
+			allow_pack_reuse = NO_PACK_REUSE;
+		}
 		return 0;
 	}
 	if (!strcmp(k, "pack.threads")) {
@@ -3931,7 +4018,7 @@ static void loosen_unused_packed_objects(void)
  */
 static int pack_options_allow_reuse(void)
 {
-	return allow_pack_reuse &&
+	return allow_pack_reuse != NO_PACK_REUSE &&
 	       pack_to_stdout &&
 	       !ignore_packed_keep_on_disk &&
 	       !ignore_packed_keep_in_core &&
@@ -3944,13 +4031,18 @@ static int get_object_list_from_bitmap(struct rev_info *revs)
 	if (!(bitmap_git = prepare_bitmap_walk(revs, 0)))
 		return -1;
 
-	if (pack_options_allow_reuse() &&
-	    !reuse_partial_packfile_from_bitmap(
-			bitmap_git,
-			&reuse_packfile,
-			&reuse_packfile_objects,
-			&reuse_packfile_bitmap)) {
-		assert(reuse_packfile_objects);
+	if (pack_options_allow_reuse())
+		reuse_partial_packfile_from_bitmap(bitmap_git,
+						   &reuse_packfiles,
+						   &reuse_packfiles_nr,
+						   &reuse_packfile_bitmap,
+						   allow_pack_reuse == MULTI_PACK_REUSE);
+
+	if (reuse_packfiles) {
+		reuse_packfile_objects = bitmap_popcount(reuse_packfile_bitmap);
+		if (!reuse_packfile_objects)
+			BUG("expected non-empty reuse bitmap");
+
 		nr_result += reuse_packfile_objects;
 		nr_seen += reuse_packfile_objects;
 		display_progress(progress_state, nr_seen);
@@ -4306,6 +4398,8 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
 		prepare_repo_settings(the_repository);
 		if (sparse < 0)
 			sparse = the_repository->settings.pack_use_sparse;
+		if (the_repository->settings.pack_use_multi_pack_reuse)
+			allow_pack_reuse = MULTI_PACK_REUSE;
 	}
 
 	reset_pack_idx_option(&pack_idx_opts);
@@ -4518,11 +4612,20 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
 		fprintf_ln(stderr,
 			   _("Total %"PRIu32" (delta %"PRIu32"),"
 			     " reused %"PRIu32" (delta %"PRIu32"),"
-			     " pack-reused %"PRIu32),
+			     " pack-reused %"PRIu32" (from %"PRIuMAX")"),
 			   written, written_delta, reused, reused_delta,
-			   reuse_packfile_objects);
+			   reuse_packfile_objects,
+			   (uintmax_t)reuse_packfiles_used_nr);
+
+	trace2_data_intmax("pack-objects", the_repository, "written", written);
+	trace2_data_intmax("pack-objects", the_repository, "written/delta", written_delta);
+	trace2_data_intmax("pack-objects", the_repository, "reused", reused);
+	trace2_data_intmax("pack-objects", the_repository, "reused/delta", reused_delta);
+	trace2_data_intmax("pack-objects", the_repository, "pack-reused", reuse_packfile_objects);
+	trace2_data_intmax("pack-objects", the_repository, "packs-reused", reuse_packfiles_used_nr);
 
 cleanup:
+	clear_packing_data(&to_pack);
 	list_objects_filter_release(&filter_options);
 	strvec_clear(&rp);
 
diff --git a/builtin/pack-refs.c b/builtin/pack-refs.c
index bcf383c..db40825 100644
--- a/builtin/pack-refs.c
+++ b/builtin/pack-refs.c
@@ -7,24 +7,28 @@
 #include "revision.h"
 
 static char const * const pack_refs_usage[] = {
-	N_("git pack-refs [--all] [--no-prune] [--include <pattern>] [--exclude <pattern>]"),
+	N_("git pack-refs [--all] [--no-prune] [--auto] [--include <pattern>] [--exclude <pattern>]"),
 	NULL
 };
 
 int cmd_pack_refs(int argc, const char **argv, const char *prefix)
 {
-	unsigned int flags = PACK_REFS_PRUNE;
-	static struct ref_exclusions excludes = REF_EXCLUSIONS_INIT;
-	static struct string_list included_refs = STRING_LIST_INIT_NODUP;
-	struct pack_refs_opts pack_refs_opts = { .exclusions = &excludes,
-						 .includes = &included_refs,
-						 .flags = flags };
-	static struct string_list option_excluded_refs = STRING_LIST_INIT_NODUP;
+	struct ref_exclusions excludes = REF_EXCLUSIONS_INIT;
+	struct string_list included_refs = STRING_LIST_INIT_NODUP;
+	struct pack_refs_opts pack_refs_opts = {
+		.exclusions = &excludes,
+		.includes = &included_refs,
+		.flags = PACK_REFS_PRUNE,
+	};
+	struct string_list option_excluded_refs = STRING_LIST_INIT_NODUP;
 	struct string_list_item *item;
+	int pack_all = 0;
+	int ret;
 
 	struct option opts[] = {
-		OPT_BIT(0, "all",   &pack_refs_opts.flags, N_("pack everything"), PACK_REFS_ALL),
+		OPT_BOOL(0, "all",   &pack_all, N_("pack everything")),
 		OPT_BIT(0, "prune", &pack_refs_opts.flags, N_("prune loose refs (default)"), PACK_REFS_PRUNE),
+		OPT_BIT(0, "auto", &pack_refs_opts.flags, N_("auto-pack refs as needed"), PACK_REFS_AUTO),
 		OPT_STRING_LIST(0, "include", pack_refs_opts.includes, N_("pattern"),
 			N_("references to include")),
 		OPT_STRING_LIST(0, "exclude", &option_excluded_refs, N_("pattern"),
@@ -38,11 +42,16 @@ int cmd_pack_refs(int argc, const char **argv, const char *prefix)
 	for_each_string_list_item(item, &option_excluded_refs)
 		add_ref_exclusion(pack_refs_opts.exclusions, item->string);
 
-	if (pack_refs_opts.flags & PACK_REFS_ALL)
+	if (pack_all)
 		string_list_append(pack_refs_opts.includes, "*");
 
 	if (!pack_refs_opts.includes->nr)
 		string_list_append(pack_refs_opts.includes, "refs/tags/*");
 
-	return refs_pack_refs(get_main_ref_store(the_repository), &pack_refs_opts);
+	ret = refs_pack_refs(get_main_ref_store(the_repository), &pack_refs_opts);
+
+	clear_ref_exclusions(&excludes);
+	string_list_clear(&included_refs, 0);
+	string_list_clear(&option_excluded_refs, 0);
+	return ret;
 }
diff --git a/builtin/pull.c b/builtin/pull.c
index 73a68b7..72cbb76 100644
--- a/builtin/pull.c
+++ b/builtin/pull.c
@@ -815,7 +815,7 @@ static int get_octopus_merge_base(struct object_id *merge_base,
 		const struct object_id *merge_head,
 		const struct object_id *fork_point)
 {
-	struct commit_list *revs = NULL, *result;
+	struct commit_list *revs = NULL, *result = NULL;
 
 	commit_list_insert(lookup_commit_reference(the_repository, curr_head),
 			   &revs);
@@ -825,7 +825,8 @@ static int get_octopus_merge_base(struct object_id *merge_base,
 		commit_list_insert(lookup_commit_reference(the_repository, fork_point),
 				   &revs);
 
-	result = get_octopus_merge_bases(revs);
+	if (get_octopus_merge_bases(revs, &result) < 0)
+		exit(128);
 	free_commit_list(revs);
 	reduce_heads_replace(&result);
 
@@ -926,6 +927,8 @@ static int get_can_ff(struct object_id *orig_head,
 	merge_head = lookup_commit_reference(the_repository, orig_merge_head);
 	ret = repo_is_descendant_of(the_repository, merge_head, list);
 	free_commit_list(list);
+	if (ret < 0)
+		exit(128);
 	return ret;
 }
 
@@ -950,6 +953,8 @@ static int already_up_to_date(struct object_id *orig_head,
 		commit_list_insert(theirs, &list);
 		ok = repo_is_descendant_of(the_repository, ours, list);
 		free_commit_list(list);
+		if (ok < 0)
+			exit(128);
 		if (!ok)
 			return 0;
 	}
diff --git a/builtin/read-tree.c b/builtin/read-tree.c
index 20e7db1..6f89cec 100644
--- a/builtin/read-tree.c
+++ b/builtin/read-tree.c
@@ -261,8 +261,9 @@ int cmd_read_tree(int argc, const char **argv, const char *cmd_prefix)
 	cache_tree_free(&the_index.cache_tree);
 	for (i = 0; i < nr_trees; i++) {
 		struct tree *tree = trees[i];
-		parse_tree(tree);
-		init_tree_desc(t+i, tree->buffer, tree->size);
+		if (parse_tree(tree) < 0)
+			return 128;
+		init_tree_desc(t+i, &tree->object.oid, tree->buffer, tree->size);
 	}
 	if (unpack_trees(nr_trees, t, &opts))
 		return 128;
diff --git a/builtin/rebase.c b/builtin/rebase.c
index 4084a6a..891f284 100644
--- a/builtin/rebase.c
+++ b/builtin/rebase.c
@@ -58,7 +58,7 @@ enum empty_type {
 	EMPTY_UNSPECIFIED = -1,
 	EMPTY_DROP,
 	EMPTY_KEEP,
-	EMPTY_ASK
+	EMPTY_STOP
 };
 
 enum action {
@@ -145,7 +145,6 @@ struct rebase_options {
 		.reapply_cherry_picks = -1,             \
 		.allow_empty_message = 1,               \
 		.autosquash = -1,                       \
-		.config_autosquash = -1,                \
 		.rebase_merges = -1,                    \
 		.config_rebase_merges = -1,             \
 		.update_refs = -1,                      \
@@ -205,7 +204,7 @@ static int edit_todo_file(unsigned flags)
 	if (strbuf_read_file(&todo_list.buf, todo_file, 0) < 0)
 		return error_errno(_("could not read '%s'."), todo_file);
 
-	strbuf_stripspace(&todo_list.buf, comment_line_char);
+	strbuf_stripspace(&todo_list.buf, comment_line_str);
 	res = edit_todo_list(the_repository, &todo_list, &new_todo, NULL, NULL, flags);
 	if (!res && todo_list_write_to_file(the_repository, &new_todo, todo_file,
 					    NULL, NULL, -1, flags & ~(TODO_LIST_SHORTEN_IDS)))
@@ -516,7 +515,7 @@ static int finish_rebase(struct rebase_options *opts)
 	int ret = 0;
 
 	delete_ref(NULL, "REBASE_HEAD", NULL, REF_NO_DEREF);
-	unlink(git_path_auto_merge(the_repository));
+	delete_ref(NULL, "AUTO_MERGE", NULL, REF_NO_DEREF);
 	apply_autostash(state_dir_path("autostash", opts));
 	/*
 	 * We ignore errors in 'git maintenance run --auto', since the
@@ -568,13 +567,6 @@ static int move_to_original_branch(struct rebase_options *opts)
 	return ret;
 }
 
-static const char *resolvemsg =
-N_("Resolve all conflicts manually, mark them as resolved with\n"
-"\"git add/rm <conflicted_files>\", then run \"git rebase --continue\".\n"
-"You can instead skip this commit: run \"git rebase --skip\".\n"
-"To abort and get back to the state before \"git rebase\", run "
-"\"git rebase --abort\".");
-
 static int run_am(struct rebase_options *opts)
 {
 	struct child_process am = CHILD_PROCESS_INIT;
@@ -588,7 +580,7 @@ static int run_am(struct rebase_options *opts)
 		     opts->reflog_action);
 	if (opts->action == ACTION_CONTINUE) {
 		strvec_push(&am.args, "--resolved");
-		strvec_pushf(&am.args, "--resolvemsg=%s", resolvemsg);
+		strvec_pushf(&am.args, "--resolvemsg=%s", rebase_resolvemsg);
 		if (opts->gpg_sign_opt)
 			strvec_push(&am.args, opts->gpg_sign_opt);
 		status = run_command(&am);
@@ -599,7 +591,7 @@ static int run_am(struct rebase_options *opts)
 	}
 	if (opts->action == ACTION_SKIP) {
 		strvec_push(&am.args, "--skip");
-		strvec_pushf(&am.args, "--resolvemsg=%s", resolvemsg);
+		strvec_pushf(&am.args, "--resolvemsg=%s", rebase_resolvemsg);
 		status = run_command(&am);
 		if (status)
 			return status;
@@ -618,7 +610,7 @@ static int run_am(struct rebase_options *opts)
 		status = error_errno(_("could not open '%s' for writing"),
 				     rebased_patches);
 		free(rebased_patches);
-		strvec_clear(&am.args);
+		child_process_clear(&am);
 		return status;
 	}
 
@@ -646,7 +638,7 @@ static int run_am(struct rebase_options *opts)
 		struct reset_head_opts ropts = { 0 };
 		unlink(rebased_patches);
 		free(rebased_patches);
-		strvec_clear(&am.args);
+		child_process_clear(&am);
 
 		ropts.oid = &opts->orig_head->object.oid;
 		ropts.branch = opts->head_name;
@@ -667,13 +659,13 @@ static int run_am(struct rebase_options *opts)
 		status = error_errno(_("could not open '%s' for reading"),
 				     rebased_patches);
 		free(rebased_patches);
-		strvec_clear(&am.args);
+		child_process_clear(&am);
 		return status;
 	}
 
 	strvec_pushv(&am.args, opts->git_am_opts.v);
 	strvec_push(&am.args, "--rebasing");
-	strvec_pushf(&am.args, "--resolvemsg=%s", resolvemsg);
+	strvec_pushf(&am.args, "--resolvemsg=%s", rebase_resolvemsg);
 	strvec_push(&am.args, "--patch-format=mboxrd");
 	if (opts->allow_rerere_autoupdate == RERERE_AUTOUPDATE)
 		strvec_push(&am.args, "--rerere-autoupdate");
@@ -701,11 +693,8 @@ static int run_specific_rebase(struct rebase_options *opts)
 
 	if (opts->type == REBASE_MERGE) {
 		/* Run sequencer-based rebase */
-		setenv("GIT_CHERRY_PICK_HELP", resolvemsg, 1);
-		if (!(opts->flags & REBASE_INTERACTIVE_EXPLICIT)) {
+		if (!(opts->flags & REBASE_INTERACTIVE_EXPLICIT))
 			setenv("GIT_SEQUENCE_EDITOR", ":", 1);
-			opts->autosquash = 0;
-		}
 		if (opts->gpg_sign_opt) {
 			/* remove the leading "-S" */
 			char *tmp = xstrdup(opts->gpg_sign_opt + 2);
@@ -870,7 +859,8 @@ static int can_fast_forward(struct commit *onto, struct commit *upstream,
 	if (!upstream)
 		goto done;
 
-	merge_bases = repo_get_merge_bases(the_repository, upstream, head);
+	if (repo_get_merge_bases(the_repository, upstream, head, &merge_bases) < 0)
+		exit(128);
 	if (!merge_bases || merge_bases->next)
 		goto done;
 
@@ -889,8 +879,9 @@ static void fill_branch_base(struct rebase_options *options,
 {
 	struct commit_list *merge_bases = NULL;
 
-	merge_bases = repo_get_merge_bases(the_repository, options->onto,
-					   options->orig_head);
+	if (repo_get_merge_bases(the_repository, options->onto,
+				 options->orig_head, &merge_bases) < 0)
+		exit(128);
 	if (!merge_bases || merge_bases->next)
 		oidcpy(branch_base, null_oid());
 	else
@@ -954,10 +945,14 @@ static enum empty_type parse_empty_value(const char *value)
 		return EMPTY_DROP;
 	else if (!strcasecmp(value, "keep"))
 		return EMPTY_KEEP;
-	else if (!strcasecmp(value, "ask"))
-		return EMPTY_ASK;
+	else if (!strcasecmp(value, "stop"))
+		return EMPTY_STOP;
+	else if (!strcasecmp(value, "ask")) {
+		warning(_("--empty=ask is deprecated; use '--empty=stop' instead."));
+		return EMPTY_STOP;
+	}
 
-	die(_("unrecognized empty type '%s'; valid values are \"drop\", \"keep\", and \"ask\"."), value);
+	die(_("unrecognized empty type '%s'; valid values are \"drop\", \"keep\", and \"stop\"."), value);
 }
 
 static int parse_opt_keep_empty(const struct option *opt, const char *arg,
@@ -1136,7 +1131,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
 				 "instead of ignoring them"),
 			      1, PARSE_OPT_HIDDEN),
 		OPT_RERERE_AUTOUPDATE(&options.allow_rerere_autoupdate),
-		OPT_CALLBACK_F(0, "empty", &options, "(drop|keep|ask)",
+		OPT_CALLBACK_F(0, "empty", &options, "(drop|keep|stop)",
 			       N_("how to handle commits that become empty"),
 			       PARSE_OPT_NONEG, parse_opt_empty),
 		OPT_CALLBACK_F('k', "keep-empty", &options, NULL,
@@ -1257,7 +1252,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
 		die(_("options '%s' and '%s' cannot be used together"), "--root", "--fork-point");
 
 	if (options.action != ACTION_NONE && !in_progress)
-		die(_("No rebase in progress?"));
+		die(_("no rebase in progress"));
 
 	if (options.action == ACTION_EDIT_TODO && !is_merge(&options))
 		die(_("The --edit-todo action can only be used during "
@@ -1396,7 +1391,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
 	if ((options.flags & REBASE_INTERACTIVE_EXPLICIT) ||
 	    (options.action != ACTION_NONE) ||
 	    (options.exec.nr > 0) ||
-	    (options.autosquash == -1 && options.config_autosquash == 1) ||
 	    options.autosquash == 1) {
 		allow_preemptive_ff = 0;
 	}
@@ -1499,8 +1493,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
 			if (is_merge(&options))
 				die(_("apply options and merge options "
 					  "cannot be used together"));
-			else if (options.autosquash == -1 && options.config_autosquash == 1)
-				die(_("apply options are incompatible with rebase.autoSquash.  Consider adding --no-autosquash"));
 			else if (options.rebase_merges == -1 && options.config_rebase_merges == 1)
 				die(_("apply options are incompatible with rebase.rebaseMerges.  Consider adding --no-rebase-merges"));
 			else if (options.update_refs == -1 && options.config_update_refs == 1)
@@ -1520,10 +1512,13 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
 	options.rebase_merges = (options.rebase_merges >= 0) ? options.rebase_merges :
 				((options.config_rebase_merges >= 0) ? options.config_rebase_merges : 0);
 
-	if (options.autosquash == 1)
+	if (options.autosquash == 1) {
 		imply_merge(&options, "--autosquash");
-	options.autosquash = (options.autosquash >= 0) ? options.autosquash :
-			     ((options.config_autosquash >= 0) ? options.config_autosquash : 0);
+	} else if (options.autosquash == -1) {
+		options.autosquash =
+			options.config_autosquash &&
+			(options.flags & REBASE_INTERACTIVE_EXPLICIT);
+	}
 
 	if (options.type == REBASE_UNSPECIFIED) {
 		if (!strcmp(options.default_backend, "merge"))
@@ -1553,7 +1548,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
 
 	if (options.empty == EMPTY_UNSPECIFIED) {
 		if (options.flags & REBASE_INTERACTIVE_EXPLICIT)
-			options.empty = EMPTY_ASK;
+			options.empty = EMPTY_STOP;
 		else if (options.exec.nr > 0)
 			options.empty = EMPTY_KEEP;
 		else
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index e36b1d6..e8d7df1 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -593,21 +593,6 @@ static char *prepare_push_cert_nonce(const char *path, timestamp_t stamp)
 	return strbuf_detach(&buf, NULL);
 }
 
-static char *find_header(const char *msg, size_t len, const char *key,
-			 const char **next_line)
-{
-	size_t out_len;
-	const char *val = find_header_mem(msg, len, key, &out_len);
-
-	if (!val)
-		return NULL;
-
-	if (next_line)
-		*next_line = val + out_len + 1;
-
-	return xmemdupz(val, out_len);
-}
-
 /*
  * Return zero if a and b are equal up to n bytes and nonzero if they are not.
  * This operation is guaranteed to run in constant time to avoid leaking data.
@@ -622,13 +607,14 @@ static int constant_memequal(const char *a, const char *b, size_t n)
 	return res;
 }
 
-static const char *check_nonce(const char *buf, size_t len)
+static const char *check_nonce(const char *buf)
 {
-	char *nonce = find_header(buf, len, "nonce", NULL);
+	size_t noncelen;
+	const char *found = find_commit_header(buf, "nonce", &noncelen);
+	char *nonce = found ? xmemdupz(found, noncelen) : NULL;
 	timestamp_t stamp, ostamp;
 	char *bohmac, *expect = NULL;
 	const char *retval = NONCE_BAD;
-	size_t noncelen;
 
 	if (!nonce) {
 		retval = NONCE_MISSING;
@@ -670,7 +656,6 @@ static const char *check_nonce(const char *buf, size_t len)
 		goto leave;
 	}
 
-	noncelen = strlen(nonce);
 	expect = prepare_push_cert_nonce(service_dir, stamp);
 	if (noncelen != strlen(expect)) {
 		/* This is not even the right size. */
@@ -718,35 +703,28 @@ static const char *check_nonce(const char *buf, size_t len)
 static int check_cert_push_options(const struct string_list *push_options)
 {
 	const char *buf = push_cert.buf;
-	int len = push_cert.len;
 
-	char *option;
-	const char *next_line;
+	const char *option;
+	size_t optionlen;
 	int options_seen = 0;
 
 	int retval = 1;
 
-	if (!len)
+	if (!*buf)
 		return 1;
 
-	while ((option = find_header(buf, len, "push-option", &next_line))) {
-		len -= (next_line - buf);
-		buf = next_line;
+	while ((option = find_commit_header(buf, "push-option", &optionlen))) {
+		buf = option + optionlen + 1;
 		options_seen++;
 		if (options_seen > push_options->nr
-		    || strcmp(option,
-			      push_options->items[options_seen - 1].string)) {
-			retval = 0;
-			goto leave;
-		}
-		free(option);
+		    || xstrncmpz(push_options->items[options_seen - 1].string,
+				 option, optionlen))
+			return 0;
 	}
 
 	if (options_seen != push_options->nr)
 		retval = 0;
 
-leave:
-	free(option);
 	return retval;
 }
 
@@ -773,7 +751,7 @@ static void prepare_push_cert_sha1(struct child_process *proc)
 		check_signature(&sigcheck, push_cert.buf + bogs,
 				push_cert.len - bogs);
 
-		nonce_status = check_nonce(push_cert.buf, bogs);
+		nonce_status = check_nonce(sigcheck.payload);
 	}
 	if (!is_null_oid(&push_cert_oid)) {
 		strvec_pushf(&proc->env, "GIT_PUSH_CERT=%s",
@@ -1548,6 +1526,7 @@ static const char *update(struct command *cmd, struct shallow_info *si)
 	    starts_with(name, "refs/heads/")) {
 		struct object *old_object, *new_object;
 		struct commit *old_commit, *new_commit;
+		int ret2;
 
 		old_object = parse_object(the_repository, old_oid);
 		new_object = parse_object(the_repository, new_oid);
@@ -1561,7 +1540,10 @@ static const char *update(struct command *cmd, struct shallow_info *si)
 		}
 		old_commit = (struct commit *)old_object;
 		new_commit = (struct commit *)new_object;
-		if (!repo_in_merge_bases(the_repository, old_commit, new_commit)) {
+		ret2 = repo_in_merge_bases(the_repository, old_commit, new_commit);
+		if (ret2 < 0)
+			exit(128);
+		if (!ret2) {
 			rp_error("denying non-fast-forward %s"
 				 " (you should pull first)", name);
 			ret = "non-fast-forward";
@@ -2603,17 +2585,16 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
 		if (auto_gc) {
 			struct child_process proc = CHILD_PROCESS_INIT;
 
-			proc.no_stdin = 1;
-			proc.stdout_to_stderr = 1;
-			proc.err = use_sideband ? -1 : 0;
-			proc.git_cmd = proc.close_object_store = 1;
-			strvec_pushl(&proc.args, "gc", "--auto", "--quiet",
-				     NULL);
+			if (prepare_auto_maintenance(1, &proc)) {
+				proc.no_stdin = 1;
+				proc.stdout_to_stderr = 1;
+				proc.err = use_sideband ? -1 : 0;
 
-			if (!start_command(&proc)) {
-				if (use_sideband)
-					copy_to_sideband(proc.err, -1, NULL);
-				finish_command(&proc);
+				if (!start_command(&proc)) {
+					if (use_sideband)
+						copy_to_sideband(proc.err, -1, NULL);
+					finish_command(&proc);
+				}
 			}
 		}
 		if (auto_update_server_info)
diff --git a/builtin/reflog.c b/builtin/reflog.c
index a5a4099..060eb33 100644
--- a/builtin/reflog.c
+++ b/builtin/reflog.c
@@ -7,11 +7,15 @@
 #include "wildmatch.h"
 #include "worktree.h"
 #include "reflog.h"
+#include "refs.h"
 #include "parse-options.h"
 
 #define BUILTIN_REFLOG_SHOW_USAGE \
 	N_("git reflog [show] [<log-options>] [<ref>]")
 
+#define BUILTIN_REFLOG_LIST_USAGE \
+	N_("git reflog list")
+
 #define BUILTIN_REFLOG_EXPIRE_USAGE \
 	N_("git reflog expire [--expire=<time>] [--expire-unreachable=<time>]\n" \
 	   "                  [--rewrite] [--updateref] [--stale-fix]\n" \
@@ -29,6 +33,11 @@ static const char *const reflog_show_usage[] = {
 	NULL,
 };
 
+static const char *const reflog_list_usage[] = {
+	BUILTIN_REFLOG_LIST_USAGE,
+	NULL,
+};
+
 static const char *const reflog_expire_usage[] = {
 	BUILTIN_REFLOG_EXPIRE_USAGE,
 	NULL
@@ -46,6 +55,7 @@ static const char *const reflog_exists_usage[] = {
 
 static const char *const reflog_usage[] = {
 	BUILTIN_REFLOG_SHOW_USAGE,
+	BUILTIN_REFLOG_LIST_USAGE,
 	BUILTIN_REFLOG_EXPIRE_USAGE,
 	BUILTIN_REFLOG_DELETE_USAGE,
 	BUILTIN_REFLOG_EXISTS_USAGE,
@@ -60,8 +70,7 @@ struct worktree_reflogs {
 	struct string_list reflogs;
 };
 
-static int collect_reflog(const char *ref, const struct object_id *oid UNUSED,
-			  int flags UNUSED, void *cb_data)
+static int collect_reflog(const char *ref, void *cb_data)
 {
 	struct worktree_reflogs *cb = cb_data;
 	struct worktree *worktree = cb->worktree;
@@ -96,8 +105,7 @@ static struct reflog_expire_cfg *find_cfg_ent(const char *pattern, size_t len)
 		reflog_expire_cfg_tail = &reflog_expire_cfg;
 
 	for (ent = reflog_expire_cfg; ent; ent = ent->next)
-		if (!strncmp(ent->pattern, pattern, len) &&
-		    ent->pattern[len] == '\0')
+		if (!xstrncmpz(ent->pattern, pattern, len))
 			return ent;
 
 	FLEX_ALLOC_MEM(ent, pattern, pattern, len);
@@ -239,6 +247,29 @@ static int cmd_reflog_show(int argc, const char **argv, const char *prefix)
 	return cmd_log_reflog(argc, argv, prefix);
 }
 
+static int show_reflog(const char *refname, void *cb_data UNUSED)
+{
+	printf("%s\n", refname);
+	return 0;
+}
+
+static int cmd_reflog_list(int argc, const char **argv, const char *prefix)
+{
+	struct option options[] = {
+		OPT_END()
+	};
+	struct ref_store *ref_store;
+
+	argc = parse_options(argc, argv, prefix, options, reflog_list_usage, 0);
+	if (argc)
+		return error(_("%s does not accept arguments: '%s'"),
+			     "list", argv[0]);
+
+	ref_store = get_main_ref_store(the_repository);
+
+	return refs_for_each_reflog(ref_store, show_reflog, NULL);
+}
+
 static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)
 {
 	struct cmd_reflog_expire_cb cmd = { 0 };
@@ -418,6 +449,7 @@ int cmd_reflog(int argc, const char **argv, const char *prefix)
 	parse_opt_subcommand_fn *fn = NULL;
 	struct option options[] = {
 		OPT_SUBCOMMAND("show", &fn, cmd_reflog_show),
+		OPT_SUBCOMMAND("list", &fn, cmd_reflog_list),
 		OPT_SUBCOMMAND("expire", &fn, cmd_reflog_expire),
 		OPT_SUBCOMMAND("delete", &fn, cmd_reflog_delete),
 		OPT_SUBCOMMAND("exists", &fn, cmd_reflog_exists),
diff --git a/builtin/remote.c b/builtin/remote.c
index d91bbe7..8412d12 100644
--- a/builtin/remote.c
+++ b/builtin/remote.c
@@ -150,7 +150,7 @@ static int parse_mirror_opt(const struct option *opt, const char *arg, int not)
 	else if (!strcmp(arg, "push"))
 		*mirror = MIRROR_PUSH;
 	else
-		return error(_("unknown mirror argument: %s"), arg);
+		return error(_("unknown --mirror argument: %s"), arg);
 	return 0;
 }
 
diff --git a/builtin/repack.c b/builtin/repack.c
index ede3632..15e4ccc 100644
--- a/builtin/repack.c
+++ b/builtin/repack.c
@@ -314,8 +314,9 @@ static int write_oid(const struct object_id *oid,
 			die(_("could not start pack-objects to repack promisor objects"));
 	}
 
-	xwrite(cmd->in, oid_to_hex(oid), the_hash_algo->hexsz);
-	xwrite(cmd->in, "\n", 1);
+	if (write_in_full(cmd->in, oid_to_hex(oid), the_hash_algo->hexsz) < 0 ||
+	    write_in_full(cmd->in, "\n", 1) < 0)
+		die(_("failed to feed promisor objects to pack-objects"));
 	return 0;
 }
 
diff --git a/builtin/replay.c b/builtin/replay.c
new file mode 100644
index 0000000..6bc4b47
--- /dev/null
+++ b/builtin/replay.c
@@ -0,0 +1,446 @@
+/*
+ * "git replay" builtin command
+ */
+
+#define USE_THE_INDEX_VARIABLE
+#include "git-compat-util.h"
+
+#include "builtin.h"
+#include "environment.h"
+#include "hex.h"
+#include "lockfile.h"
+#include "merge-ort.h"
+#include "object-name.h"
+#include "parse-options.h"
+#include "refs.h"
+#include "revision.h"
+#include "strmap.h"
+#include <oidset.h>
+#include <tree.h>
+
+static const char *short_commit_name(struct commit *commit)
+{
+	return repo_find_unique_abbrev(the_repository, &commit->object.oid,
+				       DEFAULT_ABBREV);
+}
+
+static struct commit *peel_committish(const char *name)
+{
+	struct object *obj;
+	struct object_id oid;
+
+	if (repo_get_oid(the_repository, name, &oid))
+		return NULL;
+	obj = parse_object(the_repository, &oid);
+	return (struct commit *)repo_peel_to_type(the_repository, name, 0, obj,
+						  OBJ_COMMIT);
+}
+
+static char *get_author(const char *message)
+{
+	size_t len;
+	const char *a;
+
+	a = find_commit_header(message, "author", &len);
+	if (a)
+		return xmemdupz(a, len);
+
+	return NULL;
+}
+
+static struct commit *create_commit(struct tree *tree,
+				    struct commit *based_on,
+				    struct commit *parent)
+{
+	struct object_id ret;
+	struct object *obj;
+	struct commit_list *parents = NULL;
+	char *author;
+	char *sign_commit = NULL; /* FIXME: cli users might want to sign again */
+	struct commit_extra_header *extra;
+	struct strbuf msg = STRBUF_INIT;
+	const char *out_enc = get_commit_output_encoding();
+	const char *message = repo_logmsg_reencode(the_repository, based_on,
+						   NULL, out_enc);
+	const char *orig_message = NULL;
+	const char *exclude_gpgsig[] = { "gpgsig", NULL };
+
+	commit_list_insert(parent, &parents);
+	extra = read_commit_extra_headers(based_on, exclude_gpgsig);
+	find_commit_subject(message, &orig_message);
+	strbuf_addstr(&msg, orig_message);
+	author = get_author(message);
+	reset_ident_date();
+	if (commit_tree_extended(msg.buf, msg.len, &tree->object.oid, parents,
+				 &ret, author, NULL, sign_commit, extra)) {
+		error(_("failed to write commit object"));
+		return NULL;
+	}
+	free(author);
+	strbuf_release(&msg);
+
+	obj = parse_object(the_repository, &ret);
+	return (struct commit *)obj;
+}
+
+struct ref_info {
+	struct commit *onto;
+	struct strset positive_refs;
+	struct strset negative_refs;
+	int positive_refexprs;
+	int negative_refexprs;
+};
+
+static void get_ref_information(struct rev_cmdline_info *cmd_info,
+				struct ref_info *ref_info)
+{
+	int i;
+
+	ref_info->onto = NULL;
+	strset_init(&ref_info->positive_refs);
+	strset_init(&ref_info->negative_refs);
+	ref_info->positive_refexprs = 0;
+	ref_info->negative_refexprs = 0;
+
+	/*
+	 * When the user specifies e.g.
+	 *   git replay origin/main..mybranch
+	 *   git replay ^origin/next mybranch1 mybranch2
+	 * we want to be able to determine where to replay the commits.  In
+	 * these examples, the branches are probably based on an old version
+	 * of either origin/main or origin/next, so we want to replay on the
+	 * newest version of that branch.  In contrast we would want to error
+	 * out if they ran
+	 *   git replay ^origin/master ^origin/next mybranch
+	 *   git replay mybranch~2..mybranch
+	 * the first of those because there's no unique base to choose, and
+	 * the second because they'd likely just be replaying commits on top
+	 * of the same commit and not making any difference.
+	 */
+	for (i = 0; i < cmd_info->nr; i++) {
+		struct rev_cmdline_entry *e = cmd_info->rev + i;
+		struct object_id oid;
+		const char *refexpr = e->name;
+		char *fullname = NULL;
+		int can_uniquely_dwim = 1;
+
+		if (*refexpr == '^')
+			refexpr++;
+		if (repo_dwim_ref(the_repository, refexpr, strlen(refexpr), &oid, &fullname, 0) != 1)
+			can_uniquely_dwim = 0;
+
+		if (e->flags & BOTTOM) {
+			if (can_uniquely_dwim)
+				strset_add(&ref_info->negative_refs, fullname);
+			if (!ref_info->negative_refexprs)
+				ref_info->onto = lookup_commit_reference_gently(the_repository,
+										&e->item->oid, 1);
+			ref_info->negative_refexprs++;
+		} else {
+			if (can_uniquely_dwim)
+				strset_add(&ref_info->positive_refs, fullname);
+			ref_info->positive_refexprs++;
+		}
+
+		free(fullname);
+	}
+}
+
+static void determine_replay_mode(struct rev_cmdline_info *cmd_info,
+				  const char *onto_name,
+				  const char **advance_name,
+				  struct commit **onto,
+				  struct strset **update_refs)
+{
+	struct ref_info rinfo;
+
+	get_ref_information(cmd_info, &rinfo);
+	if (!rinfo.positive_refexprs)
+		die(_("need some commits to replay"));
+	if (onto_name && *advance_name)
+		die(_("--onto and --advance are incompatible"));
+	else if (onto_name) {
+		*onto = peel_committish(onto_name);
+		if (rinfo.positive_refexprs <
+		    strset_get_size(&rinfo.positive_refs))
+			die(_("all positive revisions given must be references"));
+	} else if (*advance_name) {
+		struct object_id oid;
+		char *fullname = NULL;
+
+		*onto = peel_committish(*advance_name);
+		if (repo_dwim_ref(the_repository, *advance_name, strlen(*advance_name),
+			     &oid, &fullname, 0) == 1) {
+			*advance_name = fullname;
+		} else {
+			die(_("argument to --advance must be a reference"));
+		}
+		if (rinfo.positive_refexprs > 1)
+			die(_("cannot advance target with multiple sources because ordering would be ill-defined"));
+	} else {
+		int positive_refs_complete = (
+			rinfo.positive_refexprs ==
+			strset_get_size(&rinfo.positive_refs));
+		int negative_refs_complete = (
+			rinfo.negative_refexprs ==
+			strset_get_size(&rinfo.negative_refs));
+		/*
+		 * We need either positive_refs_complete or
+		 * negative_refs_complete, but not both.
+		 */
+		if (rinfo.negative_refexprs > 0 &&
+		    positive_refs_complete == negative_refs_complete)
+			die(_("cannot implicitly determine whether this is an --advance or --onto operation"));
+		if (negative_refs_complete) {
+			struct hashmap_iter iter;
+			struct strmap_entry *entry;
+
+			if (rinfo.negative_refexprs == 0)
+				die(_("all positive revisions given must be references"));
+			else if (rinfo.negative_refexprs > 1)
+				die(_("cannot implicitly determine whether this is an --advance or --onto operation"));
+			else if (rinfo.positive_refexprs > 1)
+				die(_("cannot advance target with multiple source branches because ordering would be ill-defined"));
+
+			/* Only one entry, but we have to loop to get it */
+			strset_for_each_entry(&rinfo.negative_refs,
+					      &iter, entry) {
+				*advance_name = entry->key;
+			}
+		} else { /* positive_refs_complete */
+			if (rinfo.negative_refexprs > 1)
+				die(_("cannot implicitly determine correct base for --onto"));
+			if (rinfo.negative_refexprs == 1)
+				*onto = rinfo.onto;
+		}
+	}
+	if (!*advance_name) {
+		*update_refs = xcalloc(1, sizeof(**update_refs));
+		**update_refs = rinfo.positive_refs;
+		memset(&rinfo.positive_refs, 0, sizeof(**update_refs));
+	}
+	strset_clear(&rinfo.negative_refs);
+	strset_clear(&rinfo.positive_refs);
+}
+
+static struct commit *mapped_commit(kh_oid_map_t *replayed_commits,
+				    struct commit *commit,
+				    struct commit *fallback)
+{
+	khint_t pos = kh_get_oid_map(replayed_commits, commit->object.oid);
+	if (pos == kh_end(replayed_commits))
+		return fallback;
+	return kh_value(replayed_commits, pos);
+}
+
+static struct commit *pick_regular_commit(struct commit *pickme,
+					  kh_oid_map_t *replayed_commits,
+					  struct commit *onto,
+					  struct merge_options *merge_opt,
+					  struct merge_result *result)
+{
+	struct commit *base, *replayed_base;
+	struct tree *pickme_tree, *base_tree;
+
+	base = pickme->parents->item;
+	replayed_base = mapped_commit(replayed_commits, base, onto);
+
+	result->tree = repo_get_commit_tree(the_repository, replayed_base);
+	pickme_tree = repo_get_commit_tree(the_repository, pickme);
+	base_tree = repo_get_commit_tree(the_repository, base);
+
+	merge_opt->branch1 = short_commit_name(replayed_base);
+	merge_opt->branch2 = short_commit_name(pickme);
+	merge_opt->ancestor = xstrfmt("parent of %s", merge_opt->branch2);
+
+	merge_incore_nonrecursive(merge_opt,
+				  base_tree,
+				  result->tree,
+				  pickme_tree,
+				  result);
+
+	free((char*)merge_opt->ancestor);
+	merge_opt->ancestor = NULL;
+	if (!result->clean)
+		return NULL;
+	return create_commit(result->tree, pickme, replayed_base);
+}
+
+int cmd_replay(int argc, const char **argv, const char *prefix)
+{
+	const char *advance_name = NULL;
+	struct commit *onto = NULL;
+	const char *onto_name = NULL;
+	int contained = 0;
+
+	struct rev_info revs;
+	struct commit *last_commit = NULL;
+	struct commit *commit;
+	struct merge_options merge_opt;
+	struct merge_result result;
+	struct strset *update_refs = NULL;
+	kh_oid_map_t *replayed_commits;
+	int ret = 0;
+
+	const char * const replay_usage[] = {
+		N_("(EXPERIMENTAL!) git replay "
+		   "([--contained] --onto <newbase> | --advance <branch>) "
+		   "<revision-range>..."),
+		NULL
+	};
+	struct option replay_options[] = {
+		OPT_STRING(0, "advance", &advance_name,
+			   N_("branch"),
+			   N_("make replay advance given branch")),
+		OPT_STRING(0, "onto", &onto_name,
+			   N_("revision"),
+			   N_("replay onto given commit")),
+		OPT_BOOL(0, "contained", &contained,
+			 N_("advance all branches contained in revision-range")),
+		OPT_END()
+	};
+
+	argc = parse_options(argc, argv, prefix, replay_options, replay_usage,
+			     PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN_OPT);
+
+	if (!onto_name && !advance_name) {
+		error(_("option --onto or --advance is mandatory"));
+		usage_with_options(replay_usage, replay_options);
+	}
+
+	if (advance_name && contained)
+		die(_("options '%s' and '%s' cannot be used together"),
+		    "--advance", "--contained");
+
+	repo_init_revisions(the_repository, &revs, prefix);
+
+	/*
+	 * Set desired values for rev walking options here. If they
+	 * are changed by some user specified option in setup_revisions()
+	 * below, we will detect that below and then warn.
+	 *
+	 * TODO: In the future we might want to either die(), or allow
+	 * some options changing these values if we think they could
+	 * be useful.
+	 */
+	revs.reverse = 1;
+	revs.sort_order = REV_SORT_IN_GRAPH_ORDER;
+	revs.topo_order = 1;
+	revs.simplify_history = 0;
+
+	argc = setup_revisions(argc, argv, &revs, NULL);
+	if (argc > 1) {
+		ret = error(_("unrecognized argument: %s"), argv[1]);
+		goto cleanup;
+	}
+
+	/*
+	 * Detect and warn if we override some user specified rev
+	 * walking options.
+	 */
+	if (revs.reverse != 1) {
+		warning(_("some rev walking options will be overridden as "
+			  "'%s' bit in 'struct rev_info' will be forced"),
+			"reverse");
+		revs.reverse = 1;
+	}
+	if (revs.sort_order != REV_SORT_IN_GRAPH_ORDER) {
+		warning(_("some rev walking options will be overridden as "
+			  "'%s' bit in 'struct rev_info' will be forced"),
+			"sort_order");
+		revs.sort_order = REV_SORT_IN_GRAPH_ORDER;
+	}
+	if (revs.topo_order != 1) {
+		warning(_("some rev walking options will be overridden as "
+			  "'%s' bit in 'struct rev_info' will be forced"),
+			"topo_order");
+		revs.topo_order = 1;
+	}
+	if (revs.simplify_history != 0) {
+		warning(_("some rev walking options will be overridden as "
+			  "'%s' bit in 'struct rev_info' will be forced"),
+			"simplify_history");
+		revs.simplify_history = 0;
+	}
+
+	determine_replay_mode(&revs.cmdline, onto_name, &advance_name,
+			      &onto, &update_refs);
+
+	if (!onto) /* FIXME: Should handle replaying down to root commit */
+		die("Replaying down to root commit is not supported yet!");
+
+	if (prepare_revision_walk(&revs) < 0) {
+		ret = error(_("error preparing revisions"));
+		goto cleanup;
+	}
+
+	init_merge_options(&merge_opt, the_repository);
+	memset(&result, 0, sizeof(result));
+	merge_opt.show_rename_progress = 0;
+	last_commit = onto;
+	replayed_commits = kh_init_oid_map();
+	while ((commit = get_revision(&revs))) {
+		const struct name_decoration *decoration;
+		khint_t pos;
+		int hr;
+
+		if (!commit->parents)
+			die(_("replaying down to root commit is not supported yet!"));
+		if (commit->parents->next)
+			die(_("replaying merge commits is not supported yet!"));
+
+		last_commit = pick_regular_commit(commit, replayed_commits, onto,
+						  &merge_opt, &result);
+		if (!last_commit)
+			break;
+
+		/* Record commit -> last_commit mapping */
+		pos = kh_put_oid_map(replayed_commits, commit->object.oid, &hr);
+		if (hr == 0)
+			BUG("Duplicate rewritten commit: %s\n",
+			    oid_to_hex(&commit->object.oid));
+		kh_value(replayed_commits, pos) = last_commit;
+
+		/* Update any necessary branches */
+		if (advance_name)
+			continue;
+		decoration = get_name_decoration(&commit->object);
+		if (!decoration)
+			continue;
+		while (decoration) {
+			if (decoration->type == DECORATION_REF_LOCAL &&
+			    (contained || strset_contains(update_refs,
+							  decoration->name))) {
+				printf("update %s %s %s\n",
+				       decoration->name,
+				       oid_to_hex(&last_commit->object.oid),
+				       oid_to_hex(&commit->object.oid));
+			}
+			decoration = decoration->next;
+		}
+	}
+
+	/* In --advance mode, advance the target ref */
+	if (result.clean == 1 && advance_name) {
+		printf("update %s %s %s\n",
+		       advance_name,
+		       oid_to_hex(&last_commit->object.oid),
+		       oid_to_hex(&onto->object.oid));
+	}
+
+	merge_finalize(&merge_opt, &result);
+	kh_destroy_oid_map(replayed_commits);
+	if (update_refs) {
+		strset_clear(update_refs);
+		free(update_refs);
+	}
+	ret = result.clean;
+
+cleanup:
+	release_revisions(&revs);
+
+	/* Return */
+	if (ret < 0)
+		exit(128);
+	return ret ? 0 : 1;
+}
diff --git a/builtin/reset.c b/builtin/reset.c
index 8390bfe..1d62ff6 100644
--- a/builtin/reset.c
+++ b/builtin/reset.c
@@ -116,6 +116,10 @@ static int reset_index(const char *ref, const struct object_id *oid, int reset_t
 
 	if (reset_type == MIXED || reset_type == HARD) {
 		tree = parse_tree_indirect(oid);
+		if (!tree) {
+			error(_("unable to read tree (%s)"), oid_to_hex(oid));
+			goto out;
+		}
 		prime_cache_tree(the_repository, the_repository->index, tree);
 	}
 
@@ -281,7 +285,9 @@ static void parse_args(struct pathspec *pathspec,
 			verify_filename(prefix, argv[0], 1);
 		}
 	}
-	*rev_ret = rev;
+
+	/* treat '@' as a shortcut for 'HEAD' */
+	*rev_ret = !strcmp("@", rev) ? "HEAD" : rev;
 
 	parse_pathspec(pathspec, 0,
 		       PATHSPEC_PREFER_FULL |
diff --git a/builtin/rev-list.c b/builtin/rev-list.c
index b3f4783..7780372 100644
--- a/builtin/rev-list.c
+++ b/builtin/rev-list.c
@@ -219,6 +219,7 @@ static void show_commit(struct commit *commit, void *data)
 		ctx.fmt = revs->commit_format;
 		ctx.output_encoding = get_log_output_encoding();
 		ctx.color = revs->diffopt.use_color;
+		ctx.rev = revs;
 		pretty_print_commit(&ctx, commit, &buf);
 		if (buf.len) {
 			if (revs->commit_format != CMIT_FMT_ONELINE)
@@ -545,6 +546,18 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
 	 *
 	 * Let "--missing" to conditionally set fetch_if_missing.
 	 */
+	/*
+	 * NEEDSWORK: These loops that attempt to find presence of
+	 * options without understanding that the options they are
+	 * skipping are broken (e.g., it would not know "--grep
+	 * --exclude-promisor-objects" is not triggering
+	 * "--exclude-promisor-objects" option).  We really need
+	 * setup_revisions() to have a mechanism to allow and disallow
+	 * some sets of options for different commands (like rev-list,
+	 * replay, etc). Such a mechanism should do an early parsing
+	 * of options and be able to manage the `--missing=...` and
+	 * `--exclude-promisor-objects` options below.
+	 */
 	for (i = 1; i < argc; i++) {
 		const char *arg = argv[i];
 		if (!strcmp(arg, "--exclude-promisor-objects")) {
@@ -753,8 +766,12 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
 
 	if (arg_print_omitted)
 		oidset_init(&omitted_objects, DEFAULT_OIDSET_SIZE);
-	if (arg_missing_action == MA_PRINT)
+	if (arg_missing_action == MA_PRINT) {
 		oidset_init(&missing_objects, DEFAULT_OIDSET_SIZE);
+		/* Add missing tips */
+		oidset_insert_from_set(&missing_objects, &revs.missing_commits);
+		oidset_clear(&revs.missing_commits);
+	}
 
 	traverse_commit_list_filtered(
 		&revs, show_commit, show_object, &info,
diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c
index 917f122..624182e 100644
--- a/builtin/rev-parse.c
+++ b/builtin/rev-parse.c
@@ -25,6 +25,7 @@
 #include "submodule.h"
 #include "commit-reach.h"
 #include "shallow.h"
+#include "object-file-convert.h"
 
 #define DO_REVS		1
 #define DO_NOREV	2
@@ -297,7 +298,7 @@ static int try_difference(const char *arg)
 		show_rev(NORMAL, &end_oid, end);
 		show_rev(symmetric ? NORMAL : REVERSED, &start_oid, start);
 		if (symmetric) {
-			struct commit_list *exclude;
+			struct commit_list *exclude = NULL;
 			struct commit *a, *b;
 			a = lookup_commit_reference(the_repository, &start_oid);
 			b = lookup_commit_reference(the_repository, &end_oid);
@@ -305,7 +306,8 @@ static int try_difference(const char *arg)
 				*dotdot = '.';
 				return 0;
 			}
-			exclude = repo_get_merge_bases(the_repository, a, b);
+			if (repo_get_merge_bases(the_repository, a, b, &exclude) < 0)
+				exit(128);
 			while (exclude) {
 				struct commit *commit = pop_commit(&exclude);
 				show_rev(REVERSED, &commit->object.oid, NULL);
@@ -675,6 +677,8 @@ static void print_path(const char *path, const char *prefix, enum format_type fo
 int cmd_rev_parse(int argc, const char **argv, const char *prefix)
 {
 	int i, as_is = 0, verify = 0, quiet = 0, revs_count = 0, type = 0;
+	const struct git_hash_algo *output_algo = NULL;
+	const struct git_hash_algo *compat = NULL;
 	int did_repo_setup = 0;
 	int has_dashdash = 0;
 	int output_prefix = 0;
@@ -746,6 +750,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
 
 			prepare_repo_settings(the_repository);
 			the_repository->settings.command_requires_full_index = 0;
+			compat = the_repository->compat_hash_algo;
 		}
 
 		if (!strcmp(arg, "--")) {
@@ -833,6 +838,22 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
 				flags |= GET_OID_QUIETLY;
 				continue;
 			}
+			if (opt_with_value(arg, "--output-object-format", &arg)) {
+				if (!arg)
+					die(_("no object format specified"));
+				if (!strcmp(arg, the_hash_algo->name) ||
+				    !strcmp(arg, "storage")) {
+					flags |= GET_OID_HASH_ANY;
+					output_algo = the_hash_algo;
+					continue;
+				}
+				else if (compat && !strcmp(arg, compat->name)) {
+					flags |= GET_OID_HASH_ANY;
+					output_algo = compat;
+					continue;
+				}
+				else die(_("unsupported object format: %s"), arg);
+			}
 			if (opt_with_value(arg, "--short", &arg)) {
 				filter &= ~(DO_FLAGS|DO_NOREV);
 				verify = 1;
@@ -882,7 +903,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
 				continue;
 			}
 			if (skip_prefix(arg, "--disambiguate=", &arg)) {
-				repo_for_each_abbrev(the_repository, arg,
+				repo_for_each_abbrev(the_repository, arg, the_hash_algo,
 						     show_abbrev, NULL);
 				continue;
 			}
@@ -1062,6 +1083,10 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
 				puts(the_hash_algo->name);
 				continue;
 			}
+			if (!strcmp(arg, "--show-ref-format")) {
+				puts(ref_storage_format_to_name(the_repository->ref_storage_format));
+				continue;
+			}
 			if (!strcmp(arg, "--end-of-options")) {
 				seen_end_of_options = 1;
 				if (filter & (DO_FLAGS | DO_REVS))
@@ -1086,6 +1111,9 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
 		}
 		if (!get_oid_with_context(the_repository, name,
 					  flags, &oid, &unused)) {
+			if (output_algo)
+				repo_oid_to_algop(the_repository, &oid,
+						  output_algo, &oid);
 			if (verify)
 				revs_count++;
 			else
diff --git a/builtin/revert.c b/builtin/revert.c
index 89821ba..53935d2 100644
--- a/builtin/revert.c
+++ b/builtin/revert.c
@@ -43,6 +43,31 @@ static const char * const *revert_or_cherry_pick_usage(struct replay_opts *opts)
 	return opts->action == REPLAY_REVERT ? revert_usage : cherry_pick_usage;
 }
 
+enum empty_action {
+	EMPTY_COMMIT_UNSPECIFIED = -1,
+	STOP_ON_EMPTY_COMMIT,      /* output errors and stop in the middle of a cherry-pick */
+	DROP_EMPTY_COMMIT,         /* skip with a notice message */
+	KEEP_EMPTY_COMMIT,         /* keep recording as empty commits */
+};
+
+static int parse_opt_empty(const struct option *opt, const char *arg, int unset)
+{
+	int *opt_value = opt->value;
+
+	BUG_ON_OPT_NEG(unset);
+
+	if (!strcmp(arg, "stop"))
+		*opt_value = STOP_ON_EMPTY_COMMIT;
+	else if (!strcmp(arg, "drop"))
+		*opt_value = DROP_EMPTY_COMMIT;
+	else if (!strcmp(arg, "keep"))
+		*opt_value = KEEP_EMPTY_COMMIT;
+	else
+		return error(_("invalid value for '%s': '%s'"), "--empty", arg);
+
+	return 0;
+}
+
 static int option_parse_m(const struct option *opt,
 			  const char *arg, int unset)
 {
@@ -85,6 +110,7 @@ static int run_sequencer(int argc, const char **argv, const char *prefix,
 	const char * const * usage_str = revert_or_cherry_pick_usage(opts);
 	const char *me = action_name(opts);
 	const char *cleanup_arg = NULL;
+	enum empty_action empty_opt = EMPTY_COMMIT_UNSPECIFIED;
 	int cmd = 0;
 	struct option base_options[] = {
 		OPT_CMDMODE(0, "quit", &cmd, N_("end revert or cherry-pick sequence"), 'q'),
@@ -114,7 +140,10 @@ static int run_sequencer(int argc, const char **argv, const char *prefix,
 			OPT_BOOL(0, "ff", &opts->allow_ff, N_("allow fast-forward")),
 			OPT_BOOL(0, "allow-empty", &opts->allow_empty, N_("preserve initially empty commits")),
 			OPT_BOOL(0, "allow-empty-message", &opts->allow_empty_message, N_("allow commits with empty messages")),
-			OPT_BOOL(0, "keep-redundant-commits", &opts->keep_redundant_commits, N_("keep redundant, empty commits")),
+			OPT_BOOL(0, "keep-redundant-commits", &opts->keep_redundant_commits, N_("deprecated: use --empty=keep instead")),
+			OPT_CALLBACK_F(0, "empty", &empty_opt, "(stop|drop|keep)",
+				       N_("how to handle commits that become empty"),
+				       PARSE_OPT_NONEG, parse_opt_empty),
 			OPT_END(),
 		};
 		options = parse_options_concat(options, cp_extra);
@@ -134,6 +163,11 @@ static int run_sequencer(int argc, const char **argv, const char *prefix,
 	prepare_repo_settings(the_repository);
 	the_repository->settings.command_requires_full_index = 0;
 
+	if (opts->action == REPLAY_PICK) {
+		opts->drop_redundant_commits = (empty_opt == DROP_EMPTY_COMMIT);
+		opts->keep_redundant_commits = opts->keep_redundant_commits || (empty_opt == KEEP_EMPTY_COMMIT);
+	}
+
 	/* implies allow_empty */
 	if (opts->keep_redundant_commits)
 		opts->allow_empty = 1;
@@ -167,6 +201,8 @@ static int run_sequencer(int argc, const char **argv, const char *prefix,
 				"--ff", opts->allow_ff,
 				"--rerere-autoupdate", opts->allow_rerere_auto == RERERE_AUTOUPDATE,
 				"--no-rerere-autoupdate", opts->allow_rerere_auto == RERERE_NOAUTOUPDATE,
+				"--keep-redundant-commits", opts->keep_redundant_commits,
+				"--empty", empty_opt != EMPTY_COMMIT_UNSPECIFIED,
 				NULL);
 	}
 
diff --git a/builtin/send-pack.c b/builtin/send-pack.c
index b7183be..3df9eaa 100644
--- a/builtin/send-pack.c
+++ b/builtin/send-pack.c
@@ -333,6 +333,7 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix)
 	}
 
 	if (!ret && !transport_refs_pushed(remote_refs))
+		/* stable plumbing output; do not modify or localize */
 		fprintf(stderr, "Everything up-to-date\n");
 
 	return ret;
diff --git a/builtin/shortlog.c b/builtin/shortlog.c
index 1307ed2..3c7cd2d 100644
--- a/builtin/shortlog.c
+++ b/builtin/shortlog.c
@@ -245,7 +245,6 @@ void shortlog_add_commit(struct shortlog *log, struct commit *commit)
 
 	ctx.fmt = CMIT_FMT_USERFORMAT;
 	ctx.abbrev = log->abbrev;
-	ctx.print_email_subject = 1;
 	ctx.date_mode = log->date_mode;
 	ctx.output_encoding = get_log_output_encoding();
 
diff --git a/builtin/show-ref.c b/builtin/show-ref.c
index 79955c2..1c15421 100644
--- a/builtin/show-ref.c
+++ b/builtin/show-ref.c
@@ -172,7 +172,7 @@ static int cmd_show_ref__verify(const struct show_one_options *show_one_opts,
 	while (*refs) {
 		struct object_id oid;
 
-		if ((starts_with(*refs, "refs/") || !strcmp(*refs, "HEAD")) &&
+		if ((starts_with(*refs, "refs/") || refname_is_safe(*refs)) &&
 		    !read_ref(*refs, &oid)) {
 			show_one(show_one_opts, *refs, &oid);
 		}
diff --git a/builtin/sparse-checkout.c b/builtin/sparse-checkout.c
index 288a832..0f52e25 100644
--- a/builtin/sparse-checkout.c
+++ b/builtin/sparse-checkout.c
@@ -773,8 +773,7 @@ static int sparse_checkout_add(int argc, const char **argv, const char *prefix)
 
 	argc = parse_options(argc, argv, prefix,
 			     builtin_sparse_checkout_add_options,
-			     builtin_sparse_checkout_add_usage,
-			     PARSE_OPT_KEEP_UNKNOWN_OPT);
+			     builtin_sparse_checkout_add_usage, 0);
 
 	sanitize_paths(argc, argv, prefix, add_opts.skip_checks);
 
@@ -820,8 +819,7 @@ static int sparse_checkout_set(int argc, const char **argv, const char *prefix)
 
 	argc = parse_options(argc, argv, prefix,
 			     builtin_sparse_checkout_set_options,
-			     builtin_sparse_checkout_set_usage,
-			     PARSE_OPT_KEEP_UNKNOWN_OPT);
+			     builtin_sparse_checkout_set_usage, 0);
 
 	if (update_modes(&set_opts.cone_mode, &set_opts.sparse_index))
 		return 1;
@@ -992,8 +990,7 @@ static int sparse_checkout_check_rules(int argc, const char **argv, const char *
 
 	argc = parse_options(argc, argv, prefix,
 			     builtin_sparse_checkout_check_rules_options,
-			     builtin_sparse_checkout_check_rules_usage,
-			     PARSE_OPT_KEEP_UNKNOWN_OPT);
+			     builtin_sparse_checkout_check_rules_usage, 0);
 
 	if (check_rules_opts.rules_file && check_rules_opts.cone_mode < 0)
 		check_rules_opts.cone_mode = 1;
diff --git a/builtin/stash.c b/builtin/stash.c
index 7fb355b..7751bca 100644
--- a/builtin/stash.c
+++ b/builtin/stash.c
@@ -284,7 +284,7 @@ static int reset_tree(struct object_id *i_tree, int update, int reset)
 	if (parse_tree(tree))
 		return -1;
 
-	init_tree_desc(t, tree->buffer, tree->size);
+	init_tree_desc(t, &tree->object.oid, tree->buffer, tree->size);
 
 	opts.head_idx = 1;
 	opts.src_index = &the_index;
@@ -870,7 +870,8 @@ static void diff_include_untracked(const struct stash_info *info, struct diff_op
 		tree[i] = parse_tree_indirect(oid[i]);
 		if (parse_tree(tree[i]) < 0)
 			die(_("failed to parse tree"));
-		init_tree_desc(&tree_desc[i], tree[i]->buffer, tree[i]->size);
+		init_tree_desc(&tree_desc[i], &tree[i]->object.oid,
+			       tree[i]->buffer, tree[i]->size);
 	}
 
 	unpack_tree_opt.head_idx = -1;
@@ -1204,8 +1205,8 @@ static int stash_staged(struct stash_info *info, struct strbuf *out_patch,
 	}
 
 	cp_diff_tree.git_cmd = 1;
-	strvec_pushl(&cp_diff_tree.args, "diff-tree", "-p", "-U1", "HEAD",
-		     oid_to_hex(&info->w_tree), "--", NULL);
+	strvec_pushl(&cp_diff_tree.args, "diff-tree", "-p", "--binary",
+		     "-U1", "HEAD", oid_to_hex(&info->w_tree), "--", NULL);
 	if (pipe_command(&cp_diff_tree, NULL, 0, out_patch, 0, NULL, 0)) {
 		ret = -1;
 		goto done;
diff --git a/builtin/stripspace.c b/builtin/stripspace.c
index 7b700a9..e5626e5 100644
--- a/builtin/stripspace.c
+++ b/builtin/stripspace.c
@@ -13,7 +13,7 @@ static void comment_lines(struct strbuf *buf)
 	size_t len;
 
 	msg = strbuf_detach(buf, &len);
-	strbuf_add_commented_lines(buf, msg, len, comment_line_char);
+	strbuf_add_commented_lines(buf, msg, len, comment_line_str);
 	free(msg);
 }
 
@@ -59,7 +59,7 @@ int cmd_stripspace(int argc, const char **argv, const char *prefix)
 
 	if (mode == STRIP_DEFAULT || mode == STRIP_COMMENTS)
 		strbuf_stripspace(&buf,
-			  mode == STRIP_COMMENTS ? comment_line_char : '\0');
+			  mode == STRIP_COMMENTS ? comment_line_str : NULL);
 	else
 		comment_lines(&buf);
 
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index fda50f2..5a71b1e 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -303,6 +303,9 @@ static void runcommand_in_submodule_cb(const struct cache_entry *list_item,
 	struct child_process cp = CHILD_PROCESS_INIT;
 	char *displaypath;
 
+	if (validate_submodule_path(path) < 0)
+		exit(128);
+
 	displaypath = get_submodule_displaypath(path, info->prefix,
 						info->super_prefix);
 
@@ -634,6 +637,9 @@ static void status_submodule(const char *path, const struct object_id *ce_oid,
 		.free_removed_argv_elements = 1,
 	};
 
+	if (validate_submodule_path(path) < 0)
+		exit(128);
+
 	if (!submodule_from_path(the_repository, null_oid(), path))
 		die(_("no submodule mapping found in .gitmodules for path '%s'"),
 		      path);
@@ -1238,6 +1244,9 @@ static void sync_submodule(const char *path, const char *prefix,
 	if (!is_submodule_active(the_repository, path))
 		return;
 
+	if (validate_submodule_path(path) < 0)
+		exit(128);
+
 	sub = submodule_from_path(the_repository, null_oid(), path);
 
 	if (sub && sub->url) {
@@ -1283,7 +1292,7 @@ static void sync_submodule(const char *path, const char *prefix,
 	submodule_to_gitdir(&sb, path);
 	strbuf_addstr(&sb, "/config");
 
-	if (git_config_set_in_file_gently(sb.buf, remote_key, sub_origin_url))
+	if (git_config_set_in_file_gently(sb.buf, remote_key, NULL, sub_origin_url))
 		die(_("failed to update remote for submodule '%s'"),
 		      path);
 
@@ -1381,6 +1390,9 @@ static void deinit_submodule(const char *path, const char *prefix,
 	struct strbuf sb_config = STRBUF_INIT;
 	char *sub_git_dir = xstrfmt("%s/.git", path);
 
+	if (validate_submodule_path(path) < 0)
+		exit(128);
+
 	sub = submodule_from_path(the_repository, null_oid(), path);
 
 	if (!sub || !sub->name)
@@ -1662,16 +1674,42 @@ static char *clone_submodule_sm_gitdir(const char *name)
 	return sm_gitdir;
 }
 
+static int dir_contains_only_dotgit(const char *path)
+{
+	DIR *dir = opendir(path);
+	struct dirent *e;
+	int ret = 1;
+
+	if (!dir)
+		return 0;
+
+	e = readdir_skip_dot_and_dotdot(dir);
+	if (!e)
+		ret = 0;
+	else if (strcmp(DEFAULT_GIT_DIR_ENVIRONMENT, e->d_name) ||
+		 (e = readdir_skip_dot_and_dotdot(dir))) {
+		error("unexpected item '%s' in '%s'", e->d_name, path);
+		ret = 0;
+	}
+
+	closedir(dir);
+	return ret;
+}
+
 static int clone_submodule(const struct module_clone_data *clone_data,
 			   struct string_list *reference)
 {
 	char *p;
 	char *sm_gitdir = clone_submodule_sm_gitdir(clone_data->name);
 	char *sm_alternate = NULL, *error_strategy = NULL;
+	struct stat st;
 	struct child_process cp = CHILD_PROCESS_INIT;
 	const char *clone_data_path = clone_data->path;
 	char *to_free = NULL;
 
+	if (validate_submodule_path(clone_data_path) < 0)
+		exit(128);
+
 	if (!is_absolute_path(clone_data->path))
 		clone_data_path = to_free = xstrfmt("%s/%s", get_git_work_tree(),
 						    clone_data->path);
@@ -1681,6 +1719,10 @@ static int clone_submodule(const struct module_clone_data *clone_data,
 		      "git dir"), sm_gitdir);
 
 	if (!file_exists(sm_gitdir)) {
+		if (clone_data->require_init && !stat(clone_data_path, &st) &&
+		    !is_empty_dir(clone_data_path))
+			die(_("directory not empty: '%s'"), clone_data_path);
+
 		if (safe_create_leading_directories_const(sm_gitdir) < 0)
 			die(_("could not create directory '%s'"), sm_gitdir);
 
@@ -1725,10 +1767,18 @@ static int clone_submodule(const struct module_clone_data *clone_data,
 		if(run_command(&cp))
 			die(_("clone of '%s' into submodule path '%s' failed"),
 			    clone_data->url, clone_data_path);
+
+		if (clone_data->require_init && !stat(clone_data_path, &st) &&
+		    !dir_contains_only_dotgit(clone_data_path)) {
+			char *dot_git = xstrfmt("%s/.git", clone_data_path);
+			unlink(dot_git);
+			free(dot_git);
+			die(_("directory not empty: '%s'"), clone_data_path);
+		}
 	} else {
 		char *path;
 
-		if (clone_data->require_init && !access(clone_data_path, X_OK) &&
+		if (clone_data->require_init && !stat(clone_data_path, &st) &&
 		    !is_empty_dir(clone_data_path))
 			die(_("directory not empty: '%s'"), clone_data_path);
 		if (safe_create_leading_directories_const(clone_data_path) < 0)
@@ -1738,6 +1788,23 @@ static int clone_submodule(const struct module_clone_data *clone_data,
 		free(path);
 	}
 
+	/*
+	 * We already performed this check at the beginning of this function,
+	 * before cloning the objects. This tries to detect racy behavior e.g.
+	 * in parallel clones, where another process could easily have made the
+	 * gitdir nested _after_ it was created.
+	 *
+	 * To prevent further harm coming from this unintentionally-nested
+	 * gitdir, let's disable it by deleting the `HEAD` file.
+	 */
+	if (validate_submodule_git_dir(sm_gitdir, clone_data->name) < 0) {
+		char *head = xstrfmt("%s/HEAD", sm_gitdir);
+		unlink(head);
+		free(head);
+		die(_("refusing to create/use '%s' in another submodule's "
+		      "git dir"), sm_gitdir);
+	}
+
 	connect_work_tree_and_git_dir(clone_data_path, sm_gitdir, 0);
 
 	p = git_pathdup_submodule(clone_data_path, "config");
@@ -2517,6 +2584,9 @@ static int update_submodule(struct update_data *update_data)
 {
 	int ret;
 
+	if (validate_submodule_path(update_data->sm_path) < 0)
+		return -1;
+
 	ret = determine_submodule_update_strategy(the_repository,
 						  update_data->just_cloned,
 						  update_data->sm_path,
@@ -2624,12 +2694,21 @@ static int update_submodules(struct update_data *update_data)
 
 	for (i = 0; i < suc.update_clone_nr; i++) {
 		struct update_clone_data ucd = suc.update_clone[i];
-		int code;
+		int code = 128;
 
 		oidcpy(&update_data->oid, &ucd.oid);
 		update_data->just_cloned = ucd.just_cloned;
 		update_data->sm_path = ucd.sub->path;
 
+		/*
+		 * Verify that the submodule path does not contain any
+		 * symlinks; if it does, it might have been tampered with.
+		 * TODO: allow exempting it via
+		 * `safe.submodule.path` or something
+		 */
+		if (validate_submodule_path(update_data->sm_path) < 0)
+			goto fail;
+
 		code = ensure_core_worktree(update_data->sm_path);
 		if (code)
 			goto fail;
@@ -3356,6 +3435,9 @@ static int module_add(int argc, const char **argv, const char *prefix)
 	normalize_path_copy(add_data.sm_path, add_data.sm_path);
 	strip_dir_trailing_slashes(add_data.sm_path);
 
+	if (validate_submodule_path(add_data.sm_path) < 0)
+		exit(128);
+
 	die_on_index_match(add_data.sm_path, force);
 	die_on_repo_without_commits(add_data.sm_path);
 
diff --git a/builtin/tag.c b/builtin/tag.c
index 79ca53c..9a33cb5 100644
--- a/builtin/tag.c
+++ b/builtin/tag.c
@@ -27,6 +27,7 @@
 #include "ref-filter.h"
 #include "date.h"
 #include "write-or-die.h"
+#include "object-file-convert.h"
 
 static const char * const git_tag_usage[] = {
 	N_("git tag [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <file>] [-e]\n"
@@ -43,18 +44,11 @@ static const char * const git_tag_usage[] = {
 static unsigned int colopts;
 static int force_sign_annotate;
 static int config_sign_tag = -1; /* unspecified */
-static int omit_empty = 0;
 
 static int list_tags(struct ref_filter *filter, struct ref_sorting *sorting,
 		     struct ref_format *format)
 {
-	struct ref_array array;
-	struct strbuf output = STRBUF_INIT;
-	struct strbuf err = STRBUF_INIT;
 	char *to_free = NULL;
-	int i;
-
-	memset(&array, 0, sizeof(array));
 
 	if (filter->lines == -1)
 		filter->lines = 0;
@@ -72,23 +66,8 @@ static int list_tags(struct ref_filter *filter, struct ref_sorting *sorting,
 	if (verify_ref_format(format))
 		die(_("unable to parse format string"));
 	filter->with_commit_tag_algo = 1;
-	filter_refs(&array, filter, FILTER_REFS_TAGS);
-	filter_ahead_behind(the_repository, format, &array);
-	ref_array_sort(sorting, &array);
+	filter_and_format_refs(filter, FILTER_REFS_TAGS, sorting, format);
 
-	for (i = 0; i < array.nr; i++) {
-		strbuf_reset(&output);
-		strbuf_reset(&err);
-		if (format_ref_array_item(array.items[i], format, &output, &err))
-			die("%s", err.buf);
-		fwrite(output.buf, 1, output.len, stdout);
-		if (output.len || !omit_empty)
-			putchar('\n');
-	}
-
-	strbuf_release(&err);
-	strbuf_release(&output);
-	ref_array_clear(&array);
 	free(to_free);
 
 	return 0;
@@ -173,18 +152,52 @@ static int verify_tag(const char *name, const char *ref UNUSED,
 	return 0;
 }
 
-static int do_sign(struct strbuf *buffer)
+static int do_sign(struct strbuf *buffer, struct object_id **compat_oid,
+		   struct object_id *compat_oid_buf)
 {
-	return sign_buffer(buffer, buffer, get_signing_key()) ? -1 : 0;
+	const struct git_hash_algo *compat = the_repository->compat_hash_algo;
+	struct strbuf sig = STRBUF_INIT, compat_sig = STRBUF_INIT;
+	struct strbuf compat_buf = STRBUF_INIT;
+	const char *keyid = get_signing_key();
+	int ret = -1;
+
+	if (sign_buffer(buffer, &sig, keyid))
+		return -1;
+
+	if (compat) {
+		const struct git_hash_algo *algo = the_repository->hash_algo;
+
+		if (convert_object_file(&compat_buf, algo, compat,
+					buffer->buf, buffer->len, OBJ_TAG, 1))
+			goto out;
+		if (sign_buffer(&compat_buf, &compat_sig, keyid))
+			goto out;
+		add_header_signature(&compat_buf, &sig, algo);
+		strbuf_addbuf(&compat_buf, &compat_sig);
+		hash_object_file(compat, compat_buf.buf, compat_buf.len,
+				 OBJ_TAG, compat_oid_buf);
+		*compat_oid = compat_oid_buf;
+	}
+
+	if (compat_sig.len)
+		add_header_signature(buffer, &compat_sig, compat);
+
+	strbuf_addbuf(buffer, &sig);
+	ret = 0;
+out:
+	strbuf_release(&sig);
+	strbuf_release(&compat_sig);
+	strbuf_release(&compat_buf);
+	return ret;
 }
 
 static const char tag_template[] =
 	N_("\nWrite a message for tag:\n  %s\n"
-	"Lines starting with '%c' will be ignored.\n");
+	"Lines starting with '%s' will be ignored.\n");
 
 static const char tag_template_nocleanup[] =
 	N_("\nWrite a message for tag:\n  %s\n"
-	"Lines starting with '%c' will be kept; you may remove them"
+	"Lines starting with '%s' will be kept; you may remove them"
 	" yourself if you want to.\n");
 
 static int git_tag_config(const char *var, const char *value,
@@ -248,9 +261,11 @@ static void write_tag_body(int fd, const struct object_id *oid)
 
 static int build_tag_object(struct strbuf *buf, int sign, struct object_id *result)
 {
-	if (sign && do_sign(buf) < 0)
+	struct object_id *compat_oid = NULL, compat_oid_buf;
+	if (sign && do_sign(buf, &compat_oid, &compat_oid_buf) < 0)
 		return error(_("unable to sign the tag"));
-	if (write_object_file(buf->buf, buf->len, OBJ_TAG, result) < 0)
+	if (write_object_file_flags(buf->buf, buf->len, OBJ_TAG, result,
+				    compat_oid, 0) < 0)
 		return error(_("unable to write tag file"));
 	return 0;
 }
@@ -313,11 +328,11 @@ static void create_tag(const struct object_id *object, const char *object_ref,
 			struct strbuf buf = STRBUF_INIT;
 			strbuf_addch(&buf, '\n');
 			if (opt->cleanup_mode == CLEANUP_ALL)
-				strbuf_commented_addf(&buf, comment_line_char,
-				      _(tag_template), tag, comment_line_char);
+				strbuf_commented_addf(&buf, comment_line_str,
+				      _(tag_template), tag, comment_line_str);
 			else
-				strbuf_commented_addf(&buf, comment_line_char,
-				      _(tag_template_nocleanup), tag, comment_line_char);
+				strbuf_commented_addf(&buf, comment_line_str,
+				      _(tag_template_nocleanup), tag, comment_line_str);
 			write_or_die(fd, buf.buf, buf.len);
 			strbuf_release(&buf);
 		}
@@ -332,7 +347,7 @@ static void create_tag(const struct object_id *object, const char *object_ref,
 
 	if (opt->cleanup_mode != CLEANUP_NONE)
 		strbuf_stripspace(buf,
-		  opt->cleanup_mode == CLEANUP_ALL ? comment_line_char : '\0');
+		  opt->cleanup_mode == CLEANUP_ALL ? comment_line_str : NULL);
 
 	if (!opt->message_given && !buf->len)
 		die(_("no tag message?"));
@@ -480,7 +495,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
 		OPT_WITHOUT(&filter.no_commit, N_("print only tags that don't contain the commit")),
 		OPT_MERGED(&filter, N_("print only tags that are merged")),
 		OPT_NO_MERGED(&filter, N_("print only tags that are not merged")),
-		OPT_BOOL(0, "omit-empty",  &omit_empty,
+		OPT_BOOL(0, "omit-empty",  &format.array_opts.omit_empty,
 			N_("do not output a newline after empty formatted refs")),
 		OPT_REF_SORT(&sorting_options),
 		{
@@ -500,7 +515,13 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
 
 	setup_ref_filter_porcelain_msg();
 
+	/*
+	 * Try to set sort keys from config. If config does not set any,
+	 * fall back on default (refname) sorting.
+	 */
 	git_config(git_tag_config, &sorting_options);
+	if (!sorting_options.nr)
+		string_list_append(&sorting_options, "refname");
 
 	memset(&opt, 0, sizeof(opt));
 	filter.lines = -1;
@@ -546,7 +567,8 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
 			struct column_options copts;
 			memset(&copts, 0, sizeof(copts));
 			copts.padding = 2;
-			run_column_filter(colopts, &copts);
+			if (run_column_filter(colopts, &copts))
+				die(_("could not start 'git column'"));
 		}
 		filter.name_patterns = argv;
 		ret = list_tags(&filter, sorting, &format);
diff --git a/builtin/unpack-objects.c b/builtin/unpack-objects.c
index e0a701f..f1c85a0 100644
--- a/builtin/unpack-objects.c
+++ b/builtin/unpack-objects.c
@@ -679,13 +679,7 @@ int cmd_unpack_objects(int argc, const char **argv, const char *prefix UNUSED)
 	use(the_hash_algo->rawsz);
 
 	/* Write the last part of the buffer to stdout */
-	while (len) {
-		int ret = xwrite(1, buffer + offset, len);
-		if (ret <= 0)
-			break;
-		len -= ret;
-		offset += ret;
-	}
+	write_in_full(1, buffer + offset, len);
 
 	/* All done */
 	return has_errors;
diff --git a/builtin/update-ref.c b/builtin/update-ref.c
index 61338a0..e46afbc 100644
--- a/builtin/update-ref.c
+++ b/builtin/update-ref.c
@@ -9,8 +9,8 @@
 #include "repository.h"
 
 static const char * const git_update_ref_usage[] = {
-	N_("git update-ref [<options>] -d <refname> [<old-val>]"),
-	N_("git update-ref [<options>]    <refname> <new-val> [<old-val>]"),
+	N_("git update-ref [<options>] -d <refname> [<old-oid>]"),
+	N_("git update-ref [<options>]    <refname> <new-oid> [<old-oid>]"),
 	N_("git update-ref [<options>] --stdin [-z]"),
 	NULL
 };
@@ -77,14 +77,14 @@ static char *parse_refname(const char **next)
 }
 
 /*
- * The value being parsed is <oldvalue> (as opposed to <newvalue>; the
+ * The value being parsed is <old-oid> (as opposed to <new-oid>; 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.
+ * <new-oid> in binary mode to be equivalent to specifying zeros.
  */
 #define PARSE_SHA1_ALLOW_EMPTY 0x02
 
@@ -140,7 +140,7 @@ static int parse_next_oid(const char **next, const char *end,
 				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",
+			warning("%s %s: missing <new-oid>, treating as zero",
 				command, refname);
 			oidclr(oid);
 		} else {
@@ -158,14 +158,14 @@ static int parse_next_oid(const char **next, const char *end,
 
  invalid:
 	die(flags & PARSE_SHA1_OLD ?
-	    "%s %s: invalid <oldvalue>: %s" :
-	    "%s %s: invalid <newvalue>: %s",
+	    "%s %s: invalid <old-oid>: %s" :
+	    "%s %s: invalid <new-oid>: %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>",
+	    "%s %s: unexpected end of input when reading <old-oid>" :
+	    "%s %s: unexpected end of input when reading <new-oid>",
 	    command, refname);
 }
 
@@ -194,7 +194,7 @@ static void parse_cmd_update(struct ref_transaction *transaction,
 
 	if (parse_next_oid(&next, end, &new_oid, "update", refname,
 			   PARSE_SHA1_ALLOW_EMPTY))
-		die("update %s: missing <newvalue>", refname);
+		die("update %s: missing <new-oid>", refname);
 
 	have_old = !parse_next_oid(&next, end, &old_oid, "update", refname,
 				   PARSE_SHA1_OLD);
@@ -225,10 +225,10 @@ static void parse_cmd_create(struct ref_transaction *transaction,
 		die("create: missing <ref>");
 
 	if (parse_next_oid(&next, end, &new_oid, "create", refname, 0))
-		die("create %s: missing <newvalue>", refname);
+		die("create %s: missing <new-oid>", refname);
 
 	if (is_null_oid(&new_oid))
-		die("create %s: zero <newvalue>", refname);
+		die("create %s: zero <new-oid>", refname);
 
 	if (*next != line_termination)
 		die("create %s: extra input: %s", refname, next);
@@ -260,7 +260,7 @@ static void parse_cmd_delete(struct ref_transaction *transaction,
 		have_old = 0;
 	} else {
 		if (is_null_oid(&old_oid))
-			die("delete %s: zero <oldvalue>", refname);
+			die("delete %s: zero <old-oid>", refname);
 		have_old = 1;
 	}
 
diff --git a/builtin/upload-pack.c b/builtin/upload-pack.c
index 9b021ef..46d9327 100644
--- a/builtin/upload-pack.c
+++ b/builtin/upload-pack.c
@@ -8,6 +8,8 @@
 #include "replace-object.h"
 #include "upload-pack.h"
 #include "serve.h"
+#include "commit.h"
+#include "environment.h"
 
 static const char * const upload_pack_usage[] = {
 	N_("git-upload-pack [--[no-]strict] [--timeout=<n>] [--stateless-rpc]\n"
@@ -37,6 +39,8 @@ int cmd_upload_pack(int argc, const char **argv, const char *prefix)
 
 	packet_trace_identity("upload-pack");
 	disable_replace_refs();
+	save_commit_buffer = 0;
+	xsetenv(NO_LAZY_FETCH_ENVIRONMENT, "1", 0);
 
 	argc = parse_options(argc, argv, prefix, options, upload_pack_usage, 0);
 
diff --git a/builtin/var.c b/builtin/var.c
index 8cf7dd9..cf55672 100644
--- a/builtin/var.c
+++ b/builtin/var.c
@@ -90,7 +90,7 @@ static char *git_config_val_global(int ident_flag UNUSED)
 	char *user, *xdg;
 	size_t unused;
 
-	git_global_config(&user, &xdg);
+	git_global_config_paths(&user, &xdg);
 	if (xdg && *xdg) {
 		normalize_path_copy(xdg, xdg);
 		strbuf_addf(&buf, "%s\n", xdg);
diff --git a/builtin/worktree.c b/builtin/worktree.c
index e1033c2..7c6c725 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -365,12 +365,12 @@ static void copy_filtered_worktree_config(const char *worktree_git_dir)
 		if (!git_configset_get_bool(&cs, "core.bare", &bare) &&
 			bare &&
 			git_config_set_multivar_in_file_gently(
-				to_file, "core.bare", NULL, "true", 0))
+				to_file, "core.bare", NULL, "true", NULL, 0))
 			error(_("failed to unset '%s' in '%s'"),
 				"core.bare", to_file);
 		if (!git_configset_get(&cs, "core.worktree") &&
 			git_config_set_in_file_gently(to_file,
-							"core.worktree", NULL))
+							"core.worktree", NULL, NULL))
 			error(_("failed to unset '%s' in '%s'"),
 				"core.worktree", to_file);
 
@@ -416,7 +416,6 @@ static int add_worktree(const char *path, const char *refname,
 	struct strbuf sb_git = STRBUF_INIT, sb_repo = STRBUF_INIT;
 	struct strbuf sb = STRBUF_INIT, realpath = STRBUF_INIT;
 	const char *name;
-	struct child_process cp = CHILD_PROCESS_INIT;
 	struct strvec child_env = STRVEC_INIT;
 	unsigned int counter = 0;
 	int len, ret;
@@ -424,7 +423,8 @@ static int add_worktree(const char *path, const char *refname,
 	struct commit *commit = NULL;
 	int is_branch = 0;
 	struct strbuf sb_name = STRBUF_INIT;
-	struct worktree **worktrees;
+	struct worktree **worktrees, *wt = NULL;
+	struct ref_store *wt_refs;
 
 	worktrees = get_worktrees();
 	check_candidate_path(path, opts->force, worktrees, "add");
@@ -495,21 +495,33 @@ static int add_worktree(const char *path, const char *refname,
 	strbuf_realpath(&realpath, get_git_common_dir(), 1);
 	write_file(sb_git.buf, "gitdir: %s/worktrees/%s",
 		   realpath.buf, name);
-	/*
-	 * This is to keep resolve_ref() happy. We need a valid HEAD
-	 * or is_git_directory() will reject the directory. Any value which
-	 * looks like an object ID will do since it will be immediately
-	 * replaced by the symbolic-ref or update-ref invocation in the new
-	 * worktree.
-	 */
-	strbuf_reset(&sb);
-	strbuf_addf(&sb, "%s/HEAD", sb_repo.buf);
-	write_file(sb.buf, "%s", oid_to_hex(null_oid()));
 	strbuf_reset(&sb);
 	strbuf_addf(&sb, "%s/commondir", sb_repo.buf);
 	write_file(sb.buf, "../..");
 
 	/*
+	 * Set up the ref store of the worktree and create the HEAD reference.
+	 */
+	wt = get_linked_worktree(name, 1);
+	if (!wt) {
+		ret = error(_("could not find created worktree '%s'"), name);
+		goto done;
+	}
+	wt_refs = get_worktree_ref_store(wt);
+
+	ret = refs_init_db(wt_refs, REFS_INIT_DB_IS_WORKTREE, &sb);
+	if (ret)
+		goto done;
+
+	if (!is_branch && commit)
+		ret = refs_update_ref(wt_refs, NULL, "HEAD", &commit->object.oid,
+				      NULL, 0, UPDATE_REFS_MSG_ON_ERR);
+	else
+		ret = refs_create_symref(wt_refs, "HEAD", symref.buf, NULL);
+	if (ret)
+		goto done;
+
+	/*
 	 * If the current worktree has sparse-checkout enabled, then copy
 	 * the sparse-checkout patterns from the current worktree.
 	 */
@@ -526,22 +538,6 @@ static int add_worktree(const char *path, const char *refname,
 
 	strvec_pushf(&child_env, "%s=%s", GIT_DIR_ENVIRONMENT, sb_git.buf);
 	strvec_pushf(&child_env, "%s=%s", GIT_WORK_TREE_ENVIRONMENT, path);
-	cp.git_cmd = 1;
-
-	if (!is_branch && commit) {
-		strvec_pushl(&cp.args, "update-ref", "HEAD",
-			     oid_to_hex(&commit->object.oid), NULL);
-	} else {
-		strvec_pushl(&cp.args, "symbolic-ref", "HEAD",
-			     symref.buf, NULL);
-		if (opts->quiet)
-			strvec_push(&cp.args, "--quiet");
-	}
-
-	strvec_pushv(&cp.env, child_env.v);
-	ret = run_command(&cp);
-	if (ret)
-		goto done;
 
 	if (opts->orphan &&
 	    (ret = make_worktree_orphan(refname, opts, &child_env)))
@@ -587,6 +583,7 @@ static int add_worktree(const char *path, const char *refname,
 	strbuf_release(&sb_git);
 	strbuf_release(&sb_name);
 	strbuf_release(&realpath);
+	free_worktree(wt);
 	return ret;
 }
 
@@ -660,7 +657,7 @@ static int can_use_local_refs(const struct add_opts *opts)
 			strbuf_add_real_path(&path, get_worktree_git_dir(NULL));
 			strbuf_addstr(&path, "/HEAD");
 			strbuf_read_file(&contents, path.buf, 64);
-			strbuf_stripspace(&contents, 0);
+			strbuf_stripspace(&contents, NULL);
 			strbuf_strip_suffix(&contents, "\n");
 
 			warning(_("HEAD points to an invalid (or orphaned) reference.\n"
diff --git a/cache-tree.c b/cache-tree.c
index 64678fe..387c0a3 100644
--- a/cache-tree.c
+++ b/cache-tree.c
@@ -447,7 +447,7 @@ static int update_one(struct cache_tree *it,
 		hash_object_file(the_hash_algo, buffer.buf, buffer.len,
 				 OBJ_TREE, &it->oid);
 	} else if (write_object_file_flags(buffer.buf, buffer.len, OBJ_TREE,
-					   &it->oid, flags & WRITE_TREE_SILENT
+					   &it->oid, NULL, flags & WRITE_TREE_SILENT
 					   ? HASH_SILENT : 0)) {
 		strbuf_release(&buffer);
 		return -1;
@@ -769,7 +769,7 @@ static void prime_cache_tree_rec(struct repository *r,
 
 	oidcpy(&it->oid, &tree->object.oid);
 
-	init_tree_desc(&desc, tree->buffer, tree->size);
+	init_tree_desc(&desc, &tree->object.oid, tree->buffer, tree->size);
 	cnt = 0;
 	while (tree_entry(&desc, &entry)) {
 		if (!S_ISDIR(entry.mode))
@@ -778,8 +778,8 @@ static void prime_cache_tree_rec(struct repository *r,
 			struct cache_tree_sub *sub;
 			struct tree *subtree = lookup_tree(r, &entry.oid);
 
-			if (!subtree->object.parsed)
-				parse_tree(subtree);
+			if (parse_tree(subtree) < 0)
+				exit(128);
 			sub = cache_tree_sub(it, entry.path);
 			sub->cache_tree = cache_tree();
 
diff --git a/ci/install-dependencies.sh b/ci/install-dependencies.sh
index 4f40753..fa0c00c 100755
--- a/ci/install-dependencies.sh
+++ b/ci/install-dependencies.sh
@@ -34,18 +34,14 @@
 	export HOMEBREW_NO_AUTO_UPDATE=1 HOMEBREW_NO_INSTALL_CLEANUP=1
 	# Uncomment this if you want to run perf tests:
 	# brew install gnu-time
-	test -z "$BREW_INSTALL_PACKAGES" ||
-	brew install $BREW_INSTALL_PACKAGES
 	brew link --force gettext
-	mkdir -p $HOME/bin
-	(
-		cd $HOME/bin
+
+	mkdir -p "$P4_PATH"
+	pushd "$P4_PATH"
 		wget -q "$P4WHENCE/bin.macosx1015x86_64/helix-core-server.tgz" &&
 		tar -xf helix-core-server.tgz &&
 		sudo xattr -d com.apple.quarantine p4 p4d 2>/dev/null || true
-	)
-	PATH="$PATH:${HOME}/bin"
-	export PATH
+	popd
 
 	if test -n "$CC_PACKAGE"
 	then
diff --git a/ci/install-docker-dependencies.sh b/ci/install-docker-dependencies.sh
index 48c43f0..eb2c9e1 100755
--- a/ci/install-docker-dependencies.sh
+++ b/ci/install-docker-dependencies.sh
@@ -21,7 +21,7 @@
 		apache2 apache2-http2 apache2-proxy apache2-ssl apache2-webdav apr-util-dbd_sqlite3 \
 		bash cvs gnupg perl-cgi perl-dbd-sqlite >/dev/null
 	;;
-linux-*)
+linux-*|StaticAnalysis)
 	# Required so that apt doesn't wait for user input on certain packages.
 	export DEBIAN_FRONTEND=noninteractive
 
@@ -31,6 +31,11 @@
 		perl-modules liberror-perl libauthen-sasl-perl libemail-valid-perl \
 		libdbd-sqlite3-perl libio-socket-ssl-perl libnet-smtp-ssl-perl ${CC_PACKAGE:-${CC:-gcc}} \
 		apache2 cvs cvsps gnupg libcgi-pm-perl subversion
+
+	if test "$jobname" = StaticAnalysis
+	then
+		apt install -q -y coccinelle
+	fi
 	;;
 pedantic)
 	dnf -yq update >/dev/null &&
diff --git a/ci/lib.sh b/ci/lib.sh
index c749b21..3856c00 100755
--- a/ci/lib.sh
+++ b/ci/lib.sh
@@ -252,7 +252,14 @@
 	CI_COMMIT="$CI_COMMIT_SHA"
 	case "$CI_JOB_IMAGE" in
 	macos-*)
-		CI_OS_NAME=osx;;
+		# GitLab CI has Python installed via multiple package managers,
+		# most notably via asdf and Homebrew. Ensure that our builds
+		# pick up the Homebrew one by prepending it to our PATH as the
+		# asdf one breaks tests.
+		export PATH="$(brew --prefix)/bin:$PATH"
+
+		CI_OS_NAME=osx
+		;;
 	alpine:*|fedora:*|ubuntu:*)
 		CI_OS_NAME=linux;;
 	*)
@@ -318,9 +325,13 @@
 		break
 	fi
 
-	PYTHON_PACKAGE=python2
-	if test "$jobname" = linux-gcc
+	# Python 2 is end of life, and Ubuntu 23.04 and newer don't actually
+	# have it anymore. We thus only test with Python 2 on older LTS
+	# releases.
+	if "$distro" = "ubuntu-20.04"
 	then
+		PYTHON_PACKAGE=python2
+	else
 		PYTHON_PACKAGE=python3
 	fi
 	MAKEFLAGS="$MAKEFLAGS PYTHON_PATH=/usr/bin/$PYTHON_PACKAGE"
@@ -344,6 +355,9 @@
 	then
 		MAKEFLAGS="$MAKEFLAGS APPLE_COMMON_CRYPTO_SHA1=Yes"
 	fi
+
+	P4_PATH="$HOME/custom/p4"
+	export PATH="$P4_PATH:$PATH"
 	;;
 esac
 
@@ -357,7 +371,7 @@
 	MAKEFLAGS="$MAKEFLAGS NO_REGEX=Yes ICONV_OMITS_BOM=Yes"
 	MAKEFLAGS="$MAKEFLAGS GIT_TEST_UTF8_LOCALE=C.UTF-8"
 	;;
-linux-leaks)
+linux-leaks|linux-reftable-leaks)
 	export SANITIZE=leak
 	export GIT_TEST_PASSING_SANITIZE_LEAK=true
 	export GIT_TEST_SANITIZE_LEAK_LOG=true
diff --git a/ci/print-test-failures.sh b/ci/print-test-failures.sh
index c33ad4e..b1f80ae 100755
--- a/ci/print-test-failures.sh
+++ b/ci/print-test-failures.sh
@@ -8,7 +8,7 @@
 # Tracing executed commands would produce too much noise in the loop below.
 set +x
 
-cd t/
+cd "${TEST_OUTPUT_DIRECTORY:-t/}"
 
 if ! ls test-results/*.exit >/dev/null 2>/dev/null
 then
diff --git a/ci/run-build-and-minimal-fuzzers.sh b/ci/run-build-and-minimal-fuzzers.sh
new file mode 100755
index 0000000..a51076d
--- /dev/null
+++ b/ci/run-build-and-minimal-fuzzers.sh
@@ -0,0 +1,19 @@
+#!/bin/sh
+#
+# Build and test Git's fuzzers
+#
+
+. ${0%/*}/lib.sh
+
+group "Build fuzzers" make \
+	CC=clang \
+	CXX=clang++ \
+	CFLAGS="-fsanitize=fuzzer-no-link,address" \
+	LIB_FUZZING_ENGINE="-fsanitize=fuzzer,address" \
+	fuzz-all
+
+for fuzzer in commit-graph config date pack-headers pack-idx ; do
+	begin_group "fuzz-$fuzzer"
+	./oss-fuzz/fuzz-$fuzzer -verbosity=0 -runs=1 || exit 1
+	end_group "fuzz-$fuzzer"
+done
diff --git a/ci/run-build-and-tests.sh b/ci/run-build-and-tests.sh
index 2528f25..c192bd6 100755
--- a/ci/run-build-and-tests.sh
+++ b/ci/run-build-and-tests.sh
@@ -37,6 +37,9 @@
 linux-sha256)
 	export GIT_TEST_DEFAULT_HASH=sha256
 	;;
+linux-reftable|linux-reftable-leaks|osx-reftable)
+	export GIT_TEST_DEFAULT_REF_FORMAT=reftable
+	;;
 pedantic)
 	# Don't run the tests; we only care about whether Git can be
 	# built.
@@ -50,6 +53,8 @@
 then
 	group "Run tests" make test ||
 	handle_failed_tests
+	group "Run unit tests" \
+		make DEFAULT_UNIT_TEST_TARGET=unit-tests-prove unit-tests
 fi
 check_unignored_build_artifacts
 
diff --git a/ci/run-test-slice.sh b/ci/run-test-slice.sh
index a3c6795..ae80943 100755
--- a/ci/run-test-slice.sh
+++ b/ci/run-test-slice.sh
@@ -15,4 +15,9 @@
 	tr '\n' ' ')" ||
 handle_failed_tests
 
+# We only have one unit test at the moment, so run it in the first slice
+if [ "$1" == "0" ] ; then
+	group "Run unit tests" make --quiet -C t unit-tests-prove
+fi
+
 check_unignored_build_artifacts
diff --git a/column.c b/column.c
index ff2f0ab..50bbccc 100644
--- a/column.c
+++ b/column.c
@@ -182,6 +182,8 @@ void print_columns(const struct string_list *list, unsigned int colopts,
 {
 	struct column_options nopts;
 
+	if (opts && (0 > opts->padding))
+		BUG("padding must be non-negative");
 	if (!list->nr)
 		return;
 	assert((colopts & COL_ENABLE_MASK) != COL_AUTO);
@@ -361,6 +363,8 @@ int run_column_filter(int colopts, const struct column_options *opts)
 {
 	struct strvec *argv;
 
+	if (opts && (0 > opts->padding))
+		BUG("padding must be non-negative");
 	if (fd_out != -1)
 		return -1;
 
diff --git a/combine-diff.c b/combine-diff.c
index db94581..d6d6fa1 100644
--- a/combine-diff.c
+++ b/combine-diff.c
@@ -337,6 +337,8 @@ static char *grab_blob(struct repository *r,
 		free_filespec(df);
 	} else {
 		blob = repo_read_object_file(r, oid, &type, size);
+		if (!blob)
+			die(_("unable to read %s"), oid_to_hex(oid));
 		if (type != OBJ_BLOB)
 			die("object '%s' is not a blob!", oid_to_hex(oid));
 	}
diff --git a/command-list.txt b/command-list.txt
index 54b2a50..c4cd0f3 100644
--- a/command-list.txt
+++ b/command-list.txt
@@ -160,6 +160,7 @@
 git-remote                              ancillarymanipulators           complete
 git-repack                              ancillarymanipulators           complete
 git-replace                             ancillarymanipulators           complete
+git-replay                              plumbingmanipulators
 git-request-pull                        foreignscminterface             complete
 git-rerere                              ancillaryinterrogators
 git-reset                               mainporcelain           history
diff --git a/commit-graph.c b/commit-graph.c
index 37bd10e..45417d7 100644
--- a/commit-graph.c
+++ b/commit-graph.c
@@ -274,68 +274,37 @@ struct commit_graph *load_commit_graph_one_fd_st(struct repository *r,
 	return ret;
 }
 
-static int verify_commit_graph_lite(struct commit_graph *g)
+static int graph_read_oid_fanout(const unsigned char *chunk_start,
+				 size_t chunk_size, void *data)
 {
+	struct commit_graph *g = data;
 	int i;
 
-	/*
-	 * Basic validation shared between parse_commit_graph()
-	 * which'll be called every time the graph is used, and the
-	 * much more expensive verify_commit_graph() used by
-	 * "commit-graph verify".
-	 *
-	 * There should only be very basic checks here to ensure that
-	 * we don't e.g. segfault in fill_commit_in_graph(), but
-	 * because this is a very hot codepath nothing that e.g. loops
-	 * over g->num_commits, or runs a checksum on the commit-graph
-	 * itself.
-	 */
-	if (!g->chunk_oid_fanout) {
-		error("commit-graph is missing the OID Fanout chunk");
-		return 1;
-	}
-	if (!g->chunk_oid_lookup) {
-		error("commit-graph is missing the OID Lookup chunk");
-		return 1;
-	}
-	if (!g->chunk_commit_data) {
-		error("commit-graph is missing the Commit Data chunk");
-		return 1;
-	}
+	if (chunk_size != 256 * sizeof(uint32_t))
+		return error(_("commit-graph oid fanout chunk is wrong size"));
+	g->chunk_oid_fanout = (const uint32_t *)chunk_start;
+	g->num_commits = ntohl(g->chunk_oid_fanout[255]);
 
 	for (i = 0; i < 255; i++) {
 		uint32_t oid_fanout1 = ntohl(g->chunk_oid_fanout[i]);
 		uint32_t oid_fanout2 = ntohl(g->chunk_oid_fanout[i + 1]);
 
 		if (oid_fanout1 > oid_fanout2) {
-			error("commit-graph fanout values out of order");
+			error(_("commit-graph fanout values out of order"));
 			return 1;
 		}
 	}
-	if (ntohl(g->chunk_oid_fanout[255]) != g->num_commits) {
-		error("commit-graph oid table and fanout disagree on size");
-		return 1;
-	}
 
 	return 0;
 }
 
-static int graph_read_oid_fanout(const unsigned char *chunk_start,
-				 size_t chunk_size, void *data)
-{
-	struct commit_graph *g = data;
-	if (chunk_size != 256 * sizeof(uint32_t))
-		return error("commit-graph oid fanout chunk is wrong size");
-	g->chunk_oid_fanout = (const uint32_t *)chunk_start;
-	return 0;
-}
-
 static int graph_read_oid_lookup(const unsigned char *chunk_start,
 				 size_t chunk_size, void *data)
 {
 	struct commit_graph *g = data;
 	g->chunk_oid_lookup = chunk_start;
-	g->num_commits = chunk_size / g->hash_len;
+	if (chunk_size / g->hash_len != g->num_commits)
+		return error(_("commit-graph OID lookup chunk is the wrong size"));
 	return 0;
 }
 
@@ -343,8 +312,8 @@ static int graph_read_commit_data(const unsigned char *chunk_start,
 				  size_t chunk_size, void *data)
 {
 	struct commit_graph *g = data;
-	if (chunk_size != g->num_commits * GRAPH_DATA_WIDTH)
-		return error("commit-graph commit data chunk is wrong size");
+	if (chunk_size / GRAPH_DATA_WIDTH != g->num_commits)
+		return error(_("commit-graph commit data chunk is wrong size"));
 	g->chunk_commit_data = chunk_start;
 	return 0;
 }
@@ -353,8 +322,8 @@ static int graph_read_generation_data(const unsigned char *chunk_start,
 				      size_t chunk_size, void *data)
 {
 	struct commit_graph *g = data;
-	if (chunk_size != g->num_commits * sizeof(uint32_t))
-		return error("commit-graph generations chunk is wrong size");
+	if (chunk_size / sizeof(uint32_t) != g->num_commits)
+		return error(_("commit-graph generations chunk is wrong size"));
 	g->chunk_generation_data = chunk_start;
 	return 0;
 }
@@ -363,8 +332,8 @@ static int graph_read_bloom_index(const unsigned char *chunk_start,
 				  size_t chunk_size, void *data)
 {
 	struct commit_graph *g = data;
-	if (chunk_size != g->num_commits * 4) {
-		warning("commit-graph changed-path index chunk is too small");
+	if (chunk_size / 4 != g->num_commits) {
+		warning(_("commit-graph changed-path index chunk is too small"));
 		return -1;
 	}
 	g->chunk_bloom_indexes = chunk_start;
@@ -378,8 +347,8 @@ static int graph_read_bloom_data(const unsigned char *chunk_start,
 	uint32_t hash_version;
 
 	if (chunk_size < BLOOMDATA_CHUNK_HEADER_SIZE) {
-		warning("ignoring too-small changed-path chunk"
-			" (%"PRIuMAX" < %"PRIuMAX") in commit-graph file",
+		warning(_("ignoring too-small changed-path chunk"
+			" (%"PRIuMAX" < %"PRIuMAX") in commit-graph file"),
 			(uintmax_t)chunk_size,
 			(uintmax_t)BLOOMDATA_CHUNK_HEADER_SIZE);
 		return -1;
@@ -461,9 +430,19 @@ struct commit_graph *parse_commit_graph(struct repo_settings *s,
 				   GRAPH_HEADER_SIZE, graph->num_chunks, 1))
 		goto free_and_return;
 
-	read_chunk(cf, GRAPH_CHUNKID_OIDFANOUT, graph_read_oid_fanout, graph);
-	read_chunk(cf, GRAPH_CHUNKID_OIDLOOKUP, graph_read_oid_lookup, graph);
-	read_chunk(cf, GRAPH_CHUNKID_DATA, graph_read_commit_data, graph);
+	if (read_chunk(cf, GRAPH_CHUNKID_OIDFANOUT, graph_read_oid_fanout, graph)) {
+		error(_("commit-graph required OID fanout chunk missing or corrupted"));
+		goto free_and_return;
+	}
+	if (read_chunk(cf, GRAPH_CHUNKID_OIDLOOKUP, graph_read_oid_lookup, graph)) {
+		error(_("commit-graph required OID lookup chunk missing or corrupted"));
+		goto free_and_return;
+	}
+	if (read_chunk(cf, GRAPH_CHUNKID_DATA, graph_read_commit_data, graph)) {
+		error(_("commit-graph required commit data chunk missing or corrupted"));
+		goto free_and_return;
+	}
+
 	pair_chunk(cf, GRAPH_CHUNKID_EXTRAEDGES, &graph->chunk_extra_edges,
 		   &graph->chunk_extra_edges_size);
 	pair_chunk(cf, GRAPH_CHUNKID_BASE, &graph->chunk_base_graphs,
@@ -498,9 +477,6 @@ struct commit_graph *parse_commit_graph(struct repo_settings *s,
 
 	oidread(&graph->oid, graph->data + graph->data_len - graph->hash_len);
 
-	if (verify_commit_graph_lite(graph))
-		goto free_and_return;
-
 	free_chunkfile(cf);
 	return graph;
 
@@ -628,7 +604,7 @@ int open_commit_graph_chain(const char *chain_file,
 			/* treat empty files the same as missing */
 			errno = ENOENT;
 		} else {
-			warning("commit-graph chain file too small");
+			warning(_("commit-graph chain file too small"));
 			errno = EINVAL;
 		}
 		return 0;
@@ -972,7 +948,7 @@ static int fill_commit_in_graph(struct repository *r,
 	parent_data_pos = edge_value & GRAPH_EDGE_LAST_MASK;
 	do {
 		if (g->chunk_extra_edges_size / sizeof(uint32_t) <= parent_data_pos) {
-			error("commit-graph extra-edges pointer out of bounds");
+			error(_("commit-graph extra-edges pointer out of bounds"));
 			free_commit_list(item->parents);
 			item->parents = NULL;
 			item->object.parsed = 0;
@@ -2643,19 +2619,16 @@ int write_commit_graph(struct object_directory *odb,
 	oid_array_clear(&ctx->oids);
 	clear_topo_level_slab(&topo_levels);
 
-	if (ctx->commit_graph_filenames_after) {
-		for (i = 0; i < ctx->num_commit_graphs_after; i++) {
-			free(ctx->commit_graph_filenames_after[i]);
-			free(ctx->commit_graph_hash_after[i]);
-		}
+	for (i = 0; i < ctx->num_commit_graphs_before; i++)
+		free(ctx->commit_graph_filenames_before[i]);
+	free(ctx->commit_graph_filenames_before);
 
-		for (i = 0; i < ctx->num_commit_graphs_before; i++)
-			free(ctx->commit_graph_filenames_before[i]);
-
-		free(ctx->commit_graph_filenames_after);
-		free(ctx->commit_graph_filenames_before);
-		free(ctx->commit_graph_hash_after);
+	for (i = 0; i < ctx->num_commit_graphs_after; i++) {
+		free(ctx->commit_graph_filenames_after[i]);
+		free(ctx->commit_graph_hash_after[i]);
 	}
+	free(ctx->commit_graph_filenames_after);
+	free(ctx->commit_graph_hash_after);
 
 	free(ctx);
 
@@ -2692,10 +2665,6 @@ static int verify_one_commit_graph(struct repository *r,
 	struct commit *seen_gen_zero = NULL;
 	struct commit *seen_gen_non_zero = NULL;
 
-	verify_commit_graph_error = verify_commit_graph_lite(g);
-	if (verify_commit_graph_error)
-		return verify_commit_graph_error;
-
 	if (!commit_graph_checksum_valid(g)) {
 		graph_report(_("the commit-graph file has incorrect checksum and is likely corrupt"));
 		verify_commit_graph_error = VERIFY_COMMIT_GRAPH_ERROR_HASH;
diff --git a/commit-reach.c b/commit-reach.c
index ecc913f..8f9b008 100644
--- a/commit-reach.c
+++ b/commit-reach.c
@@ -49,13 +49,14 @@ static int queue_has_nonstale(struct prio_queue *queue)
 }
 
 /* all input commits in one and twos[] must have been parsed! */
-static struct commit_list *paint_down_to_common(struct repository *r,
-						struct commit *one, int n,
-						struct commit **twos,
-						timestamp_t min_generation)
+static int paint_down_to_common(struct repository *r,
+				struct commit *one, int n,
+				struct commit **twos,
+				timestamp_t min_generation,
+				int ignore_missing_commits,
+				struct commit_list **result)
 {
 	struct prio_queue queue = { compare_commits_by_gen_then_commit_date };
-	struct commit_list *result = NULL;
 	int i;
 	timestamp_t last_gen = GENERATION_NUMBER_INFINITY;
 
@@ -64,8 +65,8 @@ static struct commit_list *paint_down_to_common(struct repository *r,
 
 	one->object.flags |= PARENT1;
 	if (!n) {
-		commit_list_append(one, &result);
-		return result;
+		commit_list_append(one, result);
+		return 0;
 	}
 	prio_queue_put(&queue, one);
 
@@ -93,7 +94,7 @@ static struct commit_list *paint_down_to_common(struct repository *r,
 		if (flags == (PARENT1 | PARENT2)) {
 			if (!(commit->object.flags & RESULT)) {
 				commit->object.flags |= RESULT;
-				commit_list_insert_by_date(commit, &result);
+				commit_list_insert_by_date(commit, result);
 			}
 			/* Mark parents of a found merge stale */
 			flags |= STALE;
@@ -104,67 +105,97 @@ static struct commit_list *paint_down_to_common(struct repository *r,
 			parents = parents->next;
 			if ((p->object.flags & flags) == flags)
 				continue;
-			if (repo_parse_commit(r, p))
-				return NULL;
+			if (repo_parse_commit(r, p)) {
+				clear_prio_queue(&queue);
+				free_commit_list(*result);
+				*result = NULL;
+				/*
+				 * At this stage, we know that the commit is
+				 * missing: `repo_parse_commit()` uses
+				 * `OBJECT_INFO_DIE_IF_CORRUPT` and therefore
+				 * corrupt commits would already have been
+				 * dispatched with a `die()`.
+				 */
+				if (ignore_missing_commits)
+					return 0;
+				return error(_("could not parse commit %s"),
+					     oid_to_hex(&p->object.oid));
+			}
 			p->object.flags |= flags;
 			prio_queue_put(&queue, p);
 		}
 	}
 
 	clear_prio_queue(&queue);
-	return result;
+	return 0;
 }
 
-static struct commit_list *merge_bases_many(struct repository *r,
-					    struct commit *one, int n,
-					    struct commit **twos)
+static int merge_bases_many(struct repository *r,
+			    struct commit *one, int n,
+			    struct commit **twos,
+			    struct commit_list **result)
 {
 	struct commit_list *list = NULL;
-	struct commit_list *result = NULL;
 	int i;
 
 	for (i = 0; i < n; i++) {
-		if (one == twos[i])
+		if (one == twos[i]) {
 			/*
 			 * We do not mark this even with RESULT so we do not
 			 * have to clean it up.
 			 */
-			return commit_list_insert(one, &result);
+			*result = commit_list_insert(one, result);
+			return 0;
+		}
 	}
 
+	if (!one)
+		return 0;
 	if (repo_parse_commit(r, one))
-		return NULL;
+		return error(_("could not parse commit %s"),
+			     oid_to_hex(&one->object.oid));
 	for (i = 0; i < n; i++) {
+		if (!twos[i])
+			return 0;
 		if (repo_parse_commit(r, twos[i]))
-			return NULL;
+			return error(_("could not parse commit %s"),
+				     oid_to_hex(&twos[i]->object.oid));
 	}
 
-	list = paint_down_to_common(r, one, n, twos, 0);
+	if (paint_down_to_common(r, one, n, twos, 0, 0, &list)) {
+		free_commit_list(list);
+		return -1;
+	}
 
 	while (list) {
 		struct commit *commit = pop_commit(&list);
 		if (!(commit->object.flags & STALE))
-			commit_list_insert_by_date(commit, &result);
+			commit_list_insert_by_date(commit, result);
 	}
-	return result;
+	return 0;
 }
 
-struct commit_list *get_octopus_merge_bases(struct commit_list *in)
+int get_octopus_merge_bases(struct commit_list *in, struct commit_list **result)
 {
-	struct commit_list *i, *j, *k, *ret = NULL;
+	struct commit_list *i, *j, *k;
 
 	if (!in)
-		return ret;
+		return 0;
 
-	commit_list_insert(in->item, &ret);
+	commit_list_insert(in->item, result);
 
 	for (i = in->next; i; i = i->next) {
 		struct commit_list *new_commits = NULL, *end = NULL;
 
-		for (j = ret; j; j = j->next) {
-			struct commit_list *bases;
-			bases = repo_get_merge_bases(the_repository, i->item,
-						     j->item);
+		for (j = *result; j; j = j->next) {
+			struct commit_list *bases = NULL;
+			if (repo_get_merge_bases(the_repository, i->item,
+						 j->item, &bases) < 0) {
+				free_commit_list(bases);
+				free_commit_list(*result);
+				*result = NULL;
+				return -1;
+			}
 			if (!new_commits)
 				new_commits = bases;
 			else
@@ -172,10 +203,10 @@ struct commit_list *get_octopus_merge_bases(struct commit_list *in)
 			for (k = bases; k; k = k->next)
 				end = k;
 		}
-		free_commit_list(ret);
-		ret = new_commits;
+		free_commit_list(*result);
+		*result = new_commits;
 	}
-	return ret;
+	return 0;
 }
 
 static int remove_redundant_no_gen(struct repository *r,
@@ -193,7 +224,7 @@ static int remove_redundant_no_gen(struct repository *r,
 	for (i = 0; i < cnt; i++)
 		repo_parse_commit(r, array[i]);
 	for (i = 0; i < cnt; i++) {
-		struct commit_list *common;
+		struct commit_list *common = NULL;
 		timestamp_t min_generation = commit_graph_generation(array[i]);
 
 		if (redundant[i])
@@ -209,8 +240,16 @@ static int remove_redundant_no_gen(struct repository *r,
 			if (curr_generation < min_generation)
 				min_generation = curr_generation;
 		}
-		common = paint_down_to_common(r, array[i], filled,
-					      work, min_generation);
+		if (paint_down_to_common(r, array[i], filled,
+					 work, min_generation, 0, &common)) {
+			clear_commit_marks(array[i], all_flags);
+			clear_commit_marks_many(filled, work, all_flags);
+			free_commit_list(common);
+			free(work);
+			free(redundant);
+			free(filled_index);
+			return -1;
+		}
 		if (array[i]->object.flags & PARENT2)
 			redundant[i] = 1;
 		for (j = 0; j < filled; j++)
@@ -375,69 +414,77 @@ static int remove_redundant(struct repository *r, struct commit **array, int cnt
 	return remove_redundant_no_gen(r, array, cnt);
 }
 
-static struct commit_list *get_merge_bases_many_0(struct repository *r,
-						  struct commit *one,
-						  int n,
-						  struct commit **twos,
-						  int cleanup)
+static int get_merge_bases_many_0(struct repository *r,
+				  struct commit *one,
+				  int n,
+				  struct commit **twos,
+				  int cleanup,
+				  struct commit_list **result)
 {
 	struct commit_list *list;
 	struct commit **rslt;
-	struct commit_list *result;
 	int cnt, i;
 
-	result = merge_bases_many(r, one, n, twos);
+	if (merge_bases_many(r, one, n, twos, result) < 0)
+		return -1;
 	for (i = 0; i < n; i++) {
 		if (one == twos[i])
-			return result;
+			return 0;
 	}
-	if (!result || !result->next) {
+	if (!*result || !(*result)->next) {
 		if (cleanup) {
 			clear_commit_marks(one, all_flags);
 			clear_commit_marks_many(n, twos, all_flags);
 		}
-		return result;
+		return 0;
 	}
 
 	/* There are more than one */
-	cnt = commit_list_count(result);
+	cnt = commit_list_count(*result);
 	CALLOC_ARRAY(rslt, cnt);
-	for (list = result, i = 0; list; list = list->next)
+	for (list = *result, i = 0; list; list = list->next)
 		rslt[i++] = list->item;
-	free_commit_list(result);
+	free_commit_list(*result);
+	*result = NULL;
 
 	clear_commit_marks(one, all_flags);
 	clear_commit_marks_many(n, twos, all_flags);
 
 	cnt = remove_redundant(r, rslt, cnt);
-	result = NULL;
+	if (cnt < 0) {
+		free(rslt);
+		return -1;
+	}
 	for (i = 0; i < cnt; i++)
-		commit_list_insert_by_date(rslt[i], &result);
+		commit_list_insert_by_date(rslt[i], result);
 	free(rslt);
-	return result;
+	return 0;
 }
 
-struct commit_list *repo_get_merge_bases_many(struct repository *r,
-					      struct commit *one,
-					      int n,
-					      struct commit **twos)
+int repo_get_merge_bases_many(struct repository *r,
+			      struct commit *one,
+			      int n,
+			      struct commit **twos,
+			      struct commit_list **result)
 {
-	return get_merge_bases_many_0(r, one, n, twos, 1);
+	return get_merge_bases_many_0(r, one, n, twos, 1, result);
 }
 
-struct commit_list *repo_get_merge_bases_many_dirty(struct repository *r,
-						    struct commit *one,
-						    int n,
-						    struct commit **twos)
+int repo_get_merge_bases_many_dirty(struct repository *r,
+				    struct commit *one,
+				    int n,
+				    struct commit **twos,
+				    struct commit_list **result)
 {
-	return get_merge_bases_many_0(r, one, n, twos, 0);
+	return get_merge_bases_many_0(r, one, n, twos, 0, result);
 }
 
-struct commit_list *repo_get_merge_bases(struct repository *r,
-					 struct commit *one,
-					 struct commit *two)
+int repo_get_merge_bases(struct repository *r,
+			 struct commit *one,
+			 struct commit *two,
+			 struct commit_list **result)
 {
-	return get_merge_bases_many_0(r, one, 1, &two, 1);
+	return get_merge_bases_many_0(r, one, 1, &two, 1, result);
 }
 
 /*
@@ -460,11 +507,13 @@ int repo_is_descendant_of(struct repository *r,
 	} else {
 		while (with_commit) {
 			struct commit *other;
+			int ret;
 
 			other = with_commit->item;
 			with_commit = with_commit->next;
-			if (repo_in_merge_bases_many(r, other, 1, &commit))
-				return 1;
+			ret = repo_in_merge_bases_many(r, other, 1, &commit, 0);
+			if (ret)
+				return ret;
 		}
 		return 0;
 	}
@@ -474,17 +523,18 @@ int repo_is_descendant_of(struct repository *r,
  * Is "commit" an ancestor of one of the "references"?
  */
 int repo_in_merge_bases_many(struct repository *r, struct commit *commit,
-			     int nr_reference, struct commit **reference)
+			     int nr_reference, struct commit **reference,
+			     int ignore_missing_commits)
 {
-	struct commit_list *bases;
+	struct commit_list *bases = NULL;
 	int ret = 0, i;
 	timestamp_t generation, max_generation = GENERATION_NUMBER_ZERO;
 
 	if (repo_parse_commit(r, commit))
-		return ret;
+		return ignore_missing_commits ? 0 : -1;
 	for (i = 0; i < nr_reference; i++) {
 		if (repo_parse_commit(r, reference[i]))
-			return ret;
+			return ignore_missing_commits ? 0 : -1;
 
 		generation = commit_graph_generation(reference[i]);
 		if (generation > max_generation)
@@ -495,10 +545,11 @@ int repo_in_merge_bases_many(struct repository *r, struct commit *commit,
 	if (generation > max_generation)
 		return ret;
 
-	bases = paint_down_to_common(r, commit,
-				     nr_reference, reference,
-				     generation);
-	if (commit->object.flags & PARENT2)
+	if (paint_down_to_common(r, commit,
+				 nr_reference, reference,
+				 generation, ignore_missing_commits, &bases))
+		ret = -1;
+	else if (commit->object.flags & PARENT2)
 		ret = 1;
 	clear_commit_marks(commit, all_flags);
 	clear_commit_marks_many(nr_reference, reference, all_flags);
@@ -551,6 +602,10 @@ struct commit_list *reduce_heads(struct commit_list *heads)
 		}
 	}
 	num_head = remove_redundant(the_repository, array, num_head);
+	if (num_head < 0) {
+		free(array);
+		return NULL;
+	}
 	for (i = 0; i < num_head; i++)
 		tail = &commit_list_insert(array[i], tail)->next;
 	free(array);
@@ -593,6 +648,8 @@ int ref_newer(const struct object_id *new_oid, const struct object_id *old_oid)
 	commit_list_insert(old_commit, &old_commit_list);
 	ret = repo_is_descendant_of(the_repository,
 				    new_commit, old_commit_list);
+	if (ret < 0)
+		exit(128);
 	free_commit_list(old_commit_list);
 	return ret;
 }
diff --git a/commit-reach.h b/commit-reach.h
index 35c4da4..bf63cc4 100644
--- a/commit-reach.h
+++ b/commit-reach.h
@@ -9,18 +9,21 @@ struct ref_filter;
 struct object_id;
 struct object_array;
 
-struct commit_list *repo_get_merge_bases(struct repository *r,
-					 struct commit *rev1,
-					 struct commit *rev2);
-struct commit_list *repo_get_merge_bases_many(struct repository *r,
-					      struct commit *one, int n,
-					      struct commit **twos);
+int repo_get_merge_bases(struct repository *r,
+			 struct commit *rev1,
+			 struct commit *rev2,
+			 struct commit_list **result);
+int repo_get_merge_bases_many(struct repository *r,
+			      struct commit *one, int n,
+			      struct commit **twos,
+			      struct commit_list **result);
 /* To be used only when object flags after this call no longer matter */
-struct commit_list *repo_get_merge_bases_many_dirty(struct repository *r,
-						    struct commit *one, int n,
-						    struct commit **twos);
+int repo_get_merge_bases_many_dirty(struct repository *r,
+				    struct commit *one, int n,
+				    struct commit **twos,
+				    struct commit_list **result);
 
-struct commit_list *get_octopus_merge_bases(struct commit_list *in);
+int get_octopus_merge_bases(struct commit_list *in, struct commit_list **result);
 
 int repo_is_descendant_of(struct repository *r,
 			  struct commit *commit,
@@ -30,7 +33,8 @@ int repo_in_merge_bases(struct repository *r,
 			struct commit *reference);
 int repo_in_merge_bases_many(struct repository *r,
 			     struct commit *commit,
-			     int nr_reference, struct commit **reference);
+			     int nr_reference, struct commit **reference,
+			     int ignore_missing_commits);
 
 /*
  * Takes a list of commits and returns a new list where those
diff --git a/commit.c b/commit.c
index ef679a0..1a479a9 100644
--- a/commit.c
+++ b/commit.c
@@ -27,6 +27,7 @@
 #include "tree.h"
 #include "hook.h"
 #include "parse.h"
+#include "object-file-convert.h"
 
 static struct commit_extra_header *read_commit_extra_header_lines(const char *buf, size_t len, const char **);
 
@@ -1052,7 +1053,7 @@ struct commit *get_fork_point(const char *refname, struct commit *commit)
 {
 	struct object_id oid;
 	struct rev_collect revs;
-	struct commit_list *bases;
+	struct commit_list *bases = NULL;
 	int i;
 	struct commit *ret = NULL;
 	char *full_refname;
@@ -1077,8 +1078,9 @@ struct commit *get_fork_point(const char *refname, struct commit *commit)
 	for (i = 0; i < revs.nr; i++)
 		revs.commit[i]->object.flags &= ~TMP_MARK;
 
-	bases = repo_get_merge_bases_many(the_repository, commit, revs.nr,
-					  revs.commit);
+	if (repo_get_merge_bases_many(the_repository, commit, revs.nr,
+				      revs.commit, &bases) < 0)
+		exit(128);
 
 	/*
 	 * There should be one and only one merge base, when we found
@@ -1112,12 +1114,11 @@ static const char *gpg_sig_headers[] = {
 	"gpgsig-sha256",
 };
 
-int sign_with_header(struct strbuf *buf, const char *keyid)
+int add_header_signature(struct strbuf *buf, struct strbuf *sig, const struct git_hash_algo *algo)
 {
-	struct strbuf sig = STRBUF_INIT;
 	int inspos, copypos;
 	const char *eoh;
-	const char *gpg_sig_header = gpg_sig_headers[hash_algo_by_ptr(the_hash_algo)];
+	const char *gpg_sig_header = gpg_sig_headers[hash_algo_by_ptr(algo)];
 	int gpg_sig_header_len = strlen(gpg_sig_header);
 
 	/* find the end of the header */
@@ -1127,15 +1128,8 @@ int sign_with_header(struct strbuf *buf, const char *keyid)
 	else
 		inspos = eoh - buf->buf + 1;
 
-	if (!keyid || !*keyid)
-		keyid = get_signing_key();
-	if (sign_buffer(buf, &sig, keyid)) {
-		strbuf_release(&sig);
-		return -1;
-	}
-
-	for (copypos = 0; sig.buf[copypos]; ) {
-		const char *bol = sig.buf + copypos;
+	for (copypos = 0; sig->buf[copypos]; ) {
+		const char *bol = sig->buf + copypos;
 		const char *eol = strchrnul(bol, '\n');
 		int len = (eol - bol) + !!*eol;
 
@@ -1148,11 +1142,17 @@ int sign_with_header(struct strbuf *buf, const char *keyid)
 		inspos += len;
 		copypos += len;
 	}
-	strbuf_release(&sig);
 	return 0;
 }
 
-
+static int sign_commit_to_strbuf(struct strbuf *sig, struct strbuf *buf, const char *keyid)
+{
+	if (!keyid || !*keyid)
+		keyid = get_signing_key();
+	if (sign_buffer(buf, sig, keyid))
+		return -1;
+	return 0;
+}
 
 int parse_signed_commit(const struct commit *commit,
 			struct strbuf *payload, struct strbuf *signature,
@@ -1368,6 +1368,39 @@ void append_merge_tag_headers(struct commit_list *parents,
 	}
 }
 
+static int convert_commit_extra_headers(struct commit_extra_header *orig,
+					struct commit_extra_header **result)
+{
+	const struct git_hash_algo *compat = the_repository->compat_hash_algo;
+	const struct git_hash_algo *algo = the_repository->hash_algo;
+	struct commit_extra_header *extra = NULL, **tail = &extra;
+	struct strbuf out = STRBUF_INIT;
+	while (orig) {
+		struct commit_extra_header *new;
+		CALLOC_ARRAY(new, 1);
+		if (!strcmp(orig->key, "mergetag")) {
+			if (convert_object_file(&out, algo, compat,
+						orig->value, orig->len,
+						OBJ_TAG, 1)) {
+				free(new);
+				free_commit_extra_headers(extra);
+				return -1;
+			}
+			new->key = xstrdup("mergetag");
+			new->value = strbuf_detach(&out, &new->len);
+		} else {
+			new->key = xstrdup(orig->key);
+			new->len = orig->len;
+			new->value = xmemdupz(orig->value, orig->len);
+		}
+		*tail = new;
+		tail = &new->next;
+		orig = orig->next;
+	}
+	*result = extra;
+	return 0;
+}
+
 static void add_extra_header(struct strbuf *buffer,
 			     struct commit_extra_header *extra)
 {
@@ -1611,6 +1644,49 @@ N_("Warning: commit message did not conform to UTF-8.\n"
    "You may want to amend it after fixing the message, or set the config\n"
    "variable i18n.commitEncoding to the encoding your project uses.\n");
 
+static void write_commit_tree(struct strbuf *buffer, const char *msg, size_t msg_len,
+			      const struct object_id *tree,
+			      const struct object_id *parents, size_t parents_len,
+			      const char *author, const char *committer,
+			      struct commit_extra_header *extra)
+{
+	int encoding_is_utf8;
+	size_t i;
+
+	/* Not having i18n.commitencoding is the same as having utf-8 */
+	encoding_is_utf8 = is_encoding_utf8(git_commit_encoding);
+
+	strbuf_grow(buffer, 8192); /* should avoid reallocs for the headers */
+	strbuf_addf(buffer, "tree %s\n", oid_to_hex(tree));
+
+	/*
+	 * NOTE! This ordering means that the same exact tree merged with a
+	 * different order of parents will be a _different_ changeset even
+	 * if everything else stays the same.
+	 */
+	for (i = 0; i < parents_len; i++)
+		strbuf_addf(buffer, "parent %s\n", oid_to_hex(&parents[i]));
+
+	/* Person/date information */
+	if (!author)
+		author = git_author_info(IDENT_STRICT);
+	strbuf_addf(buffer, "author %s\n", author);
+	if (!committer)
+		committer = git_committer_info(IDENT_STRICT);
+	strbuf_addf(buffer, "committer %s\n", committer);
+	if (!encoding_is_utf8)
+		strbuf_addf(buffer, "encoding %s\n", git_commit_encoding);
+
+	while (extra) {
+		add_extra_header(buffer, extra);
+		extra = extra->next;
+	}
+	strbuf_addch(buffer, '\n');
+
+	/* And add the comment */
+	strbuf_add(buffer, msg, msg_len);
+}
+
 int commit_tree_extended(const char *msg, size_t msg_len,
 			 const struct object_id *tree,
 			 struct commit_list *parents, struct object_id *ret,
@@ -1618,63 +1694,119 @@ int commit_tree_extended(const char *msg, size_t msg_len,
 			 const char *sign_commit,
 			 struct commit_extra_header *extra)
 {
-	int result;
+	struct repository *r = the_repository;
+	int result = 0;
 	int encoding_is_utf8;
-	struct strbuf buffer;
+	struct strbuf buffer = STRBUF_INIT, compat_buffer = STRBUF_INIT;
+	struct strbuf sig = STRBUF_INIT, compat_sig = STRBUF_INIT;
+	struct object_id *parent_buf = NULL, *compat_oid = NULL;
+	struct object_id compat_oid_buf;
+	size_t i, nparents;
+
+	/* Not having i18n.commitencoding is the same as having utf-8 */
+	encoding_is_utf8 = is_encoding_utf8(git_commit_encoding);
 
 	assert_oid_type(tree, OBJ_TREE);
 
 	if (memchr(msg, '\0', msg_len))
 		return error("a NUL byte in commit log message not allowed.");
 
-	/* Not having i18n.commitencoding is the same as having utf-8 */
-	encoding_is_utf8 = is_encoding_utf8(git_commit_encoding);
-
-	strbuf_init(&buffer, 8192); /* should avoid reallocs for the headers */
-	strbuf_addf(&buffer, "tree %s\n", oid_to_hex(tree));
-
-	/*
-	 * NOTE! This ordering means that the same exact tree merged with a
-	 * different order of parents will be a _different_ changeset even
-	 * if everything else stays the same.
-	 */
+	nparents = commit_list_count(parents);
+	CALLOC_ARRAY(parent_buf, nparents);
+	i = 0;
 	while (parents) {
 		struct commit *parent = pop_commit(&parents);
-		strbuf_addf(&buffer, "parent %s\n",
-			    oid_to_hex(&parent->object.oid));
+		oidcpy(&parent_buf[i++], &parent->object.oid);
 	}
 
-	/* Person/date information */
-	if (!author)
-		author = git_author_info(IDENT_STRICT);
-	strbuf_addf(&buffer, "author %s\n", author);
-	if (!committer)
-		committer = git_committer_info(IDENT_STRICT);
-	strbuf_addf(&buffer, "committer %s\n", committer);
-	if (!encoding_is_utf8)
-		strbuf_addf(&buffer, "encoding %s\n", git_commit_encoding);
-
-	while (extra) {
-		add_extra_header(&buffer, extra);
-		extra = extra->next;
-	}
-	strbuf_addch(&buffer, '\n');
-
-	/* And add the comment */
-	strbuf_add(&buffer, msg, msg_len);
-
-	/* And check the encoding */
-	if (encoding_is_utf8 && !verify_utf8(&buffer))
-		fprintf(stderr, _(commit_utf8_warn));
-
-	if (sign_commit && sign_with_header(&buffer, sign_commit)) {
+	write_commit_tree(&buffer, msg, msg_len, tree, parent_buf, nparents, author, committer, extra);
+	if (sign_commit && sign_commit_to_strbuf(&sig, &buffer, sign_commit)) {
 		result = -1;
 		goto out;
 	}
+	if (r->compat_hash_algo) {
+		struct commit_extra_header *compat_extra = NULL;
+		struct object_id mapped_tree;
+		struct object_id *mapped_parents;
 
-	result = write_object_file(buffer.buf, buffer.len, OBJ_COMMIT, ret);
+		CALLOC_ARRAY(mapped_parents, nparents);
+
+		if (repo_oid_to_algop(r, tree, r->compat_hash_algo, &mapped_tree)) {
+			result = -1;
+			free(mapped_parents);
+			goto out;
+		}
+		for (i = 0; i < nparents; i++)
+			if (repo_oid_to_algop(r, &parent_buf[i], r->compat_hash_algo, &mapped_parents[i])) {
+				result = -1;
+				free(mapped_parents);
+				goto out;
+			}
+		if (convert_commit_extra_headers(extra, &compat_extra)) {
+			result = -1;
+			free(mapped_parents);
+			goto out;
+		}
+		write_commit_tree(&compat_buffer, msg, msg_len, &mapped_tree,
+				  mapped_parents, nparents, author, committer, compat_extra);
+		free_commit_extra_headers(compat_extra);
+		free(mapped_parents);
+
+		if (sign_commit && sign_commit_to_strbuf(&compat_sig, &compat_buffer, sign_commit)) {
+			result = -1;
+			goto out;
+		}
+	}
+
+	if (sign_commit) {
+		struct sig_pairs {
+			struct strbuf *sig;
+			const struct git_hash_algo *algo;
+		} bufs [2] = {
+			{ &compat_sig, r->compat_hash_algo },
+			{ &sig, r->hash_algo },
+		};
+		int i;
+
+		/*
+		 * We write algorithms in the order they were implemented in
+		 * Git to produce a stable hash when multiple algorithms are
+		 * used.
+		 */
+		if (r->compat_hash_algo && hash_algo_by_ptr(bufs[0].algo) > hash_algo_by_ptr(bufs[1].algo))
+			SWAP(bufs[0], bufs[1]);
+
+		/*
+		 * We traverse each algorithm in order, and apply the signature
+		 * to each buffer.
+		 */
+		for (i = 0; i < ARRAY_SIZE(bufs); i++) {
+			if (!bufs[i].algo)
+				continue;
+			add_header_signature(&buffer, bufs[i].sig, bufs[i].algo);
+			if (r->compat_hash_algo)
+				add_header_signature(&compat_buffer, bufs[i].sig, bufs[i].algo);
+		}
+	}
+
+	/* And check the encoding. */
+	if (encoding_is_utf8 && (!verify_utf8(&buffer) || !verify_utf8(&compat_buffer)))
+		fprintf(stderr, _(commit_utf8_warn));
+
+	if (r->compat_hash_algo) {
+		hash_object_file(r->compat_hash_algo, compat_buffer.buf, compat_buffer.len,
+			OBJ_COMMIT, &compat_oid_buf);
+		compat_oid = &compat_oid_buf;
+	}
+
+	result = write_object_file_flags(buffer.buf, buffer.len, OBJ_COMMIT,
+					 ret, compat_oid, 0);
 out:
+	free(parent_buf);
 	strbuf_release(&buffer);
+	strbuf_release(&compat_buffer);
+	strbuf_release(&sig);
+	strbuf_release(&compat_sig);
 	return result;
 }
 
@@ -1796,7 +1928,8 @@ size_t ignored_log_message_bytes(const char *buf, size_t len)
 		else
 			next_line++;
 
-		if (buf[bol] == comment_line_char || buf[bol] == '\n') {
+		if (starts_with_mem(buf + bol, cutoff - bol, comment_line_str) ||
+		    buf[bol] == '\n') {
 			/* is this the first of the run of comments? */
 			if (!boc)
 				boc = bol;
diff --git a/commit.h b/commit.h
index 1cc872f..62fe0d7 100644
--- a/commit.h
+++ b/commit.h
@@ -370,5 +370,6 @@ int parse_buffer_signed_by_header(const char *buffer,
 				  struct strbuf *payload,
 				  struct strbuf *signature,
 				  const struct git_hash_algo *algop);
+int add_header_signature(struct strbuf *buf, struct strbuf *sig, const struct git_hash_algo *algo);
 
 #endif /* COMMIT_H */
diff --git a/compat/compiler.h b/compat/compiler.h
index 10dbb65..e9ad9db 100644
--- a/compat/compiler.h
+++ b/compat/compiler.h
@@ -1,7 +1,6 @@
 #ifndef COMPILER_H
 #define COMPILER_H
 
-#include "git-compat-util.h"
 #include "strbuf.h"
 
 #ifdef __GLIBC__
diff --git a/compat/disk.h b/compat/disk.h
index 6c979c2..23bc1be 100644
--- a/compat/disk.h
+++ b/compat/disk.h
@@ -1,7 +1,6 @@
 #ifndef COMPAT_DISK_H
 #define COMPAT_DISK_H
 
-#include "git-compat-util.h"
 #include "abspath.h"
 #include "gettext.h"
 
diff --git a/compat/mingw.c b/compat/mingw.c
index 4bcbccf..6b06ea5 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -2695,6 +2695,30 @@ static PSID get_current_user_sid(void)
 	return result;
 }
 
+static BOOL user_sid_to_user_name(PSID sid, LPSTR *str)
+{
+	SID_NAME_USE pe_use;
+	DWORD len_user = 0, len_domain = 0;
+	BOOL translate_sid_to_user;
+
+	/*
+	 * returns only FALSE, because the string pointers are NULL
+	 */
+	LookupAccountSidA(NULL, sid, NULL, &len_user, NULL, &len_domain,
+			  &pe_use);
+	/*
+	 * Alloc needed space of the strings
+	 */
+	ALLOC_ARRAY((*str), (size_t)len_domain + (size_t)len_user);
+	translate_sid_to_user = LookupAccountSidA(NULL, sid,
+	    (*str) + len_domain, &len_user, *str, &len_domain, &pe_use);
+	if (!translate_sid_to_user)
+		FREE_AND_NULL(*str);
+	else
+		(*str)[len_domain] = '/';
+	return translate_sid_to_user;
+}
+
 static int acls_supported(const char *path)
 {
 	size_t offset = offset_1st_component(path);
@@ -2776,27 +2800,47 @@ int is_path_owned_by_current_sid(const char *path, struct strbuf *report)
 			strbuf_addf(report, "'%s' is on a file system that does "
 				    "not record ownership\n", path);
 		} else if (report) {
-			LPSTR str1, str2, to_free1 = NULL, to_free2 = NULL;
+			LPSTR str1, str2, str3, str4, to_free1 = NULL,
+			    to_free3 = NULL, to_local_free2 = NULL,
+			    to_local_free4 = NULL;
 
-			if (ConvertSidToStringSidA(sid, &str1))
+			if (user_sid_to_user_name(sid, &str1))
 				to_free1 = str1;
 			else
 				str1 = "(inconvertible)";
-
-			if (!current_user_sid)
-				str2 = "(none)";
-			else if (!IsValidSid(current_user_sid))
-				str2 = "(invalid)";
-			else if (ConvertSidToStringSidA(current_user_sid, &str2))
-				to_free2 = str2;
+			if (ConvertSidToStringSidA(sid, &str2))
+				to_local_free2 = str2;
 			else
 				str2 = "(inconvertible)";
+
+			if (!current_user_sid) {
+				str3 = "(none)";
+				str4 = "(none)";
+			}
+			else if (!IsValidSid(current_user_sid)) {
+				str3 = "(invalid)";
+				str4 = "(invalid)";
+			} else {
+				if (user_sid_to_user_name(current_user_sid,
+							  &str3))
+					to_free3 = str3;
+				else
+					str3 = "(inconvertible)";
+				if (ConvertSidToStringSidA(current_user_sid,
+							   &str4))
+					to_local_free4 = str4;
+				else
+					str4 = "(inconvertible)";
+			}
 			strbuf_addf(report,
 				    "'%s' is owned by:\n"
-				    "\t'%s'\nbut the current user is:\n"
-				    "\t'%s'\n", path, str1, str2);
-			LocalFree(to_free1);
-			LocalFree(to_free2);
+				    "\t%s (%s)\nbut the current user is:\n"
+				    "\t%s (%s)\n",
+				    path, str1, str2, str3, str4);
+			free(to_free1);
+			LocalFree(to_local_free2);
+			free(to_free3);
+			LocalFree(to_local_free4);
 		}
 	}
 
@@ -3114,3 +3158,24 @@ int uname(struct utsname *buf)
 		  "%u", (v >> 16) & 0x7fff);
 	return 0;
 }
+
+#ifndef NO_UNIX_SOCKETS
+int mingw_have_unix_sockets(void)
+{
+	SC_HANDLE scm, srvc;
+	SERVICE_STATUS_PROCESS status;
+	DWORD bytes;
+	int ret = 0;
+	scm = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
+	if (scm) {
+		srvc = OpenServiceA(scm, "afunix", SERVICE_QUERY_STATUS);
+		if (srvc) {
+			if(QueryServiceStatusEx(srvc, SC_STATUS_PROCESS_INFO, (LPBYTE)&status, sizeof(SERVICE_STATUS_PROCESS), &bytes))
+				ret = status.dwCurrentState == SERVICE_RUNNING;
+			CloseServiceHandle(srvc);
+		}
+		CloseServiceHandle(scm);
+	}
+	return ret;
+}
+#endif
diff --git a/compat/mingw.h b/compat/mingw.h
index 6aec50e..27b6128 100644
--- a/compat/mingw.h
+++ b/compat/mingw.h
@@ -631,3 +631,9 @@ void open_in_gdb(void);
  * Used by Pthread API implementation for Windows
  */
 int err_win_to_posix(DWORD winerr);
+
+#ifndef NO_UNIX_SOCKETS
+int mingw_have_unix_sockets(void);
+#undef have_unix_sockets
+#define have_unix_sockets mingw_have_unix_sockets
+#endif
diff --git a/compat/regex/regcomp.c b/compat/regex/regcomp.c
index d1bc09e..2bc0f11 100644
--- a/compat/regex/regcomp.c
+++ b/compat/regex/regcomp.c
@@ -868,7 +868,7 @@ init_dfa (re_dfa_t *dfa, size_t pat_len)
     if (table_size > pat_len)
       break;
 
-  dfa->state_table = calloc (sizeof (struct re_state_table_entry), table_size);
+  dfa->state_table = calloc (table_size, sizeof (struct re_state_table_entry));
   dfa->state_hash_mask = table_size - 1;
 
   dfa->mb_cur_max = MB_CUR_MAX;
@@ -936,7 +936,7 @@ init_dfa (re_dfa_t *dfa, size_t pat_len)
 	{
 	  int i, j, ch;
 
-	  dfa->sb_char = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1);
+	  dfa->sb_char = (re_bitset_ptr_t) calloc (1, sizeof (bitset_t));
 	  if (BE (dfa->sb_char == NULL, 0))
 	    return REG_ESPACE;
 
@@ -3079,9 +3079,9 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
 						   _NL_COLLATE_SYMB_EXTRAMB);
     }
 #endif
-  sbcset = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1);
+  sbcset = (re_bitset_ptr_t) calloc (1, sizeof (bitset_t));
 #ifdef RE_ENABLE_I18N
-  mbcset = (re_charset_t *) calloc (sizeof (re_charset_t), 1);
+  mbcset = (re_charset_t *) calloc (1, sizeof (re_charset_t));
 #endif /* RE_ENABLE_I18N */
 #ifdef RE_ENABLE_I18N
   if (BE (sbcset == NULL || mbcset == NULL, 0))
@@ -3626,9 +3626,9 @@ build_charclass_op (re_dfa_t *dfa, RE_TRANSLATE_TYPE trans,
   re_token_t br_token;
   bin_tree_t *tree;
 
-  sbcset = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1);
+  sbcset = (re_bitset_ptr_t) calloc (1, sizeof (bitset_t));
 #ifdef RE_ENABLE_I18N
-  mbcset = (re_charset_t *) calloc (sizeof (re_charset_t), 1);
+  mbcset = (re_charset_t *) calloc (1, sizeof (re_charset_t));
 #endif /* RE_ENABLE_I18N */
 
 #ifdef RE_ENABLE_I18N
diff --git a/compat/regex/regex_internal.c b/compat/regex/regex_internal.c
index ec51cf3..ec5cc5d 100644
--- a/compat/regex/regex_internal.c
+++ b/compat/regex/regex_internal.c
@@ -1628,7 +1628,7 @@ create_ci_newstate (const re_dfa_t *dfa, const re_node_set *nodes,
   reg_errcode_t err;
   re_dfastate_t *newstate;
 
-  newstate = (re_dfastate_t *) calloc (sizeof (re_dfastate_t), 1);
+  newstate = (re_dfastate_t *) calloc (1, sizeof (re_dfastate_t));
   if (BE (newstate == NULL, 0))
     return NULL;
   err = re_node_set_init_copy (&newstate->nodes, nodes);
@@ -1678,7 +1678,7 @@ create_cd_newstate (const re_dfa_t *dfa, const re_node_set *nodes,
   reg_errcode_t err;
   re_dfastate_t *newstate;
 
-  newstate = (re_dfastate_t *) calloc (sizeof (re_dfastate_t), 1);
+  newstate = (re_dfastate_t *) calloc (1, sizeof (re_dfastate_t));
   if (BE (newstate == NULL, 0))
     return NULL;
   err = re_node_set_init_copy (&newstate->nodes, nodes);
diff --git a/compat/regex/regexec.c b/compat/regex/regexec.c
index 49358ae..e92be57 100644
--- a/compat/regex/regexec.c
+++ b/compat/regex/regexec.c
@@ -2796,8 +2796,8 @@ get_subexp (re_match_context_t *mctx, int bkref_node, int bkref_str_idx)
 	    continue; /* No.  */
 	  if (sub_top->path == NULL)
 	    {
-	      sub_top->path = calloc (sizeof (state_array_t),
-				      sl_str - sub_top->str_idx + 1);
+	      sub_top->path = calloc (sl_str - sub_top->str_idx + 1,
+				      sizeof (state_array_t));
 	      if (sub_top->path == NULL)
 		return REG_ESPACE;
 	    }
@@ -3361,7 +3361,7 @@ build_trtable (const re_dfa_t *dfa, re_dfastate_t *state)
       if (ndests == 0)
 	{
 	  state->trtable = (re_dfastate_t **)
-	    calloc (sizeof (re_dfastate_t *), SBC_MAX);
+	    calloc (SBC_MAX, sizeof (re_dfastate_t *));
 	  return 1;
 	}
       return 0;
@@ -3457,7 +3457,7 @@ build_trtable (const re_dfa_t *dfa, re_dfastate_t *state)
 	 discern by looking at the character code: allocate a
 	 256-entry transition table.  */
       trtable = state->trtable =
-	(re_dfastate_t **) calloc (sizeof (re_dfastate_t *), SBC_MAX);
+	(re_dfastate_t **) calloc (SBC_MAX, sizeof (re_dfastate_t *));
       if (BE (trtable == NULL, 0))
 	goto out_free;
 
@@ -3488,7 +3488,7 @@ build_trtable (const re_dfa_t *dfa, re_dfastate_t *state)
 	 transition tables, one starting at trtable[0] and one
 	 starting at trtable[SBC_MAX].  */
       trtable = state->word_trtable =
-	(re_dfastate_t **) calloc (sizeof (re_dfastate_t *), 2 * SBC_MAX);
+	(re_dfastate_t **) calloc (2 * SBC_MAX, sizeof (re_dfastate_t *));
       if (BE (trtable == NULL, 0))
 	goto out_free;
 
diff --git a/config.c b/config.c
index 9ff6ae1..ae3652b 100644
--- a/config.c
+++ b/config.c
@@ -95,7 +95,6 @@ static long config_file_ftell(struct config_source *conf)
 	return ftell(conf->u.file);
 }
 
-
 static int config_buf_fgetc(struct config_source *conf)
 {
 	if (conf->u.buf.pos < conf->u.buf.len)
@@ -818,7 +817,8 @@ static int get_next_char(struct config_source *cs)
 
 static char *parse_value(struct config_source *cs)
 {
-	int quote = 0, comment = 0, space = 0;
+	int quote = 0, comment = 0;
+	size_t trim_len = 0;
 
 	strbuf_reset(&cs->value);
 	for (;;) {
@@ -828,13 +828,17 @@ static char *parse_value(struct config_source *cs)
 				cs->linenr--;
 				return NULL;
 			}
+			if (trim_len)
+				strbuf_setlen(&cs->value, trim_len);
 			return cs->value.buf;
 		}
 		if (comment)
 			continue;
 		if (isspace(c) && !quote) {
+			if (!trim_len)
+				trim_len = cs->value.len;
 			if (cs->value.len)
-				space++;
+				strbuf_addch(&cs->value, c);
 			continue;
 		}
 		if (!quote) {
@@ -843,8 +847,8 @@ static char *parse_value(struct config_source *cs)
 				continue;
 			}
 		}
-		for (; space; space--)
-			strbuf_addch(&cs->value, ' ');
+		if (trim_len)
+			trim_len = 0;
 		if (c == '\\') {
 			c = get_next_char(cs);
 			switch (c) {
@@ -870,7 +874,7 @@ static char *parse_value(struct config_source *cs)
 			continue;
 		}
 		if (c == '"') {
-			quote = 1-quote;
+			quote = 1 - quote;
 			continue;
 		}
 		strbuf_addch(&cs->value, c);
@@ -1561,24 +1565,29 @@ static int git_default_core_config(const char *var, const char *value,
 	if (!strcmp(var, "core.editor"))
 		return git_config_string(&editor_program, var, value);
 
-	if (!strcmp(var, "core.commentchar")) {
+	if (!strcmp(var, "core.commentchar") ||
+	    !strcmp(var, "core.commentstring")) {
 		if (!value)
 			return config_error_nonbool(var);
 		else if (!strcasecmp(value, "auto"))
 			auto_comment_line_char = 1;
-		else if (value[0] && !value[1]) {
-			comment_line_char = value[0];
+		else if (value[0]) {
+			if (strchr(value, '\n'))
+				return error(_("%s cannot contain newline"), var);
+			comment_line_str = xstrdup(value);
 			auto_comment_line_char = 0;
 		} else
-			return error(_("core.commentChar should only be one ASCII character"));
+			return error(_("%s must have at least one character"), var);
 		return 0;
 	}
 
 	if (!strcmp(var, "core.askpass"))
 		return git_config_string(&askpass_program, var, value);
 
-	if (!strcmp(var, "core.excludesfile"))
+	if (!strcmp(var, "core.excludesfile")) {
+		free((char *)excludes_file);
 		return git_config_pathname(&excludes_file, var, value);
+	}
 
 	if (!strcmp(var, "core.whitespace")) {
 		if (!value)
@@ -1988,7 +1997,27 @@ char *git_system_config(void)
 	return system_config;
 }
 
-void git_global_config(char **user_out, char **xdg_out)
+char *git_global_config(void)
+{
+	char *user_config, *xdg_config;
+
+	git_global_config_paths(&user_config, &xdg_config);
+	if (!user_config) {
+		free(xdg_config);
+		return NULL;
+	}
+
+	if (access_or_warn(user_config, R_OK, 0) && xdg_config &&
+	    !access_or_warn(xdg_config, R_OK, 0)) {
+		free(user_config);
+		return xdg_config;
+	} else {
+		free(xdg_config);
+		return user_config;
+	}
+}
+
+void git_global_config_paths(char **user_out, char **xdg_out)
 {
 	char *user_config = xstrdup_or_null(getenv("GIT_CONFIG_GLOBAL"));
 	char *xdg_config = NULL;
@@ -2041,7 +2070,7 @@ static int do_git_config_sequence(const struct config_options *opts,
 							 data, CONFIG_SCOPE_SYSTEM,
 							 NULL);
 
-	git_global_config(&user_config, &xdg_config);
+	git_global_config_paths(&user_config, &xdg_config);
 
 	if (xdg_config && !access_or_die(xdg_config, R_OK, ACCESS_EACCES_OK))
 		ret += git_config_from_file_with_options(fn, xdg_config, data,
@@ -2982,6 +3011,7 @@ static ssize_t write_section(int fd, const char *key,
 }
 
 static ssize_t write_pair(int fd, const char *key, const char *value,
+			  const char *comment,
 			  const struct config_store_data *store)
 {
 	int i;
@@ -3022,7 +3052,11 @@ static ssize_t write_pair(int fd, const char *key, const char *value,
 			strbuf_addch(&sb, value[i]);
 			break;
 		}
-	strbuf_addf(&sb, "%s\n", quote);
+
+	if (comment)
+		strbuf_addf(&sb, "%s%s\n", quote, comment);
+	else
+		strbuf_addf(&sb, "%s\n", quote);
 
 	ret = write_in_full(fd, sb.buf, sb.len);
 	strbuf_release(&sb);
@@ -3111,9 +3145,9 @@ static void maybe_remove_section(struct config_store_data *store,
 }
 
 int git_config_set_in_file_gently(const char *config_filename,
-				  const char *key, const char *value)
+				  const char *key, const char *comment, const char *value)
 {
-	return git_config_set_multivar_in_file_gently(config_filename, key, value, NULL, 0);
+	return git_config_set_multivar_in_file_gently(config_filename, key, value, NULL, comment, 0);
 }
 
 void git_config_set_in_file(const char *config_filename,
@@ -3134,7 +3168,7 @@ int repo_config_set_worktree_gently(struct repository *r,
 	if (r->repository_format_worktree_config) {
 		char *file = repo_git_path(r, "config.worktree");
 		int ret = git_config_set_multivar_in_file_gently(
-					file, key, value, NULL, 0);
+					file, key, value, NULL, NULL, 0);
 		free(file);
 		return ret;
 	}
@@ -3149,6 +3183,62 @@ void git_config_set(const char *key, const char *value)
 }
 
 /*
+ * The ownership rule is that the caller will own the string
+ * if it receives a piece of memory different from what it passed
+ * as the parameter.
+ */
+const char *git_config_prepare_comment_string(const char *comment)
+{
+	size_t leading_blanks;
+
+	if (!comment)
+		return NULL;
+
+	if (strchr(comment, '\n'))
+		die(_("no multi-line comment allowed: '%s'"), comment);
+
+	/*
+	 * If it begins with one or more leading whitespace characters
+	 * followed by '#", the comment string is used as-is.
+	 *
+	 * If it begins with '#', a SP is inserted between the comment
+	 * and the value the comment is about.
+	 *
+	 * Otherwise, the value is followed by a SP followed by '#'
+	 * followed by SP and then the comment string comes.
+	 */
+
+	leading_blanks = strspn(comment, " \t");
+	if (leading_blanks && comment[leading_blanks] == '#')
+		; /* use it as-is */
+	else if (comment[0] == '#')
+		comment = xstrfmt(" %s", comment);
+	else
+		comment = xstrfmt(" # %s", comment);
+
+	return comment;
+}
+
+static void validate_comment_string(const char *comment)
+{
+	size_t leading_blanks;
+
+	if (!comment)
+		return;
+	/*
+	 * The front-end must have massaged the comment string
+	 * properly before calling us.
+	 */
+	if (strchr(comment, '\n'))
+		BUG("multi-line comments are not permitted: '%s'", comment);
+
+	leading_blanks = strspn(comment, " \t");
+	if (!leading_blanks || comment[leading_blanks] != '#')
+		BUG("comment must begin with one or more SP followed by '#': '%s'",
+		    comment);
+}
+
+/*
  * If value==NULL, unset in (remove from) config,
  * if value_pattern!=NULL, disregard key/value pairs where value does not match.
  * if value_pattern==CONFIG_REGEX_NONE, do not match any existing values
@@ -3176,6 +3266,7 @@ void git_config_set(const char *key, const char *value)
 int git_config_set_multivar_in_file_gently(const char *config_filename,
 					   const char *key, const char *value,
 					   const char *value_pattern,
+					   const char *comment,
 					   unsigned flags)
 {
 	int fd = -1, in_fd = -1;
@@ -3186,6 +3277,8 @@ int git_config_set_multivar_in_file_gently(const char *config_filename,
 	size_t contents_sz;
 	struct config_store_data store = CONFIG_STORE_INIT;
 
+	validate_comment_string(comment);
+
 	/* parse-key returns negative; flip the sign to feed exit(3) */
 	ret = 0 - git_config_parse_key(key, &store.key, &store.baselen);
 	if (ret)
@@ -3226,7 +3319,7 @@ int git_config_set_multivar_in_file_gently(const char *config_filename,
 		free(store.key);
 		store.key = xstrdup(key);
 		if (write_section(fd, key, &store) < 0 ||
-		    write_pair(fd, key, value, &store) < 0)
+		    write_pair(fd, key, value, comment, &store) < 0)
 			goto write_err_out;
 	} else {
 		struct stat st;
@@ -3380,7 +3473,7 @@ int git_config_set_multivar_in_file_gently(const char *config_filename,
 				if (write_section(fd, key, &store) < 0)
 					goto write_err_out;
 			}
-			if (write_pair(fd, key, value, &store) < 0)
+			if (write_pair(fd, key, value, comment, &store) < 0)
 				goto write_err_out;
 		}
 
@@ -3418,7 +3511,6 @@ int git_config_set_multivar_in_file_gently(const char *config_filename,
 write_err_out:
 	ret = write_error(get_lock_file_path(&lock));
 	goto out_free;
-
 }
 
 void git_config_set_multivar_in_file(const char *config_filename,
@@ -3426,7 +3518,7 @@ void git_config_set_multivar_in_file(const char *config_filename,
 				     const char *value_pattern, unsigned flags)
 {
 	if (!git_config_set_multivar_in_file_gently(config_filename, key, value,
-						    value_pattern, flags))
+						    value_pattern, NULL, flags))
 		return;
 	if (value)
 		die(_("could not set '%s' to '%s'"), key, value);
@@ -3449,7 +3541,7 @@ int repo_config_set_multivar_gently(struct repository *r, const char *key,
 	int res = git_config_set_multivar_in_file_gently(file,
 							 key, value,
 							 value_pattern,
-							 flags);
+							 NULL, flags);
 	free(file);
 	return res;
 }
diff --git a/config.h b/config.h
index 14f881e..f4966e3 100644
--- a/config.h
+++ b/config.h
@@ -290,7 +290,7 @@ int git_config_pathname(const char **, const char *, const char *);
 
 int git_config_expiry_date(timestamp_t *, const char *, const char *);
 int git_config_color(char *, const char *, const char *);
-int git_config_set_in_file_gently(const char *, const char *, const char *);
+int git_config_set_in_file_gently(const char *, const char *, const char *, const char *);
 
 /**
  * write config values to a specific config file, takes a key/value pair as
@@ -336,7 +336,9 @@ int git_config_parse_key(const char *, char **, size_t *);
 int git_config_set_multivar_gently(const char *, const char *, const char *, unsigned);
 void git_config_set_multivar(const char *, const char *, const char *, unsigned);
 int repo_config_set_multivar_gently(struct repository *, const char *, const char *, const char *, unsigned);
-int git_config_set_multivar_in_file_gently(const char *, const char *, const char *, const char *, unsigned);
+int git_config_set_multivar_in_file_gently(const char *, const char *, const char *, const char *, const char *, unsigned);
+
+const char *git_config_prepare_comment_string(const char *);
 
 /**
  * takes four parameters:
@@ -382,7 +384,8 @@ int config_error_nonbool(const char *);
 #endif
 
 char *git_system_config(void);
-void git_global_config(char **user, char **xdg);
+char *git_global_config(void);
+void git_global_config_paths(char **user, char **xdg);
 
 int git_config_parse_parameter(const char *, config_fn_t fn, void *data);
 
diff --git a/config.mak.uname b/config.mak.uname
index 3bb03f4..a7607a5 100644
--- a/config.mak.uname
+++ b/config.mak.uname
@@ -65,9 +65,9 @@
 	HAVE_PLATFORM_PROCINFO = YesPlease
 	COMPAT_OBJS += compat/linux/procinfo.o
 	# centos7/rhel7 provides gcc 4.8.5 and zlib 1.2.7.
-	ifneq ($(findstring .el7.,$(uname_R)),)
+        ifneq ($(findstring .el7.,$(uname_R)),)
 		BASIC_CFLAGS += -std=c99
-	endif
+        endif
 endif
 ifeq ($(uname_S),GNU/kFreeBSD)
 	HAVE_ALLOCA_H = YesPlease
@@ -95,13 +95,13 @@
 	NO_MEMMEM = YesPlease
 endif
 ifeq ($(uname_S),SCO_SV)
-	ifeq ($(uname_R),3.2)
+        ifeq ($(uname_R),3.2)
 		CFLAGS = -O2
-	endif
-	ifeq ($(uname_R),5)
+        endif
+        ifeq ($(uname_R),5)
 		CC = cc
 		BASIC_CFLAGS += -Kthread
-	endif
+        endif
 	NEEDS_SOCKET = YesPlease
 	NEEDS_NSL = YesPlease
 	NEEDS_SSL_WITH_CRYPTO = YesPlease
@@ -124,19 +124,19 @@
 	# - MacOS 10.0.* and MacOS 10.1.0 = Darwin 1.*
 	# - MacOS 10.x.* = Darwin (x+4).* for (1 <= x)
 	# i.e. "begins with [15678] and a dot" means "10.4.* or older".
-	ifeq ($(shell expr "$(uname_R)" : '[15678]\.'),2)
+        ifeq ($(shell expr "$(uname_R)" : '[15678]\.'),2)
 		OLD_ICONV = UnfortunatelyYes
 		NO_APPLE_COMMON_CRYPTO = YesPlease
-	endif
-	ifeq ($(shell expr "$(uname_R)" : '[15]\.'),2)
+        endif
+        ifeq ($(shell expr "$(uname_R)" : '[15]\.'),2)
 		NO_STRLCPY = YesPlease
-	endif
-	ifeq ($(shell test "`expr "$(uname_R)" : '\([0-9][0-9]*\)\.'`" -ge 11 && echo 1),1)
+        endif
+        ifeq ($(shell test "`expr "$(uname_R)" : '\([0-9][0-9]*\)\.'`" -ge 11 && echo 1),1)
 		HAVE_GETDELIM = YesPlease
-	endif
-	ifeq ($(shell test "`expr "$(uname_R)" : '\([0-9][0-9]*\)\.'`" -ge 20 && echo 1),1)
+        endif
+        ifeq ($(shell test "`expr "$(uname_R)" : '\([0-9][0-9]*\)\.'`" -ge 20 && echo 1),1)
 		OPEN_RETURNS_EINTR = UnfortunatelyYes
-	endif
+        endif
 	NO_MEMMEM = YesPlease
 	USE_ST_TIMESPEC = YesPlease
 	HAVE_DEV_TTY = YesPlease
@@ -152,22 +152,35 @@
 	# Workaround for `gettext` being keg-only and not even being linked via
 	# `brew link --force gettext`, should be obsolete as of
 	# https://github.com/Homebrew/homebrew-core/pull/53489
-	ifeq ($(shell test -d /usr/local/opt/gettext/ && echo y),y)
+        ifeq ($(shell test -d /usr/local/opt/gettext/ && echo y),y)
 		BASIC_CFLAGS += -I/usr/local/include -I/usr/local/opt/gettext/include
 		BASIC_LDFLAGS += -L/usr/local/lib -L/usr/local/opt/gettext/lib
-		ifeq ($(shell test -x /usr/local/opt/gettext/bin/msgfmt && echo y),y)
+                ifeq ($(shell test -x /usr/local/opt/gettext/bin/msgfmt && echo y),y)
 			MSGFMT = /usr/local/opt/gettext/bin/msgfmt
-		endif
-	endif
+                endif
+	# On newer ARM-based machines the default installation path has changed to
+	# /opt/homebrew. Include it in our search paths so that the user does not
+	# have to configure this manually.
+	#
+	# Note that we do not employ the same workaround as above where we manually
+	# add gettext. The issue was fixed more than three years ago by now, and at
+	# that point there haven't been any ARM-based Macs yet.
+        else ifeq ($(shell test -d /opt/homebrew/ && echo y),y)
+		BASIC_CFLAGS += -I/opt/homebrew/include
+		BASIC_LDFLAGS += -L/opt/homebrew/lib
+                ifeq ($(shell test -x /opt/homebrew/bin/msgfmt && echo y),y)
+			MSGFMT = /opt/homebrew/bin/msgfmt
+                endif
+        endif
 
 	# The builtin FSMonitor on MacOS builds upon Simple-IPC.  Both require
 	# Unix domain sockets and PThreads.
-	ifndef NO_PTHREADS
-	ifndef NO_UNIX_SOCKETS
+        ifndef NO_PTHREADS
+        ifndef NO_UNIX_SOCKETS
 	FSMONITOR_DAEMON_BACKEND = darwin
 	FSMONITOR_OS_SETTINGS = darwin
-	endif
-	endif
+        endif
+        endif
 
 	BASIC_LDFLAGS += -framework CoreServices
 endif
@@ -183,7 +196,7 @@
 	NO_REGEX = YesPlease
 	NO_MSGFMT_EXTENDED_OPTIONS = YesPlease
 	HAVE_DEV_TTY = YesPlease
-	ifeq ($(uname_R),5.6)
+        ifeq ($(uname_R),5.6)
 		SOCKLEN_T = int
 		NO_HSTRERROR = YesPlease
 		NO_IPV6 = YesPlease
@@ -193,8 +206,8 @@
 		NO_STRLCPY = YesPlease
 		NO_STRTOUMAX = YesPlease
 		GIT_TEST_CMP = cmp
-	endif
-	ifeq ($(uname_R),5.7)
+        endif
+        ifeq ($(uname_R),5.7)
 		NEEDS_RESOLV = YesPlease
 		NO_IPV6 = YesPlease
 		NO_SOCKADDR_STORAGE = YesPlease
@@ -203,25 +216,25 @@
 		NO_STRLCPY = YesPlease
 		NO_STRTOUMAX = YesPlease
 		GIT_TEST_CMP = cmp
-	endif
-	ifeq ($(uname_R),5.8)
+        endif
+        ifeq ($(uname_R),5.8)
 		NO_UNSETENV = YesPlease
 		NO_SETENV = YesPlease
 		NO_STRTOUMAX = YesPlease
 		GIT_TEST_CMP = cmp
-	endif
-	ifeq ($(uname_R),5.9)
+        endif
+        ifeq ($(uname_R),5.9)
 		NO_UNSETENV = YesPlease
 		NO_SETENV = YesPlease
 		NO_STRTOUMAX = YesPlease
 		GIT_TEST_CMP = cmp
-	endif
+        endif
 	INSTALL = /usr/ucb/install
 	TAR = gtar
 	BASIC_CFLAGS += -D__EXTENSIONS__ -D__sun__
 endif
 ifeq ($(uname_O),Cygwin)
-	ifeq ($(shell expr "$(uname_R)" : '1\.[1-6]\.'),4)
+        ifeq ($(shell expr "$(uname_R)" : '1\.[1-6]\.'),4)
 		NO_D_TYPE_IN_DIRENT = YesPlease
 		NO_STRCASESTR = YesPlease
 		NO_MEMMEM = YesPlease
@@ -232,9 +245,9 @@
 		# On some boxes NO_MMAP is needed, and not so elsewhere.
 		# Try commenting this out if you suspect MMAP is more efficient
 		NO_MMAP = YesPlease
-	else
+        else
 		NO_REGEX = UnfortunatelyYes
-	endif
+        endif
 	HAVE_ALLOCA_H = YesPlease
 	NEEDS_LIBICONV = YesPlease
 	NO_FAST_WORKING_DIRECTORY = UnfortunatelyYes
@@ -250,25 +263,25 @@
 	NEEDS_LIBICONV = YesPlease
 	# Versions up to 10.1 require OLD_ICONV; 10.2 and beyond don't.
 	# A typical version string looks like "10.2-RELEASE".
-	ifeq ($(shell expr "$(uname_R)" : '[1-9]\.'),2)
+        ifeq ($(shell expr "$(uname_R)" : '[1-9]\.'),2)
 		OLD_ICONV = YesPlease
-	endif
-	ifeq ($(firstword $(subst -, ,$(uname_R))),10.0)
+        endif
+        ifeq ($(firstword $(subst -, ,$(uname_R))),10.0)
 		OLD_ICONV = YesPlease
-	endif
-	ifeq ($(firstword $(subst -, ,$(uname_R))),10.1)
+        endif
+        ifeq ($(firstword $(subst -, ,$(uname_R))),10.1)
 		OLD_ICONV = YesPlease
-	endif
+        endif
 	NO_MEMMEM = YesPlease
 	BASIC_CFLAGS += -I/usr/local/include
 	BASIC_LDFLAGS += -L/usr/local/lib
 	DIR_HAS_BSD_GROUP_SEMANTICS = YesPlease
 	USE_ST_TIMESPEC = YesPlease
-	ifeq ($(shell expr "$(uname_R)" : '4\.'),2)
+        ifeq ($(shell expr "$(uname_R)" : '4\.'),2)
 		PTHREAD_LIBS = -pthread
 		NO_UINTMAX_T = YesPlease
 		NO_STRTOUMAX = YesPlease
-	endif
+        endif
 	PYTHON_PATH = /usr/local/bin/python
 	PERL_PATH = /usr/local/bin/perl
 	HAVE_PATHS_H = YesPlease
@@ -304,9 +317,9 @@
 	CSPRNG_METHOD = arc4random
 endif
 ifeq ($(uname_S),NetBSD)
-	ifeq ($(shell expr "$(uname_R)" : '[01]\.'),2)
+        ifeq ($(shell expr "$(uname_R)" : '[01]\.'),2)
 		NEEDS_LIBICONV = YesPlease
-	endif
+        endif
 	BASIC_CFLAGS += -I/usr/pkg/include
 	BASIC_LDFLAGS += -L/usr/pkg/lib $(CC_LD_DYNPATH)/usr/pkg/lib
 	USE_ST_TIMESPEC = YesPlease
@@ -330,14 +343,14 @@
 	BASIC_CFLAGS += -D_LARGE_FILES
 	FILENO_IS_A_MACRO = UnfortunatelyYes
 	NEED_ACCESS_ROOT_HANDLER = UnfortunatelyYes
-	ifeq ($(shell expr "$(uname_V)" : '[1234]'),1)
+        ifeq ($(shell expr "$(uname_V)" : '[1234]'),1)
 		NO_PTHREADS = YesPlease
-	else
+        else
 		PTHREAD_LIBS = -lpthread
-	endif
-	ifeq ($(shell expr "$(uname_V).$(uname_R)" : '5\.1'),3)
+        endif
+        ifeq ($(shell expr "$(uname_V).$(uname_R)" : '5\.1'),3)
 		INLINE = ''
-	endif
+        endif
 	GIT_TEST_CMP = cmp
 endif
 ifeq ($(uname_S),GNU)
@@ -397,29 +410,29 @@
 	NO_SYS_SELECT_H = YesPlease
 	SNPRINTF_RETURNS_BOGUS = YesPlease
 	NO_NSEC = YesPlease
-	ifeq ($(uname_R),B.11.00)
+        ifeq ($(uname_R),B.11.00)
 		NO_INET_NTOP = YesPlease
 		NO_INET_PTON = YesPlease
-	endif
-	ifeq ($(uname_R),B.10.20)
+        endif
+        ifeq ($(uname_R),B.10.20)
 		# Override HP-UX 11.x setting:
 		INLINE =
 		SOCKLEN_T = size_t
 		NO_PREAD = YesPlease
 		NO_INET_NTOP = YesPlease
 		NO_INET_PTON = YesPlease
-	endif
+        endif
 	GIT_TEST_CMP = cmp
 endif
 ifeq ($(uname_S),Windows)
 	GIT_VERSION := $(GIT_VERSION).MSVC
 	pathsep = ;
 	# Assume that this is built in Git for Windows' SDK
-	ifeq (MINGW32,$(MSYSTEM))
+        ifeq (MINGW32,$(MSYSTEM))
 		prefix = /mingw32
-	else
+        else
 		prefix = /mingw64
-	endif
+        endif
 	# Prepend MSVC 64-bit tool-chain to PATH.
 	#
 	# A regular Git Bash *does not* have cl.exe in its $PATH. As there is a
@@ -434,7 +447,6 @@
 	NO_POLL = YesPlease
 	NO_SYMLINK_HEAD = YesPlease
 	NO_IPV6 = YesPlease
-	NO_UNIX_SOCKETS = YesPlease
 	NO_SETENV = YesPlease
 	NO_STRCASESTR = YesPlease
 	NO_STRLCPY = YesPlease
@@ -537,16 +549,16 @@
 	NO_MKDTEMP = YesPlease
 	NO_STRTOUMAX = YesPlease
 	NO_NSEC = YesPlease
-	ifeq ($(uname_R),3.5)
+        ifeq ($(uname_R),3.5)
 		NO_INET_NTOP = YesPlease
 		NO_INET_PTON = YesPlease
 		NO_SOCKADDR_STORAGE = YesPlease
-	endif
-	ifeq ($(uname_R),5.2)
+        endif
+        ifeq ($(uname_R),5.2)
 		NO_INET_NTOP = YesPlease
 		NO_INET_PTON = YesPlease
 		NO_SOCKADDR_STORAGE = YesPlease
-	endif
+        endif
 endif
 ifeq ($(uname_S),Minix)
 	NO_IPV6 = YesPlease
@@ -566,12 +578,12 @@
 	# still not compile in c89 mode, due to non-const array initializations.
 	CC = cc -c99
 	# Build down-rev compatible objects that don't use our new getopt_long.
-	ifeq ($(uname_R).$(uname_V),J06.21)
+        ifeq ($(uname_R).$(uname_V),J06.21)
 		CC += -WRVU=J06.20
-	endif
-	ifeq ($(uname_R).$(uname_V),L17.02)
+        endif
+        ifeq ($(uname_R).$(uname_V),L17.02)
 		CC += -WRVU=L16.05
-	endif
+        endif
 	# Disable all optimization, seems to result in bad code, with -O or -O2
 	# or even -O1 (default), /usr/local/libexec/git-core/git-pack-objects
 	# abends on "git push". Needs more investigation.
@@ -625,10 +637,22 @@
 	SANE_TOOL_PATH = /usr/coreutils/bin:/usr/local/bin
 	SHELL_PATH = /usr/coreutils/bin/bash
 endif
+ifeq ($(uname_S),OS/390)
+	NO_SYS_POLL_H = YesPlease
+	NO_STRCASESTR = YesPlease
+	NO_REGEX = YesPlease
+	NO_MMAP = YesPlease
+	NO_NSEC = YesPlease
+	NO_STRLCPY = YesPlease
+	NO_MEMMEM = YesPlease
+	NO_GECOS_IN_PWENT = YesPlease
+	HAVE_STRINGS_H = YesPlease
+	NEEDS_MODE_TRANSLATION = YesPlease
+endif
 ifeq ($(uname_S),MINGW)
-	ifeq ($(shell expr "$(uname_R)" : '1\.'),2)
+        ifeq ($(shell expr "$(uname_R)" : '1\.'),2)
 		$(error "Building with MSys is no longer supported")
-	endif
+        endif
 	pathsep = ;
 	HAVE_ALLOCA_H = YesPlease
 	NO_PREAD = YesPlease
@@ -636,7 +660,6 @@
 	NO_LIBGEN_H = YesPlease
 	NO_POLL = YesPlease
 	NO_SYMLINK_HEAD = YesPlease
-	NO_UNIX_SOCKETS = YesPlease
 	NO_SETENV = YesPlease
 	NO_STRCASESTR = YesPlease
 	NO_STRLCPY = YesPlease
@@ -687,22 +710,22 @@
 	# Enable DEP
 	BASIC_LDFLAGS += -Wl,--nxcompat
 	# Enable ASLR (unless debugging)
-	ifneq (,$(findstring -O,$(filter-out -O0 -Og,$(CFLAGS))))
+        ifneq (,$(findstring -O,$(filter-out -O0 -Og,$(CFLAGS))))
 		BASIC_LDFLAGS += -Wl,--dynamicbase
-	endif
-	ifeq (MINGW32,$(MSYSTEM))
+        endif
+        ifeq (MINGW32,$(MSYSTEM))
 		prefix = /mingw32
 		HOST_CPU = i686
 		BASIC_LDFLAGS += -Wl,--pic-executable,-e,_mainCRTStartup
-	endif
-	ifeq (MINGW64,$(MSYSTEM))
+        endif
+        ifeq (MINGW64,$(MSYSTEM))
 		prefix = /mingw64
 		HOST_CPU = x86_64
 		BASIC_LDFLAGS += -Wl,--pic-executable,-e,mainCRTStartup
-	else
+        else
 		COMPAT_CFLAGS += -D_USE_32BIT_TIME_T
 		BASIC_LDFLAGS += -Wl,--large-address-aware
-	endif
+        endif
 	CC = gcc
 	COMPAT_CFLAGS += -D__USE_MINGW_ANSI_STDIO=0 -DDETECT_MSYS_TTY \
 		-fstack-protector-strong
@@ -714,11 +737,11 @@
 	USE_GETTEXT_SCHEME = fallthrough
 	USE_LIBPCRE = YesPlease
 	USE_NED_ALLOCATOR = YesPlease
-	ifeq (/mingw64,$(subst 32,64,$(prefix)))
+        ifeq (/mingw64,$(subst 32,64,$(prefix)))
 		# Move system config into top-level /etc/
 		ETC_GITCONFIG = ../etc/gitconfig
 		ETC_GITATTRIBUTES = ../etc/gitattributes
-	endif
+        endif
 endif
 ifeq ($(uname_S),QNX)
 	COMPAT_CFLAGS += -DSA_RESTART=0
diff --git a/configure.ac b/configure.ac
index 276593c..d1a96da 100644
--- a/configure.ac
+++ b/configure.ac
@@ -94,7 +94,7 @@
 [AC_ARG_WITH([$1],
  [AS_HELP_STRING([--with-$1=VALUE], $3)],
  if test -n "$withval"; then
-  if test "$withval" = "yes" -o "$withval" = "no"; then
+  if test "$withval" = "yes" || test "$withval" = "no"; then
     AC_MSG_WARN([You likely do not want either 'yes' or 'no' as]
 		     [a value for $1 ($2).  Maybe you do...?])
   fi
diff --git a/contrib/buildsystems/CMakeLists.txt b/contrib/buildsystems/CMakeLists.txt
index 6b819e2..804629c 100644
--- a/contrib/buildsystems/CMakeLists.txt
+++ b/contrib/buildsystems/CMakeLists.txt
@@ -974,6 +974,35 @@
 parse_makefile_for_sources(test-reftable_SOURCES "REFTABLE_TEST_OBJS")
 list(TRANSFORM test-reftable_SOURCES PREPEND "${CMAKE_SOURCE_DIR}/")
 
+#unit-tests
+add_library(unit-test-lib OBJECT ${CMAKE_SOURCE_DIR}/t/unit-tests/test-lib.c)
+
+parse_makefile_for_scripts(unit_test_PROGRAMS "UNIT_TEST_PROGRAMS" "")
+foreach(unit_test ${unit_test_PROGRAMS})
+	add_executable("${unit_test}" "${CMAKE_SOURCE_DIR}/t/unit-tests/${unit_test}.c")
+	target_link_libraries("${unit_test}" unit-test-lib common-main)
+	set_target_properties("${unit_test}"
+		PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/t/unit-tests/bin)
+	if(MSVC)
+		set_target_properties("${unit_test}"
+			PROPERTIES RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/t/unit-tests/bin)
+		set_target_properties("${unit_test}"
+			PROPERTIES RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/t/unit-tests/bin)
+	endif()
+	list(APPEND PROGRAMS_BUILT "${unit_test}")
+
+	# t-basic intentionally fails tests, to validate the unit-test infrastructure.
+	# Therefore, it should only be run as part of t0080, which verifies that it
+	# fails only in the expected ways.
+	#
+	# All other unit tests should be run.
+	if(NOT ${unit_test} STREQUAL "t-basic")
+		add_test(NAME "t.unit-tests.${unit_test}"
+			COMMAND "./${unit_test}"
+			WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/t/unit-tests/bin)
+	endif()
+endforeach()
+
 #test-tool
 parse_makefile_for_sources(test-tool_SOURCES "TEST_BUILTINS_OBJS")
 
@@ -1093,17 +1122,18 @@
 	file(COPY ${CMAKE_SOURCE_DIR}/contrib/completion/git-completion.bash DESTINATION ${CMAKE_BINARY_DIR}/contrib/completion/)
 endif()
 
-file(GLOB test_scipts "${CMAKE_SOURCE_DIR}/t/t[0-9]*.sh")
+file(GLOB test_scripts "${CMAKE_SOURCE_DIR}/t/t[0-9]*.sh")
 
 #test
-foreach(tsh ${test_scipts})
-	add_test(NAME ${tsh}
+foreach(tsh ${test_scripts})
+	string(REGEX REPLACE ".*/(.*)\\.sh" "\\1" test_name ${tsh})
+	add_test(NAME "t.suite.${test_name}"
 		COMMAND ${SH_EXE} ${tsh} --no-bin-wrappers --no-chain-lint -vx
 		WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/t)
 endforeach()
 
 # This test script takes an extremely long time and is known to time out even
 # on fast machines because it requires in excess of one hour to run
-set_tests_properties("${CMAKE_SOURCE_DIR}/t/t7112-reset-submodule.sh" PROPERTIES TIMEOUT 4000)
+set_tests_properties("t.suite.t7112-reset-submodule" PROPERTIES TIMEOUT 4000)
 
 endif()#BUILD_TESTING
diff --git a/contrib/coccinelle/xstrncmpz.cocci b/contrib/coccinelle/xstrncmpz.cocci
new file mode 100644
index 0000000..ccb39e2
--- /dev/null
+++ b/contrib/coccinelle/xstrncmpz.cocci
@@ -0,0 +1,28 @@
+@@
+expression S, T, L;
+@@
+(
+- strncmp(S, T, L) || S[L]
++ !!xstrncmpz(S, T, L)
+|
+- strncmp(S, T, L) || S[L] != '\0'
++ !!xstrncmpz(S, T, L)
+|
+- strncmp(S, T, L) || T[L]
++ !!xstrncmpz(T, S, L)
+|
+- strncmp(S, T, L) || T[L] != '\0'
++ !!xstrncmpz(T, S, L)
+|
+- !strncmp(S, T, L) && !S[L]
++ !xstrncmpz(S, T, L)
+|
+- !strncmp(S, T, L) && S[L] == '\0'
++ !xstrncmpz(S, T, L)
+|
+- !strncmp(S, T, L) && !T[L]
++ !xstrncmpz(T, S, L)
+|
+- !strncmp(S, T, L) && T[L] == '\0'
++ !xstrncmpz(T, S, L)
+)
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index e21a39b..75193de 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -137,6 +137,9 @@
 __git_pseudoref_exists ()
 {
 	local ref=$1
+	local head
+
+	__git_find_repo_path
 
 	# If the reftable is in use, we have to shell out to 'git rev-parse'
 	# to determine whether the ref exists instead of looking directly in
@@ -144,9 +147,8 @@
 	# Bash builtins since executing Git commands are expensive on some
 	# platforms.
 	if __git_eread "$__git_repo_path/HEAD" head; then
-		b="${head#ref: }"
-		if [ "$b" == "refs/heads/.invalid" ]; then
-			__git -C "$__git_repo_path" rev-parse --verify --quiet "$ref" 2>/dev/null
+		if [ "$head" == "ref: refs/heads/.invalid" ]; then
+			__git show-ref --exists "$ref"
 			return $?
 		fi
 	fi
@@ -452,16 +454,18 @@
 
 # This function is equivalent to
 #
-#    __gitcomp "$(git xxx --git-completion-helper) ..."
+#    ___git_resolved_builtins=$(git xxx --git-completion-helper)
 #
-# except that the output is cached. Accept 1-3 arguments:
+# except that the result of the execution is cached.
+#
+# Accept 1-3 arguments:
 # 1: the git command to execute, this is also the cache key
+#    (use "_" when the command contains spaces, e.g. "remote add"
+#    becomes "remote_add")
 # 2: extra options to be added on top (e.g. negative forms)
 # 3: options to be excluded
-__gitcomp_builtin ()
+__git_resolve_builtins ()
 {
-	# spaces must be replaced with underscore for multi-word
-	# commands, e.g. "git remote add" becomes remote_add.
 	local cmd="$1"
 	local incl="${2-}"
 	local excl="${3-}"
@@ -487,7 +491,24 @@
 		eval "$var=\"$options\""
 	fi
 
-	__gitcomp "$options"
+	___git_resolved_builtins="$options"
+}
+
+# This function is equivalent to
+#
+#    __gitcomp "$(git xxx --git-completion-helper) ..."
+#
+# except that the output is cached. Accept 1-3 arguments:
+# 1: the git command to execute, this is also the cache key
+#    (use "_" when the command contains spaces, e.g. "remote add"
+#    becomes "remote_add")
+# 2: extra options to be added on top (e.g. negative forms)
+# 3: options to be excluded
+__gitcomp_builtin ()
+{
+	__git_resolve_builtins "$1" "$2" "$3"
+
+	__gitcomp "$___git_resolved_builtins"
 }
 
 # Variation of __gitcomp_nl () that appends to the existing list of
@@ -554,6 +575,26 @@
 	true
 }
 
+# Find the current subcommand for commands that follow the syntax:
+#
+#    git <command> <subcommand>
+#
+# 1: List of possible subcommands.
+# 2: Optional subcommand to return when none is found.
+__git_find_subcommand ()
+{
+	local subcommand subcommands="$1" default_subcommand="$2"
+
+	for subcommand in $subcommands; do
+		if [ "$subcommand" = "${words[__git_cmd_idx+1]}" ]; then
+			echo $subcommand
+			return
+		fi
+	done
+
+	echo $default_subcommand
+}
+
 # Execute 'git ls-files', unless the --committable option is specified, in
 # which case it runs 'git diff-index' to find out the files that can be
 # committed.  It return paths relative to the directory specified in the first
@@ -1481,12 +1522,32 @@
 {
 	__git_has_doubledash && return
 
-	local subcommands="start bad good skip reset visualize replay log run"
-	local subcommand="$(__git_find_on_cmdline "$subcommands")"
+	__git_find_repo_path
+
+	# If a bisection is in progress get the terms being used.
+	local term_bad term_good
+	if [ -f "$__git_repo_path"/BISECT_TERMS ]; then
+		term_bad=$(__git bisect terms --term-bad)
+		term_good=$(__git bisect terms --term-good)
+	fi
+
+	# We will complete any custom terms, but still always complete the
+	# more usual bad/new/good/old because git bisect gives a good error
+	# message if these are given when not in use, and that's better than
+	# silent refusal to complete if the user is confused.
+	#
+	# We want to recognize 'view' but not complete it, because it overlaps
+	# with 'visualize' too much and is just an alias for it.
+	#
+	local completable_subcommands="start bad new $term_bad good old $term_good terms skip reset visualize replay log run help"
+	local all_subcommands="$completable_subcommands view"
+
+	local subcommand="$(__git_find_on_cmdline "$all_subcommands")"
+
 	if [ -z "$subcommand" ]; then
 		__git_find_repo_path
 		if [ -f "$__git_repo_path"/BISECT_START ]; then
-			__gitcomp "$subcommands"
+			__gitcomp "$completable_subcommands"
 		else
 			__gitcomp "replay start"
 		fi
@@ -1494,7 +1555,26 @@
 	fi
 
 	case "$subcommand" in
-	bad|good|reset|skip|start)
+	start)
+		case "$cur" in
+		--*)
+			__gitcomp "--first-parent --no-checkout --term-new --term-bad --term-old --term-good"
+			return
+			;;
+		*)
+			__git_complete_refs
+			;;
+		esac
+		;;
+	terms)
+		__gitcomp "--term-good --term-old --term-bad --term-new"
+		return
+		;;
+	visualize|view)
+		__git_complete_log_opts
+		return
+		;;
+	bad|new|"$term_bad"|good|old|"$term_good"|reset|skip)
 		__git_complete_refs
 		;;
 	*)
@@ -1656,7 +1736,6 @@
 
 _git_cherry_pick ()
 {
-	__git_find_repo_path
 	if __git_pseudoref_exists CHERRY_PICK_HEAD; then
 		__gitcomp "$__git_cherry_pick_inprogress_options"
 		return
@@ -1807,7 +1886,7 @@
 			--output= --output-indicator-context=
 			--output-indicator-new= --output-indicator-old=
 			--ws-error-highlight=
-			--pickaxe-all --pickaxe-regex
+			--pickaxe-all --pickaxe-regex --patch-with-raw
 "
 
 # Options for diff/difftool
@@ -2071,6 +2150,16 @@
 	--min-age= --until= --before=
 	--min-parents= --max-parents=
 	--no-min-parents --no-max-parents
+	--alternate-refs --ancestry-path
+	--author-date-order --basic-regexp
+	--bisect --boundary --exclude-first-parent-only
+	--exclude-hidden --extended-regexp
+	--fixed-strings --grep-reflog
+	--ignore-missing --left-only --perl-regexp
+	--reflog --regexp-ignore-case --remove-empty
+	--right-only --show-linear-break
+	--show-notes-by-default --show-pulls
+	--since-as-filter --single-worktree
 "
 # Options that go well for log and gitk (not shortlog)
 __git_log_gitk_options="
@@ -2086,6 +2175,7 @@
 # Options accepted by log and show
 __git_log_show_options="
 	--diff-merges --diff-merges= --no-diff-merges --dd --remerge-diff
+	--encoding=
 "
 
 __git_diff_merges_opts="off none on first-parent 1 separate m combined c dense-combined cc remerge r"
@@ -2093,10 +2183,12 @@
 __git_log_pretty_formats="oneline short medium full fuller reference email raw format: tformat: mboxrd"
 __git_log_date_formats="relative iso8601 iso8601-strict rfc2822 short local default human raw unix auto: format:"
 
-_git_log ()
+# Complete porcelain (i.e. not git-rev-list) options and at least some
+# option arguments accepted by git-log.  Note that this same set of options
+# are also accepted by some other git commands besides git-log.
+__git_complete_log_opts ()
 {
-	__git_has_doubledash && return
-	__git_find_repo_path
+	COMPREPLY=()
 
 	local merge=""
 	if __git_pseudoref_exists MERGE_HEAD; then
@@ -2169,6 +2261,8 @@
 			--no-walk --no-walk= --do-walk
 			--parents --children
 			--expand-tabs --expand-tabs= --no-expand-tabs
+			--clear-decorations --decorate-refs=
+			--decorate-refs-exclude=
 			$merge
 			$__git_diff_common_options
 			"
@@ -2190,6 +2284,16 @@
 		return
 		;;
 	esac
+}
+
+_git_log ()
+{
+	__git_has_doubledash && return
+	__git_find_repo_path
+
+	__git_complete_log_opts
+        [ ${#COMPREPLY[@]} -eq 0 ] || return
+
 	__git_complete_revlist
 }
 
@@ -2406,13 +2510,30 @@
 
 _git_reflog ()
 {
-	local subcommands="show delete expire"
-	local subcommand="$(__git_find_on_cmdline "$subcommands")"
+	local subcommands subcommand
 
-	if [ -z "$subcommand" ]; then
-		__gitcomp "$subcommands"
-	else
-		__git_complete_refs
+	__git_resolve_builtins "reflog"
+
+	subcommands="$___git_resolved_builtins"
+	subcommand="$(__git_find_subcommand "$subcommands" "show")"
+
+	case "$subcommand,$cur" in
+	show,--*)
+		__gitcomp "
+			$__git_log_common_options
+			"
+		return
+		;;
+	$subcommand,--*)
+		__gitcomp_builtin "reflog_$subcommand"
+		return
+		;;
+	esac
+
+	__git_complete_refs
+
+	if [ $((cword - __git_cmd_idx)) -eq 1 ]; then
+		__gitcompappend "$subcommands" "" "$cur" " "
 	fi
 }
 
@@ -2595,6 +2716,33 @@
 	__git_config_vars="$(git help --config-for-completion)"
 }
 
+__git_config_vars_all=
+__git_compute_config_vars_all ()
+{
+	test -n "$__git_config_vars_all" ||
+	__git_config_vars_all="$(git --no-pager help --config)"
+}
+
+__git_compute_first_level_config_vars_for_section ()
+{
+	local section="$1"
+	__git_compute_config_vars
+	local this_section="__git_first_level_config_vars_for_section_${section}"
+	test -n "${!this_section}" ||
+	printf -v "__git_first_level_config_vars_for_section_${section}" %s \
+		"$(echo "$__git_config_vars" | awk -F. "/^${section}\.[a-z]/ { print \$2 }")"
+}
+
+__git_compute_second_level_config_vars_for_section ()
+{
+	local section="$1"
+	__git_compute_config_vars_all
+	local this_section="__git_second_level_config_vars_for_section_${section}"
+	test -n "${!this_section}" ||
+	printf -v "__git_second_level_config_vars_for_section_${section}" %s \
+		"$(echo "$__git_config_vars_all" | awk -F. "/^${section}\.</ { print \$3 }")"
+}
+
 __git_config_sections=
 __git_compute_config_sections ()
 {
@@ -2739,73 +2887,50 @@
 	done
 
 	case "$cur_" in
-	branch.*.*)
+	branch.*.*|guitool.*.*|difftool.*.*|man.*.*|mergetool.*.*|remote.*.*|submodule.*.*|url.*.*)
 		local pfx="${cur_%.*}."
 		cur_="${cur_##*.}"
-		__gitcomp "remote pushRemote merge mergeOptions rebase" "$pfx" "$cur_" "$sfx"
+		local section="${pfx%.*.}"
+		__git_compute_second_level_config_vars_for_section "${section}"
+		local this_section="__git_second_level_config_vars_for_section_${section}"
+		__gitcomp "${!this_section}" "$pfx" "$cur_" "$sfx"
 		return
 		;;
 	branch.*)
 		local pfx="${cur_%.*}."
 		cur_="${cur_#*.}"
+		local section="${pfx%.}"
 		__gitcomp_direct "$(__git_heads "$pfx" "$cur_" ".")"
-		__gitcomp_nl_append $'autoSetupMerge\nautoSetupRebase\n' "$pfx" "$cur_" "${sfx- }"
-		return
-		;;
-	guitool.*.*)
-		local pfx="${cur_%.*}."
-		cur_="${cur_##*.}"
-		__gitcomp "
-			argPrompt cmd confirm needsFile noConsole noRescan
-			prompt revPrompt revUnmerged title
-			" "$pfx" "$cur_" "$sfx"
-		return
-		;;
-	difftool.*.*)
-		local pfx="${cur_%.*}."
-		cur_="${cur_##*.}"
-		__gitcomp "cmd path" "$pfx" "$cur_" "$sfx"
-		return
-		;;
-	man.*.*)
-		local pfx="${cur_%.*}."
-		cur_="${cur_##*.}"
-		__gitcomp "cmd path" "$pfx" "$cur_" "$sfx"
-		return
-		;;
-	mergetool.*.*)
-		local pfx="${cur_%.*}."
-		cur_="${cur_##*.}"
-		__gitcomp "cmd path trustExitCode" "$pfx" "$cur_" "$sfx"
+		__git_compute_first_level_config_vars_for_section "${section}"
+		local this_section="__git_first_level_config_vars_for_section_${section}"
+		__gitcomp_nl_append "${!this_section}" "$pfx" "$cur_" "${sfx:- }"
 		return
 		;;
 	pager.*)
 		local pfx="${cur_%.*}."
 		cur_="${cur_#*.}"
 		__git_compute_all_commands
-		__gitcomp_nl "$__git_all_commands" "$pfx" "$cur_" "${sfx- }"
-		return
-		;;
-	remote.*.*)
-		local pfx="${cur_%.*}."
-		cur_="${cur_##*.}"
-		__gitcomp "
-			url proxy fetch push mirror skipDefaultUpdate
-			receivepack uploadpack tagOpt pushurl
-			" "$pfx" "$cur_" "$sfx"
+		__gitcomp_nl "$__git_all_commands" "$pfx" "$cur_" "${sfx:- }"
 		return
 		;;
 	remote.*)
 		local pfx="${cur_%.*}."
 		cur_="${cur_#*.}"
+		local section="${pfx%.}"
 		__gitcomp_nl "$(__git_remotes)" "$pfx" "$cur_" "."
-		__gitcomp_nl_append "pushDefault" "$pfx" "$cur_" "${sfx- }"
+		__git_compute_first_level_config_vars_for_section "${section}"
+		local this_section="__git_first_level_config_vars_for_section_${section}"
+		__gitcomp_nl_append "${!this_section}" "$pfx" "$cur_" "${sfx:- }"
 		return
 		;;
-	url.*.*)
+	submodule.*)
 		local pfx="${cur_%.*}."
-		cur_="${cur_##*.}"
-		__gitcomp "insteadOf pushInsteadOf" "$pfx" "$cur_" "$sfx"
+		cur_="${cur_#*.}"
+		local section="${pfx%.}"
+		__gitcomp_nl "$(__git config -f "$(__git rev-parse --show-toplevel)/.gitmodules" --get-regexp 'submodule.*.path' | awk -F. '{print $2}')" "$pfx" "$cur_" "."
+		__git_compute_first_level_config_vars_for_section "${section}"
+		local this_section="__git_first_level_config_vars_for_section_${section}"
+		__gitcomp_nl_append "${!this_section}" "$pfx" "$cur_" "${sfx:- }"
 		return
 		;;
 	*.*)
@@ -2966,7 +3091,6 @@
 
 _git_restore ()
 {
-	__git_find_repo_path
 	case "$prev" in
 	-s)
 		__git_complete_refs
@@ -2995,7 +3119,6 @@
 
 _git_revert ()
 {
-	__git_find_repo_path
 	if __git_pseudoref_exists REVERT_HEAD; then
 		__gitcomp "$__git_revert_inprogress_options"
 		return
@@ -3117,12 +3240,119 @@
 			COMPREPLY+=("$c/")
 			_found=1
 		fi
-	done < <(git ls-tree -z -d --name-only HEAD $_tmp_dir)
+	done < <(__git ls-tree -z -d --name-only HEAD $_tmp_dir)
 
 	if [[ $_found == 0 ]] && [[ "$cur" =~ /$ ]]; then
 		# No possible further completions any deeper, so assume we're at
 		# a leaf directory and just consider it complete
 		__gitcomp_direct_append "$cur "
+	elif [[ $_found == 0 ]]; then
+		# No possible completions found.  Avoid falling back to
+		# bash's default file and directory completion, because all
+		# valid completions have already been searched and the
+		# fallbacks can do nothing but mislead.  In fact, they can
+		# mislead in three different ways:
+		#    1) Fallback file completion makes no sense when asking
+		#       for directory completions, as this function does.
+		#    2) Fallback directory completion is bad because
+		#       e.g. "/pro" is invalid and should NOT complete to
+		#       "/proc".
+		#    3) Fallback file/directory completion only completes
+		#       on paths that exist in the current working tree,
+		#       i.e. which are *already* part of their
+		#       sparse-checkout.  Thus, normal file and directory
+		#       completion is always useless for "git
+		#       sparse-checkout add" and is also probelmatic for
+		#       "git sparse-checkout set" unless using it to
+		#       strictly narrow the checkout.
+		COMPREPLY=( "" )
+	fi
+}
+
+# In non-cone mode, the arguments to {set,add} are supposed to be
+# patterns, relative to the toplevel directory.  These can be any kind
+# of general pattern, like 'subdir/*.c' and we can't complete on all
+# of those.  However, if the user presses Tab to get tab completion, we
+# presume that they are trying to provide a pattern that names a specific
+# path.
+__gitcomp_slash_leading_paths ()
+{
+	local dequoted_word pfx="" cur_ toplevel
+
+	# Since we are dealing with a sparse-checkout, subdirectories may not
+	# exist in the local working copy.  Therefore, we want to run all
+	# ls-files commands relative to the repository toplevel.
+	toplevel="$(git rev-parse --show-toplevel)/"
+
+	__git_dequote "$cur"
+
+	# If the paths provided by the user already start with '/', then
+	# they are considered relative to the toplevel of the repository
+	# already.  If they do not start with /, then we need to adjust
+	# them to start with the appropriate prefix.
+	case "$cur" in
+	/*)
+		cur="${cur:1}"
+		;;
+	*)
+		pfx="$(__git rev-parse --show-prefix)"
+	esac
+
+	# Since sparse-index is limited to cone-mode, in non-cone-mode the
+	# list of valid paths is precisely the cached files in the index.
+	#
+	# NEEDSWORK:
+	#   1) We probably need to take care of cases where ls-files
+	#      responds with special quoting.
+	#   2) We probably need to take care of cases where ${cur} has
+	#      some kind of special quoting.
+	#   3) On top of any quoting from 1 & 2, we have to provide an extra
+	#      level of quoting for any paths that contain a '*', '?', '\',
+	#      '[', ']', or leading '#' or '!' since those will be
+	#      interpreted by sparse-checkout as something other than a
+	#      literal path character.
+	# Since there are two types of quoting here, this might get really
+	# complex.  For now, just punt on all of this...
+	completions="$(__git -C "${toplevel}" -c core.quotePath=false \
+			 ls-files --cached -- "${pfx}${cur}*" \
+			 | sed -e s%^%/% -e 's%$% %')"
+	# Note, above, though that we needed all of the completions to be
+	# prefixed with a '/', and we want to add a space so that bash
+	# completion will actually complete an entry and let us move on to
+	# the next one.
+
+	# Return what we've found.
+	if test -n "$completions"; then
+		# We found some completions; return them
+		local IFS=$'\n'
+		COMPREPLY=($completions)
+	else
+		# Do NOT fall back to bash-style all-local-files-and-dirs
+		# when we find no match.  Such options are worse than
+		# useless:
+		#     1. "git sparse-checkout add" needs paths that are NOT
+		#        currently in the working copy.  "git
+		#        sparse-checkout set" does as well, except in the
+		#        special cases when users are only trying to narrow
+		#        their sparse checkout to a subset of what they
+		#        already have.
+		#
+		#     2. A path like '.config' is ambiguous as to whether
+		#        the user wants all '.config' files throughout the
+		#        tree, or just the one under the current directory.
+		#        It would result in a warning from the
+		#        sparse-checkout command due to this.  As such, all
+		#        completions of paths should be prefixed with a
+		#        '/'.
+		#
+		#     3. We don't want paths prefixed with a '/' to
+		#        complete files in the system root directory, we
+		#        want it to complete on files relative to the
+		#        repository root.
+		#
+		# As such, make sure that NO completions are offered rather
+		# than falling back to bash's default completions.
+		COMPREPLY=( "" )
 	fi
 }
 
@@ -3130,6 +3360,7 @@
 {
 	local subcommands="list init set disable add reapply"
 	local subcommand="$(__git_find_on_cmdline "$subcommands")"
+	local using_cone=true
 	if [ -z "$subcommand" ]; then
 		__gitcomp "$subcommands"
 		return
@@ -3140,9 +3371,18 @@
 		__gitcomp_builtin sparse-checkout_$subcommand "" "--"
 		;;
 	set,*|add,*)
-		if [ "$(__git config core.sparseCheckoutCone)" == "true" ] ||
-		[ -n "$(__git_find_on_cmdline --cone)" ]; then
+		if [[ "$(__git config core.sparseCheckout)" == "true" &&
+		      "$(__git config core.sparseCheckoutCone)" == "false" &&
+		      -z "$(__git_find_on_cmdline --cone)" ]]; then
+			using_cone=false
+		fi
+		if [[ -n "$(__git_find_on_cmdline --no-cone)" ]]; then
+			using_cone=false
+		fi
+		if [[ "$using_cone" == "true" ]]; then
 			__gitcomp_directories
+		else
+			 __gitcomp_slash_leading_paths
 		fi
 	esac
 }
@@ -3389,7 +3629,7 @@
 	# Generate completion reply from worktree list skipping the first
 	# entry: it's the path of the main worktree, which can't be moved,
 	# removed, locked, etc.
-	__gitcomp_nl "$(git worktree list --porcelain |
+	__gitcomp_nl "$(__git worktree list --porcelain |
 		sed -n -e '2,$ s/^worktree //p')"
 }
 
diff --git a/contrib/completion/git-completion.zsh b/contrib/completion/git-completion.zsh
index cac6f61..f5877bd 100644
--- a/contrib/completion/git-completion.zsh
+++ b/contrib/completion/git-completion.zsh
@@ -272,6 +272,7 @@
 {
 	local _ret=1
 	local cur cword prev
+	local __git_repo_path
 
 	cur=${words[CURRENT]}
 	prev=${words[CURRENT-1]}
diff --git a/contrib/completion/git-prompt.sh b/contrib/completion/git-prompt.sh
index 2c03005..5330e76 100644
--- a/contrib/completion/git-prompt.sh
+++ b/contrib/completion/git-prompt.sh
@@ -141,7 +141,7 @@
 
 	# parse configuration values
 	local option
-	for option in ${GIT_PS1_SHOWUPSTREAM}; do
+	for option in ${GIT_PS1_SHOWUPSTREAM-}; do
 		case "$option" in
 		git|svn) upstream_type="$option" ;;
 		verbose) verbose=1 ;;
@@ -408,7 +408,7 @@
 
 	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 \
+		--is-bare-repository --is-inside-work-tree --show-ref-format \
 		--short HEAD 2>/dev/null)"
 	rev_parse_exit_code="$?"
 
@@ -421,6 +421,8 @@
 		short_sha="${repo_info##*$'\n'}"
 		repo_info="${repo_info%$'\n'*}"
 	fi
+	local ref_format="${repo_info##*$'\n'}"
+	repo_info="${repo_info%$'\n'*}"
 	local inside_worktree="${repo_info##*$'\n'}"
 	repo_info="${repo_info%$'\n'*}"
 	local bare_repo="${repo_info##*$'\n'}"
@@ -479,12 +481,25 @@
 			b="$(git symbolic-ref HEAD 2>/dev/null)"
 		else
 			local head=""
-			if ! __git_eread "$g/HEAD" head; then
-				return $exit
-			fi
-			# is it a symbolic ref?
-			b="${head#ref: }"
-			if [ "$head" = "$b" ]; then
+
+			case "$ref_format" in
+			files)
+				if ! __git_eread "$g/HEAD" head; then
+					return $exit
+				fi
+
+				if [[ $head == "ref: "* ]]; then
+					head="${head#ref: }"
+				else
+					head=""
+				fi
+				;;
+			*)
+				head="$(git symbolic-ref HEAD 2>/dev/null)"
+				;;
+			esac
+
+			if test -z "$head"; then
 				detached=yes
 				b="$(
 				case "${GIT_PS1_DESCRIBE_STYLE-}" in
@@ -502,6 +517,8 @@
 
 				b="$short_sha..."
 				b="($b)"
+			else
+				b="$head"
 			fi
 		fi
 	fi
@@ -511,7 +528,7 @@
 	fi
 
 	local conflict="" # state indicator for unresolved conflicts
-	if [[ "${GIT_PS1_SHOWCONFLICTSTATE}" == "yes" ]] &&
+	if [[ "${GIT_PS1_SHOWCONFLICTSTATE-}" == "yes" ]] &&
 	   [[ $(git ls-files --unmerged 2>/dev/null) ]]; then
 		conflict="|CONFLICT"
 	fi
diff --git a/contrib/coverage-diff.sh b/contrib/coverage-diff.sh
index 4ec419f..6ce9603 100755
--- a/contrib/coverage-diff.sh
+++ b/contrib/coverage-diff.sh
@@ -74,8 +74,7 @@
 	sort >uncovered_lines.txt
 
 	comm -12 uncovered_lines.txt new_lines.txt |
-	sed -e 's/$/\)/' |
-	sed -e 's/^/ /' >uncovered_new_lines.txt
+	sed -e 's/$/\)/' -e 's/^/ /' >uncovered_new_lines.txt
 
 	grep -q '[^[:space:]]' <uncovered_new_lines.txt &&
 	echo $file >>coverage-data.txt &&
@@ -91,11 +90,7 @@
 
 echo "Commits introducing uncovered code:"
 
-commit_list=$(cat coverage-data.txt |
-	grep -E '^[0-9a-f]{7,} ' |
-	awk '{print $1;}' |
-	sort |
-	uniq)
+commit_list=$(awk '/^[0-9a-f]{7,}/ { print $1 }' coverage-data.txt | sort -u)
 
 (
 	for commit in $commit_list
diff --git a/contrib/credential/libsecret/git-credential-libsecret.c b/contrib/credential/libsecret/git-credential-libsecret.c
index 215a81d..90034d0 100644
--- a/contrib/credential/libsecret/git-credential-libsecret.c
+++ b/contrib/credential/libsecret/git-credential-libsecret.c
@@ -164,6 +164,9 @@ static int keyring_get(struct credential *c)
 			if (g_strv_length(parts) >= 1) {
 				g_free(c->password);
 				c->password = g_strdup(parts[0]);
+			} else {
+				g_free(c->password);
+				c->password = g_strdup("");
 			}
 			for (int i = 1; i < g_strv_length(parts); i++) {
 				if (g_str_has_prefix(parts[i], "password_expiry_utc=")) {
diff --git a/contrib/credential/osxkeychain/Makefile b/contrib/credential/osxkeychain/Makefile
index 4b3a08a..238f5f8 100644
--- a/contrib/credential/osxkeychain/Makefile
+++ b/contrib/credential/osxkeychain/Makefile
@@ -8,7 +8,8 @@
 -include ../../../config.mak
 
 git-credential-osxkeychain: git-credential-osxkeychain.o
-	$(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) -Wl,-framework -Wl,Security
+	$(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) \
+		-framework Security -framework CoreFoundation
 
 git-credential-osxkeychain.o: git-credential-osxkeychain.c
 	$(CC) -c $(CFLAGS) $<
diff --git a/contrib/credential/osxkeychain/git-credential-osxkeychain.c b/contrib/credential/osxkeychain/git-credential-osxkeychain.c
index 5f2e5f1..6a40917 100644
--- a/contrib/credential/osxkeychain/git-credential-osxkeychain.c
+++ b/contrib/credential/osxkeychain/git-credential-osxkeychain.c
@@ -3,14 +3,51 @@
 #include <stdlib.h>
 #include <Security/Security.h>
 
-static SecProtocolType protocol;
-static char *host;
-static char *path;
-static char *username;
-static char *password;
-static UInt16 port;
+#define ENCODING kCFStringEncodingUTF8
+static CFStringRef protocol; /* Stores constant strings - not memory managed */
+static CFStringRef host;
+static CFNumberRef port;
+static CFStringRef path;
+static CFStringRef username;
+static CFDataRef password;
+static CFDataRef password_expiry_utc;
+static CFDataRef oauth_refresh_token;
 
-__attribute__((format (printf, 1, 2)))
+static void clear_credential(void)
+{
+	if (host) {
+		CFRelease(host);
+		host = NULL;
+	}
+	if (port) {
+		CFRelease(port);
+		port = NULL;
+	}
+	if (path) {
+		CFRelease(path);
+		path = NULL;
+	}
+	if (username) {
+		CFRelease(username);
+		username = NULL;
+	}
+	if (password) {
+		CFRelease(password);
+		password = NULL;
+	}
+	if (password_expiry_utc) {
+		CFRelease(password_expiry_utc);
+		password_expiry_utc = NULL;
+	}
+	if (oauth_refresh_token) {
+		CFRelease(oauth_refresh_token);
+		oauth_refresh_token = NULL;
+	}
+}
+
+#define STRING_WITH_LENGTH(s) s, sizeof(s) - 1
+
+__attribute__((format (printf, 1, 2), __noreturn__))
 static void die(const char *err, ...)
 {
 	char msg[4096];
@@ -19,70 +56,199 @@ static void die(const char *err, ...)
 	vsnprintf(msg, sizeof(msg), err, params);
 	fprintf(stderr, "%s\n", msg);
 	va_end(params);
+	clear_credential();
 	exit(1);
 }
 
-static void *xstrdup(const char *s1)
+static void *xmalloc(size_t len)
 {
-	void *ret = strdup(s1);
+	void *ret = malloc(len);
 	if (!ret)
 		die("Out of memory");
 	return ret;
 }
 
-#define KEYCHAIN_ITEM(x) (x ? strlen(x) : 0), x
-#define KEYCHAIN_ARGS \
-	NULL, /* default keychain */ \
-	KEYCHAIN_ITEM(host), \
-	0, NULL, /* account domain */ \
-	KEYCHAIN_ITEM(username), \
-	KEYCHAIN_ITEM(path), \
-	port, \
-	protocol, \
-	kSecAuthenticationTypeDefault
+static CFDictionaryRef create_dictionary(CFAllocatorRef allocator, ...)
+{
+	va_list args;
+	const void *key;
+	CFMutableDictionaryRef result;
 
-static void write_item(const char *what, const char *buf, int len)
+	result = CFDictionaryCreateMutable(allocator,
+					   0,
+					   &kCFTypeDictionaryKeyCallBacks,
+					   &kCFTypeDictionaryValueCallBacks);
+
+
+	va_start(args, allocator);
+	while ((key = va_arg(args, const void *)) != NULL) {
+		const void *value;
+		value = va_arg(args, const void *);
+		if (value)
+			CFDictionarySetValue(result, key, value);
+	}
+	va_end(args);
+
+	return result;
+}
+
+#define CREATE_SEC_ATTRIBUTES(...) \
+	create_dictionary(kCFAllocatorDefault, \
+			  kSecClass, kSecClassInternetPassword, \
+			  kSecAttrServer, host, \
+			  kSecAttrAccount, username, \
+			  kSecAttrPath, path, \
+			  kSecAttrPort, port, \
+			  kSecAttrProtocol, protocol, \
+			  kSecAttrAuthenticationType, \
+			  kSecAttrAuthenticationTypeDefault, \
+			  __VA_ARGS__);
+
+static void write_item(const char *what, const char *buf, size_t len)
 {
 	printf("%s=", what);
 	fwrite(buf, 1, len, stdout);
 	putchar('\n');
 }
 
-static void find_username_in_item(SecKeychainItemRef item)
+static void find_username_in_item(CFDictionaryRef item)
 {
-	SecKeychainAttributeList list;
-	SecKeychainAttribute attr;
+	CFStringRef account_ref;
+	char *username_buf;
+	CFIndex buffer_len;
 
-	list.count = 1;
-	list.attr = &attr;
-	attr.tag = kSecAccountItemAttr;
-
-	if (SecKeychainItemCopyContent(item, NULL, &list, NULL, NULL))
+	account_ref = CFDictionaryGetValue(item, kSecAttrAccount);
+	if (!account_ref)
+	{
+		write_item("username", "", 0);
 		return;
+	}
 
-	write_item("username", attr.data, attr.length);
-	SecKeychainItemFreeContent(&list, NULL);
+	username_buf = (char *)CFStringGetCStringPtr(account_ref, ENCODING);
+	if (username_buf)
+	{
+		write_item("username", username_buf, strlen(username_buf));
+		return;
+	}
+
+	/* If we can't get a CString pointer then
+	 * we need to allocate our own buffer */
+	buffer_len = CFStringGetMaximumSizeForEncoding(
+			CFStringGetLength(account_ref), ENCODING) + 1;
+	username_buf = xmalloc(buffer_len);
+	if (CFStringGetCString(account_ref,
+				username_buf,
+				buffer_len,
+				ENCODING)) {
+		write_item("username", username_buf, buffer_len - 1);
+	}
+	free(username_buf);
 }
 
-static void find_internet_password(void)
+static OSStatus find_internet_password(void)
 {
-	void *buf;
-	UInt32 len;
-	SecKeychainItemRef item;
+	CFDictionaryRef attrs;
+	CFDictionaryRef item;
+	CFDataRef data;
+	OSStatus result;
 
-	if (SecKeychainFindInternetPassword(KEYCHAIN_ARGS, &len, &buf, &item))
-		return;
+	attrs = CREATE_SEC_ATTRIBUTES(kSecMatchLimit, kSecMatchLimitOne,
+				      kSecReturnAttributes, kCFBooleanTrue,
+				      kSecReturnData, kCFBooleanTrue,
+				      NULL);
+	result = SecItemCopyMatching(attrs, (CFTypeRef *)&item);
+	if (result) {
+		goto out;
+	}
 
-	write_item("password", buf, len);
+	data = CFDictionaryGetValue(item, kSecValueData);
+
+	write_item("password",
+		   (const char *)CFDataGetBytePtr(data),
+		   CFDataGetLength(data));
 	if (!username)
 		find_username_in_item(item);
 
-	SecKeychainItemFreeContent(NULL, buf);
+	CFRelease(item);
+
+out:
+	CFRelease(attrs);
+
+	/* We consider not found to not be an error */
+	if (result == errSecItemNotFound)
+		result = errSecSuccess;
+
+	return result;
 }
 
-static void delete_internet_password(void)
+static OSStatus delete_ref(const void *itemRef)
 {
-	SecKeychainItemRef item;
+	CFArrayRef item_ref_list;
+	CFDictionaryRef delete_query;
+	OSStatus result;
+
+	item_ref_list = CFArrayCreate(kCFAllocatorDefault,
+				      &itemRef,
+				      1,
+				      &kCFTypeArrayCallBacks);
+	delete_query = create_dictionary(kCFAllocatorDefault,
+					 kSecClass, kSecClassInternetPassword,
+					 kSecMatchItemList, item_ref_list,
+					 NULL);
+
+	if (password) {
+		/* We only want to delete items with a matching password */
+		CFIndex capacity;
+		CFMutableDictionaryRef query;
+		CFDataRef data;
+
+		capacity = CFDictionaryGetCount(delete_query) + 1;
+		query = CFDictionaryCreateMutableCopy(kCFAllocatorDefault,
+						      capacity,
+						      delete_query);
+		CFDictionarySetValue(query, kSecReturnData, kCFBooleanTrue);
+		result = SecItemCopyMatching(query, (CFTypeRef *)&data);
+		if (!result) {
+			CFDataRef kc_password;
+			const UInt8 *raw_data;
+			const UInt8 *line;
+
+			/* Don't match appended metadata */
+			raw_data = CFDataGetBytePtr(data);
+			line = memchr(raw_data, '\n', CFDataGetLength(data));
+			if (line)
+				kc_password = CFDataCreateWithBytesNoCopy(
+						kCFAllocatorDefault,
+						raw_data,
+						line - raw_data,
+						kCFAllocatorNull);
+			else
+				kc_password = data;
+
+			if (CFEqual(kc_password, password))
+				result = SecItemDelete(delete_query);
+
+			if (line)
+				CFRelease(kc_password);
+			CFRelease(data);
+		}
+
+		CFRelease(query);
+	} else {
+		result = SecItemDelete(delete_query);
+	}
+
+	CFRelease(delete_query);
+	CFRelease(item_ref_list);
+
+	return result;
+}
+
+static OSStatus delete_internet_password(void)
+{
+	CFDictionaryRef attrs;
+	CFArrayRef refs;
+	OSStatus result;
 
 	/*
 	 * Require at least a protocol and host for removal, which is what git
@@ -90,25 +256,69 @@ static void delete_internet_password(void)
 	 * Keychain manager.
 	 */
 	if (!protocol || !host)
-		return;
+		return -1;
 
-	if (SecKeychainFindInternetPassword(KEYCHAIN_ARGS, 0, NULL, &item))
-		return;
+	attrs = CREATE_SEC_ATTRIBUTES(kSecMatchLimit, kSecMatchLimitAll,
+				      kSecReturnRef, kCFBooleanTrue,
+				      NULL);
+	result = SecItemCopyMatching(attrs, (CFTypeRef *)&refs);
+	CFRelease(attrs);
 
-	SecKeychainItemDelete(item);
+	if (!result) {
+		for (CFIndex i = 0; !result && i < CFArrayGetCount(refs); i++)
+			result = delete_ref(CFArrayGetValueAtIndex(refs, i));
+
+		CFRelease(refs);
+	}
+
+	/* We consider not found to not be an error */
+	if (result == errSecItemNotFound)
+		result = errSecSuccess;
+
+	return result;
 }
 
-static void add_internet_password(void)
+static OSStatus add_internet_password(void)
 {
+	CFMutableDataRef data;
+	CFDictionaryRef attrs;
+	OSStatus result;
+
 	/* Only store complete credentials */
 	if (!protocol || !host || !username || !password)
-		return;
+		return -1;
 
-	if (SecKeychainAddInternetPassword(
-	      KEYCHAIN_ARGS,
-	      KEYCHAIN_ITEM(password),
-	      NULL))
-		return;
+	data = CFDataCreateMutableCopy(kCFAllocatorDefault, 0, password);
+	if (password_expiry_utc) {
+		CFDataAppendBytes(data,
+		    (const UInt8 *)STRING_WITH_LENGTH("\npassword_expiry_utc="));
+		CFDataAppendBytes(data,
+				  CFDataGetBytePtr(password_expiry_utc),
+				  CFDataGetLength(password_expiry_utc));
+	}
+	if (oauth_refresh_token) {
+		CFDataAppendBytes(data,
+		    (const UInt8 *)STRING_WITH_LENGTH("\noauth_refresh_token="));
+		CFDataAppendBytes(data,
+				  CFDataGetBytePtr(oauth_refresh_token),
+				  CFDataGetLength(oauth_refresh_token));
+	}
+
+	attrs = CREATE_SEC_ATTRIBUTES(kSecValueData, data,
+				      NULL);
+
+	result = SecItemAdd(attrs, NULL);
+	if (result == errSecDuplicateItem) {
+		CFDictionaryRef query;
+		query = CREATE_SEC_ATTRIBUTES(NULL);
+		result = SecItemUpdate(query, attrs);
+		CFRelease(query);
+	}
+
+	CFRelease(data);
+	CFRelease(attrs);
+
+	return result;
 }
 
 static void read_credential(void)
@@ -131,36 +341,60 @@ static void read_credential(void)
 
 		if (!strcmp(buf, "protocol")) {
 			if (!strcmp(v, "imap"))
-				protocol = kSecProtocolTypeIMAP;
+				protocol = kSecAttrProtocolIMAP;
 			else if (!strcmp(v, "imaps"))
-				protocol = kSecProtocolTypeIMAPS;
+				protocol = kSecAttrProtocolIMAPS;
 			else if (!strcmp(v, "ftp"))
-				protocol = kSecProtocolTypeFTP;
+				protocol = kSecAttrProtocolFTP;
 			else if (!strcmp(v, "ftps"))
-				protocol = kSecProtocolTypeFTPS;
+				protocol = kSecAttrProtocolFTPS;
 			else if (!strcmp(v, "https"))
-				protocol = kSecProtocolTypeHTTPS;
+				protocol = kSecAttrProtocolHTTPS;
 			else if (!strcmp(v, "http"))
-				protocol = kSecProtocolTypeHTTP;
+				protocol = kSecAttrProtocolHTTP;
 			else if (!strcmp(v, "smtp"))
-				protocol = kSecProtocolTypeSMTP;
-			else /* we don't yet handle other protocols */
+				protocol = kSecAttrProtocolSMTP;
+			else {
+				/* we don't yet handle other protocols */
+				clear_credential();
 				exit(0);
+			}
 		}
 		else if (!strcmp(buf, "host")) {
 			char *colon = strchr(v, ':');
 			if (colon) {
+				UInt16 port_i;
 				*colon++ = '\0';
-				port = atoi(colon);
+				port_i = atoi(colon);
+				port = CFNumberCreate(kCFAllocatorDefault,
+						      kCFNumberShortType,
+						      &port_i);
 			}
-			host = xstrdup(v);
+			host = CFStringCreateWithCString(kCFAllocatorDefault,
+							 v,
+							 ENCODING);
 		}
 		else if (!strcmp(buf, "path"))
-			path = xstrdup(v);
+			path = CFStringCreateWithCString(kCFAllocatorDefault,
+							 v,
+							 ENCODING);
 		else if (!strcmp(buf, "username"))
-			username = xstrdup(v);
+			username = CFStringCreateWithCString(
+					kCFAllocatorDefault,
+					v,
+					ENCODING);
 		else if (!strcmp(buf, "password"))
-			password = xstrdup(v);
+			password = CFDataCreate(kCFAllocatorDefault,
+						(UInt8 *)v,
+						strlen(v));
+		else if (!strcmp(buf, "password_expiry_utc"))
+			password_expiry_utc = CFDataCreate(kCFAllocatorDefault,
+							   (UInt8 *)v,
+							   strlen(v));
+		else if (!strcmp(buf, "oauth_refresh_token"))
+			oauth_refresh_token = CFDataCreate(kCFAllocatorDefault,
+							   (UInt8 *)v,
+							   strlen(v));
 		/*
 		 * Ignore other lines; we don't know what they mean, but
 		 * this future-proofs us when later versions of git do
@@ -173,6 +407,7 @@ static void read_credential(void)
 
 int main(int argc, const char **argv)
 {
+	OSStatus result = 0;
 	const char *usage =
 		"usage: git credential-osxkeychain <get|store|erase>";
 
@@ -182,12 +417,17 @@ int main(int argc, const char **argv)
 	read_credential();
 
 	if (!strcmp(argv[1], "get"))
-		find_internet_password();
+		result = find_internet_password();
 	else if (!strcmp(argv[1], "store"))
-		add_internet_password();
+		result = add_internet_password();
 	else if (!strcmp(argv[1], "erase"))
-		delete_internet_password();
+		result = delete_internet_password();
 	/* otherwise, ignore unknown action */
 
+	if (result)
+		die("failed to %s: %d", argv[1], (int)result);
+
+	clear_credential();
+
 	return 0;
 }
diff --git a/contrib/credential/wincred/git-credential-wincred.c b/contrib/credential/wincred/git-credential-wincred.c
index 4cd56c4..4be0d58 100644
--- a/contrib/credential/wincred/git-credential-wincred.c
+++ b/contrib/credential/wincred/git-credential-wincred.c
@@ -35,7 +35,7 @@ static void *xmalloc(size_t size)
 }
 
 static WCHAR *wusername, *password, *protocol, *host, *path, target[1024],
-	*password_expiry_utc;
+	*password_expiry_utc, *oauth_refresh_token;
 
 static void write_item(const char *what, LPCWSTR wbuf, int wlen)
 {
@@ -140,6 +140,11 @@ static void get_credential(void)
 	DWORD num_creds;
 	int i;
 	CREDENTIAL_ATTRIBUTEW *attr;
+	WCHAR *secret;
+	WCHAR *line;
+	WCHAR *remaining_lines;
+	WCHAR *part;
+	WCHAR *remaining_parts;
 
 	if (!CredEnumerateW(L"git:*", 0, &num_creds, &creds))
 		return;
@@ -149,9 +154,24 @@ static void get_credential(void)
 		if (match_cred(creds[i], 0)) {
 			write_item("username", creds[i]->UserName,
 				creds[i]->UserName ? wcslen(creds[i]->UserName) : 0);
-			write_item("password",
-				(LPCWSTR)creds[i]->CredentialBlob,
-				creds[i]->CredentialBlobSize / sizeof(WCHAR));
+			if (creds[i]->CredentialBlobSize > 0) {
+				secret = xmalloc(creds[i]->CredentialBlobSize);
+				wcsncpy_s(secret, creds[i]->CredentialBlobSize, (LPCWSTR)creds[i]->CredentialBlob, creds[i]->CredentialBlobSize / sizeof(WCHAR));
+				line = wcstok_s(secret, L"\r\n", &remaining_lines);
+				write_item("password", line, line ? wcslen(line) : 0);
+				while(line != NULL) {
+					part = wcstok_s(line, L"=", &remaining_parts);
+					if (!wcscmp(part, L"oauth_refresh_token")) {
+						write_item("oauth_refresh_token", remaining_parts, remaining_parts ? wcslen(remaining_parts) : 0);
+					}
+					line = wcstok_s(NULL, L"\r\n", &remaining_lines);
+				}
+				free(secret);
+			} else {
+				write_item("password",
+						(LPCWSTR)creds[i]->CredentialBlob,
+						creds[i]->CredentialBlobSize / sizeof(WCHAR));
+			}
 			for (int j = 0; j < creds[i]->AttributeCount; j++) {
 				attr = creds[i]->Attributes + j;
 				if (!wcscmp(attr->Keyword, L"git_password_expiry_utc")) {
@@ -170,16 +190,26 @@ static void store_credential(void)
 {
 	CREDENTIALW cred;
 	CREDENTIAL_ATTRIBUTEW expiry_attr;
+	WCHAR *secret;
+	int wlen;
 
 	if (!wusername || !password)
 		return;
 
+	if (oauth_refresh_token) {
+		wlen = _scwprintf(L"%s\r\noauth_refresh_token=%s", password, oauth_refresh_token);
+		secret = xmalloc(sizeof(WCHAR) * wlen);
+		_snwprintf_s(secret, sizeof(WCHAR) * wlen, wlen, L"%s\r\noauth_refresh_token=%s", password, oauth_refresh_token);
+	} else {
+		secret = _wcsdup(password);
+	}
+
 	cred.Flags = 0;
 	cred.Type = CRED_TYPE_GENERIC;
 	cred.TargetName = target;
 	cred.Comment = L"saved by git-credential-wincred";
-	cred.CredentialBlobSize = (wcslen(password)) * sizeof(WCHAR);
-	cred.CredentialBlob = (LPVOID)password;
+	cred.CredentialBlobSize = wcslen(secret) * sizeof(WCHAR);
+	cred.CredentialBlob = (LPVOID)_wcsdup(secret);
 	cred.Persist = CRED_PERSIST_LOCAL_MACHINE;
 	cred.AttributeCount = 0;
 	cred.Attributes = NULL;
@@ -194,6 +224,8 @@ static void store_credential(void)
 	cred.TargetAlias = NULL;
 	cred.UserName = wusername;
 
+	free(secret);
+
 	if (!CredWriteW(&cred, 0))
 		die("CredWrite failed");
 }
@@ -265,6 +297,8 @@ static void read_credential(void)
 			password = utf8_to_utf16_dup(v);
 		else if (!strcmp(buf, "password_expiry_utc"))
 			password_expiry_utc = utf8_to_utf16_dup(v);
+		else if (!strcmp(buf, "oauth_refresh_token"))
+			oauth_refresh_token = utf8_to_utf16_dup(v);
 		/*
 		 * Ignore other lines; we don't know what they mean, but
 		 * this future-proofs us when later versions of git do
diff --git a/contrib/hg-to-git/hg-to-git.py b/contrib/hg-to-git/hg-to-git.py
deleted file mode 100755
index 7eb1b24..0000000
--- a/contrib/hg-to-git/hg-to-git.py
+++ /dev/null
@@ -1,254 +0,0 @@
-#!/usr/bin/env python
-
-""" hg-to-git.py - A Mercurial to GIT converter
-
-    Copyright (C)2007 Stelian Pop <stelian@popies.net>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2, or (at your option)
-    any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, see <http://www.gnu.org/licenses/>.
-"""
-
-import os, os.path, sys
-import tempfile, pickle, getopt
-import re
-
-if sys.hexversion < 0x02030000:
-   # The behavior of the pickle module changed significantly in 2.3
-   sys.stderr.write("hg-to-git.py: requires Python 2.3 or later.\n")
-   sys.exit(1)
-
-# Maps hg version -> git version
-hgvers = {}
-# List of children for each hg revision
-hgchildren = {}
-# List of parents for each hg revision
-hgparents = {}
-# Current branch for each hg revision
-hgbranch = {}
-# Number of new changesets converted from hg
-hgnewcsets = 0
-
-#------------------------------------------------------------------------------
-
-def usage():
-
-        print("""\
-%s: [OPTIONS] <hgprj>
-
-options:
-    -s, --gitstate=FILE: name of the state to be saved/read
-                         for incrementals
-    -n, --nrepack=INT:   number of changesets that will trigger
-                         a repack (default=0, -1 to deactivate)
-    -v, --verbose:       be verbose
-
-required:
-    hgprj:  name of the HG project to import (directory)
-""" % sys.argv[0])
-
-#------------------------------------------------------------------------------
-
-def getgitenv(user, date):
-    env = ''
-    elems = re.compile('(.*?)\s+<(.*)>').match(user)
-    if elems:
-        env += 'export GIT_AUTHOR_NAME="%s" ;' % elems.group(1)
-        env += 'export GIT_COMMITTER_NAME="%s" ;' % elems.group(1)
-        env += 'export GIT_AUTHOR_EMAIL="%s" ;' % elems.group(2)
-        env += 'export GIT_COMMITTER_EMAIL="%s" ;' % elems.group(2)
-    else:
-        env += 'export GIT_AUTHOR_NAME="%s" ;' % user
-        env += 'export GIT_COMMITTER_NAME="%s" ;' % user
-        env += 'export GIT_AUTHOR_EMAIL= ;'
-        env += 'export GIT_COMMITTER_EMAIL= ;'
-
-    env += 'export GIT_AUTHOR_DATE="%s" ;' % date
-    env += 'export GIT_COMMITTER_DATE="%s" ;' % date
-    return env
-
-#------------------------------------------------------------------------------
-
-state = ''
-opt_nrepack = 0
-verbose = False
-
-try:
-    opts, args = getopt.getopt(sys.argv[1:], 's:t:n:v', ['gitstate=', 'tempdir=', 'nrepack=', 'verbose'])
-    for o, a in opts:
-        if o in ('-s', '--gitstate'):
-            state = a
-            state = os.path.abspath(state)
-        if o in ('-n', '--nrepack'):
-            opt_nrepack = int(a)
-        if o in ('-v', '--verbose'):
-            verbose = True
-    if len(args) != 1:
-        raise Exception('params')
-except:
-    usage()
-    sys.exit(1)
-
-hgprj = args[0]
-os.chdir(hgprj)
-
-if state:
-    if os.path.exists(state):
-        if verbose:
-            print('State does exist, reading')
-        f = open(state, 'r')
-        hgvers = pickle.load(f)
-    else:
-        print('State does not exist, first run')
-
-sock = os.popen('hg tip --template "{rev}"')
-tip = sock.read()
-if sock.close():
-    sys.exit(1)
-if verbose:
-    print('tip is', tip)
-
-# Calculate the branches
-if verbose:
-    print('analysing the branches...')
-hgchildren["0"] = ()
-hgparents["0"] = (None, None)
-hgbranch["0"] = "master"
-for cset in range(1, int(tip) + 1):
-    hgchildren[str(cset)] = ()
-    prnts = os.popen('hg log -r %d --template "{parents}"' % cset).read().strip().split(' ')
-    prnts = map(lambda x: x[:x.find(':')], prnts)
-    if prnts[0] != '':
-        parent = prnts[0].strip()
-    else:
-        parent = str(cset - 1)
-    hgchildren[parent] += ( str(cset), )
-    if len(prnts) > 1:
-        mparent = prnts[1].strip()
-        hgchildren[mparent] += ( str(cset), )
-    else:
-        mparent = None
-
-    hgparents[str(cset)] = (parent, mparent)
-
-    if mparent:
-        # For merge changesets, take either one, preferably the 'master' branch
-        if hgbranch[mparent] == 'master':
-            hgbranch[str(cset)] = 'master'
-        else:
-            hgbranch[str(cset)] = hgbranch[parent]
-    else:
-        # Normal changesets
-        # For first children, take the parent branch, for the others create a new branch
-        if hgchildren[parent][0] == str(cset):
-            hgbranch[str(cset)] = hgbranch[parent]
-        else:
-            hgbranch[str(cset)] = "branch-" + str(cset)
-
-if "0" not in hgvers:
-    print('creating repository')
-    os.system('git init')
-
-# loop through every hg changeset
-for cset in range(int(tip) + 1):
-
-    # incremental, already seen
-    if str(cset) in hgvers:
-        continue
-    hgnewcsets += 1
-
-    # get info
-    log_data = os.popen('hg log -r %d --template "{tags}\n{date|date}\n{author}\n"' % cset).readlines()
-    tag = log_data[0].strip()
-    date = log_data[1].strip()
-    user = log_data[2].strip()
-    parent = hgparents[str(cset)][0]
-    mparent = hgparents[str(cset)][1]
-
-    #get comment
-    (fdcomment, filecomment) = tempfile.mkstemp()
-    csetcomment = os.popen('hg log -r %d --template "{desc}"' % cset).read().strip()
-    os.write(fdcomment, csetcomment)
-    os.close(fdcomment)
-
-    print('-----------------------------------------')
-    print('cset:', cset)
-    print('branch:', hgbranch[str(cset)])
-    print('user:', user)
-    print('date:', date)
-    print('comment:', csetcomment)
-    if parent:
-        print('parent:', parent)
-    if mparent:
-        print('mparent:', mparent)
-    if tag:
-        print('tag:', tag)
-    print('-----------------------------------------')
-
-    # checkout the parent if necessary
-    if cset != 0:
-        if hgbranch[str(cset)] == "branch-" + str(cset):
-            print('creating new branch', hgbranch[str(cset)])
-            os.system('git checkout -b %s %s' % (hgbranch[str(cset)], hgvers[parent]))
-        else:
-            print('checking out branch', hgbranch[str(cset)])
-            os.system('git checkout %s' % hgbranch[str(cset)])
-
-    # merge
-    if mparent:
-        if hgbranch[parent] == hgbranch[str(cset)]:
-            otherbranch = hgbranch[mparent]
-        else:
-            otherbranch = hgbranch[parent]
-        print('merging', otherbranch, 'into', hgbranch[str(cset)])
-        os.system(getgitenv(user, date) + 'git merge --no-commit -s ours "" %s %s' % (hgbranch[str(cset)], otherbranch))
-
-    # remove everything except .git and .hg directories
-    os.system('find . \( -path "./.hg" -o -path "./.git" \) -prune -o ! -name "." -print | xargs rm -rf')
-
-    # repopulate with checkouted files
-    os.system('hg update -C %d' % cset)
-
-    # add new files
-    os.system('git ls-files -x .hg --others | git update-index --add --stdin')
-    # delete removed files
-    os.system('git ls-files -x .hg --deleted | git update-index --remove --stdin')
-
-    # commit
-    os.system(getgitenv(user, date) + 'git commit --allow-empty --allow-empty-message -a -F %s' % filecomment)
-    os.unlink(filecomment)
-
-    # tag
-    if tag and tag != 'tip':
-        os.system(getgitenv(user, date) + 'git tag %s' % tag)
-
-    # delete branch if not used anymore...
-    if mparent and len(hgchildren[str(cset)]):
-        print("Deleting unused branch:", otherbranch)
-        os.system('git branch -d %s' % otherbranch)
-
-    # retrieve and record the version
-    vvv = os.popen('git show --quiet --pretty=format:%H').read()
-    print('record', cset, '->', vvv)
-    hgvers[str(cset)] = vvv
-
-if hgnewcsets >= opt_nrepack and opt_nrepack != -1:
-    os.system('git repack -a -d')
-
-# write the state for incrementals
-if state:
-    if verbose:
-        print('Writing state')
-    f = open(state, 'w')
-    pickle.dump(hgvers, f)
-
-# vim: et ts=8 sw=4 sts=4
diff --git a/contrib/hg-to-git/hg-to-git.txt b/contrib/hg-to-git/hg-to-git.txt
deleted file mode 100644
index 91f8fe6..0000000
--- a/contrib/hg-to-git/hg-to-git.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-hg-to-git.py is able to convert a Mercurial repository into a git one,
-and preserves the branches in the process (unlike tailor)
-
-hg-to-git.py can probably be greatly improved (it's a rather crude
-combination of shell and python) but it does already work quite well for
-me. Features:
-	- supports incremental conversion
-	  (for keeping a git repo in sync with a hg one)
-        - supports hg branches
-        - converts hg tags
-
-Note that the git repository will be created 'in place' (at the same
-location as the source hg repo). You will have to manually remove the
-'.hg' directory after the conversion.
-
-Also note that the incremental conversion uses 'simple' hg changesets
-identifiers (ordinals, as opposed to SHA-1 ids), and since these ids
-are not stable across different repositories the hg-to-git.py state file
-is forever tied to one hg repository.
-
-Stelian Pop <stelian@popies.net>
diff --git a/contrib/subtree/git-subtree.sh b/contrib/subtree/git-subtree.sh
index e0c5d3b..5dab3f5 100755
--- a/contrib/subtree/git-subtree.sh
+++ b/contrib/subtree/git-subtree.sh
@@ -373,7 +373,8 @@
 
 # Usage: process_subtree_split_trailer SPLIT_HASH MAIN_HASH [REPOSITORY]
 process_subtree_split_trailer () {
-	assert test $# = 2 -o $# = 3
+	assert test $# -ge 2
+	assert test $# -le 3
 	b="$1"
 	sq="$2"
 	repository=""
@@ -402,7 +403,8 @@
 
 # Usage: find_latest_squash DIR [REPOSITORY]
 find_latest_squash () {
-	assert test $# = 1 -o $# = 2
+	assert test $# -ge 1
+	assert test $# -le 2
 	dir="$1"
 	repository=""
 	if test "$#" = 2
@@ -455,7 +457,8 @@
 
 # Usage: find_existing_splits DIR REV [REPOSITORY]
 find_existing_splits () {
-	assert test $# = 2 -o $# = 3
+	assert test $# -ge 2
+	assert test $# -le 3
 	debug "Looking for prior splits..."
 	local indent=$(($indent + 1))
 
@@ -489,13 +492,13 @@
 			;;
 		END)
 			debug "Main is: '$main'"
-			if test -z "$main" -a -n "$sub"
+			if test -z "$main" && test -n "$sub"
 			then
 				# squash commits refer to a subtree
 				debug "  Squash: $sq from $sub"
 				cache_set "$sq" "$sub"
 			fi
-			if test -n "$main" -a -n "$sub"
+			if test -n "$main" && test -n "$sub"
 			then
 				debug "  Prior: $main -> $sub"
 				cache_set $main $sub
@@ -638,10 +641,16 @@
 	while read mode type tree name
 	do
 		assert test "$name" = "$dir"
-		assert test "$type" = "tree" -o "$type" = "commit"
-		test "$type" = "commit" && continue  # ignore submodules
-		echo $tree
-		break
+
+		case "$type" in
+		commit)
+			continue;; # ignore submodules
+		tree)
+			echo $tree
+			break;;
+		*)
+			die "fatal: tree entry is of type ${type}, expected tree or commit";;
+		esac
 	done || exit $?
 }
 
@@ -778,6 +787,22 @@
 		die "fatal: '$1' does not look like a ref"
 }
 
+# Usage: check if a commit from another subtree should be
+# ignored from processing for splits
+should_ignore_subtree_split_commit () {
+	assert test $# = 1
+	local rev="$1"
+	if test -n "$(git log -1 --grep="git-subtree-dir:" $rev)"
+	then
+		if test -z "$(git log -1 --grep="git-subtree-mainline:" $rev)" &&
+			test -z "$(git log -1 --grep="git-subtree-dir: $arg_prefix$" $rev)"
+		then
+			return 0
+		fi
+	fi
+	return 1
+}
+
 # Usage: process_split_commit REV PARENTS
 process_split_commit () {
 	assert test $# = 2
@@ -916,7 +941,7 @@
 	if test $# -eq 0
 	then
 		rev=$(git rev-parse HEAD)
-	elif test $# -eq 1 -o $# -eq 2
+	elif test $# -eq 1 || test $# -eq 2
 	then
 		rev=$(git rev-parse -q --verify "$1^{commit}") ||
 			die "fatal: '$1' does not refer to a commit"
@@ -963,7 +988,19 @@
 	eval "$grl" |
 	while read rev parents
 	do
-		process_split_commit "$rev" "$parents"
+		if should_ignore_subtree_split_commit "$rev"
+		then
+			continue
+		fi
+		parsedparents=''
+		for parent in $parents
+		do
+			if ! should_ignore_subtree_split_commit "$parent"
+			then
+				parsedparents="$parsedparents$parent "
+			fi
+		done
+		process_split_commit "$rev" "$parsedparents"
 	done || exit $?
 
 	latest_new=$(cache_get latest_new) || exit $?
@@ -1006,8 +1043,11 @@
 
 # Usage: cmd_merge REV [REPOSITORY]
 cmd_merge () {
-	test $# -eq 1 -o $# -eq 2 ||
+	if test $# -lt 1 || test $# -gt 2
+	then
 		die "fatal: you must provide exactly one revision, and optionally a repository. Got: '$*'"
+	fi
+
 	rev=$(git rev-parse -q --verify "$1^{commit}") ||
 		die "fatal: '$1' does not refer to a commit"
 	repository=""
diff --git a/contrib/subtree/t/t7900-subtree.sh b/contrib/subtree/t/t7900-subtree.sh
index 49a21dd..c3bd2a5 100755
--- a/contrib/subtree/t/t7900-subtree.sh
+++ b/contrib/subtree/t/t7900-subtree.sh
@@ -63,7 +63,7 @@
 	git -C "$1" log -1 --format=%B HEAD^2 >msg &&
 	test_commit -C "$1-sub" --annotate sub2 &&
 	git clone --no-local "$1" "$1-clone" &&
-	new_commit=$(cat msg | sed -e "s/$commit/$tag/" | git -C "$1-clone" commit-tree HEAD^2^{tree}) &&
+	new_commit=$(sed -e "s/$commit/$tag/" msg | git -C "$1-clone" commit-tree HEAD^2^{tree}) &&
 	git -C "$1-clone" replace HEAD^2 $new_commit
 }
 
@@ -385,6 +385,46 @@
 	)
 '
 
+# Tests that commits from other subtrees are not processed as
+# part of a split.
+#
+# This test performs the following:
+# - Creates Repo with subtrees 'subA' and 'subB'
+# - Creates commits in the repo including changes to subtrees
+# - Runs the following 'split' and commit' commands in order:
+# 	- Perform 'split' on subtree A
+# 	- Perform 'split' on subtree B
+# 	- Create new commits with changes to subtree A and B
+# 	- Perform split on subtree A
+# 	- Check that the commits in subtree B are not processed
+#			as part of the subtree A split
+test_expect_success 'split with multiple subtrees' '
+	subtree_test_create_repo "$test_count" &&
+	subtree_test_create_repo "$test_count/subA" &&
+	subtree_test_create_repo "$test_count/subB" &&
+	test_create_commit "$test_count" main1 &&
+	test_create_commit "$test_count/subA" subA1 &&
+	test_create_commit "$test_count/subA" subA2 &&
+	test_create_commit "$test_count/subA" subA3 &&
+	test_create_commit "$test_count/subB" subB1 &&
+	git -C "$test_count" fetch ./subA HEAD &&
+	git -C "$test_count" subtree add --prefix=subADir FETCH_HEAD &&
+	git -C "$test_count" fetch ./subB HEAD &&
+	git -C "$test_count" subtree add --prefix=subBDir FETCH_HEAD &&
+	test_create_commit "$test_count" subADir/main-subA1 &&
+	test_create_commit "$test_count" subBDir/main-subB1 &&
+	git -C "$test_count" subtree split --prefix=subADir \
+		--squash --rejoin -m "Sub A Split 1" &&
+	git -C "$test_count" subtree split --prefix=subBDir \
+		--squash --rejoin -m "Sub B Split 1" &&
+	test_create_commit "$test_count" subADir/main-subA2 &&
+	test_create_commit "$test_count" subBDir/main-subB2 &&
+	git -C "$test_count" subtree split --prefix=subADir \
+		--squash --rejoin -m "Sub A Split 2" &&
+	test "$(git -C "$test_count" subtree split --prefix=subBDir \
+		--squash --rejoin -d -m "Sub B Split 1" 2>&1 | grep -w "\[1\]")" = ""
+'
+
 test_expect_success 'split sub dir/ with --rejoin from scratch' '
 	subtree_test_create_repo "$test_count" &&
 	test_create_commit "$test_count" main1 &&
diff --git a/contrib/vscode/init.sh b/contrib/vscode/init.sh
index 521d303..f2d61bb 100755
--- a/contrib/vscode/init.sh
+++ b/contrib/vscode/init.sh
@@ -92,7 +92,6 @@
         "isexe",
         "iskeychar",
         "kompare",
-        "mksnpath",
         "mktag",
         "mktree",
         "mmblob",
diff --git a/contrib/workdir/git-new-workdir b/contrib/workdir/git-new-workdir
index 888c34a..989197a 100755
--- a/contrib/workdir/git-new-workdir
+++ b/contrib/workdir/git-new-workdir
@@ -79,7 +79,7 @@
 # create the links to the original repo.  explicitly exclude index, HEAD and
 # logs/HEAD from the list since they are purely related to the current working
 # directory, and should not be shared.
-for x in config refs logs/refs objects info hooks packed-refs remotes rr-cache svn
+for x in config refs logs/refs objects info hooks packed-refs remotes rr-cache svn reftable
 do
 	# create a containing directory if needed
 	case $x in
diff --git a/convert.c b/convert.c
index a8870ba..35b25eb 100644
--- a/convert.c
+++ b/convert.c
@@ -1028,7 +1028,7 @@ static int read_convert_config(const char *var, const char *value,
 	if (parse_config_key(var, "filter", &name, &namelen, &key) < 0 || !name)
 		return 0;
 	for (drv = user_convert; drv; drv = drv->next)
-		if (!strncmp(drv->name, name, namelen) && !drv->name[namelen])
+		if (!xstrncmpz(drv->name, name, namelen))
 			break;
 	if (!drv) {
 		CALLOC_ARRAY(drv, 1);
diff --git a/copy.c b/copy.c
index 23d84c6..d9d2092 100644
--- a/copy.c
+++ b/copy.c
@@ -1,6 +1,9 @@
 #include "git-compat-util.h"
 #include "copy.h"
 #include "path.h"
+#include "gettext.h"
+#include "strbuf.h"
+#include "abspath.h"
 
 int copy_fd(int ifd, int ofd)
 {
diff --git a/date.c b/date.c
index 619ada5..7365a4a 100644
--- a/date.c
+++ b/date.c
@@ -207,13 +207,13 @@ void show_date_relative(timestamp_t time, struct strbuf *timebuf)
 		 (diff + 183) / 365);
 }
 
-struct date_mode *date_mode_from_type(enum date_mode_type type)
+struct date_mode date_mode_from_type(enum date_mode_type type)
 {
-	static struct date_mode mode = DATE_MODE_INIT;
+	struct date_mode mode = DATE_MODE_INIT;
 	if (type == DATE_STRFTIME)
 		BUG("cannot create anonymous strftime date_mode struct");
 	mode.type = type;
-	return &mode;
+	return mode;
 }
 
 static void show_date_normal(struct strbuf *buf, timestamp_t time, struct tm *tm, int tz, struct tm *human_tm, int human_tz, int local)
@@ -283,7 +283,7 @@ static void show_date_normal(struct strbuf *buf, timestamp_t time, struct tm *tm
 		strbuf_addf(buf, " %+05d", tz);
 }
 
-const char *show_date(timestamp_t time, int tz, const struct date_mode *mode)
+const char *show_date(timestamp_t time, int tz, struct date_mode mode)
 {
 	struct tm *tm;
 	struct tm tmbuf = { 0 };
@@ -291,13 +291,13 @@ const char *show_date(timestamp_t time, int tz, const struct date_mode *mode)
 	int human_tz = -1;
 	static struct strbuf timebuf = STRBUF_INIT;
 
-	if (mode->type == DATE_UNIX) {
+	if (mode.type == DATE_UNIX) {
 		strbuf_reset(&timebuf);
 		strbuf_addf(&timebuf, "%"PRItime, time);
 		return timebuf.buf;
 	}
 
-	if (mode->type == DATE_HUMAN) {
+	if (mode.type == DATE_HUMAN) {
 		struct timeval now;
 
 		get_time(&now);
@@ -306,22 +306,22 @@ const char *show_date(timestamp_t time, int tz, const struct date_mode *mode)
 		human_tz = local_time_tzoffset(now.tv_sec, &human_tm);
 	}
 
-	if (mode->local)
+	if (mode.local)
 		tz = local_tzoffset(time);
 
-	if (mode->type == DATE_RAW) {
+	if (mode.type == DATE_RAW) {
 		strbuf_reset(&timebuf);
 		strbuf_addf(&timebuf, "%"PRItime" %+05d", time, tz);
 		return timebuf.buf;
 	}
 
-	if (mode->type == DATE_RELATIVE) {
+	if (mode.type == DATE_RELATIVE) {
 		strbuf_reset(&timebuf);
 		show_date_relative(time, &timebuf);
 		return timebuf.buf;
 	}
 
-	if (mode->local)
+	if (mode.local)
 		tm = time_to_tm_local(time, &tmbuf);
 	else
 		tm = time_to_tm(time, tz, &tmbuf);
@@ -331,35 +331,39 @@ const char *show_date(timestamp_t time, int tz, const struct date_mode *mode)
 	}
 
 	strbuf_reset(&timebuf);
-	if (mode->type == DATE_SHORT)
+	if (mode.type == DATE_SHORT)
 		strbuf_addf(&timebuf, "%04d-%02d-%02d", tm->tm_year + 1900,
 				tm->tm_mon + 1, tm->tm_mday);
-	else if (mode->type == DATE_ISO8601)
+	else if (mode.type == DATE_ISO8601)
 		strbuf_addf(&timebuf, "%04d-%02d-%02d %02d:%02d:%02d %+05d",
 				tm->tm_year + 1900,
 				tm->tm_mon + 1,
 				tm->tm_mday,
 				tm->tm_hour, tm->tm_min, tm->tm_sec,
 				tz);
-	else if (mode->type == DATE_ISO8601_STRICT) {
-		char sign = (tz >= 0) ? '+' : '-';
-		tz = abs(tz);
-		strbuf_addf(&timebuf, "%04d-%02d-%02dT%02d:%02d:%02d%c%02d:%02d",
+	else if (mode.type == DATE_ISO8601_STRICT) {
+		strbuf_addf(&timebuf, "%04d-%02d-%02dT%02d:%02d:%02d",
 				tm->tm_year + 1900,
 				tm->tm_mon + 1,
 				tm->tm_mday,
-				tm->tm_hour, tm->tm_min, tm->tm_sec,
-				sign, tz / 100, tz % 100);
-	} else if (mode->type == DATE_RFC2822)
+				tm->tm_hour, tm->tm_min, tm->tm_sec);
+		if (tz == 0) {
+			strbuf_addch(&timebuf, 'Z');
+		} else {
+			strbuf_addch(&timebuf, tz >= 0 ? '+' : '-');
+			tz = abs(tz);
+			strbuf_addf(&timebuf, "%02d:%02d", tz / 100, tz % 100);
+		}
+	} else if (mode.type == DATE_RFC2822)
 		strbuf_addf(&timebuf, "%.3s, %d %.3s %d %02d:%02d:%02d %+05d",
 			weekday_names[tm->tm_wday], tm->tm_mday,
 			month_names[tm->tm_mon], tm->tm_year + 1900,
 			tm->tm_hour, tm->tm_min, tm->tm_sec, tz);
-	else if (mode->type == DATE_STRFTIME)
-		strbuf_addftime(&timebuf, mode->strftime_fmt, tm, tz,
-				!mode->local);
+	else if (mode.type == DATE_STRFTIME)
+		strbuf_addftime(&timebuf, mode.strftime_fmt, tm, tz,
+				!mode.local);
 	else
-		show_date_normal(&timebuf, time, tm, tz, &human_tm, human_tz, mode->local);
+		show_date_normal(&timebuf, time, tm, tz, &human_tm, human_tz, mode.local);
 	return timebuf.buf;
 }
 
diff --git a/date.h b/date.h
index 6136212..0747864 100644
--- a/date.h
+++ b/date.h
@@ -22,8 +22,8 @@ enum date_mode_type {
 
 struct date_mode {
 	enum date_mode_type type;
-	const char *strftime_fmt;
 	int local;
+	const char *strftime_fmt;
 };
 
 #define DATE_MODE_INIT { \
@@ -36,14 +36,14 @@ struct date_mode {
  *   show_date(t, tz, DATE_MODE(NORMAL));
  */
 #define DATE_MODE(t) date_mode_from_type(DATE_##t)
-struct date_mode *date_mode_from_type(enum date_mode_type type);
+struct date_mode date_mode_from_type(enum date_mode_type type);
 
 /**
  * Format <'time', 'timezone'> into static memory according to 'mode'
  * and return it. The mode is an initialized "struct date_mode"
  * (usually from the DATE_MODE() macro).
  */
-const char *show_date(timestamp_t time, int timezone, const struct date_mode *mode);
+const char *show_date(timestamp_t time, int timezone, struct date_mode mode);
 
 /**
  * Parse a date format for later use with show_date().
diff --git a/delta-islands.c b/delta-islands.c
index ee2318d..f7e0794 100644
--- a/delta-islands.c
+++ b/delta-islands.c
@@ -284,7 +284,7 @@ void resolve_tree_islands(struct repository *r,
 		if (!tree || parse_tree(tree) < 0)
 			die(_("bad tree object %s"), oid_to_hex(&ent->idx.oid));
 
-		init_tree_desc(&desc, tree->buffer, tree->size);
+		init_tree_desc(&desc, &tree->object.oid, tree->buffer, tree->size);
 		while (tree_entry(&desc, &entry)) {
 			struct object *obj;
 
diff --git a/diff-lib.c b/diff-lib.c
index 8fde93d..12b1541 100644
--- a/diff-lib.c
+++ b/diff-lib.c
@@ -37,7 +37,13 @@
  */
 static int check_removed(const struct cache_entry *ce, struct stat *st)
 {
-	if (lstat(ce->name, st) < 0) {
+	int stat_err;
+
+	if (!(ce->ce_flags & CE_FSMONITOR_VALID))
+		stat_err = lstat(ce->name, st);
+	else
+		stat_err = fake_lstat(ce, st);
+	if (stat_err < 0) {
 		if (!is_missing_file_error(errno))
 			return -1;
 		return 1;
@@ -121,7 +127,16 @@ void run_diff_files(struct rev_info *revs, unsigned int option)
 		if (diff_can_quit_early(&revs->diffopt))
 			break;
 
-		if (!ce_path_match(istate, ce, &revs->prune_data, NULL))
+		/*
+		 * NEEDSWORK:
+		 * Here we filter with pathspec but the result is further
+		 * filtered out when --relative is in effect.  To end-users,
+		 * a pathspec element that matched only to paths outside the
+		 * current directory is like not matching anything at all;
+		 * the handling of ps_matched[] here may become problematic
+		 * if/when we add the "--error-unmatch" option to "git diff".
+		 */
+		if (!ce_path_match(istate, ce, &revs->prune_data, revs->ps_matched))
 			continue;
 
 		if (revs->diffopt.prefix &&
@@ -556,7 +571,7 @@ static int diff_cache(struct rev_info *revs,
 	opts.pathspec = &revs->diffopt.pathspec;
 	opts.pathspec->recursive = 1;
 
-	init_tree_desc(&t, tree->buffer, tree->size);
+	init_tree_desc(&t, &tree->object.oid, tree->buffer, tree->size);
 	return unpack_trees(1, &t, &opts);
 }
 
@@ -564,7 +579,7 @@ void diff_get_merge_base(const struct rev_info *revs, struct object_id *mb)
 {
 	int i;
 	struct commit *mb_child[2] = {0};
-	struct commit_list *merge_bases;
+	struct commit_list *merge_bases = NULL;
 
 	for (i = 0; i < revs->pending.nr; i++) {
 		struct object *obj = revs->pending.objects[i].item;
@@ -591,7 +606,8 @@ void diff_get_merge_base(const struct rev_info *revs, struct object_id *mb)
 		mb_child[1] = lookup_commit_reference(the_repository, &oid);
 	}
 
-	merge_bases = repo_get_merge_bases(the_repository, mb_child[0], mb_child[1]);
+	if (repo_get_merge_bases(the_repository, mb_child[0], mb_child[1], &merge_bases) < 0)
+		exit(128);
 	if (!merge_bases)
 		die(_("no merge base found"));
 	if (merge_bases->next)
@@ -644,7 +660,6 @@ int do_diff_cache(const struct object_id *tree_oid, struct diff_options *opt)
 
 	repo_init_revisions(opt->repo, &revs, NULL);
 	copy_pathspec(&revs.prune_data, &opt->pathspec);
-	diff_setup_done(&revs.diffopt);
 	revs.diffopt = *opt;
 
 	if (diff_cache(&revs, tree_oid, NULL, 1))
diff --git a/diff.c b/diff.c
index ccfa1fc..108c187 100644
--- a/diff.c
+++ b/diff.c
@@ -62,6 +62,8 @@ static const char *diff_order_file_cfg;
 int diff_auto_refresh_index = 1;
 static int diff_mnemonic_prefix;
 static int diff_no_prefix;
+static const char *diff_src_prefix = "a/";
+static const char *diff_dst_prefix = "b/";
 static int diff_relative;
 static int diff_stat_name_width;
 static int diff_stat_graph_width;
@@ -408,6 +410,12 @@ int git_diff_ui_config(const char *var, const char *value,
 		diff_no_prefix = git_config_bool(var, value);
 		return 0;
 	}
+	if (!strcmp(var, "diff.srcprefix")) {
+		return git_config_string(&diff_src_prefix, var, value);
+	}
+	if (!strcmp(var, "diff.dstprefix")) {
+		return git_config_string(&diff_dst_prefix, var, value);
+	}
 	if (!strcmp(var, "diff.relative")) {
 		diff_relative = git_config_bool(var, value);
 		return 0;
@@ -3425,8 +3433,8 @@ void diff_set_noprefix(struct diff_options *options)
 
 void diff_set_default_prefix(struct diff_options *options)
 {
-	options->a_prefix = "a/";
-	options->b_prefix = "b/";
+	options->a_prefix = diff_src_prefix;
+	options->b_prefix = diff_dst_prefix;
 }
 
 struct userdiff_driver *get_textconv(struct repository *r,
@@ -5362,6 +5370,8 @@ static int diff_opt_default_prefix(const struct option *opt,
 
 	BUG_ON_OPT_NEG(unset);
 	BUG_ON_OPT_ARG(optarg);
+	diff_src_prefix = "a/";
+	diff_dst_prefix = "b/";
 	diff_set_default_prefix(options);
 	return 0;
 }
@@ -5590,7 +5600,7 @@ struct option *add_diff_options(const struct option *opts,
 		OPT_BITOP(0, "shortstat", &options->output_format,
 			  N_("output only the last line of --stat"),
 			  DIFF_FORMAT_SHORTSTAT, DIFF_FORMAT_NO_OUTPUT),
-		OPT_CALLBACK_F('X', "dirstat", options, N_("<param1,param2>..."),
+		OPT_CALLBACK_F('X', "dirstat", options, N_("<param1>,<param2>..."),
 			       N_("output the distribution of relative amount of changes for each sub-directory"),
 			       PARSE_OPT_NONEG | PARSE_OPT_OPTARG,
 			       diff_opt_dirstat),
@@ -5598,8 +5608,8 @@ struct option *add_diff_options(const struct option *opts,
 			       N_("synonym for --dirstat=cumulative"),
 			       PARSE_OPT_NONEG | PARSE_OPT_NOARG,
 			       diff_opt_dirstat),
-		OPT_CALLBACK_F(0, "dirstat-by-file", options, N_("<param1,param2>..."),
-			       N_("synonym for --dirstat=files,param1,param2..."),
+		OPT_CALLBACK_F(0, "dirstat-by-file", options, N_("<param1>,<param2>..."),
+			       N_("synonym for --dirstat=files,<param1>,<param2>..."),
 			       PARSE_OPT_NONEG | PARSE_OPT_OPTARG,
 			       diff_opt_dirstat),
 		OPT_BIT_F(0, "check", &options->output_format,
diff --git a/dir-iterator.c b/dir-iterator.c
index 278b042..de61984 100644
--- a/dir-iterator.c
+++ b/dir-iterator.c
@@ -2,11 +2,20 @@
 #include "dir.h"
 #include "iterator.h"
 #include "dir-iterator.h"
+#include "string-list.h"
 
 struct dir_iterator_level {
 	DIR *dir;
 
 	/*
+	 * The directory entries of the current level. This list will only be
+	 * populated when the iterator is ordered. In that case, `dir` will be
+	 * set to `NULL`.
+	 */
+	struct string_list entries;
+	size_t entries_idx;
+
+	/*
 	 * The length of the directory part of path at this level
 	 * (including a trailing '/'):
 	 */
@@ -43,6 +52,31 @@ struct dir_iterator_int {
 	unsigned int flags;
 };
 
+static int next_directory_entry(DIR *dir, const char *path,
+				struct dirent **out)
+{
+	struct dirent *de;
+
+repeat:
+	errno = 0;
+	de = readdir(dir);
+	if (!de) {
+		if (errno) {
+			warning_errno("error reading directory '%s'",
+				      path);
+			return -1;
+		}
+
+		return 1;
+	}
+
+	if (is_dot_or_dotdot(de->d_name))
+		goto repeat;
+
+	*out = de;
+	return 0;
+}
+
 /*
  * Push a level in the iter stack and initialize it with information from
  * the directory pointed by iter->base->path. It is assumed that this
@@ -72,6 +106,35 @@ static int push_level(struct dir_iterator_int *iter)
 		return -1;
 	}
 
+	string_list_init_dup(&level->entries);
+	level->entries_idx = 0;
+
+	/*
+	 * When the iterator is sorted we read and sort all directory entries
+	 * directly.
+	 */
+	if (iter->flags & DIR_ITERATOR_SORTED) {
+		struct dirent *de;
+
+		while (1) {
+			int ret = next_directory_entry(level->dir, iter->base.path.buf, &de);
+			if (ret < 0) {
+				if (errno != ENOENT &&
+				    iter->flags & DIR_ITERATOR_PEDANTIC)
+					return -1;
+				continue;
+			} else if (ret > 0) {
+				break;
+			}
+
+			string_list_append(&level->entries, de->d_name);
+		}
+		string_list_sort(&level->entries);
+
+		closedir(level->dir);
+		level->dir = NULL;
+	}
+
 	return 0;
 }
 
@@ -88,21 +151,22 @@ static int pop_level(struct dir_iterator_int *iter)
 		warning_errno("error closing directory '%s'",
 			      iter->base.path.buf);
 	level->dir = NULL;
+	string_list_clear(&level->entries, 0);
 
 	return --iter->levels_nr;
 }
 
 /*
  * Populate iter->base with the necessary information on the next iteration
- * entry, represented by the given dirent de. Return 0 on success and -1
+ * entry, represented by the given name. Return 0 on success and -1
  * otherwise, setting errno accordingly.
  */
 static int prepare_next_entry_data(struct dir_iterator_int *iter,
-				   struct dirent *de)
+				   const char *name)
 {
 	int err, saved_errno;
 
-	strbuf_addstr(&iter->base.path, de->d_name);
+	strbuf_addstr(&iter->base.path, name);
 	/*
 	 * We have to reset these because the path strbuf might have
 	 * been realloc()ed at the previous strbuf_addstr().
@@ -139,27 +203,34 @@ int dir_iterator_advance(struct dir_iterator *dir_iterator)
 		struct dirent *de;
 		struct dir_iterator_level *level =
 			&iter->levels[iter->levels_nr - 1];
+		const char *name;
 
 		strbuf_setlen(&iter->base.path, level->prefix_len);
-		errno = 0;
-		de = readdir(level->dir);
 
-		if (!de) {
-			if (errno) {
-				warning_errno("error reading directory '%s'",
-					      iter->base.path.buf);
+		if (level->dir) {
+			int ret = next_directory_entry(level->dir, iter->base.path.buf, &de);
+			if (ret < 0) {
 				if (iter->flags & DIR_ITERATOR_PEDANTIC)
 					goto error_out;
-			} else if (pop_level(iter) == 0) {
-				return dir_iterator_abort(dir_iterator);
+				continue;
+			} else if (ret > 0) {
+				if (pop_level(iter) == 0)
+					return dir_iterator_abort(dir_iterator);
+				continue;
 			}
-			continue;
+
+			name = de->d_name;
+		} else {
+			if (level->entries_idx >= level->entries.nr) {
+				if (pop_level(iter) == 0)
+					return dir_iterator_abort(dir_iterator);
+				continue;
+			}
+
+			name = level->entries.items[level->entries_idx++].string;
 		}
 
-		if (is_dot_or_dotdot(de->d_name))
-			continue;
-
-		if (prepare_next_entry_data(iter, de)) {
+		if (prepare_next_entry_data(iter, name)) {
 			if (errno != ENOENT && iter->flags & DIR_ITERATOR_PEDANTIC)
 				goto error_out;
 			continue;
@@ -188,6 +259,8 @@ int dir_iterator_abort(struct dir_iterator *dir_iterator)
 			warning_errno("error closing directory '%s'",
 				      iter->base.path.buf);
 		}
+
+		string_list_clear(&level->entries, 0);
 	}
 
 	free(iter->levels);
diff --git a/dir-iterator.h b/dir-iterator.h
index 479e1ec..6d43880 100644
--- a/dir-iterator.h
+++ b/dir-iterator.h
@@ -54,8 +54,11 @@
  *   and ITER_ERROR is returned immediately. In both cases, a meaningful
  *   warning is emitted. Note: ENOENT errors are always ignored so that
  *   the API users may remove files during iteration.
+ *
+ * - DIR_ITERATOR_SORTED: sort directory entries alphabetically.
  */
 #define DIR_ITERATOR_PEDANTIC (1 << 0)
+#define DIR_ITERATOR_SORTED   (1 << 1)
 
 struct dir_iterator {
 	/* The current path: */
diff --git a/dir.c b/dir.c
index 3e75c12..2d83f33 100644
--- a/dir.c
+++ b/dir.c
@@ -100,6 +100,18 @@ int fspathncmp(const char *a, const char *b, size_t count)
 	return ignore_case ? strncasecmp(a, b, count) : strncmp(a, b, count);
 }
 
+int paths_collide(const char *a, const char *b)
+{
+	size_t len_a = strlen(a), len_b = strlen(b);
+
+	if (len_a == len_b)
+		return fspatheq(a, b);
+
+	if (len_a < len_b)
+		return is_dir_sep(b[len_a]) && !fspathncmp(a, b, len_a);
+	return is_dir_sep(a[len_b]) && !fspathncmp(a, b, len_b);
+}
+
 unsigned int fspathhash(const char *str)
 {
 	return ignore_case ? strihash(str) : strhash(str);
@@ -2178,7 +2190,8 @@ static int exclude_matches_pathspec(const char *path, int pathlen,
 		       PATHSPEC_LITERAL |
 		       PATHSPEC_GLOB |
 		       PATHSPEC_ICASE |
-		       PATHSPEC_EXCLUDE);
+		       PATHSPEC_EXCLUDE |
+		       PATHSPEC_ATTR);
 
 	for (i = 0; i < pathspec->nr; i++) {
 		const struct pathspec_item *item = &pathspec->items[i];
@@ -3917,6 +3930,26 @@ void untracked_cache_invalidate_path(struct index_state *istate,
 				 path, strlen(path));
 }
 
+void untracked_cache_invalidate_trimmed_path(struct index_state *istate,
+					     const char *path,
+					     int safe_path)
+{
+	size_t len = strlen(path);
+
+	if (!len)
+		BUG("untracked_cache_invalidate_trimmed_path given zero length path");
+
+	if (path[len - 1] != '/') {
+		untracked_cache_invalidate_path(istate, path, safe_path);
+	} else {
+		struct strbuf tmp = STRBUF_INIT;
+
+		strbuf_add(&tmp, path, len - 1);
+		untracked_cache_invalidate_path(istate, tmp.buf, safe_path);
+		strbuf_release(&tmp);
+	}
+}
+
 void untracked_cache_remove_from_index(struct index_state *istate,
 				       const char *path)
 {
diff --git a/dir.h b/dir.h
index 98aa85f..b9e8e96 100644
--- a/dir.h
+++ b/dir.h
@@ -549,6 +549,13 @@ int fspathncmp(const char *a, const char *b, size_t count);
 unsigned int fspathhash(const char *str);
 
 /*
+ * Reports whether paths collide. This may be because the paths differ only in
+ * case on a case-sensitive filesystem, or that one path refers to a symlink
+ * that collides with one of the parent directories of the other.
+ */
+int paths_collide(const char *a, const char *b);
+
+/*
  * The prefix part of pattern must not contains wildcards.
  */
 struct pathspec_item;
@@ -576,6 +583,13 @@ int cmp_dir_entry(const void *p1, const void *p2);
 int check_dir_entry_contains(const struct dir_entry *out, const struct dir_entry *in);
 
 void untracked_cache_invalidate_path(struct index_state *, const char *, int safe_path);
+/*
+ * Invalidate the untracked-cache for this path, but first strip
+ * off a trailing slash, if present.
+ */
+void untracked_cache_invalidate_trimmed_path(struct index_state *,
+					     const char *path,
+					     int safe_path);
 void untracked_cache_remove_from_index(struct index_state *, const char *);
 void untracked_cache_add_to_index(struct index_state *, const char *);
 
diff --git a/editor.c b/editor.c
index b67b802..d1ba2d7 100644
--- a/editor.c
+++ b/editor.c
@@ -104,16 +104,15 @@ static int launch_specified_editor(const char *editor, const char *path,
 		sigchain_pop(SIGQUIT);
 		if (sig == SIGINT || sig == SIGQUIT)
 			raise(sig);
-		if (ret)
-			return error("There was a problem with the editor '%s'.",
-					editor);
-
 		if (print_waiting_for_editor && !is_terminal_dumb())
 			/*
 			 * Erase the entire line to avoid wasting the
 			 * vertical space.
 			 */
 			term_clear_line();
+		if (ret)
+			return error("there was a problem with the editor '%s'",
+					editor);
 	}
 
 	if (!buffer)
diff --git a/entry.c b/entry.c
index f918a3a..b8c257f 100644
--- a/entry.c
+++ b/entry.c
@@ -460,7 +460,7 @@ static void mark_colliding_entries(const struct checkout *state,
 			continue;
 
 		if ((trust_ino && !match_stat_data(&dup->ce_stat_data, st)) ||
-		    (!trust_ino && !fspathcmp(ce->name, dup->name))) {
+		    paths_collide(ce->name, dup->name)) {
 			dup->ce_flags |= CE_MATCHED;
 			break;
 		}
@@ -547,6 +547,20 @@ int checkout_entry_ca(struct cache_entry *ce, struct conv_attrs *ca,
 			/* If it is a gitlink, leave it alone! */
 			if (S_ISGITLINK(ce->ce_mode))
 				return 0;
+			/*
+			 * We must avoid replacing submodules' leading
+			 * directories with symbolic links, lest recursive
+			 * clones can write into arbitrary locations.
+			 *
+			 * Technically, this logic is not limited
+			 * to recursive clones, or for that matter to
+			 * submodules' paths colliding with symbolic links'
+			 * paths. Yet it strikes a balance in favor of
+			 * simplicity, and if paths are colliding, we might
+			 * just as well keep the directories during a clone.
+			 */
+			if (state->clone && S_ISLNK(ce->ce_mode))
+				return 0;
 			remove_subtree(&path);
 		} else if (unlink(path.buf))
 			return error_errno("unable to unlink old '%s'", path.buf);
diff --git a/environment.c b/environment.c
index 90632a3..a73ba9c 100644
--- a/environment.c
+++ b/environment.c
@@ -110,7 +110,7 @@ int protect_ntfs = PROTECT_NTFS_DEFAULT;
  * The character that begins a commented line in user-editable file
  * that is subject to stripspace.
  */
-char comment_line_char = '#';
+const char *comment_line_str = "#";
 int auto_comment_line_char;
 
 /* Parallel index stat data preload? */
@@ -207,6 +207,9 @@ void setup_git_env(const char *git_dir)
 	shallow_file = getenv(GIT_SHALLOW_FILE_ENVIRONMENT);
 	if (shallow_file)
 		set_alternate_shallow_file(the_repository, shallow_file, 0);
+
+	if (git_env_bool(NO_LAZY_FETCH_ENVIRONMENT, 0))
+		fetch_if_missing = 0;
 }
 
 int is_bare_repository(void)
diff --git a/environment.h b/environment.h
index e5351c9..05fd94d 100644
--- a/environment.h
+++ b/environment.h
@@ -8,7 +8,7 @@ struct strvec;
  * The character that begins a commented line in user-editable file
  * that is subject to stripspace.
  */
-extern char comment_line_char;
+extern const char *comment_line_str;
 extern int auto_comment_line_char;
 
 /*
@@ -36,6 +36,7 @@ const char *getenv_safe(struct strvec *argv, const char *name);
 #define CEILING_DIRECTORIES_ENVIRONMENT "GIT_CEILING_DIRECTORIES"
 #define NO_REPLACE_OBJECTS_ENVIRONMENT "GIT_NO_REPLACE_OBJECTS"
 #define GIT_REPLACE_REF_BASE_ENVIRONMENT "GIT_REPLACE_REF_BASE"
+#define NO_LAZY_FETCH_ENVIRONMENT "GIT_NO_LAZY_FETCH"
 #define GITATTRIBUTES_FILE ".gitattributes"
 #define INFOATTRIBUTES_FILE "info/attributes"
 #define ATTRIBUTE_MACRO_PREFIX "[attr]"
diff --git a/ewah/bitmap.c b/ewah/bitmap.c
index 7b525b1..ac7e0af 100644
--- a/ewah/bitmap.c
+++ b/ewah/bitmap.c
@@ -169,6 +169,15 @@ size_t bitmap_popcount(struct bitmap *self)
 	return count;
 }
 
+int bitmap_is_empty(struct bitmap *self)
+{
+	size_t i;
+	for (i = 0; i < self->word_alloc; i++)
+		if (self->words[i])
+			return 0;
+	return 1;
+}
+
 int bitmap_equals(struct bitmap *self, struct bitmap *other)
 {
 	struct bitmap *big, *small;
diff --git a/ewah/ewok.h b/ewah/ewok.h
index 7eb8b9b..c11d76c 100644
--- a/ewah/ewok.h
+++ b/ewah/ewok.h
@@ -189,5 +189,6 @@ void bitmap_or_ewah(struct bitmap *self, struct ewah_bitmap *other);
 void bitmap_or(struct bitmap *self, const struct bitmap *other);
 
 size_t bitmap_popcount(struct bitmap *self);
+int bitmap_is_empty(struct bitmap *self);
 
 #endif
diff --git a/fmt-merge-msg.c b/fmt-merge-msg.c
index 66e4744..ae201e2 100644
--- a/fmt-merge-msg.c
+++ b/fmt-merge-msg.c
@@ -321,7 +321,7 @@ static void credit_people(struct strbuf *out,
 	     skip_prefix(me, them->items->string, &me) &&
 	     starts_with(me, " <")))
 		return;
-	strbuf_addf(out, "\n%c %s ", comment_line_char, label);
+	strbuf_addf(out, "\n%s %s ", comment_line_str, label);
 	add_people_count(out, them);
 }
 
@@ -510,7 +510,7 @@ static void fmt_tag_signature(struct strbuf *tagbuf,
 	if (sig->len) {
 		strbuf_addch(tagbuf, '\n');
 		strbuf_add_commented_lines(tagbuf, sig->buf, sig->len,
-					   comment_line_char);
+					   comment_line_str);
 	}
 }
 
@@ -557,7 +557,7 @@ static void fmt_merge_msg_sigs(struct strbuf *out)
 				strbuf_add_commented_lines(&tagline,
 						origins.items[first_tag].string,
 						strlen(origins.items[first_tag].string),
-						comment_line_char);
+						comment_line_str);
 				strbuf_insert(&tagbuf, 0, tagline.buf,
 					      tagline.len);
 				strbuf_release(&tagline);
@@ -566,7 +566,7 @@ static void fmt_merge_msg_sigs(struct strbuf *out)
 			strbuf_add_commented_lines(&tagbuf,
 					origins.items[i].string,
 					strlen(origins.items[i].string),
-					comment_line_char);
+					comment_line_str);
 			fmt_tag_signature(&tagbuf, &sig, buf, len);
 		}
 		strbuf_release(&payload);
diff --git a/fsck.c b/fsck.c
index 1ad02fc..78af29d 100644
--- a/fsck.c
+++ b/fsck.c
@@ -20,7 +20,6 @@
 #include "packfile.h"
 #include "submodule-config.h"
 #include "config.h"
-#include "credential.h"
 #include "help.h"
 
 static ssize_t max_tree_entry_len = 4096;
@@ -328,7 +327,8 @@ static int fsck_walk_tree(struct tree *tree, void *data, struct fsck_options *op
 		return -1;
 
 	name = fsck_get_object_name(options, &tree->object.oid);
-	if (init_tree_desc_gently(&desc, tree->buffer, tree->size, 0))
+	if (init_tree_desc_gently(&desc, &tree->object.oid,
+				  tree->buffer, tree->size, 0))
 		return -1;
 	while (tree_entry_gently(&desc, &entry)) {
 		struct object *obj;
@@ -599,7 +599,8 @@ static int fsck_tree(const struct object_id *tree_oid,
 	const char *o_name;
 	struct name_stack df_dup_candidates = { NULL };
 
-	if (init_tree_desc_gently(&desc, buffer, size, TREE_DESC_RAW_MODES)) {
+	if (init_tree_desc_gently(&desc, tree_oid, buffer, size,
+				  TREE_DESC_RAW_MODES)) {
 		retval += report(options, tree_oid, OBJ_TREE,
 				 FSCK_MSG_BAD_TREE,
 				 "cannot be parsed as a tree");
@@ -1047,138 +1048,6 @@ int fsck_tag_standalone(const struct object_id *oid, const char *buffer,
 	return ret;
 }
 
-static int starts_with_dot_slash(const char *const path)
-{
-	return path_match_flags(path, PATH_MATCH_STARTS_WITH_DOT_SLASH |
-				PATH_MATCH_XPLATFORM);
-}
-
-static int starts_with_dot_dot_slash(const char *const path)
-{
-	return path_match_flags(path, PATH_MATCH_STARTS_WITH_DOT_DOT_SLASH |
-				PATH_MATCH_XPLATFORM);
-}
-
-static int submodule_url_is_relative(const char *url)
-{
-	return starts_with_dot_slash(url) || starts_with_dot_dot_slash(url);
-}
-
-/*
- * Count directory components that a relative submodule URL should chop
- * from the remote_url it is to be resolved against.
- *
- * In other words, this counts "../" components at the start of a
- * submodule URL.
- *
- * Returns the number of directory components to chop and writes a
- * pointer to the next character of url after all leading "./" and
- * "../" components to out.
- */
-static int count_leading_dotdots(const char *url, const char **out)
-{
-	int result = 0;
-	while (1) {
-		if (starts_with_dot_dot_slash(url)) {
-			result++;
-			url += strlen("../");
-			continue;
-		}
-		if (starts_with_dot_slash(url)) {
-			url += strlen("./");
-			continue;
-		}
-		*out = url;
-		return result;
-	}
-}
-/*
- * Check whether a transport is implemented by git-remote-curl.
- *
- * If it is, returns 1 and writes the URL that would be passed to
- * git-remote-curl to the "out" parameter.
- *
- * Otherwise, returns 0 and leaves "out" untouched.
- *
- * Examples:
- *   http::https://example.com/repo.git -> 1, https://example.com/repo.git
- *   https://example.com/repo.git -> 1, https://example.com/repo.git
- *   git://example.com/repo.git -> 0
- *
- * This is for use in checking for previously exploitable bugs that
- * required a submodule URL to be passed to git-remote-curl.
- */
-static int url_to_curl_url(const char *url, const char **out)
-{
-	/*
-	 * We don't need to check for case-aliases, "http.exe", and so
-	 * on because in the default configuration, is_transport_allowed
-	 * prevents URLs with those schemes from being cloned
-	 * automatically.
-	 */
-	if (skip_prefix(url, "http::", out) ||
-	    skip_prefix(url, "https::", out) ||
-	    skip_prefix(url, "ftp::", out) ||
-	    skip_prefix(url, "ftps::", out))
-		return 1;
-	if (starts_with(url, "http://") ||
-	    starts_with(url, "https://") ||
-	    starts_with(url, "ftp://") ||
-	    starts_with(url, "ftps://")) {
-		*out = url;
-		return 1;
-	}
-	return 0;
-}
-
-static int check_submodule_url(const char *url)
-{
-	const char *curl_url;
-
-	if (looks_like_command_line_option(url))
-		return -1;
-
-	if (submodule_url_is_relative(url) || starts_with(url, "git://")) {
-		char *decoded;
-		const char *next;
-		int has_nl;
-
-		/*
-		 * This could be appended to an http URL and url-decoded;
-		 * check for malicious characters.
-		 */
-		decoded = url_decode(url);
-		has_nl = !!strchr(decoded, '\n');
-
-		free(decoded);
-		if (has_nl)
-			return -1;
-
-		/*
-		 * URLs which escape their root via "../" can overwrite
-		 * the host field and previous components, resolving to
-		 * URLs like https::example.com/submodule.git and
-		 * https:///example.com/submodule.git that were
-		 * susceptible to CVE-2020-11008.
-		 */
-		if (count_leading_dotdots(url, &next) > 0 &&
-		    (*next == ':' || *next == '/'))
-			return -1;
-	}
-
-	else if (url_to_curl_url(url, &curl_url)) {
-		struct credential c = CREDENTIAL_INIT;
-		int ret = 0;
-		if (credential_from_url_gently(&c, curl_url, 1) ||
-		    !*c.host)
-			ret = -1;
-		credential_clear(&c);
-		return ret;
-	}
-
-	return 0;
-}
-
 struct fsck_gitmodules_data {
 	const struct object_id *oid;
 	struct fsck_options *options;
diff --git a/fsmonitor.c b/fsmonitor.c
index f670c50..2b17d60 100644
--- a/fsmonitor.c
+++ b/fsmonitor.c
@@ -5,6 +5,7 @@
 #include "ewah/ewok.h"
 #include "fsmonitor.h"
 #include "fsmonitor-ipc.h"
+#include "name-hash.h"
 #include "run-command.h"
 #include "strbuf.h"
 #include "trace2.h"
@@ -183,79 +184,282 @@ static int query_fsmonitor_hook(struct repository *r,
 	return result;
 }
 
+/*
+ * Invalidate the FSM bit on this CE.  This is like mark_fsmonitor_invalid()
+ * but we've already handled the untracked-cache, so let's not repeat that
+ * work.  This also lets us have a different trace message so that we can
+ * see everything that was done as part of the refresh-callback.
+ */
+static void invalidate_ce_fsm(struct cache_entry *ce)
+{
+	if (ce->ce_flags & CE_FSMONITOR_VALID) {
+		trace_printf_key(&trace_fsmonitor,
+				 "fsmonitor_refresh_callback INV: '%s'",
+				 ce->name);
+		ce->ce_flags &= ~CE_FSMONITOR_VALID;
+	}
+}
+
+static size_t handle_path_with_trailing_slash(
+	struct index_state *istate, const char *name, int pos);
+
+/*
+ * Use the name-hash to do a case-insensitive cache-entry lookup with
+ * the pathname and invalidate the cache-entry.
+ *
+ * Returns the number of cache-entries that we invalidated.
+ */
+static size_t handle_using_name_hash_icase(
+	struct index_state *istate, const char *name)
+{
+	struct cache_entry *ce = NULL;
+
+	ce = index_file_exists(istate, name, strlen(name), 1);
+	if (!ce)
+		return 0;
+
+	/*
+	 * A case-insensitive search in the name-hash using the
+	 * observed pathname found a cache-entry, so the observed path
+	 * is case-incorrect.  Invalidate the cache-entry and use the
+	 * correct spelling from the cache-entry to invalidate the
+	 * untracked-cache.  Since we now have sparse-directories in
+	 * the index, the observed pathname may represent a regular
+	 * file or a sparse-index directory.
+	 *
+	 * Note that we should not have seen FSEvents for a
+	 * sparse-index directory, but we handle it just in case.
+	 *
+	 * Either way, we know that there are not any cache-entries for
+	 * children inside the cone of the directory, so we don't need to
+	 * do the usual scan.
+	 */
+	trace_printf_key(&trace_fsmonitor,
+			 "fsmonitor_refresh_callback MAP: '%s' '%s'",
+			 name, ce->name);
+
+	/*
+	 * NEEDSWORK: We used the name-hash to find the correct
+	 * case-spelling of the pathname in the cache-entry[], so
+	 * technically this is a tracked file or a sparse-directory.
+	 * It should not have any entries in the untracked-cache, so
+	 * we should not need to use the case-corrected spelling to
+	 * invalidate the the untracked-cache.  So we may not need to
+	 * do this.  For now, I'm going to be conservative and always
+	 * do it; we can revisit this later.
+	 */
+	untracked_cache_invalidate_trimmed_path(istate, ce->name, 0);
+
+	invalidate_ce_fsm(ce);
+	return 1;
+}
+
+/*
+ * Use the dir-name-hash to find the correct-case spelling of the
+ * directory.  Use the canonical spelling to invalidate all of the
+ * cache-entries within the matching cone.
+ *
+ * Returns the number of cache-entries that we invalidated.
+ */
+static size_t handle_using_dir_name_hash_icase(
+	struct index_state *istate, const char *name)
+{
+	struct strbuf canonical_path = STRBUF_INIT;
+	int pos;
+	size_t len = strlen(name);
+	size_t nr_in_cone;
+
+	if (name[len - 1] == '/')
+		len--;
+
+	if (!index_dir_find(istate, name, len, &canonical_path))
+		return 0; /* name is untracked */
+
+	if (!memcmp(name, canonical_path.buf, canonical_path.len)) {
+		strbuf_release(&canonical_path);
+		/*
+		 * NEEDSWORK: Our caller already tried an exact match
+		 * and failed to find one.  They called us to do an
+		 * ICASE match, so we should never get an exact match,
+		 * so we could promote this to a BUG() here if we
+		 * wanted to.  It doesn't hurt anything to just return
+		 * 0 and go on because we should never get here.  Or we
+		 * could just get rid of the memcmp() and this "if"
+		 * clause completely.
+		 */
+		BUG("handle_using_dir_name_hash_icase(%s) did not exact match",
+		    name);
+	}
+
+	trace_printf_key(&trace_fsmonitor,
+			 "fsmonitor_refresh_callback MAP: '%s' '%s'",
+			 name, canonical_path.buf);
+
+	/*
+	 * The dir-name-hash only tells us the corrected spelling of
+	 * the prefix.  We have to use this canonical path to do a
+	 * lookup in the cache-entry array so that we repeat the
+	 * original search using the case-corrected spelling.
+	 */
+	strbuf_addch(&canonical_path, '/');
+	pos = index_name_pos(istate, canonical_path.buf,
+			     canonical_path.len);
+	nr_in_cone = handle_path_with_trailing_slash(
+		istate, canonical_path.buf, pos);
+	strbuf_release(&canonical_path);
+	return nr_in_cone;
+}
+
+/*
+ * The daemon sent an observed pathname without a trailing slash.
+ * (This is the normal case.)  We do not know if it is a tracked or
+ * untracked file, a sparse-directory, or a populated directory (on a
+ * platform such as Windows where FSEvents are not qualified).
+ *
+ * The pathname contains the observed case reported by the FS. We
+ * do not know it is case-correct or -incorrect.
+ *
+ * Assume it is case-correct and try an exact match.
+ *
+ * Return the number of cache-entries that we invalidated.
+ */
+static size_t handle_path_without_trailing_slash(
+	struct index_state *istate, const char *name, int pos)
+{
+	/*
+	 * Mark the untracked cache dirty for this path (regardless of
+	 * whether or not we find an exact match for it in the index).
+	 * Since the path is unqualified (no trailing slash hint in the
+	 * FSEvent), it may refer to a file or directory. So we should
+	 * not assume one or the other and should always let the untracked
+	 * cache decide what needs to invalidated.
+	 */
+	untracked_cache_invalidate_trimmed_path(istate, name, 0);
+
+	if (pos >= 0) {
+		/*
+		 * An exact match on a tracked file. We assume that we
+		 * do not need to scan forward for a sparse-directory
+		 * cache-entry with the same pathname, nor for a cone
+		 * at that directory. (That is, assume no D/F conflicts.)
+		 */
+		invalidate_ce_fsm(istate->cache[pos]);
+		return 1;
+	} else {
+		size_t nr_in_cone;
+		struct strbuf work_path = STRBUF_INIT;
+
+		/*
+		 * The negative "pos" gives us the suggested insertion
+		 * point for the pathname (without the trailing slash).
+		 * We need to see if there is a directory with that
+		 * prefix, but there can be lots of pathnames between
+		 * "foo" and "foo/" like "foo-" or "foo-bar", so we
+		 * don't want to do our own scan.
+		 */
+		strbuf_add(&work_path, name, strlen(name));
+		strbuf_addch(&work_path, '/');
+		pos = index_name_pos(istate, work_path.buf, work_path.len);
+		nr_in_cone = handle_path_with_trailing_slash(
+			istate, work_path.buf, pos);
+		strbuf_release(&work_path);
+		return nr_in_cone;
+	}
+}
+
+/*
+ * The daemon can decorate directory events, such as a move or rename,
+ * by adding a trailing slash to the observed name.  Use this to
+ * explicitly invalidate the entire cone under that directory.
+ *
+ * The daemon can only reliably do that if the OS FSEvent contains
+ * sufficient information in the event.
+ *
+ * macOS FSEvents have enough information.
+ *
+ * Other platforms may or may not be able to do it (and it might
+ * depend on the type of event (for example, a daemon could lstat() an
+ * observed pathname after a rename, but not after a delete)).
+ *
+ * If we find an exact match in the index for a path with a trailing
+ * slash, it means that we matched a sparse-index directory in a
+ * cone-mode sparse-checkout (since that's the only time we have
+ * directories in the index).  We should never see this in practice
+ * (because sparse directories should not be present and therefore
+ * not generating FS events).  Either way, we can treat them in the
+ * same way and just invalidate the cache-entry and the untracked
+ * cache (and in this case, the forward cache-entry scan won't find
+ * anything and it doesn't hurt to let it run).
+ *
+ * Return the number of cache-entries that we invalidated.  We will
+ * use this later to determine if we need to attempt a second
+ * case-insensitive search on case-insensitive file systems.  That is,
+ * if the search using the observed-case in the FSEvent yields any
+ * results, we assume the prefix is case-correct.  If there are no
+ * matches, we still don't know if the observed path is simply
+ * untracked or case-incorrect.
+ */
+static size_t handle_path_with_trailing_slash(
+	struct index_state *istate, const char *name, int pos)
+{
+	int i;
+	size_t nr_in_cone = 0;
+
+	/*
+	 * Mark the untracked cache dirty for this directory path
+	 * (regardless of whether or not we find an exact match for it
+	 * in the index or find it to be proper prefix of one or more
+	 * files in the index), since the FSEvent is hinting that
+	 * there may be changes on or within the directory.
+	 */
+	untracked_cache_invalidate_trimmed_path(istate, name, 0);
+
+	if (pos < 0)
+		pos = -pos - 1;
+
+	/* Mark all entries for the folder invalid */
+	for (i = pos; i < istate->cache_nr; i++) {
+		if (!starts_with(istate->cache[i]->name, name))
+			break;
+		invalidate_ce_fsm(istate->cache[i]);
+		nr_in_cone++;
+	}
+
+	return nr_in_cone;
+}
+
 static void fsmonitor_refresh_callback(struct index_state *istate, char *name)
 {
-	int i, len = strlen(name);
+	int len = strlen(name);
 	int pos = index_name_pos(istate, name, len);
+	size_t nr_in_cone;
 
 	trace_printf_key(&trace_fsmonitor,
 			 "fsmonitor_refresh_callback '%s' (pos %d)",
 			 name, pos);
 
-	if (name[len - 1] == '/') {
-		/*
-		 * The daemon can decorate directory events, such as
-		 * moves or renames, with a trailing slash if the OS
-		 * FS Event contains sufficient information, such as
-		 * MacOS.
-		 *
-		 * Use this to invalidate the entire cone under that
-		 * directory.
-		 *
-		 * We do not expect an exact match because the index
-		 * does not normally contain directory entries, so we
-		 * start at the insertion point and scan.
-		 */
-		if (pos < 0)
-			pos = -pos - 1;
-
-		/* Mark all entries for the folder invalid */
-		for (i = pos; i < istate->cache_nr; i++) {
-			if (!starts_with(istate->cache[i]->name, name))
-				break;
-			istate->cache[i]->ce_flags &= ~CE_FSMONITOR_VALID;
-		}
-
-		/*
-		 * We need to remove the traling "/" from the path
-		 * for the untracked cache.
-		 */
-		name[len - 1] = '\0';
-	} else if (pos >= 0) {
-		/*
-		 * We have an exact match for this path and can just
-		 * invalidate it.
-		 */
-		istate->cache[pos]->ce_flags &= ~CE_FSMONITOR_VALID;
-	} else {
-		/*
-		 * The path is not a tracked file -or- it is a
-		 * directory event on a platform that cannot
-		 * distinguish between file and directory events in
-		 * the event handler, such as Windows.
-		 *
-		 * Scan as if it is a directory and invalidate the
-		 * cone under it.  (But remember to ignore items
-		 * between "name" and "name/", such as "name-" and
-		 * "name.".
-		 */
-		pos = -pos - 1;
-
-		for (i = pos; i < istate->cache_nr; i++) {
-			if (!starts_with(istate->cache[i]->name, name))
-				break;
-			if ((unsigned char)istate->cache[i]->name[len] > '/')
-				break;
-			if (istate->cache[i]->name[len] == '/')
-				istate->cache[i]->ce_flags &= ~CE_FSMONITOR_VALID;
-		}
-	}
+	if (name[len - 1] == '/')
+		nr_in_cone = handle_path_with_trailing_slash(istate, name, pos);
+	else
+		nr_in_cone = handle_path_without_trailing_slash(istate, name, pos);
 
 	/*
-	 * Mark the untracked cache dirty even if it wasn't found in the index
-	 * as it could be a new untracked file.
+	 * If we did not find an exact match for this pathname or any
+	 * cache-entries with this directory prefix and we're on a
+	 * case-insensitive file system, try again using the name-hash
+	 * and dir-name-hash.
 	 */
-	untracked_cache_invalidate_path(istate, name, 0);
+	if (!nr_in_cone && ignore_case) {
+		nr_in_cone = handle_using_name_hash_icase(istate, name);
+		if (!nr_in_cone)
+			nr_in_cone = handle_using_dir_name_hash_icase(
+				istate, name);
+	}
+
+	if (nr_in_cone)
+		trace_printf_key(&trace_fsmonitor,
+				 "fsmonitor_refresh_callback CNT: %d",
+				 (int)nr_in_cone);
 }
 
 /*
diff --git a/git-compat-util.h b/git-compat-util.h
index 3e7a59b..ca7678a 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -218,6 +218,18 @@ struct strbuf;
 #define GIT_WINDOWS_NATIVE
 #endif
 
+#if defined(NO_UNIX_SOCKETS) || !defined(GIT_WINDOWS_NATIVE)
+static inline int _have_unix_sockets(void)
+{
+#if defined(NO_UNIX_SOCKETS)
+	return 0;
+#else
+	return 1;
+#endif
+}
+#define have_unix_sockets _have_unix_sockets
+#endif
+
 #include <unistd.h>
 #include <stdio.h>
 #include <sys/stat.h>
@@ -225,6 +237,7 @@ struct strbuf;
 #include <stddef.h>
 #include <stdlib.h>
 #include <stdarg.h>
+#include <stdbool.h>
 #include <string.h>
 #ifdef HAVE_STRINGS_H
 #include <strings.h> /* for strcasecmp() */
@@ -390,6 +403,7 @@ char *gitdirname(char *);
 
 #ifndef NO_OPENSSL
 #ifdef __APPLE__
+#undef __AVAILABILITY_MACROS_USES_AVAILABILITY
 #define __AVAILABILITY_MACROS_USES_AVAILABILITY 0
 #include <AvailabilityMacros.h>
 #undef DEPRECATED_ATTRIBUTE
@@ -684,11 +698,11 @@ report_fn get_warn_routine(void);
 void set_die_is_recursing_routine(int (*routine)(void));
 
 /*
- * If the string "str" begins with the string found in "prefix", return 1.
+ * If the string "str" begins with the string found in "prefix", return true.
  * The "out" parameter is set to "str + strlen(prefix)" (i.e., to the point in
  * the string right after the prefix).
  *
- * Otherwise, return 0 and leave "out" untouched.
+ * Otherwise, return false and leave "out" untouched.
  *
  * Examples:
  *
@@ -699,57 +713,58 @@ void set_die_is_recursing_routine(int (*routine)(void));
  *   [skip prefix if present, otherwise use whole string]
  *   skip_prefix(name, "refs/heads/", &name);
  */
-static inline int skip_prefix(const char *str, const char *prefix,
-			      const char **out)
+static inline bool skip_prefix(const char *str, const char *prefix,
+			       const char **out)
 {
 	do {
 		if (!*prefix) {
 			*out = str;
-			return 1;
+			return true;
 		}
 	} while (*str++ == *prefix++);
-	return 0;
+	return false;
 }
 
 /*
  * Like skip_prefix, but promises never to read past "len" bytes of the input
  * buffer, and returns the remaining number of bytes in "out" via "outlen".
  */
-static inline int skip_prefix_mem(const char *buf, size_t len,
-				  const char *prefix,
-				  const char **out, size_t *outlen)
+static inline bool skip_prefix_mem(const char *buf, size_t len,
+				   const char *prefix,
+				   const char **out, size_t *outlen)
 {
 	size_t prefix_len = strlen(prefix);
 	if (prefix_len <= len && !memcmp(buf, prefix, prefix_len)) {
 		*out = buf + prefix_len;
 		*outlen = len - prefix_len;
-		return 1;
+		return true;
 	}
-	return 0;
+	return false;
 }
 
 /*
- * If buf ends with suffix, return 1 and subtract the length of the suffix
- * from *len. Otherwise, return 0 and leave *len untouched.
+ * If buf ends with suffix, return true and subtract the length of the suffix
+ * from *len. Otherwise, return false and leave *len untouched.
  */
-static inline int strip_suffix_mem(const char *buf, size_t *len,
-				   const char *suffix)
+static inline bool strip_suffix_mem(const char *buf, size_t *len,
+				    const char *suffix)
 {
 	size_t suflen = strlen(suffix);
 	if (*len < suflen || memcmp(buf + (*len - suflen), suffix, suflen))
-		return 0;
+		return false;
 	*len -= suflen;
-	return 1;
+	return true;
 }
 
 /*
- * If str ends with suffix, return 1 and set *len to the size of the string
- * without the suffix. Otherwise, return 0 and set *len to the size of the
+ * If str ends with suffix, return true and set *len to the size of the string
+ * without the suffix. Otherwise, return false and set *len to the size of the
  * string.
  *
  * Note that we do _not_ NUL-terminate str to the new length.
  */
-static inline int strip_suffix(const char *str, const char *suffix, size_t *len)
+static inline bool strip_suffix(const char *str, const char *suffix,
+				size_t *len)
 {
 	*len = strlen(str);
 	return strip_suffix_mem(str, len, suffix);
@@ -1013,6 +1028,15 @@ static inline unsigned long cast_size_t_to_ulong(size_t a)
 	return (unsigned long)a;
 }
 
+static inline uint32_t cast_size_t_to_uint32_t(size_t a)
+{
+	if (a != (uint32_t)a)
+		die("object too large to read on this platform: %"
+		    PRIuMAX" is cut off to %u",
+		    (uintmax_t)a, (uint32_t)a);
+	return (uint32_t)a;
+}
+
 static inline int cast_size_t_to_int(size_t a)
 {
 	if (a > INT_MAX)
diff --git a/git-curl-compat.h b/git-curl-compat.h
index fd96b3c..e1d0bdd 100644
--- a/git-curl-compat.h
+++ b/git-curl-compat.h
@@ -127,6 +127,15 @@
 #endif
 
 /**
+ * Versions before curl 7.66.0 (September 2019) required manually setting the
+ * transfer-encoding for a streaming POST; after that this is handled
+ * automatically.
+ */
+#if LIBCURL_VERSION_NUM < 0x074200
+#define GIT_CURL_NEED_TRANSFER_ENCODING_HEADER
+#endif
+
+/**
  * CURLOPT_PROTOCOLS_STR and CURLOPT_REDIR_PROTOCOLS_STR were added in 7.85.0,
  * released in August 2022.
  */
diff --git a/git-difftool--helper.sh b/git-difftool--helper.sh
index e4e820e..dd0c9a5 100755
--- a/git-difftool--helper.sh
+++ b/git-difftool--helper.sh
@@ -91,6 +91,19 @@
 	# ignore the error from the above --- run_merge_tool
 	# will diagnose unusable tool by itself
 	run_merge_tool "$merge_tool" false
+
+	status=$?
+	if test $status -ge 126
+	then
+		# Command not found (127), not executable (126) or
+		# exited via a signal (>= 128).
+		exit $status
+	fi
+
+	if test "$GIT_DIFFTOOL_TRUST_EXIT_CODE" = true
+	then
+		exit $status
+	fi
 else
 	# Launch the merge tool on each path provided by 'git diff'
 	while test $# -gt 6
diff --git a/git-gui/.gitattributes b/git-gui/.gitattributes
index 59cd41d..118d56c 100644
--- a/git-gui/.gitattributes
+++ b/git-gui/.gitattributes
@@ -3,3 +3,4 @@
 git-gui.sh  encoding=UTF-8
 /po/*.po    encoding=UTF-8
 /GIT-VERSION-GEN eol=lf
+Makefile    whitespace=!indent,trail,space
diff --git a/git-gui/Makefile b/git-gui/Makefile
index 3f80435..667c39e 100644
--- a/git-gui/Makefile
+++ b/git-gui/Makefile
@@ -107,12 +107,12 @@
 
 ifeq ($(uname_S),Darwin)
 	TKFRAMEWORK = /Library/Frameworks/Tk.framework/Resources/Wish.app
-	ifeq ($(shell echo "$(uname_R)" | awk -F. '{if ($$1 >= 9) print "y"}')_$(shell test -d $(TKFRAMEWORK) || echo n),y_n)
+        ifeq ($(shell echo "$(uname_R)" | awk -F. '{if ($$1 >= 9) print "y"}')_$(shell test -d $(TKFRAMEWORK) || echo n),y_n)
 		TKFRAMEWORK = /System/Library/Frameworks/Tk.framework/Resources/Wish.app
-		ifeq ($(shell test -d $(TKFRAMEWORK) || echo n),n)
+                ifeq ($(shell test -d $(TKFRAMEWORK) || echo n),n)
 			TKFRAMEWORK = /System/Library/Frameworks/Tk.framework/Resources/Wish\ Shell.app
-		endif
-	endif
+                endif
+        endif
 	TKEXECUTABLE = $(shell basename "$(TKFRAMEWORK)" .app)
 endif
 
@@ -143,9 +143,9 @@
 endif
 gg_libdir_sed_in := $(gg_libdir)
 ifeq ($(uname_S),Darwin)
-	ifeq ($(shell test -d $(TKFRAMEWORK) && echo y),y)
+        ifeq ($(shell test -d $(TKFRAMEWORK) && echo y),y)
 		GITGUI_MACOSXAPP := YesPlease
-	endif
+        endif
 endif
 ifneq (,$(findstring MINGW,$(uname_S)))
 ifeq ($(shell expr "$(uname_R)" : '1\.'),2)
@@ -220,9 +220,9 @@
 	MSGFMT ?= $(TCL_PATH) po/po2msg.sh
 else
 	MSGFMT ?= msgfmt
-	ifneq ($(shell $(MSGFMT) --tcl -l C -d . /dev/null 2>/dev/null; echo $$?),0)
+        ifneq ($(shell $(MSGFMT) --tcl -l C -d . /dev/null 2>/dev/null; echo $$?),0)
 		MSGFMT := $(TCL_PATH) po/po2msg.sh
-	endif
+        endif
 endif
 
 msgsdir     = $(gg_libdir)/msgs
diff --git a/git-p4.py b/git-p4.py
index 156597a..f1ab31d 100755
--- a/git-p4.py
+++ b/git-p4.py
@@ -3253,17 +3253,19 @@ def streamP4FilesCb(self, marshalled):
             if self.stream_have_file_info:
                 if "depotFile" in self.stream_file:
                     f = self.stream_file["depotFile"]
-            # force a failure in fast-import, else an empty
-            # commit will be made
-            self.gitStream.write("\n")
-            self.gitStream.write("die-now\n")
-            self.gitStream.close()
-            # ignore errors, but make sure it exits first
-            self.importProcess.wait()
-            if f:
-                die("Error from p4 print for %s: %s" % (f, err))
-            else:
-                die("Error from p4 print: %s" % err)
+            try:
+                # force a failure in fast-import, else an empty
+                # commit will be made
+                self.gitStream.write("\n")
+                self.gitStream.write("die-now\n")
+                self.gitStream.close()
+                # ignore errors, but make sure it exits first
+                self.importProcess.wait()
+            finally:
+                if f:
+                    die("Error from p4 print for %s: %s" % (f, err))
+                else:
+                    die("Error from p4 print: %s" % err)
 
         if 'depotFile' in marshalled and self.stream_have_file_info:
             # start of a new file - output the old one first
@@ -4251,7 +4253,8 @@ def run(self, args):
         if self.tempBranches != []:
             for branch in self.tempBranches:
                 read_pipe(["git", "update-ref", "-d", branch])
-            os.rmdir(os.path.join(os.environ.get("GIT_DIR", ".git"), self.tempBranchLocation))
+            if len(read_pipe(["git", "for-each-ref", self.tempBranchLocation])) > 0:
+                   die("There are unexpected temporary branches")
 
         # Create a symbolic ref p4/HEAD pointing to p4/<branch> to allow
         # a convenient shortcut refname "p4".
diff --git a/git-quiltimport.sh b/git-quiltimport.sh
index e3d3909..eb34cda 100755
--- a/git-quiltimport.sh
+++ b/git-quiltimport.sh
@@ -148,7 +148,7 @@
 	if [ -z "$dry_run" ] ; then
 		git apply --index -C1 ${level:+"$level"} "$tmp_patch" &&
 		tree=$(git write-tree) &&
-		commit=$( (echo "$SUBJECT"; echo; cat "$tmp_msg") | git commit-tree $tree -p $commit) &&
+		commit=$( { echo "$SUBJECT"; echo; cat "$tmp_msg"; } | git commit-tree $tree -p $commit) &&
 		git update-ref -m "quiltimport: $patch_name" HEAD $commit || exit 4
 	fi
 done 3<"$QUILT_SERIES"
diff --git a/git.c b/git.c
index c67e44d..654d615 100644
--- a/git.c
+++ b/git.c
@@ -4,6 +4,7 @@
 #include "exec-cmd.h"
 #include "gettext.h"
 #include "help.h"
+#include "object-file.h"
 #include "pager.h"
 #include "read-cache-ll.h"
 #include "run-command.h"
@@ -186,6 +187,11 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)
 			use_pager = 0;
 			if (envchanged)
 				*envchanged = 1;
+		} else if (!strcmp(cmd, "--no-lazy-fetch")) {
+			fetch_if_missing = 0;
+			setenv(NO_LAZY_FETCH_ENVIRONMENT, "1", 1);
+			if (envchanged)
+				*envchanged = 1;
 		} else if (!strcmp(cmd, "--no-replace-objects")) {
 			disable_replace_refs();
 			setenv(NO_REPLACE_OBJECTS_ENVIRONMENT, "1", 1);
@@ -373,8 +379,6 @@ static int handle_alias(int *argcp, const char ***argv)
 			strvec_pushv(&child.args, (*argv) + 1);
 
 			trace2_cmd_alias(alias_command, child.args.v);
-			trace2_cmd_list_config();
-			trace2_cmd_list_env_vars();
 			trace2_cmd_name("_run_shell_alias_");
 
 			ret = run_command(&child);
@@ -411,8 +415,6 @@ static int handle_alias(int *argcp, const char ***argv)
 		COPY_ARRAY(new_argv + count, *argv + 1, *argcp);
 
 		trace2_cmd_alias(alias_command, new_argv);
-		trace2_cmd_list_config();
-		trace2_cmd_list_env_vars();
 
 		*argv = new_argv;
 		*argcp += count - 1;
@@ -462,8 +464,6 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv)
 
 	trace_argv_printf(argv, "trace: built-in: git");
 	trace2_cmd_name(p->cmd);
-	trace2_cmd_list_config();
-	trace2_cmd_list_env_vars();
 
 	validate_cache_entries(the_repository->index);
 	status = p->fn(argc, argv, prefix);
@@ -594,6 +594,7 @@ static struct cmd_struct commands[] = {
 	{ "remote-fd", cmd_remote_fd, NO_PARSEOPT },
 	{ "repack", cmd_repack, RUN_SETUP },
 	{ "replace", cmd_replace, RUN_SETUP },
+	{ "replay", cmd_replay, RUN_SETUP },
 	{ "rerere", cmd_rerere, RUN_SETUP },
 	{ "reset", cmd_reset, RUN_SETUP },
 	{ "restore", cmd_restore, RUN_SETUP | NEED_WORK_TREE },
diff --git a/gitk-git/Makefile b/gitk-git/Makefile
index 5bdd52a..e1f0aff 100644
--- a/gitk-git/Makefile
+++ b/gitk-git/Makefile
@@ -33,9 +33,9 @@
 	MSGFMT ?= $(TCL_PATH) po/po2msg.sh
 else
 	MSGFMT ?= msgfmt
-	ifneq ($(shell $(MSGFMT) --tcl -l C -d . /dev/null 2>/dev/null; echo $$?),0)
+        ifneq ($(shell $(MSGFMT) --tcl -l C -d . /dev/null 2>/dev/null; echo $$?),0)
 		MSGFMT := $(TCL_PATH) po/po2msg.sh
-	endif
+        endif
 endif
 
 PO_TEMPLATE = po/gitk.pot
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index fc6d5dd..ccd14e0 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -728,9 +728,11 @@
 sub read_config_file {
 	my $filename = shift;
 	return unless defined $filename;
-	# die if there are errors parsing config file
 	if (-e $filename) {
 		do $filename;
+		# die if there is a problem accessing the file
+		die $! if $!;
+		# die if there are errors parsing config file
 		die $@ if $@;
 		return 1;
 	}
diff --git a/gpg-interface.c b/gpg-interface.c
index 95e764a..1ff9426 100644
--- a/gpg-interface.c
+++ b/gpg-interface.c
@@ -483,7 +483,7 @@ static int verify_ssh_signed_buffer(struct signature_check *sigc,
 
 	if (sigc->payload_timestamp)
 		strbuf_addf(&verify_time, "-Overify-time=%s",
-			show_date(sigc->payload_timestamp, 0, &verify_date_mode));
+			show_date(sigc->payload_timestamp, 0, verify_date_mode));
 
 	/* Find the principal from the signers */
 	strvec_pushl(&ssh_keygen.args, fmt->program,
@@ -586,8 +586,8 @@ static int verify_ssh_signed_buffer(struct signature_check *sigc,
 		}
 	}
 
-	strbuf_stripspace(&ssh_keygen_out, '\0');
-	strbuf_stripspace(&ssh_keygen_err, '\0');
+	strbuf_stripspace(&ssh_keygen_out, NULL);
+	strbuf_stripspace(&ssh_keygen_err, NULL);
 	/* Add stderr outputs to show the user actual ssh-keygen errors */
 	strbuf_add(&ssh_keygen_out, ssh_principals_err.buf, ssh_principals_err.len);
 	strbuf_add(&ssh_keygen_out, ssh_keygen_err.buf, ssh_keygen_err.len);
diff --git a/grep.c b/grep.c
index 5f23d1a..ac34bfe 100644
--- a/grep.c
+++ b/grep.c
@@ -621,7 +621,7 @@ static struct grep_expr *compile_pattern_atom(struct grep_pat **list)
 		*list = p->next;
 		x = compile_pattern_or(list);
 		if (!*list || (*list)->token != GREP_CLOSE_PAREN)
-			die("unmatched parenthesis");
+			die("unmatched ( for expression group");
 		*list = (*list)->next;
 		return x;
 	default:
@@ -792,7 +792,7 @@ void compile_grep_patterns(struct grep_opt *opt)
 	if (p)
 		opt->pattern_expression = compile_pattern_expr(&p);
 	if (p)
-		die("incomplete pattern expression: %s", p->pattern);
+		die("incomplete pattern expression group: %s", p->pattern);
 
 	if (opt->no_body_match && opt->pattern_expression)
 		opt->pattern_expression = grep_not_expr(opt->pattern_expression);
diff --git a/hash-ll.h b/hash-ll.h
index 10d84cc..2cfde63 100644
--- a/hash-ll.h
+++ b/hash-ll.h
@@ -145,6 +145,7 @@ struct object_id {
 #define GET_OID_RECORD_PATH     0200
 #define GET_OID_ONLY_TO_DIE    04000
 #define GET_OID_REQUIRE_PATH  010000
+#define GET_OID_HASH_ANY      020000
 
 #define GET_OID_DISAMBIGUATORS \
 	(GET_OID_COMMIT | GET_OID_COMMITTISH | \
diff --git a/hash.h b/hash.h
index 615ae06..e064807 100644
--- a/hash.h
+++ b/hash.h
@@ -73,10 +73,15 @@ static inline void oidclr(struct object_id *oid)
 	oid->algo = hash_algo_by_ptr(the_hash_algo);
 }
 
+static inline void oidread_algop(struct object_id *oid, const unsigned char *hash, const struct git_hash_algo *algop)
+{
+	memcpy(oid->hash, hash, algop->rawsz);
+	oid->algo = hash_algo_by_ptr(algop);
+}
+
 static inline void oidread(struct object_id *oid, const unsigned char *hash)
 {
-	memcpy(oid->hash, hash, the_hash_algo->rawsz);
-	oid->algo = hash_algo_by_ptr(the_hash_algo);
+	oidread_algop(oid, hash, the_hash_algo);
 }
 
 static inline int is_empty_blob_sha1(const unsigned char *sha1)
diff --git a/hook.c b/hook.c
index f6306d7..7e90787 100644
--- a/hook.c
+++ b/hook.c
@@ -7,25 +7,31 @@
 #include "run-command.h"
 #include "config.h"
 #include "strbuf.h"
+#include "environment.h"
+#include "setup.h"
 
 const char *find_hook(const char *name)
 {
 	static struct strbuf path = STRBUF_INIT;
 
+	int found_hook;
+
 	strbuf_reset(&path);
 	strbuf_git_path(&path, "hooks/%s", name);
-	if (access(path.buf, X_OK) < 0) {
+	found_hook = access(path.buf, X_OK) >= 0;
+#ifdef STRIP_EXTENSION
+	if (!found_hook) {
 		int err = errno;
 
-#ifdef STRIP_EXTENSION
 		strbuf_addstr(&path, STRIP_EXTENSION);
-		if (access(path.buf, X_OK) >= 0)
-			return path.buf;
-		if (errno == EACCES)
-			err = errno;
+		found_hook = access(path.buf, X_OK) >= 0;
+		if (!found_hook)
+			errno = err;
+	}
 #endif
 
-		if (err == EACCES && advice_enabled(ADVICE_IGNORED_HOOK)) {
+	if (!found_hook) {
+		if (errno == EACCES && advice_enabled(ADVICE_IGNORED_HOOK)) {
 			static struct string_list advise_given = STRING_LIST_INIT_DUP;
 
 			if (!string_list_lookup(&advise_given, name)) {
diff --git a/http-backend.c b/http-backend.c
index ff07b87..1ed1e29 100644
--- a/http-backend.c
+++ b/http-backend.c
@@ -38,6 +38,7 @@ struct rpc_service {
 static struct rpc_service rpc_service[] = {
 	{ "upload-pack", "uploadpack", 1, 1 },
 	{ "receive-pack", "receivepack", 0, -1 },
+	{ "upload-archive", "uploadarchive", 0, -1 },
 };
 
 static struct string_list *get_parameters(void)
@@ -639,10 +640,15 @@ static void check_content_type(struct strbuf *hdr, const char *accepted_type)
 
 static void service_rpc(struct strbuf *hdr, char *service_name)
 {
-	const char *argv[] = {NULL, "--stateless-rpc", ".", NULL};
+	struct strvec argv = STRVEC_INIT;
 	struct rpc_service *svc = select_service(hdr, service_name);
 	struct strbuf buf = STRBUF_INIT;
 
+	strvec_push(&argv, svc->name);
+	if (strcmp(service_name, "git-upload-archive"))
+		strvec_push(&argv, "--stateless-rpc");
+	strvec_push(&argv, ".");
+
 	strbuf_reset(&buf);
 	strbuf_addf(&buf, "application/x-git-%s-request", svc->name);
 	check_content_type(hdr, buf.buf);
@@ -655,9 +661,9 @@ static void service_rpc(struct strbuf *hdr, char *service_name)
 
 	end_headers(hdr);
 
-	argv[0] = svc->name;
-	run_service(argv, svc->buffer_input);
+	run_service(argv.v, svc->buffer_input);
 	strbuf_release(&buf);
+	strvec_clear(&argv);
 }
 
 static int dead;
@@ -723,6 +729,7 @@ static struct service_cmd {
 	{"GET", "/objects/pack/pack-[0-9a-f]{64}\\.idx$", get_idx_file},
 
 	{"POST", "/git-upload-pack$", service_rpc},
+	{"POST", "/git-upload-archive$", service_rpc},
 	{"POST", "/git-receive-pack$", service_rpc}
 };
 
diff --git a/http-push.c b/http-push.c
index b4d0b2a..1fe5122 100644
--- a/http-push.c
+++ b/http-push.c
@@ -1307,7 +1307,7 @@ static struct object_list **process_tree(struct tree *tree,
 	obj->flags |= SEEN;
 	p = add_one_object(obj, p);
 
-	init_tree_desc(&desc, tree->buffer, tree->size);
+	init_tree_desc(&desc, &tree->object.oid, tree->buffer, tree->size);
 
 	while (tree_entry(&desc, &entry))
 		switch (object_type(entry.mode)) {
@@ -1575,8 +1575,11 @@ static int verify_merge_base(struct object_id *head_oid, struct ref *remote)
 	struct commit *head = lookup_commit_or_die(head_oid, "HEAD");
 	struct commit *branch = lookup_commit_or_die(&remote->old_oid,
 						     remote->name);
+	int ret = repo_in_merge_bases(the_repository, branch, head);
 
-	return repo_in_merge_bases(the_repository, branch, head);
+	if (ret < 0)
+		exit(128);
+	return ret;
 }
 
 static int delete_remote_branch(const char *pattern, int force)
@@ -1851,6 +1854,7 @@ int cmd_main(int argc, const char **argv)
 
 		if (oideq(&ref->old_oid, &ref->peer_ref->new_oid)) {
 			if (push_verbosely)
+				/* stable plumbing output; do not modify or localize */
 				fprintf(stderr, "'%s': up-to-date\n", ref->name);
 			if (helper_status)
 				printf("ok %s up to date\n", ref->name);
@@ -1871,6 +1875,7 @@ int cmd_main(int argc, const char **argv)
 				 * commits at the remote end and likely
 				 * we were not up to date to begin with.
 				 */
+				/* stable plumbing output; do not modify or localize */
 				error("remote '%s' is not an ancestor of\n"
 				      "local '%s'.\n"
 				      "Maybe you are not up-to-date and "
diff --git a/http.c b/http.c
index e73b136..3d80bd6 100644
--- a/http.c
+++ b/http.c
@@ -1452,6 +1452,7 @@ struct active_request_slot *get_active_slot(void)
 	curl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, NULL);
 	curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, NULL);
 	curl_easy_setopt(slot->curl, CURLOPT_POSTFIELDS, NULL);
+	curl_easy_setopt(slot->curl, CURLOPT_POSTFIELDSIZE, -1L);
 	curl_easy_setopt(slot->curl, CURLOPT_UPLOAD, 0);
 	curl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1);
 	curl_easy_setopt(slot->curl, CURLOPT_FAILONERROR, 1);
diff --git a/imap-send.c b/imap-send.c
index f2e1947..0afd088 100644
--- a/imap-send.c
+++ b/imap-send.c
@@ -68,23 +68,6 @@ static void imap_warn(const char *, ...);
 
 static char *next_arg(char **);
 
-__attribute__((format (printf, 3, 4)))
-static int nfsnprintf(char *buf, int blen, const char *fmt, ...);
-
-static int nfvasprintf(char **strp, const char *fmt, va_list ap)
-{
-	int len;
-	char tmp[8192];
-
-	len = vsnprintf(tmp, sizeof(tmp), fmt, ap);
-	if (len < 0)
-		die("Fatal: Out of memory");
-	if (len >= sizeof(tmp))
-		die("imap command overflow!");
-	*strp = xmemdupz(tmp, len);
-	return len;
-}
-
 struct imap_server_conf {
 	const char *name;
 	const char *tunnel;
@@ -500,30 +483,17 @@ static char *next_arg(char **s)
 	return ret;
 }
 
-__attribute__((format (printf, 3, 4)))
-static int nfsnprintf(char *buf, int blen, const char *fmt, ...)
-{
-	int ret;
-	va_list va;
-
-	va_start(va, fmt);
-	if (blen <= 0 || (unsigned)(ret = vsnprintf(buf, blen, fmt, va)) >= (unsigned)blen)
-		BUG("buffer too small. Please report a bug.");
-	va_end(va);
-	return ret;
-}
-
 static struct imap_cmd *issue_imap_cmd(struct imap_store *ctx,
 				       struct imap_cmd_cb *cb,
 				       const char *fmt, va_list ap)
 {
 	struct imap *imap = ctx->imap;
 	struct imap_cmd *cmd;
-	int n, bufl;
-	char buf[1024];
+	int n;
+	struct strbuf buf = STRBUF_INIT;
 
 	cmd = xmalloc(sizeof(struct imap_cmd));
-	nfvasprintf(&cmd->cmd, fmt, ap);
+	cmd->cmd = xstrvfmt(fmt, ap);
 	cmd->tag = ++imap->nexttag;
 
 	if (cb)
@@ -535,27 +505,30 @@ static struct imap_cmd *issue_imap_cmd(struct imap_store *ctx,
 		get_cmd_result(ctx, NULL);
 
 	if (!cmd->cb.data)
-		bufl = nfsnprintf(buf, sizeof(buf), "%d %s\r\n", cmd->tag, cmd->cmd);
+		strbuf_addf(&buf, "%d %s\r\n", cmd->tag, cmd->cmd);
 	else
-		bufl = nfsnprintf(buf, sizeof(buf), "%d %s{%d%s}\r\n",
-				  cmd->tag, cmd->cmd, cmd->cb.dlen,
-				  CAP(LITERALPLUS) ? "+" : "");
+		strbuf_addf(&buf, "%d %s{%d%s}\r\n", cmd->tag, cmd->cmd,
+			    cmd->cb.dlen, CAP(LITERALPLUS) ? "+" : "");
+	if (buf.len > INT_MAX)
+		die("imap command overflow!");
 
 	if (0 < verbosity) {
 		if (imap->num_in_progress)
 			printf("(%d in progress) ", imap->num_in_progress);
 		if (!starts_with(cmd->cmd, "LOGIN"))
-			printf(">>> %s", buf);
+			printf(">>> %s", buf.buf);
 		else
 			printf(">>> %d LOGIN <user> <pass>\n", cmd->tag);
 	}
-	if (socket_write(&imap->buf.sock, buf, bufl) != bufl) {
+	if (socket_write(&imap->buf.sock, buf.buf, buf.len) != buf.len) {
 		free(cmd->cmd);
 		free(cmd);
 		if (cb)
 			free(cb->data);
+		strbuf_release(&buf);
 		return NULL;
 	}
+	strbuf_release(&buf);
 	if (cmd->cb.data) {
 		if (CAP(LITERALPLUS)) {
 			n = socket_write(&imap->buf.sock, cmd->cb.data, cmd->cb.dlen);
diff --git a/list-objects-filter.c b/list-objects-filter.c
index da287cc..4346f8d 100644
--- a/list-objects-filter.c
+++ b/list-objects-filter.c
@@ -711,15 +711,6 @@ static void filter_combine__free(void *filter_data)
 	free(d);
 }
 
-static void add_all(struct oidset *dest, struct oidset *src) {
-	struct oidset_iter iter;
-	struct object_id *src_oid;
-
-	oidset_iter_init(src, &iter);
-	while ((src_oid = oidset_iter_next(&iter)) != NULL)
-		oidset_insert(dest, src_oid);
-}
-
 static void filter_combine__finalize_omits(
 	struct oidset *omits,
 	void *filter_data)
@@ -728,7 +719,7 @@ static void filter_combine__finalize_omits(
 	size_t sub;
 
 	for (sub = 0; sub < d->nr; sub++) {
-		add_all(omits, &d->sub[sub].omits);
+		oidset_insert_from_set(omits, &d->sub[sub].omits);
 		oidset_clear(&d->sub[sub].omits);
 	}
 }
diff --git a/list-objects.c b/list-objects.c
index f39b68f..11ad8be 100644
--- a/list-objects.c
+++ b/list-objects.c
@@ -102,7 +102,7 @@ static void process_tree_contents(struct traversal_context *ctx,
 	enum interesting match = ctx->revs->diffopt.pathspec.nr == 0 ?
 		all_entries_interesting : entry_not_interesting;
 
-	init_tree_desc(&desc, tree->buffer, tree->size);
+	init_tree_desc(&desc, &tree->object.oid, tree->buffer, tree->size);
 
 	while (tree_entry(&desc, &entry)) {
 		if (match != all_entries_interesting) {
diff --git a/lockfile.h b/lockfile.h
index 90af4e6..1bb9926 100644
--- a/lockfile.h
+++ b/lockfile.h
@@ -321,11 +321,11 @@ static inline int commit_lock_file_to(struct lock_file *lk, const char *path)
  * Roll back `lk`: close the file descriptor and/or file pointer and
  * remove the lockfile. It is a NOOP to call `rollback_lock_file()`
  * for a `lock_file` object that has already been committed or rolled
- * back.
+ * back. No error will be returned in this case.
  */
-static inline void rollback_lock_file(struct lock_file *lk)
+static inline int rollback_lock_file(struct lock_file *lk)
 {
-	delete_tempfile(&lk->tempfile);
+	return delete_tempfile(&lk->tempfile);
 }
 
 #endif /* LOCKFILE_H */
diff --git a/log-tree.c b/log-tree.c
index 337b933..16031b4 100644
--- a/log-tree.c
+++ b/log-tree.c
@@ -470,16 +470,19 @@ void fmt_output_email_subject(struct strbuf *sb, struct rev_info *opt)
 }
 
 void log_write_email_headers(struct rev_info *opt, struct commit *commit,
-			     const char **extra_headers_p,
+			     char **extra_headers_p,
 			     int *need_8bit_cte_p,
 			     int maybe_multipart)
 {
-	const char *extra_headers = opt->extra_headers;
+	struct strbuf headers = STRBUF_INIT;
 	const char *name = oid_to_hex(opt->zero_commit ?
 				      null_oid() : &commit->object.oid);
 
 	*need_8bit_cte_p = 0; /* unknown */
 
+	if (opt->extra_headers && *opt->extra_headers)
+		strbuf_addstr(&headers, opt->extra_headers);
+
 	fprintf(opt->diffopt.file, "From %s Mon Sep 17 00:00:00 2001\n", name);
 	graph_show_oneline(opt->graph);
 	if (opt->message_id) {
@@ -496,16 +499,13 @@ void log_write_email_headers(struct rev_info *opt, struct commit *commit,
 		graph_show_oneline(opt->graph);
 	}
 	if (opt->mime_boundary && maybe_multipart) {
-		static struct strbuf subject_buffer = STRBUF_INIT;
 		static struct strbuf buffer = STRBUF_INIT;
 		struct strbuf filename =  STRBUF_INIT;
 		*need_8bit_cte_p = -1; /* NEVER */
 
-		strbuf_reset(&subject_buffer);
 		strbuf_reset(&buffer);
 
-		strbuf_addf(&subject_buffer,
-			 "%s"
+		strbuf_addf(&headers,
 			 "MIME-Version: 1.0\n"
 			 "Content-Type: multipart/mixed;"
 			 " boundary=\"%s%s\"\n"
@@ -516,10 +516,8 @@ void log_write_email_headers(struct rev_info *opt, struct commit *commit,
 			 "Content-Type: text/plain; "
 			 "charset=UTF-8; format=fixed\n"
 			 "Content-Transfer-Encoding: 8bit\n\n",
-			 extra_headers ? extra_headers : "",
 			 mime_boundary_leader, opt->mime_boundary,
 			 mime_boundary_leader, opt->mime_boundary);
-		extra_headers = subject_buffer.buf;
 
 		if (opt->numbered_files)
 			strbuf_addf(&filename, "%d", opt->nr);
@@ -539,7 +537,7 @@ void log_write_email_headers(struct rev_info *opt, struct commit *commit,
 		opt->diffopt.stat_sep = buffer.buf;
 		strbuf_release(&filename);
 	}
-	*extra_headers_p = extra_headers;
+	*extra_headers_p = headers.len ? strbuf_detach(&headers, NULL) : NULL;
 }
 
 static void show_sig_lines(struct rev_info *opt, int status, const char *bol)
@@ -678,7 +676,6 @@ void show_log(struct rev_info *opt)
 	struct log_info *log = opt->loginfo;
 	struct commit *commit = log->commit, *parent = log->parent;
 	int abbrev_commit = opt->abbrev_commit ? opt->abbrev : the_hash_algo->hexsz;
-	const char *extra_headers = opt->extra_headers;
 	struct pretty_print_context ctx = {0};
 
 	opt->loginfo = NULL;
@@ -739,10 +736,9 @@ void show_log(struct rev_info *opt)
 	 */
 
 	if (cmit_fmt_is_mail(opt->commit_format)) {
-		log_write_email_headers(opt, commit, &extra_headers,
+		log_write_email_headers(opt, commit, &ctx.after_subject,
 					&ctx.need_8bit_cte, 1);
 		ctx.rev = opt;
-		ctx.print_email_subject = 1;
 	} else if (opt->commit_format != CMIT_FMT_USERFORMAT) {
 		fputs(diff_get_color_opt(&opt->diffopt, DIFF_COMMIT), opt->diffopt.file);
 		if (opt->commit_format != CMIT_FMT_ONELINE)
@@ -777,7 +773,7 @@ void show_log(struct rev_info *opt)
 			 */
 			show_reflog_message(opt->reflog_info,
 					    opt->commit_format == CMIT_FMT_ONELINE,
-					    &opt->date_mode,
+					    opt->date_mode,
 					    opt->date_mode_explicit);
 			if (opt->commit_format == CMIT_FMT_ONELINE)
 				return;
@@ -808,7 +804,6 @@ void show_log(struct rev_info *opt)
 	ctx.date_mode = opt->date_mode;
 	ctx.date_mode_explicit = opt->date_mode_explicit;
 	ctx.abbrev = opt->diffopt.abbrev;
-	ctx.after_subject = extra_headers;
 	ctx.preserve_subject = opt->preserve_subject;
 	ctx.encode_email_headers = opt->encode_email_headers;
 	ctx.reflog_info = opt->reflog_info;
@@ -857,6 +852,7 @@ void show_log(struct rev_info *opt)
 
 	strbuf_release(&msgbuf);
 	free(ctx.notes_message);
+	free(ctx.after_subject);
 
 	if (cmit_fmt_is_mail(ctx.fmt) && opt->idiff_oid1) {
 		struct diff_queue_struct dq;
@@ -1011,7 +1007,7 @@ static int do_remerge_diff(struct rev_info *opt,
 			   struct object_id *oid)
 {
 	struct merge_options o;
-	struct commit_list *bases;
+	struct commit_list *bases = NULL;
 	struct merge_result res = {0};
 	struct pretty_print_context ctx = {0};
 	struct commit *parent1 = parents->item;
@@ -1036,7 +1032,8 @@ static int do_remerge_diff(struct rev_info *opt,
 	/* Parse the relevant commits and get the merge bases */
 	parse_commit_or_die(parent1);
 	parse_commit_or_die(parent2);
-	bases = repo_get_merge_bases(the_repository, parent1, parent2);
+	if (repo_get_merge_bases(the_repository, parent1, parent2, &bases) < 0)
+		exit(128);
 
 	/* Re-merge the parents */
 	merge_incore_recursive(&o, bases, parent1, parent2, &res);
diff --git a/log-tree.h b/log-tree.h
index 41c776f..94978e2 100644
--- a/log-tree.h
+++ b/log-tree.h
@@ -29,7 +29,7 @@ void format_decorations(struct strbuf *sb, const struct commit *commit,
 			int use_color, const struct decoration_options *opts);
 void show_decorations(struct rev_info *opt, struct commit *commit);
 void log_write_email_headers(struct rev_info *opt, struct commit *commit,
-			     const char **extra_headers_p,
+			     char **extra_headers_p,
 			     int *need_8bit_cte_p,
 			     int maybe_multipart);
 void load_ref_decorations(struct decoration_filter *filter, int flags);
diff --git a/loose.c b/loose.c
new file mode 100644
index 0000000..f6faa62
--- /dev/null
+++ b/loose.c
@@ -0,0 +1,259 @@
+#include "git-compat-util.h"
+#include "hash.h"
+#include "path.h"
+#include "object-store.h"
+#include "hex.h"
+#include "wrapper.h"
+#include "gettext.h"
+#include "loose.h"
+#include "lockfile.h"
+#include "oidtree.h"
+
+static const char *loose_object_header = "# loose-object-idx\n";
+
+static inline int should_use_loose_object_map(struct repository *repo)
+{
+	return repo->compat_hash_algo && repo->gitdir;
+}
+
+void loose_object_map_init(struct loose_object_map **map)
+{
+	struct loose_object_map *m;
+	m = xmalloc(sizeof(**map));
+	m->to_compat = kh_init_oid_map();
+	m->to_storage = kh_init_oid_map();
+	*map = m;
+}
+
+static int insert_oid_pair(kh_oid_map_t *map, const struct object_id *key, const struct object_id *value)
+{
+	khiter_t pos;
+	int ret;
+	struct object_id *stored;
+
+	pos = kh_put_oid_map(map, *key, &ret);
+
+	/* This item already exists in the map. */
+	if (ret == 0)
+		return 0;
+
+	stored = xmalloc(sizeof(*stored));
+	oidcpy(stored, value);
+	kh_value(map, pos) = stored;
+	return 1;
+}
+
+static int insert_loose_map(struct object_directory *odb,
+			    const struct object_id *oid,
+			    const struct object_id *compat_oid)
+{
+	struct loose_object_map *map = odb->loose_map;
+	int inserted = 0;
+
+	inserted |= insert_oid_pair(map->to_compat, oid, compat_oid);
+	inserted |= insert_oid_pair(map->to_storage, compat_oid, oid);
+	if (inserted)
+		oidtree_insert(odb->loose_objects_cache, compat_oid);
+
+	return inserted;
+}
+
+static int load_one_loose_object_map(struct repository *repo, struct object_directory *dir)
+{
+	struct strbuf buf = STRBUF_INIT, path = STRBUF_INIT;
+	FILE *fp;
+
+	if (!dir->loose_map)
+		loose_object_map_init(&dir->loose_map);
+	if (!dir->loose_objects_cache) {
+		ALLOC_ARRAY(dir->loose_objects_cache, 1);
+		oidtree_init(dir->loose_objects_cache);
+	}
+
+	insert_loose_map(dir, repo->hash_algo->empty_tree, repo->compat_hash_algo->empty_tree);
+	insert_loose_map(dir, repo->hash_algo->empty_blob, repo->compat_hash_algo->empty_blob);
+	insert_loose_map(dir, repo->hash_algo->null_oid, repo->compat_hash_algo->null_oid);
+
+	strbuf_git_common_path(&path, repo, "objects/loose-object-idx");
+	fp = fopen(path.buf, "rb");
+	if (!fp) {
+		strbuf_release(&path);
+		return 0;
+	}
+
+	errno = 0;
+	if (strbuf_getwholeline(&buf, fp, '\n') || strcmp(buf.buf, loose_object_header))
+		goto err;
+	while (!strbuf_getline_lf(&buf, fp)) {
+		const char *p;
+		struct object_id oid, compat_oid;
+		if (parse_oid_hex_algop(buf.buf, &oid, &p, repo->hash_algo) ||
+		    *p++ != ' ' ||
+		    parse_oid_hex_algop(p, &compat_oid, &p, repo->compat_hash_algo) ||
+		    p != buf.buf + buf.len)
+			goto err;
+		insert_loose_map(dir, &oid, &compat_oid);
+	}
+
+	strbuf_release(&buf);
+	strbuf_release(&path);
+	return errno ? -1 : 0;
+err:
+	strbuf_release(&buf);
+	strbuf_release(&path);
+	return -1;
+}
+
+int repo_read_loose_object_map(struct repository *repo)
+{
+	struct object_directory *dir;
+
+	if (!should_use_loose_object_map(repo))
+		return 0;
+
+	prepare_alt_odb(repo);
+
+	for (dir = repo->objects->odb; dir; dir = dir->next) {
+		if (load_one_loose_object_map(repo, dir) < 0) {
+			return -1;
+		}
+	}
+	return 0;
+}
+
+int repo_write_loose_object_map(struct repository *repo)
+{
+	kh_oid_map_t *map = repo->objects->odb->loose_map->to_compat;
+	struct lock_file lock;
+	int fd;
+	khiter_t iter;
+	struct strbuf buf = STRBUF_INIT, path = STRBUF_INIT;
+
+	if (!should_use_loose_object_map(repo))
+		return 0;
+
+	strbuf_git_common_path(&path, repo, "objects/loose-object-idx");
+	fd = hold_lock_file_for_update_timeout(&lock, path.buf, LOCK_DIE_ON_ERROR, -1);
+	iter = kh_begin(map);
+	if (write_in_full(fd, loose_object_header, strlen(loose_object_header)) < 0)
+		goto errout;
+
+	for (; iter != kh_end(map); iter++) {
+		if (kh_exist(map, iter)) {
+			if (oideq(&kh_key(map, iter), the_hash_algo->empty_tree) ||
+			    oideq(&kh_key(map, iter), the_hash_algo->empty_blob))
+				continue;
+			strbuf_addf(&buf, "%s %s\n", oid_to_hex(&kh_key(map, iter)), oid_to_hex(kh_value(map, iter)));
+			if (write_in_full(fd, buf.buf, buf.len) < 0)
+				goto errout;
+			strbuf_reset(&buf);
+		}
+	}
+	strbuf_release(&buf);
+	if (commit_lock_file(&lock) < 0) {
+		error_errno(_("could not write loose object index %s"), path.buf);
+		strbuf_release(&path);
+		return -1;
+	}
+	strbuf_release(&path);
+	return 0;
+errout:
+	rollback_lock_file(&lock);
+	strbuf_release(&buf);
+	error_errno(_("failed to write loose object index %s\n"), path.buf);
+	strbuf_release(&path);
+	return -1;
+}
+
+static int write_one_object(struct repository *repo, const struct object_id *oid,
+			    const struct object_id *compat_oid)
+{
+	struct lock_file lock;
+	int fd;
+	struct stat st;
+	struct strbuf buf = STRBUF_INIT, path = STRBUF_INIT;
+
+	strbuf_git_common_path(&path, repo, "objects/loose-object-idx");
+	hold_lock_file_for_update_timeout(&lock, path.buf, LOCK_DIE_ON_ERROR, -1);
+
+	fd = open(path.buf, O_WRONLY | O_CREAT | O_APPEND, 0666);
+	if (fd < 0)
+		goto errout;
+	if (fstat(fd, &st) < 0)
+		goto errout;
+	if (!st.st_size && write_in_full(fd, loose_object_header, strlen(loose_object_header)) < 0)
+		goto errout;
+
+	strbuf_addf(&buf, "%s %s\n", oid_to_hex(oid), oid_to_hex(compat_oid));
+	if (write_in_full(fd, buf.buf, buf.len) < 0)
+		goto errout;
+	if (close(fd))
+		goto errout;
+	adjust_shared_perm(path.buf);
+	rollback_lock_file(&lock);
+	strbuf_release(&buf);
+	strbuf_release(&path);
+	return 0;
+errout:
+	error_errno(_("failed to write loose object index %s\n"), path.buf);
+	close(fd);
+	rollback_lock_file(&lock);
+	strbuf_release(&buf);
+	strbuf_release(&path);
+	return -1;
+}
+
+int repo_add_loose_object_map(struct repository *repo, const struct object_id *oid,
+			      const struct object_id *compat_oid)
+{
+	int inserted = 0;
+
+	if (!should_use_loose_object_map(repo))
+		return 0;
+
+	inserted = insert_loose_map(repo->objects->odb, oid, compat_oid);
+	if (inserted)
+		return write_one_object(repo, oid, compat_oid);
+	return 0;
+}
+
+int repo_loose_object_map_oid(struct repository *repo,
+			      const struct object_id *src,
+			      const struct git_hash_algo *to,
+			      struct object_id *dest)
+{
+	struct object_directory *dir;
+	kh_oid_map_t *map;
+	khiter_t pos;
+
+	for (dir = repo->objects->odb; dir; dir = dir->next) {
+		struct loose_object_map *loose_map = dir->loose_map;
+		if (!loose_map)
+			continue;
+		map = (to == repo->compat_hash_algo) ?
+			loose_map->to_compat :
+			loose_map->to_storage;
+		pos = kh_get_oid_map(map, *src);
+		if (pos < kh_end(map)) {
+			oidcpy(dest, kh_value(map, pos));
+			return 0;
+		}
+	}
+	return -1;
+}
+
+void loose_object_map_clear(struct loose_object_map **map)
+{
+	struct loose_object_map *m = *map;
+	struct object_id *oid;
+
+	if (!m)
+		return;
+
+	kh_foreach_value(m->to_compat, oid, free(oid));
+	kh_foreach_value(m->to_storage, oid, free(oid));
+	kh_destroy_oid_map(m->to_compat);
+	kh_destroy_oid_map(m->to_storage);
+	free(m);
+	*map = NULL;
+}
diff --git a/loose.h b/loose.h
new file mode 100644
index 0000000..2c29570
--- /dev/null
+++ b/loose.h
@@ -0,0 +1,22 @@
+#ifndef LOOSE_H
+#define LOOSE_H
+
+#include "khash.h"
+
+struct loose_object_map {
+	kh_oid_map_t *to_compat;
+	kh_oid_map_t *to_storage;
+};
+
+void loose_object_map_init(struct loose_object_map **map);
+void loose_object_map_clear(struct loose_object_map **map);
+int repo_loose_object_map_oid(struct repository *repo,
+			      const struct object_id *src,
+			      const struct git_hash_algo *dest_algo,
+			      struct object_id *dest);
+int repo_add_loose_object_map(struct repository *repo, const struct object_id *oid,
+			      const struct object_id *compat_oid);
+int repo_read_loose_object_map(struct repository *repo);
+int repo_write_loose_object_map(struct repository *repo);
+
+#endif
diff --git a/match-trees.c b/match-trees.c
index 0885ac6..3412b6a 100644
--- a/match-trees.c
+++ b/match-trees.c
@@ -63,7 +63,7 @@ static void *fill_tree_desc_strict(struct tree_desc *desc,
 		die("unable to read tree (%s)", oid_to_hex(hash));
 	if (type != OBJ_TREE)
 		die("%s is not a tree", oid_to_hex(hash));
-	init_tree_desc(desc, buffer, size);
+	init_tree_desc(desc, hash, buffer, size);
 	return buffer;
 }
 
@@ -194,7 +194,7 @@ static int splice_tree(const struct object_id *oid1, const char *prefix,
 	buf = repo_read_object_file(the_repository, oid1, &type, &sz);
 	if (!buf)
 		die("cannot read tree %s", oid_to_hex(oid1));
-	init_tree_desc(&desc, buf, sz);
+	init_tree_desc(&desc, oid1, buf, sz);
 
 	rewrite_here = NULL;
 	while (desc.size) {
diff --git a/mem-pool.c b/mem-pool.c
index c34846d..a3ba388 100644
--- a/mem-pool.c
+++ b/mem-pool.c
@@ -4,6 +4,7 @@
 
 #include "git-compat-util.h"
 #include "mem-pool.h"
+#include "gettext.h"
 
 #define BLOCK_GROWTH_SIZE (1024 * 1024 - sizeof(struct mp_block))
 
@@ -89,9 +90,7 @@ void *mem_pool_alloc(struct mem_pool *pool, size_t len)
 	struct mp_block *p = NULL;
 	void *r;
 
-	/* round up to a 'GIT_MAX_ALIGNMENT' alignment */
-	if (len & (GIT_MAX_ALIGNMENT - 1))
-		len += GIT_MAX_ALIGNMENT - (len & (GIT_MAX_ALIGNMENT - 1));
+	len = DIV_ROUND_UP(len, GIT_MAX_ALIGNMENT) * GIT_MAX_ALIGNMENT;
 
 	if (pool->mp_block &&
 	    pool->mp_block->end - pool->mp_block->next_free >= len)
@@ -99,9 +98,9 @@ void *mem_pool_alloc(struct mem_pool *pool, size_t len)
 
 	if (!p) {
 		if (len >= (pool->block_alloc / 2))
-			return mem_pool_alloc_block(pool, len, pool->mp_block);
-
-		p = mem_pool_alloc_block(pool, pool->block_alloc, NULL);
+			p = mem_pool_alloc_block(pool, len, pool->mp_block);
+		else
+			p = mem_pool_alloc_block(pool, pool->block_alloc, NULL);
 	}
 
 	r = p->next_free;
@@ -109,6 +108,47 @@ void *mem_pool_alloc(struct mem_pool *pool, size_t len)
 	return r;
 }
 
+static char *mem_pool_strvfmt(struct mem_pool *pool, const char *fmt,
+			      va_list ap)
+{
+	struct mp_block *block = pool->mp_block;
+	char *next_free = block ? block->next_free : NULL;
+	size_t available = block ? block->end - block->next_free : 0;
+	va_list cp;
+	int len, len2;
+	size_t size;
+	char *ret;
+
+	va_copy(cp, ap);
+	len = vsnprintf(next_free, available, fmt, cp);
+	va_end(cp);
+	if (len < 0)
+		die(_("unable to format message: %s"), fmt);
+
+	size = st_add(len, 1); /* 1 for NUL */
+	ret = mem_pool_alloc(pool, size);
+
+	/* Shortcut; relies on mem_pool_alloc() not touching buffer contents. */
+	if (ret == next_free)
+		return ret;
+
+	len2 = vsnprintf(ret, size, fmt, ap);
+	if (len2 != len)
+		BUG("your vsnprintf is broken (returns inconsistent lengths)");
+	return ret;
+}
+
+char *mem_pool_strfmt(struct mem_pool *pool, const char *fmt, ...)
+{
+	va_list ap;
+	char *ret;
+
+	va_start(ap, fmt);
+	ret = mem_pool_strvfmt(pool, fmt, ap);
+	va_end(ap);
+	return ret;
+}
+
 void *mem_pool_calloc(struct mem_pool *pool, size_t count, size_t size)
 {
 	size_t len = st_mult(count, size);
diff --git a/mem-pool.h b/mem-pool.h
index fe7507f..d1c6641 100644
--- a/mem-pool.h
+++ b/mem-pool.h
@@ -48,6 +48,11 @@ char *mem_pool_strdup(struct mem_pool *pool, const char *str);
 char *mem_pool_strndup(struct mem_pool *pool, const char *str, size_t len);
 
 /*
+ * Allocate memory from the memory pool and format a string into it.
+ */
+char *mem_pool_strfmt(struct mem_pool *pool, const char *fmt, ...);
+
+/*
  * Move the memory associated with the 'src' pool to the 'dst' pool. The 'src'
  * pool will be empty and not contain any memory. It still needs to be free'd
  * with a call to `mem_pool_discard`.
diff --git a/merge-ll.c b/merge-ll.c
index 1df58eb..bf1077a 100644
--- a/merge-ll.c
+++ b/merge-ll.c
@@ -128,7 +128,9 @@ static enum ll_merge_result ll_xdl_merge(const struct ll_merge_driver *drv_unuse
 	xmp.level = XDL_MERGE_ZEALOUS;
 	xmp.favor = opts->variant;
 	xmp.xpp.flags = opts->xdl_opts;
-	if (git_xmerge_style >= 0)
+	if (opts->conflict_style >= 0)
+		xmp.style = opts->conflict_style;
+	else if (git_xmerge_style >= 0)
 		xmp.style = git_xmerge_style;
 	if (marker_size > 0)
 		xmp.marker_size = marker_size;
@@ -185,9 +187,9 @@ static void create_temp(mmfile_t *src, char *path, size_t len)
 static enum ll_merge_result ll_ext_merge(const struct ll_merge_driver *fn,
 			mmbuffer_t *result,
 			const char *path,
-			mmfile_t *orig, const char *orig_name UNUSED,
-			mmfile_t *src1, const char *name1 UNUSED,
-			mmfile_t *src2, const char *name2 UNUSED,
+			mmfile_t *orig, const char *orig_name,
+			mmfile_t *src1, const char *name1,
+			mmfile_t *src2, const char *name2,
 			const struct ll_merge_options *opts,
 			int marker_size)
 {
@@ -222,6 +224,12 @@ static enum ll_merge_result ll_ext_merge(const struct ll_merge_driver *fn,
 			strbuf_addf(&cmd, "%d", marker_size);
 		else if (skip_prefix(format, "P", &format))
 			sq_quote_buf(&cmd, path);
+		else if (skip_prefix(format, "S", &format))
+			sq_quote_buf(&cmd, orig_name ? orig_name : "");
+		else if (skip_prefix(format, "X", &format))
+			sq_quote_buf(&cmd, name1 ? name1 : "");
+		else if (skip_prefix(format, "Y", &format))
+			sq_quote_buf(&cmd, name2 ? name2 : "");
 		else
 			strbuf_addch(&cmd, '%');
 	}
@@ -286,7 +294,7 @@ static int read_merge_config(const char *var, const char *value,
 	 * after seeing merge.<name>.var1.
 	 */
 	for (fn = ll_user_merge; fn; fn = fn->next)
-		if (!strncmp(fn->name, name, namelen) && !fn->name[namelen])
+		if (!xstrncmpz(fn->name, name, namelen))
 			break;
 	if (!fn) {
 		CALLOC_ARRAY(fn, 1);
@@ -315,7 +323,12 @@ static int read_merge_config(const char *var, const char *value,
 		 *    %B - temporary file name for the other branches' version.
 		 *    %L - conflict marker length
 		 *    %P - the original path (safely quoted for the shell)
+		 *    %S - the revision for the merge base
+		 *    %X - the revision for our version
+		 *    %Y - the revision for their version
 		 *
+		 * If the file is not named indentically in all versions, then each
+		 * revision is joined with the corresponding path, separated by a colon.
 		 * The external merge driver should write the results in the
 		 * file named by %A, and signal that it has done with zero exit
 		 * status.
@@ -390,7 +403,7 @@ enum ll_merge_result ll_merge(mmbuffer_t *result_buf,
 	     const struct ll_merge_options *opts)
 {
 	struct attr_check *check = load_merge_attributes();
-	static const struct ll_merge_options default_opts;
+	static const struct ll_merge_options default_opts = LL_MERGE_OPTIONS_INIT;
 	const char *ll_driver_name = NULL;
 	int marker_size = DEFAULT_CONFLICT_MARKER_SIZE;
 	const struct ll_merge_driver *driver;
diff --git a/merge-ll.h b/merge-ll.h
index e4a20e8..d038ee0 100644
--- a/merge-ll.h
+++ b/merge-ll.h
@@ -78,10 +78,15 @@ struct ll_merge_options {
 	 */
 	unsigned extra_marker_size;
 
+	/* Override the global conflict style. */
+	int conflict_style;
+
 	/* Extra xpparam_t flags as defined in xdiff/xdiff.h. */
 	long xdl_opts;
 };
 
+#define LL_MERGE_OPTIONS_INIT { .conflict_style = -1 }
+
 enum ll_merge_result {
 	LL_MERGE_ERROR = -1,
 	LL_MERGE_OK = 0,
diff --git a/merge-ort.c b/merge-ort.c
index cb83449..eaede6c 100644
--- a/merge-ort.c
+++ b/merge-ort.c
@@ -18,6 +18,7 @@
 #include "merge-ort.h"
 
 #include "alloc.h"
+#include "advice.h"
 #include "attr.h"
 #include "cache-tree.h"
 #include "commit.h"
@@ -38,6 +39,7 @@
 #include "path.h"
 #include "promisor-remote.h"
 #include "read-cache-ll.h"
+#include "refs.h"
 #include "revision.h"
 #include "sparse-index.h"
 #include "strmap.h"
@@ -541,6 +543,7 @@ enum conflict_and_info_types {
 	CONFLICT_SUBMODULE_HISTORY_NOT_AVAILABLE,
 	CONFLICT_SUBMODULE_MAY_HAVE_REWINDS,
 	CONFLICT_SUBMODULE_NULL_MERGE_BASE,
+	CONFLICT_SUBMODULE_CORRUPT,
 
 	/* Keep this entry _last_ in the list */
 	NB_CONFLICT_TYPES,
@@ -593,7 +596,9 @@ static const char *type_short_descriptions[] = {
 	[CONFLICT_SUBMODULE_MAY_HAVE_REWINDS] =
 		"CONFLICT (submodule may have rewinds)",
 	[CONFLICT_SUBMODULE_NULL_MERGE_BASE] =
-		"CONFLICT (submodule lacks merge base)"
+		"CONFLICT (submodule lacks merge base)",
+	[CONFLICT_SUBMODULE_CORRUPT] =
+		"CONFLICT (submodule corrupt)"
 };
 
 struct logical_conflict_info {
@@ -1656,12 +1661,14 @@ static int collect_merge_info(struct merge_options *opt,
 	info.data = opt;
 	info.show_all_errors = 1;
 
-	parse_tree(merge_base);
-	parse_tree(side1);
-	parse_tree(side2);
-	init_tree_desc(t + 0, merge_base->buffer, merge_base->size);
-	init_tree_desc(t + 1, side1->buffer, side1->size);
-	init_tree_desc(t + 2, side2->buffer, side2->size);
+	if (parse_tree(merge_base) < 0 ||
+	    parse_tree(side1) < 0 ||
+	    parse_tree(side2) < 0)
+		return -1;
+	init_tree_desc(t + 0, &merge_base->object.oid,
+		       merge_base->buffer, merge_base->size);
+	init_tree_desc(t + 1, &side1->object.oid, side1->buffer, side1->size);
+	init_tree_desc(t + 2, &side2->object.oid, side2->buffer, side2->size);
 
 	trace2_region_enter("merge", "traverse_trees", opt->repo);
 	ret = traverse_trees(NULL, 3, t, &info);
@@ -1707,7 +1714,14 @@ static int find_first_merges(struct repository *repo,
 		die("revision walk setup failed");
 	while ((commit = get_revision(&revs)) != NULL) {
 		struct object *o = &(commit->object);
-		if (repo_in_merge_bases(repo, b, commit))
+		int ret = repo_in_merge_bases(repo, b, commit);
+
+		if (ret < 0) {
+			object_array_clear(&merges);
+			release_revisions(&revs);
+			return ret;
+		}
+		if (ret > 0)
 			add_object_array(o, NULL, &merges);
 	}
 	reset_revision_walk();
@@ -1722,9 +1736,17 @@ static int find_first_merges(struct repository *repo,
 		contains_another = 0;
 		for (j = 0; j < merges.nr; j++) {
 			struct commit *m2 = (struct commit *) merges.objects[j].item;
-			if (i != j && repo_in_merge_bases(repo, m2, m1)) {
-				contains_another = 1;
-				break;
+			if (i != j) {
+				int ret = repo_in_merge_bases(repo, m2, m1);
+				if (ret < 0) {
+					object_array_clear(&merges);
+					release_revisions(&revs);
+					return ret;
+				}
+				if (ret > 0) {
+					contains_another = 1;
+					break;
+				}
 			}
 		}
 
@@ -1746,7 +1768,7 @@ static int merge_submodule(struct merge_options *opt,
 {
 	struct repository subrepo;
 	struct strbuf sb = STRBUF_INIT;
-	int ret = 0;
+	int ret = 0, ret2;
 	struct commit *commit_o, *commit_a, *commit_b;
 	int parent_count;
 	struct object_array merges;
@@ -1793,8 +1815,28 @@ static int merge_submodule(struct merge_options *opt,
 	}
 
 	/* check whether both changes are forward */
-	if (!repo_in_merge_bases(&subrepo, commit_o, commit_a) ||
-	    !repo_in_merge_bases(&subrepo, commit_o, commit_b)) {
+	ret2 = repo_in_merge_bases(&subrepo, commit_o, commit_a);
+	if (ret2 < 0) {
+		path_msg(opt, CONFLICT_SUBMODULE_CORRUPT, 0,
+			 path, NULL, NULL, NULL,
+			 _("Failed to merge submodule %s "
+			   "(repository corrupt)"),
+			 path);
+		ret = -1;
+		goto cleanup;
+	}
+	if (ret2 > 0)
+		ret2 = repo_in_merge_bases(&subrepo, commit_o, commit_b);
+	if (ret2 < 0) {
+		path_msg(opt, CONFLICT_SUBMODULE_CORRUPT, 0,
+			 path, NULL, NULL, NULL,
+			 _("Failed to merge submodule %s "
+			   "(repository corrupt)"),
+			 path);
+		ret = -1;
+		goto cleanup;
+	}
+	if (!ret2) {
 		path_msg(opt, CONFLICT_SUBMODULE_MAY_HAVE_REWINDS, 0,
 			 path, NULL, NULL, NULL,
 			 _("Failed to merge submodule %s "
@@ -1804,7 +1846,17 @@ static int merge_submodule(struct merge_options *opt,
 	}
 
 	/* Case #1: a is contained in b or vice versa */
-	if (repo_in_merge_bases(&subrepo, commit_a, commit_b)) {
+	ret2 = repo_in_merge_bases(&subrepo, commit_a, commit_b);
+	if (ret2 < 0) {
+		path_msg(opt, CONFLICT_SUBMODULE_CORRUPT, 0,
+			 path, NULL, NULL, NULL,
+			 _("Failed to merge submodule %s "
+			   "(repository corrupt)"),
+			 path);
+		ret = -1;
+		goto cleanup;
+	}
+	if (ret2 > 0) {
 		oidcpy(result, b);
 		path_msg(opt, INFO_SUBMODULE_FAST_FORWARDING, 1,
 			 path, NULL, NULL, NULL,
@@ -1813,7 +1865,17 @@ static int merge_submodule(struct merge_options *opt,
 		ret = 1;
 		goto cleanup;
 	}
-	if (repo_in_merge_bases(&subrepo, commit_b, commit_a)) {
+	ret2 = repo_in_merge_bases(&subrepo, commit_b, commit_a);
+	if (ret2 < 0) {
+		path_msg(opt, CONFLICT_SUBMODULE_CORRUPT, 0,
+			 path, NULL, NULL, NULL,
+			 _("Failed to merge submodule %s "
+			   "(repository corrupt)"),
+			 path);
+		ret = -1;
+		goto cleanup;
+	}
+	if (ret2 > 0) {
 		oidcpy(result, a);
 		path_msg(opt, INFO_SUBMODULE_FAST_FORWARDING, 1,
 			 path, NULL, NULL, NULL,
@@ -1838,6 +1900,14 @@ static int merge_submodule(struct merge_options *opt,
 	parent_count = find_first_merges(&subrepo, path, commit_a, commit_b,
 					 &merges);
 	switch (parent_count) {
+	case -1:
+		path_msg(opt, CONFLICT_SUBMODULE_CORRUPT, 0,
+			 path, NULL, NULL, NULL,
+			 _("Failed to merge submodule %s "
+			   "(repository corrupt)"),
+			 path);
+		ret = -1;
+		break;
 	case 0:
 		path_msg(opt, CONFLICT_SUBMODULE_FAILED_TO_MERGE, 0,
 			 path, NULL, NULL, NULL,
@@ -1955,7 +2025,7 @@ static int merge_3way(struct merge_options *opt,
 		      mmbuffer_t *result_buf)
 {
 	mmfile_t orig, src1, src2;
-	struct ll_merge_options ll_opts = {0};
+	struct ll_merge_options ll_opts = LL_MERGE_OPTIONS_INIT;
 	char *base, *name1, *name2;
 	enum ll_merge_result merge_status;
 
@@ -1965,6 +2035,7 @@ static int merge_3way(struct merge_options *opt,
 	ll_opts.renormalize = opt->renormalize;
 	ll_opts.extra_marker_size = extra_marker_size;
 	ll_opts.xdl_opts = opt->xdl_opts;
+	ll_opts.conflict_style = opt->conflict_style;
 
 	if (opt->priv->call_depth) {
 		ll_opts.virtual_ancestor = 1;
@@ -4375,10 +4446,12 @@ static int checkout(struct merge_options *opt,
 	unpack_opts.verbose_update = (opt->verbosity > 2);
 	unpack_opts.fn = twoway_merge;
 	unpack_opts.preserve_ignored = 0; /* FIXME: !opts->overwrite_ignore */
-	parse_tree(prev);
-	init_tree_desc(&trees[0], prev->buffer, prev->size);
-	parse_tree(next);
-	init_tree_desc(&trees[1], next->buffer, next->size);
+	if (parse_tree(prev) < 0)
+		return -1;
+	init_tree_desc(&trees[0], &prev->object.oid, prev->buffer, prev->size);
+	if (parse_tree(next) < 0)
+		return -1;
+	init_tree_desc(&trees[1], &next->object.oid, next->buffer, next->size);
 
 	ret = unpack_trees(2, trees, &unpack_opts);
 	clear_unpack_trees_porcelain(&unpack_opts);
@@ -4555,7 +4628,7 @@ static void print_submodule_conflict_suggestion(struct string_list *csub) {
 		      " - commit the resulting index in the superproject\n"),
 		    tmp.buf, subs.buf);
 
-	printf("%s", msg.buf);
+	advise_if_enabled(ADVICE_SUBMODULE_MERGE_CONFLICT, "%s", msg.buf);
 
 	strbuf_release(&subs);
 	strbuf_release(&tmp);
@@ -4659,9 +4732,6 @@ void merge_switch_to_result(struct merge_options *opt,
 {
 	assert(opt->priv == NULL);
 	if (result->clean >= 0 && update_worktree_and_index) {
-		const char *filename;
-		FILE *fp;
-
 		trace2_region_enter("merge", "checkout", opt->repo);
 		if (checkout(opt, head, result->tree)) {
 			/* failure to function */
@@ -4687,10 +4757,17 @@ void merge_switch_to_result(struct merge_options *opt,
 		trace2_region_leave("merge", "record_conflicted", opt->repo);
 
 		trace2_region_enter("merge", "write_auto_merge", opt->repo);
-		filename = git_path_auto_merge(opt->repo);
-		fp = xfopen(filename, "w");
-		fprintf(fp, "%s\n", oid_to_hex(&result->tree->object.oid));
-		fclose(fp);
+		if (refs_update_ref(get_main_ref_store(opt->repo), "", "AUTO_MERGE",
+				    &result->tree->object.oid, NULL, REF_NO_DEREF,
+				    UPDATE_REFS_MSG_ON_ERR)) {
+			/* failure to function */
+			opt->priv = NULL;
+			result->clean = -1;
+			merge_finalize(opt, result);
+			trace2_region_leave("merge", "write_auto_merge",
+					    opt->repo);
+			return;
+		}
 		trace2_region_leave("merge", "write_auto_merge", opt->repo);
 	}
 	if (display_update_msgs)
@@ -4977,6 +5054,9 @@ static void merge_ort_nonrecursive_internal(struct merge_options *opt,
 
 	if (result->clean >= 0) {
 		result->tree = parse_tree_indirect(&working_tree_oid);
+		if (!result->tree)
+			die(_("unable to read tree (%s)"),
+			    oid_to_hex(&working_tree_oid));
 		/* existence of conflicted entries implies unclean */
 		result->clean &= strmap_empty(&opt->priv->conflicted);
 	}
@@ -5002,7 +5082,11 @@ static void merge_ort_internal(struct merge_options *opt,
 	struct strbuf merge_base_abbrev = STRBUF_INIT;
 
 	if (!merge_bases) {
-		merge_bases = repo_get_merge_bases(the_repository, h1, h2);
+		if (repo_get_merge_bases(the_repository, h1, h2,
+					 &merge_bases) < 0) {
+			result->clean = -1;
+			return;
+		}
 		/* See merge-ort.h:merge_incore_recursive() declaration NOTE */
 		merge_bases = reverse_commit_list(merge_bases);
 	}
diff --git a/merge-recursive.c b/merge-recursive.c
index a0c3e7a..8ff29ed 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -405,8 +405,9 @@ static inline int merge_detect_rename(struct merge_options *opt)
 
 static void init_tree_desc_from_tree(struct tree_desc *desc, struct tree *tree)
 {
-	parse_tree(tree);
-	init_tree_desc(desc, tree->buffer, tree->size);
+	if (parse_tree(tree) < 0)
+		exit(128);
+	init_tree_desc(desc, &tree->object.oid, tree->buffer, tree->size);
 }
 
 static int unpack_trees_start(struct merge_options *opt,
@@ -1047,13 +1048,14 @@ static int merge_3way(struct merge_options *opt,
 		      const int extra_marker_size)
 {
 	mmfile_t orig, src1, src2;
-	struct ll_merge_options ll_opts = {0};
+	struct ll_merge_options ll_opts = LL_MERGE_OPTIONS_INIT;
 	char *base, *name1, *name2;
 	enum ll_merge_result merge_status;
 
 	ll_opts.renormalize = opt->renormalize;
 	ll_opts.extra_marker_size = extra_marker_size;
 	ll_opts.xdl_opts = opt->xdl_opts;
+	ll_opts.conflict_style = opt->conflict_style;
 
 	if (opt->priv->call_depth) {
 		ll_opts.virtual_ancestor = 1;
@@ -1139,7 +1141,13 @@ static int find_first_merges(struct repository *repo,
 		die("revision walk setup failed");
 	while ((commit = get_revision(&revs)) != NULL) {
 		struct object *o = &(commit->object);
-		if (repo_in_merge_bases(repo, b, commit))
+		int ret = repo_in_merge_bases(repo, b, commit);
+		if (ret < 0) {
+			object_array_clear(&merges);
+			release_revisions(&revs);
+			return ret;
+		}
+		if (ret)
 			add_object_array(o, NULL, &merges);
 	}
 	reset_revision_walk();
@@ -1154,9 +1162,17 @@ static int find_first_merges(struct repository *repo,
 		contains_another = 0;
 		for (j = 0; j < merges.nr; j++) {
 			struct commit *m2 = (struct commit *) merges.objects[j].item;
-			if (i != j && repo_in_merge_bases(repo, m2, m1)) {
-				contains_another = 1;
-				break;
+			if (i != j) {
+				int ret = repo_in_merge_bases(repo, m2, m1);
+				if (ret < 0) {
+					object_array_clear(&merges);
+					release_revisions(&revs);
+					return ret;
+				}
+				if (ret > 0) {
+					contains_another = 1;
+					break;
+				}
 			}
 		}
 
@@ -1192,7 +1208,7 @@ static int merge_submodule(struct merge_options *opt,
 			   const struct object_id *b)
 {
 	struct repository subrepo;
-	int ret = 0;
+	int ret = 0, ret2;
 	struct commit *commit_base, *commit_a, *commit_b;
 	int parent_count;
 	struct object_array merges;
@@ -1229,14 +1245,32 @@ static int merge_submodule(struct merge_options *opt,
 	}
 
 	/* check whether both changes are forward */
-	if (!repo_in_merge_bases(&subrepo, commit_base, commit_a) ||
-	    !repo_in_merge_bases(&subrepo, commit_base, commit_b)) {
+	ret2 = repo_in_merge_bases(&subrepo, commit_base, commit_a);
+	if (ret2 < 0) {
+		output(opt, 1, _("Failed to merge submodule %s (repository corrupt)"), path);
+		ret = -1;
+		goto cleanup;
+	}
+	if (ret2 > 0)
+		ret2 = repo_in_merge_bases(&subrepo, commit_base, commit_b);
+	if (ret2 < 0) {
+		output(opt, 1, _("Failed to merge submodule %s (repository corrupt)"), path);
+		ret = -1;
+		goto cleanup;
+	}
+	if (!ret2) {
 		output(opt, 1, _("Failed to merge submodule %s (commits don't follow merge-base)"), path);
 		goto cleanup;
 	}
 
 	/* Case #1: a is contained in b or vice versa */
-	if (repo_in_merge_bases(&subrepo, commit_a, commit_b)) {
+	ret2 = repo_in_merge_bases(&subrepo, commit_a, commit_b);
+	if (ret2 < 0) {
+		output(opt, 1, _("Failed to merge submodule %s (repository corrupt)"), path);
+		ret = -1;
+		goto cleanup;
+	}
+	if (ret2) {
 		oidcpy(result, b);
 		if (show(opt, 3)) {
 			output(opt, 3, _("Fast-forwarding submodule %s to the following commit:"), path);
@@ -1249,7 +1283,13 @@ static int merge_submodule(struct merge_options *opt,
 		ret = 1;
 		goto cleanup;
 	}
-	if (repo_in_merge_bases(&subrepo, commit_b, commit_a)) {
+	ret2 = repo_in_merge_bases(&subrepo, commit_b, commit_a);
+	if (ret2 < 0) {
+		output(opt, 1, _("Failed to merge submodule %s (repository corrupt)"), path);
+		ret = -1;
+		goto cleanup;
+	}
+	if (ret2) {
 		oidcpy(result, a);
 		if (show(opt, 3)) {
 			output(opt, 3, _("Fast-forwarding submodule %s to the following commit:"), path);
@@ -1278,6 +1318,10 @@ static int merge_submodule(struct merge_options *opt,
 	parent_count = find_first_merges(&subrepo, &merges, path,
 					 commit_a, commit_b);
 	switch (parent_count) {
+	case -1:
+		output(opt, 1,_("Failed to merge submodule %s (repository corrupt)"), path);
+		ret = -1;
+		break;
 	case 0:
 		output(opt, 1, _("Failed to merge submodule %s (merge following commits not found)"), path);
 		break;
@@ -1392,11 +1436,14 @@ static int merge_mode_and_contents(struct merge_options *opt,
 			/* FIXME: bug, what if modes didn't match? */
 			result->clean = (merge_status == 0);
 		} else if (S_ISGITLINK(a->mode)) {
-			result->clean = merge_submodule(opt, &result->blob.oid,
-							o->path,
-							&o->oid,
-							&a->oid,
-							&b->oid);
+			int clean = merge_submodule(opt, &result->blob.oid,
+						    o->path,
+						    &o->oid,
+						    &a->oid,
+						    &b->oid);
+			if (clean < 0)
+				return -1;
+			result->clean = clean;
 		} else if (S_ISLNK(a->mode)) {
 			switch (opt->recursive_variant) {
 			case MERGE_VARIANT_NORMAL:
@@ -3597,7 +3644,9 @@ static int merge_recursive_internal(struct merge_options *opt,
 	}
 
 	if (!merge_bases) {
-		merge_bases = repo_get_merge_bases(the_repository, h1, h2);
+		if (repo_get_merge_bases(the_repository, h1, h2,
+					 &merge_bases) < 0)
+			return -1;
 		merge_bases = reverse_commit_list(merge_bases);
 	}
 
@@ -3899,6 +3948,8 @@ void init_merge_options(struct merge_options *opt,
 
 	opt->renormalize = 0;
 
+	opt->conflict_style = -1;
+
 	merge_recursive_config(opt);
 	merge_verbosity = getenv("GIT_MERGE_VERBOSITY");
 	if (merge_verbosity)
diff --git a/merge-recursive.h b/merge-recursive.h
index 3d3b3e3..e67d38c 100644
--- a/merge-recursive.h
+++ b/merge-recursive.h
@@ -31,6 +31,7 @@ struct merge_options {
 
 	/* xdiff-related options (patience, ignore whitespace, ours/theirs) */
 	long xdl_opts;
+	int conflict_style;
 	enum {
 		MERGE_VARIANT_NORMAL = 0,
 		MERGE_VARIANT_OURS,
diff --git a/merge.c b/merge.c
index ca89b31..752a937 100644
--- a/merge.c
+++ b/merge.c
@@ -77,8 +77,12 @@ int checkout_fast_forward(struct repository *r,
 		return -1;
 	}
 	for (i = 0; i < nr_trees; i++) {
-		parse_tree(trees[i]);
-		init_tree_desc(t+i, trees[i]->buffer, trees[i]->size);
+		if (parse_tree(trees[i]) < 0) {
+			rollback_lock_file(&lock_file);
+			return -1;
+		}
+		init_tree_desc(t+i, &trees[i]->object.oid,
+			       trees[i]->buffer, trees[i]->size);
 	}
 
 	memset(&opts, 0, sizeof(opts));
diff --git a/mergetools/vimdiff b/mergetools/vimdiff
index 06937ac..734d15a 100644
--- a/mergetools/vimdiff
+++ b/mergetools/vimdiff
@@ -72,7 +72,6 @@
 	nested=0
 	nested_min=100
 
-
 	# Step 1:
 	#
 	# Increase/decrease "start"/"end" indices respectively to get rid of
@@ -87,7 +86,7 @@
 	IFS=#
 	for c in $(echo "$LAYOUT" | sed 's:.:&#:g')
 	do
-		if test "$c" = " "
+		if test -z "$c" || test "$c" = " "
 		then
 			continue
 		fi
@@ -371,9 +370,17 @@
 
 
 merge_cmd () {
-	layout=$(git config mergetool.vimdiff.layout)
+	TOOL=$1
 
-	case "$1" in
+	layout=$(git config "mergetool.$TOOL.layout")
+
+	# backward compatibility:
+	if test -z "$layout"
+	then
+		layout=$(git config mergetool.vimdiff.layout)
+	fi
+
+	case "$TOOL" in
 	*vimdiff)
 		if test -z "$layout"
 		then
diff --git a/midx-write.c b/midx-write.c
new file mode 100644
index 0000000..65e69d2
--- /dev/null
+++ b/midx-write.c
@@ -0,0 +1,1525 @@
+#include "git-compat-util.h"
+#include "abspath.h"
+#include "config.h"
+#include "hex.h"
+#include "lockfile.h"
+#include "packfile.h"
+#include "object-file.h"
+#include "hash-lookup.h"
+#include "midx.h"
+#include "progress.h"
+#include "trace2.h"
+#include "run-command.h"
+#include "chunk-format.h"
+#include "pack-bitmap.h"
+#include "refs.h"
+#include "revision.h"
+#include "list-objects.h"
+
+#define PACK_EXPIRED UINT_MAX
+#define BITMAP_POS_UNKNOWN (~((uint32_t)0))
+#define MIDX_CHUNK_FANOUT_SIZE (sizeof(uint32_t) * 256)
+#define MIDX_CHUNK_LARGE_OFFSET_WIDTH (sizeof(uint64_t))
+
+extern int midx_checksum_valid(struct multi_pack_index *m);
+extern void clear_midx_files_ext(const char *object_dir, const char *ext,
+				 unsigned char *keep_hash);
+extern int cmp_idx_or_pack_name(const char *idx_or_pack_name,
+				const char *idx_name);
+
+static size_t write_midx_header(struct hashfile *f,
+				unsigned char num_chunks,
+				uint32_t num_packs)
+{
+	hashwrite_be32(f, MIDX_SIGNATURE);
+	hashwrite_u8(f, MIDX_VERSION);
+	hashwrite_u8(f, oid_version(the_hash_algo));
+	hashwrite_u8(f, num_chunks);
+	hashwrite_u8(f, 0); /* unused */
+	hashwrite_be32(f, num_packs);
+
+	return MIDX_HEADER_SIZE;
+}
+
+struct pack_info {
+	uint32_t orig_pack_int_id;
+	char *pack_name;
+	struct packed_git *p;
+
+	uint32_t bitmap_pos;
+	uint32_t bitmap_nr;
+
+	unsigned expired : 1;
+};
+
+static void fill_pack_info(struct pack_info *info,
+			   struct packed_git *p, const char *pack_name,
+			   uint32_t orig_pack_int_id)
+{
+	memset(info, 0, sizeof(struct pack_info));
+
+	info->orig_pack_int_id = orig_pack_int_id;
+	info->pack_name = xstrdup(pack_name);
+	info->p = p;
+	info->bitmap_pos = BITMAP_POS_UNKNOWN;
+}
+
+static int pack_info_compare(const void *_a, const void *_b)
+{
+	struct pack_info *a = (struct pack_info *)_a;
+	struct pack_info *b = (struct pack_info *)_b;
+	return strcmp(a->pack_name, b->pack_name);
+}
+
+static int idx_or_pack_name_cmp(const void *_va, const void *_vb)
+{
+	const char *pack_name = _va;
+	const struct pack_info *compar = _vb;
+
+	return cmp_idx_or_pack_name(pack_name, compar->pack_name);
+}
+
+struct write_midx_context {
+	struct pack_info *info;
+	size_t nr;
+	size_t alloc;
+	struct multi_pack_index *m;
+	struct progress *progress;
+	unsigned pack_paths_checked;
+
+	struct pack_midx_entry *entries;
+	size_t entries_nr;
+
+	uint32_t *pack_perm;
+	uint32_t *pack_order;
+	unsigned large_offsets_needed:1;
+	uint32_t num_large_offsets;
+
+	int preferred_pack_idx;
+
+	struct string_list *to_include;
+};
+
+static void add_pack_to_midx(const char *full_path, size_t full_path_len,
+			     const char *file_name, void *data)
+{
+	struct write_midx_context *ctx = data;
+	struct packed_git *p;
+
+	if (ends_with(file_name, ".idx")) {
+		display_progress(ctx->progress, ++ctx->pack_paths_checked);
+		/*
+		 * Note that at most one of ctx->m and ctx->to_include are set,
+		 * so we are testing midx_contains_pack() and
+		 * string_list_has_string() independently (guarded by the
+		 * appropriate NULL checks).
+		 *
+		 * We could support passing to_include while reusing an existing
+		 * MIDX, but don't currently since the reuse process drags
+		 * forward all packs from an existing MIDX (without checking
+		 * whether or not they appear in the to_include list).
+		 *
+		 * If we added support for that, these next two conditional
+		 * should be performed independently (likely checking
+		 * to_include before the existing MIDX).
+		 */
+		if (ctx->m && midx_contains_pack(ctx->m, file_name))
+			return;
+		else if (ctx->to_include &&
+			 !string_list_has_string(ctx->to_include, file_name))
+			return;
+
+		ALLOC_GROW(ctx->info, ctx->nr + 1, ctx->alloc);
+
+		p = add_packed_git(full_path, full_path_len, 0);
+		if (!p) {
+			warning(_("failed to add packfile '%s'"),
+				full_path);
+			return;
+		}
+
+		if (open_pack_index(p)) {
+			warning(_("failed to open pack-index '%s'"),
+				full_path);
+			close_pack(p);
+			free(p);
+			return;
+		}
+
+		fill_pack_info(&ctx->info[ctx->nr], p, file_name, ctx->nr);
+		ctx->nr++;
+	}
+}
+
+struct pack_midx_entry {
+	struct object_id oid;
+	uint32_t pack_int_id;
+	time_t pack_mtime;
+	uint64_t offset;
+	unsigned preferred : 1;
+};
+
+static int midx_oid_compare(const void *_a, const void *_b)
+{
+	const struct pack_midx_entry *a = (const struct pack_midx_entry *)_a;
+	const struct pack_midx_entry *b = (const struct pack_midx_entry *)_b;
+	int cmp = oidcmp(&a->oid, &b->oid);
+
+	if (cmp)
+		return cmp;
+
+	/* Sort objects in a preferred pack first when multiple copies exist. */
+	if (a->preferred > b->preferred)
+		return -1;
+	if (a->preferred < b->preferred)
+		return 1;
+
+	if (a->pack_mtime > b->pack_mtime)
+		return -1;
+	else if (a->pack_mtime < b->pack_mtime)
+		return 1;
+
+	return a->pack_int_id - b->pack_int_id;
+}
+
+static int nth_midxed_pack_midx_entry(struct multi_pack_index *m,
+				      struct pack_midx_entry *e,
+				      uint32_t pos)
+{
+	if (pos >= m->num_objects)
+		return 1;
+
+	nth_midxed_object_oid(&e->oid, m, pos);
+	e->pack_int_id = nth_midxed_pack_int_id(m, pos);
+	e->offset = nth_midxed_offset(m, pos);
+
+	/* consider objects in midx to be from "old" packs */
+	e->pack_mtime = 0;
+	return 0;
+}
+
+static void fill_pack_entry(uint32_t pack_int_id,
+			    struct packed_git *p,
+			    uint32_t cur_object,
+			    struct pack_midx_entry *entry,
+			    int preferred)
+{
+	if (nth_packed_object_id(&entry->oid, p, cur_object) < 0)
+		die(_("failed to locate object %d in packfile"), cur_object);
+
+	entry->pack_int_id = pack_int_id;
+	entry->pack_mtime = p->mtime;
+
+	entry->offset = nth_packed_object_offset(p, cur_object);
+	entry->preferred = !!preferred;
+}
+
+struct midx_fanout {
+	struct pack_midx_entry *entries;
+	size_t nr, alloc;
+};
+
+static void midx_fanout_grow(struct midx_fanout *fanout, size_t nr)
+{
+	if (nr < fanout->nr)
+		BUG("negative growth in midx_fanout_grow() (%"PRIuMAX" < %"PRIuMAX")",
+		    (uintmax_t)nr, (uintmax_t)fanout->nr);
+	ALLOC_GROW(fanout->entries, nr, fanout->alloc);
+}
+
+static void midx_fanout_sort(struct midx_fanout *fanout)
+{
+	QSORT(fanout->entries, fanout->nr, midx_oid_compare);
+}
+
+static void midx_fanout_add_midx_fanout(struct midx_fanout *fanout,
+					struct multi_pack_index *m,
+					uint32_t cur_fanout,
+					int preferred_pack)
+{
+	uint32_t start = 0, end;
+	uint32_t cur_object;
+
+	if (cur_fanout)
+		start = ntohl(m->chunk_oid_fanout[cur_fanout - 1]);
+	end = ntohl(m->chunk_oid_fanout[cur_fanout]);
+
+	for (cur_object = start; cur_object < end; cur_object++) {
+		if ((preferred_pack > -1) &&
+		    (preferred_pack == nth_midxed_pack_int_id(m, cur_object))) {
+			/*
+			 * Objects from preferred packs are added
+			 * separately.
+			 */
+			continue;
+		}
+
+		midx_fanout_grow(fanout, fanout->nr + 1);
+		nth_midxed_pack_midx_entry(m,
+					   &fanout->entries[fanout->nr],
+					   cur_object);
+		fanout->entries[fanout->nr].preferred = 0;
+		fanout->nr++;
+	}
+}
+
+static void midx_fanout_add_pack_fanout(struct midx_fanout *fanout,
+					struct pack_info *info,
+					uint32_t cur_pack,
+					int preferred,
+					uint32_t cur_fanout)
+{
+	struct packed_git *pack = info[cur_pack].p;
+	uint32_t start = 0, end;
+	uint32_t cur_object;
+
+	if (cur_fanout)
+		start = get_pack_fanout(pack, cur_fanout - 1);
+	end = get_pack_fanout(pack, cur_fanout);
+
+	for (cur_object = start; cur_object < end; cur_object++) {
+		midx_fanout_grow(fanout, fanout->nr + 1);
+		fill_pack_entry(cur_pack,
+				info[cur_pack].p,
+				cur_object,
+				&fanout->entries[fanout->nr],
+				preferred);
+		fanout->nr++;
+	}
+}
+
+/*
+ * It is possible to artificially get into a state where there are many
+ * duplicate copies of objects. That can create high memory pressure if
+ * we are to create a list of all objects before de-duplication. To reduce
+ * this memory pressure without a significant performance drop, automatically
+ * group objects by the first byte of their object id. Use the IDX fanout
+ * tables to group the data, copy to a local array, then sort.
+ *
+ * Copy only the de-duplicated entries (selected by most-recent modified time
+ * of a packfile containing the object).
+ */
+static struct pack_midx_entry *get_sorted_entries(struct multi_pack_index *m,
+						  struct pack_info *info,
+						  uint32_t nr_packs,
+						  size_t *nr_objects,
+						  int preferred_pack)
+{
+	uint32_t cur_fanout, cur_pack, cur_object;
+	size_t alloc_objects, total_objects = 0;
+	struct midx_fanout fanout = { 0 };
+	struct pack_midx_entry *deduplicated_entries = NULL;
+	uint32_t start_pack = m ? m->num_packs : 0;
+
+	for (cur_pack = start_pack; cur_pack < nr_packs; cur_pack++)
+		total_objects = st_add(total_objects,
+				       info[cur_pack].p->num_objects);
+
+	/*
+	 * As we de-duplicate by fanout value, we expect the fanout
+	 * slices to be evenly distributed, with some noise. Hence,
+	 * allocate slightly more than one 256th.
+	 */
+	alloc_objects = fanout.alloc = total_objects > 3200 ? total_objects / 200 : 16;
+
+	ALLOC_ARRAY(fanout.entries, fanout.alloc);
+	ALLOC_ARRAY(deduplicated_entries, alloc_objects);
+	*nr_objects = 0;
+
+	for (cur_fanout = 0; cur_fanout < 256; cur_fanout++) {
+		fanout.nr = 0;
+
+		if (m)
+			midx_fanout_add_midx_fanout(&fanout, m, cur_fanout,
+						    preferred_pack);
+
+		for (cur_pack = start_pack; cur_pack < nr_packs; cur_pack++) {
+			int preferred = cur_pack == preferred_pack;
+			midx_fanout_add_pack_fanout(&fanout,
+						    info, cur_pack,
+						    preferred, cur_fanout);
+		}
+
+		if (-1 < preferred_pack && preferred_pack < start_pack)
+			midx_fanout_add_pack_fanout(&fanout, info,
+						    preferred_pack, 1,
+						    cur_fanout);
+
+		midx_fanout_sort(&fanout);
+
+		/*
+		 * The batch is now sorted by OID and then mtime (descending).
+		 * Take only the first duplicate.
+		 */
+		for (cur_object = 0; cur_object < fanout.nr; cur_object++) {
+			if (cur_object && oideq(&fanout.entries[cur_object - 1].oid,
+						&fanout.entries[cur_object].oid))
+				continue;
+
+			ALLOC_GROW(deduplicated_entries, st_add(*nr_objects, 1),
+				   alloc_objects);
+			memcpy(&deduplicated_entries[*nr_objects],
+			       &fanout.entries[cur_object],
+			       sizeof(struct pack_midx_entry));
+			(*nr_objects)++;
+		}
+	}
+
+	free(fanout.entries);
+	return deduplicated_entries;
+}
+
+static int write_midx_pack_names(struct hashfile *f, void *data)
+{
+	struct write_midx_context *ctx = data;
+	uint32_t i;
+	unsigned char padding[MIDX_CHUNK_ALIGNMENT];
+	size_t written = 0;
+
+	for (i = 0; i < ctx->nr; i++) {
+		size_t writelen;
+
+		if (ctx->info[i].expired)
+			continue;
+
+		if (i && strcmp(ctx->info[i].pack_name, ctx->info[i - 1].pack_name) <= 0)
+			BUG("incorrect pack-file order: %s before %s",
+			    ctx->info[i - 1].pack_name,
+			    ctx->info[i].pack_name);
+
+		writelen = strlen(ctx->info[i].pack_name) + 1;
+		hashwrite(f, ctx->info[i].pack_name, writelen);
+		written += writelen;
+	}
+
+	/* add padding to be aligned */
+	i = MIDX_CHUNK_ALIGNMENT - (written % MIDX_CHUNK_ALIGNMENT);
+	if (i < MIDX_CHUNK_ALIGNMENT) {
+		memset(padding, 0, sizeof(padding));
+		hashwrite(f, padding, i);
+	}
+
+	return 0;
+}
+
+static int write_midx_bitmapped_packs(struct hashfile *f, void *data)
+{
+	struct write_midx_context *ctx = data;
+	size_t i;
+
+	for (i = 0; i < ctx->nr; i++) {
+		struct pack_info *pack = &ctx->info[i];
+		if (pack->expired)
+			continue;
+
+		if (pack->bitmap_pos == BITMAP_POS_UNKNOWN && pack->bitmap_nr)
+			BUG("pack '%s' has no bitmap position, but has %d bitmapped object(s)",
+			    pack->pack_name, pack->bitmap_nr);
+
+		hashwrite_be32(f, pack->bitmap_pos);
+		hashwrite_be32(f, pack->bitmap_nr);
+	}
+	return 0;
+}
+
+static int write_midx_oid_fanout(struct hashfile *f,
+				 void *data)
+{
+	struct write_midx_context *ctx = data;
+	struct pack_midx_entry *list = ctx->entries;
+	struct pack_midx_entry *last = ctx->entries + ctx->entries_nr;
+	uint32_t count = 0;
+	uint32_t i;
+
+	/*
+	* Write the first-level table (the list is sorted,
+	* but we use a 256-entry lookup to be able to avoid
+	* having to do eight extra binary search iterations).
+	*/
+	for (i = 0; i < 256; i++) {
+		struct pack_midx_entry *next = list;
+
+		while (next < last && next->oid.hash[0] == i) {
+			count++;
+			next++;
+		}
+
+		hashwrite_be32(f, count);
+		list = next;
+	}
+
+	return 0;
+}
+
+static int write_midx_oid_lookup(struct hashfile *f,
+				 void *data)
+{
+	struct write_midx_context *ctx = data;
+	unsigned char hash_len = the_hash_algo->rawsz;
+	struct pack_midx_entry *list = ctx->entries;
+	uint32_t i;
+
+	for (i = 0; i < ctx->entries_nr; i++) {
+		struct pack_midx_entry *obj = list++;
+
+		if (i < ctx->entries_nr - 1) {
+			struct pack_midx_entry *next = list;
+			if (oidcmp(&obj->oid, &next->oid) >= 0)
+				BUG("OIDs not in order: %s >= %s",
+				    oid_to_hex(&obj->oid),
+				    oid_to_hex(&next->oid));
+		}
+
+		hashwrite(f, obj->oid.hash, (int)hash_len);
+	}
+
+	return 0;
+}
+
+static int write_midx_object_offsets(struct hashfile *f,
+				     void *data)
+{
+	struct write_midx_context *ctx = data;
+	struct pack_midx_entry *list = ctx->entries;
+	uint32_t i, nr_large_offset = 0;
+
+	for (i = 0; i < ctx->entries_nr; i++) {
+		struct pack_midx_entry *obj = list++;
+
+		if (ctx->pack_perm[obj->pack_int_id] == PACK_EXPIRED)
+			BUG("object %s is in an expired pack with int-id %d",
+			    oid_to_hex(&obj->oid),
+			    obj->pack_int_id);
+
+		hashwrite_be32(f, ctx->pack_perm[obj->pack_int_id]);
+
+		if (ctx->large_offsets_needed && obj->offset >> 31)
+			hashwrite_be32(f, MIDX_LARGE_OFFSET_NEEDED | nr_large_offset++);
+		else if (!ctx->large_offsets_needed && obj->offset >> 32)
+			BUG("object %s requires a large offset (%"PRIx64") but the MIDX is not writing large offsets!",
+			    oid_to_hex(&obj->oid),
+			    obj->offset);
+		else
+			hashwrite_be32(f, (uint32_t)obj->offset);
+	}
+
+	return 0;
+}
+
+static int write_midx_large_offsets(struct hashfile *f,
+				    void *data)
+{
+	struct write_midx_context *ctx = data;
+	struct pack_midx_entry *list = ctx->entries;
+	struct pack_midx_entry *end = ctx->entries + ctx->entries_nr;
+	uint32_t nr_large_offset = ctx->num_large_offsets;
+
+	while (nr_large_offset) {
+		struct pack_midx_entry *obj;
+		uint64_t offset;
+
+		if (list >= end)
+			BUG("too many large-offset objects");
+
+		obj = list++;
+		offset = obj->offset;
+
+		if (!(offset >> 31))
+			continue;
+
+		hashwrite_be64(f, offset);
+
+		nr_large_offset--;
+	}
+
+	return 0;
+}
+
+static int write_midx_revindex(struct hashfile *f,
+			       void *data)
+{
+	struct write_midx_context *ctx = data;
+	uint32_t i;
+
+	for (i = 0; i < ctx->entries_nr; i++)
+		hashwrite_be32(f, ctx->pack_order[i]);
+
+	return 0;
+}
+
+struct midx_pack_order_data {
+	uint32_t nr;
+	uint32_t pack;
+	off_t offset;
+};
+
+static int midx_pack_order_cmp(const void *va, const void *vb)
+{
+	const struct midx_pack_order_data *a = va, *b = vb;
+	if (a->pack < b->pack)
+		return -1;
+	else if (a->pack > b->pack)
+		return 1;
+	else if (a->offset < b->offset)
+		return -1;
+	else if (a->offset > b->offset)
+		return 1;
+	else
+		return 0;
+}
+
+static uint32_t *midx_pack_order(struct write_midx_context *ctx)
+{
+	struct midx_pack_order_data *data;
+	uint32_t *pack_order;
+	uint32_t i;
+
+	trace2_region_enter("midx", "midx_pack_order", the_repository);
+
+	ALLOC_ARRAY(data, ctx->entries_nr);
+	for (i = 0; i < ctx->entries_nr; i++) {
+		struct pack_midx_entry *e = &ctx->entries[i];
+		data[i].nr = i;
+		data[i].pack = ctx->pack_perm[e->pack_int_id];
+		if (!e->preferred)
+			data[i].pack |= (1U << 31);
+		data[i].offset = e->offset;
+	}
+
+	QSORT(data, ctx->entries_nr, midx_pack_order_cmp);
+
+	ALLOC_ARRAY(pack_order, ctx->entries_nr);
+	for (i = 0; i < ctx->entries_nr; i++) {
+		struct pack_midx_entry *e = &ctx->entries[data[i].nr];
+		struct pack_info *pack = &ctx->info[ctx->pack_perm[e->pack_int_id]];
+		if (pack->bitmap_pos == BITMAP_POS_UNKNOWN)
+			pack->bitmap_pos = i;
+		pack->bitmap_nr++;
+		pack_order[i] = data[i].nr;
+	}
+	for (i = 0; i < ctx->nr; i++) {
+		struct pack_info *pack = &ctx->info[ctx->pack_perm[i]];
+		if (pack->bitmap_pos == BITMAP_POS_UNKNOWN)
+			pack->bitmap_pos = 0;
+	}
+	free(data);
+
+	trace2_region_leave("midx", "midx_pack_order", the_repository);
+
+	return pack_order;
+}
+
+static void write_midx_reverse_index(char *midx_name, unsigned char *midx_hash,
+				     struct write_midx_context *ctx)
+{
+	struct strbuf buf = STRBUF_INIT;
+	const char *tmp_file;
+
+	trace2_region_enter("midx", "write_midx_reverse_index", the_repository);
+
+	strbuf_addf(&buf, "%s-%s.rev", midx_name, hash_to_hex(midx_hash));
+
+	tmp_file = write_rev_file_order(NULL, ctx->pack_order, ctx->entries_nr,
+					midx_hash, WRITE_REV);
+
+	if (finalize_object_file(tmp_file, buf.buf))
+		die(_("cannot store reverse index file"));
+
+	strbuf_release(&buf);
+
+	trace2_region_leave("midx", "write_midx_reverse_index", the_repository);
+}
+
+static void prepare_midx_packing_data(struct packing_data *pdata,
+				      struct write_midx_context *ctx)
+{
+	uint32_t i;
+
+	trace2_region_enter("midx", "prepare_midx_packing_data", the_repository);
+
+	memset(pdata, 0, sizeof(struct packing_data));
+	prepare_packing_data(the_repository, pdata);
+
+	for (i = 0; i < ctx->entries_nr; i++) {
+		struct pack_midx_entry *from = &ctx->entries[ctx->pack_order[i]];
+		struct object_entry *to = packlist_alloc(pdata, &from->oid);
+
+		oe_set_in_pack(pdata, to,
+			       ctx->info[ctx->pack_perm[from->pack_int_id]].p);
+	}
+
+	trace2_region_leave("midx", "prepare_midx_packing_data", the_repository);
+}
+
+static int add_ref_to_pending(const char *refname,
+			      const struct object_id *oid,
+			      int flag, void *cb_data)
+{
+	struct rev_info *revs = (struct rev_info*)cb_data;
+	struct object_id peeled;
+	struct object *object;
+
+	if ((flag & REF_ISSYMREF) && (flag & REF_ISBROKEN)) {
+		warning("symbolic ref is dangling: %s", refname);
+		return 0;
+	}
+
+	if (!peel_iterated_oid(oid, &peeled))
+		oid = &peeled;
+
+	object = parse_object_or_die(oid, refname);
+	if (object->type != OBJ_COMMIT)
+		return 0;
+
+	add_pending_object(revs, object, "");
+	if (bitmap_is_preferred_refname(revs->repo, refname))
+		object->flags |= NEEDS_BITMAP;
+	return 0;
+}
+
+struct bitmap_commit_cb {
+	struct commit **commits;
+	size_t commits_nr, commits_alloc;
+
+	struct write_midx_context *ctx;
+};
+
+static const struct object_id *bitmap_oid_access(size_t index,
+						 const void *_entries)
+{
+	const struct pack_midx_entry *entries = _entries;
+	return &entries[index].oid;
+}
+
+static void bitmap_show_commit(struct commit *commit, void *_data)
+{
+	struct bitmap_commit_cb *data = _data;
+	int pos = oid_pos(&commit->object.oid, data->ctx->entries,
+			  data->ctx->entries_nr,
+			  bitmap_oid_access);
+	if (pos < 0)
+		return;
+
+	ALLOC_GROW(data->commits, data->commits_nr + 1, data->commits_alloc);
+	data->commits[data->commits_nr++] = commit;
+}
+
+static int read_refs_snapshot(const char *refs_snapshot,
+			      struct rev_info *revs)
+{
+	struct strbuf buf = STRBUF_INIT;
+	struct object_id oid;
+	FILE *f = xfopen(refs_snapshot, "r");
+
+	while (strbuf_getline(&buf, f) != EOF) {
+		struct object *object;
+		int preferred = 0;
+		char *hex = buf.buf;
+		const char *end = NULL;
+
+		if (buf.len && *buf.buf == '+') {
+			preferred = 1;
+			hex = &buf.buf[1];
+		}
+
+		if (parse_oid_hex(hex, &oid, &end) < 0)
+			die(_("could not parse line: %s"), buf.buf);
+		if (*end)
+			die(_("malformed line: %s"), buf.buf);
+
+		object = parse_object_or_die(&oid, NULL);
+		if (preferred)
+			object->flags |= NEEDS_BITMAP;
+
+		add_pending_object(revs, object, "");
+	}
+
+	fclose(f);
+	strbuf_release(&buf);
+	return 0;
+}
+static struct commit **find_commits_for_midx_bitmap(uint32_t *indexed_commits_nr_p,
+						    const char *refs_snapshot,
+						    struct write_midx_context *ctx)
+{
+	struct rev_info revs;
+	struct bitmap_commit_cb cb = {0};
+
+	trace2_region_enter("midx", "find_commits_for_midx_bitmap",
+			    the_repository);
+
+	cb.ctx = ctx;
+
+	repo_init_revisions(the_repository, &revs, NULL);
+	if (refs_snapshot) {
+		read_refs_snapshot(refs_snapshot, &revs);
+	} else {
+		setup_revisions(0, NULL, &revs, NULL);
+		for_each_ref(add_ref_to_pending, &revs);
+	}
+
+	/*
+	 * Skipping promisor objects here is intentional, since it only excludes
+	 * them from the list of reachable commits that we want to select from
+	 * when computing the selection of MIDX'd commits to receive bitmaps.
+	 *
+	 * Reachability bitmaps do require that their objects be closed under
+	 * reachability, but fetching any objects missing from promisors at this
+	 * point is too late. But, if one of those objects can be reached from
+	 * an another object that is included in the bitmap, then we will
+	 * complain later that we don't have reachability closure (and fail
+	 * appropriately).
+	 */
+	fetch_if_missing = 0;
+	revs.exclude_promisor_objects = 1;
+
+	if (prepare_revision_walk(&revs))
+		die(_("revision walk setup failed"));
+
+	traverse_commit_list(&revs, bitmap_show_commit, NULL, &cb);
+	if (indexed_commits_nr_p)
+		*indexed_commits_nr_p = cb.commits_nr;
+
+	release_revisions(&revs);
+
+	trace2_region_leave("midx", "find_commits_for_midx_bitmap",
+			    the_repository);
+
+	return cb.commits;
+}
+
+static int write_midx_bitmap(const char *midx_name,
+			     const unsigned char *midx_hash,
+			     struct packing_data *pdata,
+			     struct commit **commits,
+			     uint32_t commits_nr,
+			     uint32_t *pack_order,
+			     unsigned flags)
+{
+	int ret, i;
+	uint16_t options = 0;
+	struct pack_idx_entry **index;
+	char *bitmap_name = xstrfmt("%s-%s.bitmap", midx_name,
+					hash_to_hex(midx_hash));
+
+	trace2_region_enter("midx", "write_midx_bitmap", the_repository);
+
+	if (flags & MIDX_WRITE_BITMAP_HASH_CACHE)
+		options |= BITMAP_OPT_HASH_CACHE;
+
+	if (flags & MIDX_WRITE_BITMAP_LOOKUP_TABLE)
+		options |= BITMAP_OPT_LOOKUP_TABLE;
+
+	/*
+	 * Build the MIDX-order index based on pdata.objects (which is already
+	 * in MIDX order; c.f., 'midx_pack_order_cmp()' for the definition of
+	 * this order).
+	 */
+	ALLOC_ARRAY(index, pdata->nr_objects);
+	for (i = 0; i < pdata->nr_objects; i++)
+		index[i] = &pdata->objects[i].idx;
+
+	bitmap_writer_show_progress(flags & MIDX_PROGRESS);
+	bitmap_writer_build_type_index(pdata, index, pdata->nr_objects);
+
+	/*
+	 * bitmap_writer_finish expects objects in lex order, but pack_order
+	 * gives us exactly that. use it directly instead of re-sorting the
+	 * array.
+	 *
+	 * This changes the order of objects in 'index' between
+	 * bitmap_writer_build_type_index and bitmap_writer_finish.
+	 *
+	 * The same re-ordering takes place in the single-pack bitmap code via
+	 * write_idx_file(), which is called by finish_tmp_packfile(), which
+	 * happens between bitmap_writer_build_type_index() and
+	 * bitmap_writer_finish().
+	 */
+	for (i = 0; i < pdata->nr_objects; i++)
+		index[pack_order[i]] = &pdata->objects[i].idx;
+
+	bitmap_writer_select_commits(commits, commits_nr, -1);
+	ret = bitmap_writer_build(pdata);
+	if (ret < 0)
+		goto cleanup;
+
+	bitmap_writer_set_checksum(midx_hash);
+	bitmap_writer_finish(index, pdata->nr_objects, bitmap_name, options);
+
+cleanup:
+	free(index);
+	free(bitmap_name);
+
+	trace2_region_leave("midx", "write_midx_bitmap", the_repository);
+
+	return ret;
+}
+
+static struct multi_pack_index *lookup_multi_pack_index(struct repository *r,
+							const char *object_dir)
+{
+	struct multi_pack_index *result = NULL;
+	struct multi_pack_index *cur;
+	char *obj_dir_real = real_pathdup(object_dir, 1);
+	struct strbuf cur_path_real = STRBUF_INIT;
+
+	/* Ensure the given object_dir is local, or a known alternate. */
+	find_odb(r, obj_dir_real);
+
+	for (cur = get_multi_pack_index(r); cur; cur = cur->next) {
+		strbuf_realpath(&cur_path_real, cur->object_dir, 1);
+		if (!strcmp(obj_dir_real, cur_path_real.buf)) {
+			result = cur;
+			goto cleanup;
+		}
+	}
+
+cleanup:
+	free(obj_dir_real);
+	strbuf_release(&cur_path_real);
+	return result;
+}
+
+static int write_midx_internal(const char *object_dir,
+			       struct string_list *packs_to_include,
+			       struct string_list *packs_to_drop,
+			       const char *preferred_pack_name,
+			       const char *refs_snapshot,
+			       unsigned flags)
+{
+	struct strbuf midx_name = STRBUF_INIT;
+	unsigned char midx_hash[GIT_MAX_RAWSZ];
+	uint32_t i;
+	struct hashfile *f = NULL;
+	struct lock_file lk;
+	struct write_midx_context ctx = { 0 };
+	int bitmapped_packs_concat_len = 0;
+	int pack_name_concat_len = 0;
+	int dropped_packs = 0;
+	int result = 0;
+	struct chunkfile *cf;
+
+	trace2_region_enter("midx", "write_midx_internal", the_repository);
+
+	get_midx_filename(&midx_name, object_dir);
+	if (safe_create_leading_directories(midx_name.buf))
+		die_errno(_("unable to create leading directories of %s"),
+			  midx_name.buf);
+
+	if (!packs_to_include) {
+		/*
+		 * Only reference an existing MIDX when not filtering which
+		 * packs to include, since all packs and objects are copied
+		 * blindly from an existing MIDX if one is present.
+		 */
+		ctx.m = lookup_multi_pack_index(the_repository, object_dir);
+	}
+
+	if (ctx.m && !midx_checksum_valid(ctx.m)) {
+		warning(_("ignoring existing multi-pack-index; checksum mismatch"));
+		ctx.m = NULL;
+	}
+
+	ctx.nr = 0;
+	ctx.alloc = ctx.m ? ctx.m->num_packs : 16;
+	ctx.info = NULL;
+	ALLOC_ARRAY(ctx.info, ctx.alloc);
+
+	if (ctx.m) {
+		for (i = 0; i < ctx.m->num_packs; i++) {
+			ALLOC_GROW(ctx.info, ctx.nr + 1, ctx.alloc);
+
+			if (flags & MIDX_WRITE_REV_INDEX) {
+				/*
+				 * If generating a reverse index, need to have
+				 * packed_git's loaded to compare their
+				 * mtimes and object count.
+				 */
+				if (prepare_midx_pack(the_repository, ctx.m, i)) {
+					error(_("could not load pack"));
+					result = 1;
+					goto cleanup;
+				}
+
+				if (open_pack_index(ctx.m->packs[i]))
+					die(_("could not open index for %s"),
+					    ctx.m->packs[i]->pack_name);
+			}
+
+			fill_pack_info(&ctx.info[ctx.nr++], ctx.m->packs[i],
+				       ctx.m->pack_names[i], i);
+		}
+	}
+
+	ctx.pack_paths_checked = 0;
+	if (flags & MIDX_PROGRESS)
+		ctx.progress = start_delayed_progress(_("Adding packfiles to multi-pack-index"), 0);
+	else
+		ctx.progress = NULL;
+
+	ctx.to_include = packs_to_include;
+
+	for_each_file_in_pack_dir(object_dir, add_pack_to_midx, &ctx);
+	stop_progress(&ctx.progress);
+
+	if ((ctx.m && ctx.nr == ctx.m->num_packs) &&
+	    !(packs_to_include || packs_to_drop)) {
+		struct bitmap_index *bitmap_git;
+		int bitmap_exists;
+		int want_bitmap = flags & MIDX_WRITE_BITMAP;
+
+		bitmap_git = prepare_midx_bitmap_git(ctx.m);
+		bitmap_exists = bitmap_git && bitmap_is_midx(bitmap_git);
+		free_bitmap_index(bitmap_git);
+
+		if (bitmap_exists || !want_bitmap) {
+			/*
+			 * The correct MIDX already exists, and so does a
+			 * corresponding bitmap (or one wasn't requested).
+			 */
+			if (!want_bitmap)
+				clear_midx_files_ext(object_dir, ".bitmap",
+						     NULL);
+			goto cleanup;
+		}
+	}
+
+	if (preferred_pack_name) {
+		ctx.preferred_pack_idx = -1;
+
+		for (i = 0; i < ctx.nr; i++) {
+			if (!cmp_idx_or_pack_name(preferred_pack_name,
+						  ctx.info[i].pack_name)) {
+				ctx.preferred_pack_idx = i;
+				break;
+			}
+		}
+
+		if (ctx.preferred_pack_idx == -1)
+			warning(_("unknown preferred pack: '%s'"),
+				preferred_pack_name);
+	} else if (ctx.nr &&
+		   (flags & (MIDX_WRITE_REV_INDEX | MIDX_WRITE_BITMAP))) {
+		struct packed_git *oldest = ctx.info[ctx.preferred_pack_idx].p;
+		ctx.preferred_pack_idx = 0;
+
+		if (packs_to_drop && packs_to_drop->nr)
+			BUG("cannot write a MIDX bitmap during expiration");
+
+		/*
+		 * set a preferred pack when writing a bitmap to ensure that
+		 * the pack from which the first object is selected in pseudo
+		 * pack-order has all of its objects selected from that pack
+		 * (and not another pack containing a duplicate)
+		 */
+		for (i = 1; i < ctx.nr; i++) {
+			struct packed_git *p = ctx.info[i].p;
+
+			if (!oldest->num_objects || p->mtime < oldest->mtime) {
+				oldest = p;
+				ctx.preferred_pack_idx = i;
+			}
+		}
+
+		if (!oldest->num_objects) {
+			/*
+			 * If all packs are empty; unset the preferred index.
+			 * This is acceptable since there will be no duplicate
+			 * objects to resolve, so the preferred value doesn't
+			 * matter.
+			 */
+			ctx.preferred_pack_idx = -1;
+		}
+	} else {
+		/*
+		 * otherwise don't mark any pack as preferred to avoid
+		 * interfering with expiration logic below
+		 */
+		ctx.preferred_pack_idx = -1;
+	}
+
+	if (ctx.preferred_pack_idx > -1) {
+		struct packed_git *preferred = ctx.info[ctx.preferred_pack_idx].p;
+		if (!preferred->num_objects) {
+			error(_("cannot select preferred pack %s with no objects"),
+			      preferred->pack_name);
+			result = 1;
+			goto cleanup;
+		}
+	}
+
+	ctx.entries = get_sorted_entries(ctx.m, ctx.info, ctx.nr, &ctx.entries_nr,
+					 ctx.preferred_pack_idx);
+
+	ctx.large_offsets_needed = 0;
+	for (i = 0; i < ctx.entries_nr; i++) {
+		if (ctx.entries[i].offset > 0x7fffffff)
+			ctx.num_large_offsets++;
+		if (ctx.entries[i].offset > 0xffffffff)
+			ctx.large_offsets_needed = 1;
+	}
+
+	QSORT(ctx.info, ctx.nr, pack_info_compare);
+
+	if (packs_to_drop && packs_to_drop->nr) {
+		int drop_index = 0;
+		int missing_drops = 0;
+
+		for (i = 0; i < ctx.nr && drop_index < packs_to_drop->nr; i++) {
+			int cmp = strcmp(ctx.info[i].pack_name,
+					 packs_to_drop->items[drop_index].string);
+
+			if (!cmp) {
+				drop_index++;
+				ctx.info[i].expired = 1;
+			} else if (cmp > 0) {
+				error(_("did not see pack-file %s to drop"),
+				      packs_to_drop->items[drop_index].string);
+				drop_index++;
+				missing_drops++;
+				i--;
+			} else {
+				ctx.info[i].expired = 0;
+			}
+		}
+
+		if (missing_drops) {
+			result = 1;
+			goto cleanup;
+		}
+	}
+
+	/*
+	 * pack_perm stores a permutation between pack-int-ids from the
+	 * previous multi-pack-index to the new one we are writing:
+	 *
+	 * pack_perm[old_id] = new_id
+	 */
+	ALLOC_ARRAY(ctx.pack_perm, ctx.nr);
+	for (i = 0; i < ctx.nr; i++) {
+		if (ctx.info[i].expired) {
+			dropped_packs++;
+			ctx.pack_perm[ctx.info[i].orig_pack_int_id] = PACK_EXPIRED;
+		} else {
+			ctx.pack_perm[ctx.info[i].orig_pack_int_id] = i - dropped_packs;
+		}
+	}
+
+	for (i = 0; i < ctx.nr; i++) {
+		if (ctx.info[i].expired)
+			continue;
+		pack_name_concat_len += strlen(ctx.info[i].pack_name) + 1;
+		bitmapped_packs_concat_len += 2 * sizeof(uint32_t);
+	}
+
+	/* Check that the preferred pack wasn't expired (if given). */
+	if (preferred_pack_name) {
+		struct pack_info *preferred = bsearch(preferred_pack_name,
+						      ctx.info, ctx.nr,
+						      sizeof(*ctx.info),
+						      idx_or_pack_name_cmp);
+		if (preferred) {
+			uint32_t perm = ctx.pack_perm[preferred->orig_pack_int_id];
+			if (perm == PACK_EXPIRED)
+				warning(_("preferred pack '%s' is expired"),
+					preferred_pack_name);
+		}
+	}
+
+	if (pack_name_concat_len % MIDX_CHUNK_ALIGNMENT)
+		pack_name_concat_len += MIDX_CHUNK_ALIGNMENT -
+					(pack_name_concat_len % MIDX_CHUNK_ALIGNMENT);
+
+	hold_lock_file_for_update(&lk, midx_name.buf, LOCK_DIE_ON_ERROR);
+	f = hashfd(get_lock_file_fd(&lk), get_lock_file_path(&lk));
+
+	if (ctx.nr - dropped_packs == 0) {
+		error(_("no pack files to index."));
+		result = 1;
+		goto cleanup;
+	}
+
+	if (!ctx.entries_nr) {
+		if (flags & MIDX_WRITE_BITMAP)
+			warning(_("refusing to write multi-pack .bitmap without any objects"));
+		flags &= ~(MIDX_WRITE_REV_INDEX | MIDX_WRITE_BITMAP);
+	}
+
+	cf = init_chunkfile(f);
+
+	add_chunk(cf, MIDX_CHUNKID_PACKNAMES, pack_name_concat_len,
+		  write_midx_pack_names);
+	add_chunk(cf, MIDX_CHUNKID_OIDFANOUT, MIDX_CHUNK_FANOUT_SIZE,
+		  write_midx_oid_fanout);
+	add_chunk(cf, MIDX_CHUNKID_OIDLOOKUP,
+		  st_mult(ctx.entries_nr, the_hash_algo->rawsz),
+		  write_midx_oid_lookup);
+	add_chunk(cf, MIDX_CHUNKID_OBJECTOFFSETS,
+		  st_mult(ctx.entries_nr, MIDX_CHUNK_OFFSET_WIDTH),
+		  write_midx_object_offsets);
+
+	if (ctx.large_offsets_needed)
+		add_chunk(cf, MIDX_CHUNKID_LARGEOFFSETS,
+			st_mult(ctx.num_large_offsets,
+				MIDX_CHUNK_LARGE_OFFSET_WIDTH),
+			write_midx_large_offsets);
+
+	if (flags & (MIDX_WRITE_REV_INDEX | MIDX_WRITE_BITMAP)) {
+		ctx.pack_order = midx_pack_order(&ctx);
+		add_chunk(cf, MIDX_CHUNKID_REVINDEX,
+			  st_mult(ctx.entries_nr, sizeof(uint32_t)),
+			  write_midx_revindex);
+		add_chunk(cf, MIDX_CHUNKID_BITMAPPEDPACKS,
+			  bitmapped_packs_concat_len,
+			  write_midx_bitmapped_packs);
+	}
+
+	write_midx_header(f, get_num_chunks(cf), ctx.nr - dropped_packs);
+	write_chunkfile(cf, &ctx);
+
+	finalize_hashfile(f, midx_hash, FSYNC_COMPONENT_PACK_METADATA,
+			  CSUM_FSYNC | CSUM_HASH_IN_STREAM);
+	free_chunkfile(cf);
+
+	if (flags & MIDX_WRITE_REV_INDEX &&
+	    git_env_bool("GIT_TEST_MIDX_WRITE_REV", 0))
+		write_midx_reverse_index(midx_name.buf, midx_hash, &ctx);
+
+	if (flags & MIDX_WRITE_BITMAP) {
+		struct packing_data pdata;
+		struct commit **commits;
+		uint32_t commits_nr;
+
+		if (!ctx.entries_nr)
+			BUG("cannot write a bitmap without any objects");
+
+		prepare_midx_packing_data(&pdata, &ctx);
+
+		commits = find_commits_for_midx_bitmap(&commits_nr, refs_snapshot, &ctx);
+
+		/*
+		 * The previous steps translated the information from
+		 * 'entries' into information suitable for constructing
+		 * bitmaps. We no longer need that array, so clear it to
+		 * reduce memory pressure.
+		 */
+		FREE_AND_NULL(ctx.entries);
+		ctx.entries_nr = 0;
+
+		if (write_midx_bitmap(midx_name.buf, midx_hash, &pdata,
+				      commits, commits_nr, ctx.pack_order,
+				      flags) < 0) {
+			error(_("could not write multi-pack bitmap"));
+			result = 1;
+			clear_packing_data(&pdata);
+			free(commits);
+			goto cleanup;
+		}
+
+		clear_packing_data(&pdata);
+		free(commits);
+	}
+	/*
+	 * NOTE: Do not use ctx.entries beyond this point, since it might
+	 * have been freed in the previous if block.
+	 */
+
+	if (ctx.m)
+		close_object_store(the_repository->objects);
+
+	if (commit_lock_file(&lk) < 0)
+		die_errno(_("could not write multi-pack-index"));
+
+	clear_midx_files_ext(object_dir, ".bitmap", midx_hash);
+	clear_midx_files_ext(object_dir, ".rev", midx_hash);
+
+cleanup:
+	for (i = 0; i < ctx.nr; i++) {
+		if (ctx.info[i].p) {
+			close_pack(ctx.info[i].p);
+			free(ctx.info[i].p);
+		}
+		free(ctx.info[i].pack_name);
+	}
+
+	free(ctx.info);
+	free(ctx.entries);
+	free(ctx.pack_perm);
+	free(ctx.pack_order);
+	strbuf_release(&midx_name);
+
+	trace2_region_leave("midx", "write_midx_internal", the_repository);
+
+	return result;
+}
+
+int write_midx_file(const char *object_dir,
+		    const char *preferred_pack_name,
+		    const char *refs_snapshot,
+		    unsigned flags)
+{
+	return write_midx_internal(object_dir, NULL, NULL, preferred_pack_name,
+				   refs_snapshot, flags);
+}
+
+int write_midx_file_only(const char *object_dir,
+			 struct string_list *packs_to_include,
+			 const char *preferred_pack_name,
+			 const char *refs_snapshot,
+			 unsigned flags)
+{
+	return write_midx_internal(object_dir, packs_to_include, NULL,
+				   preferred_pack_name, refs_snapshot, flags);
+}
+
+int expire_midx_packs(struct repository *r, const char *object_dir, unsigned flags)
+{
+	uint32_t i, *count, result = 0;
+	struct string_list packs_to_drop = STRING_LIST_INIT_DUP;
+	struct multi_pack_index *m = lookup_multi_pack_index(r, object_dir);
+	struct progress *progress = NULL;
+
+	if (!m)
+		return 0;
+
+	CALLOC_ARRAY(count, m->num_packs);
+
+	if (flags & MIDX_PROGRESS)
+		progress = start_delayed_progress(_("Counting referenced objects"),
+					  m->num_objects);
+	for (i = 0; i < m->num_objects; i++) {
+		int pack_int_id = nth_midxed_pack_int_id(m, i);
+		count[pack_int_id]++;
+		display_progress(progress, i + 1);
+	}
+	stop_progress(&progress);
+
+	if (flags & MIDX_PROGRESS)
+		progress = start_delayed_progress(_("Finding and deleting unreferenced packfiles"),
+					  m->num_packs);
+	for (i = 0; i < m->num_packs; i++) {
+		char *pack_name;
+		display_progress(progress, i + 1);
+
+		if (count[i])
+			continue;
+
+		if (prepare_midx_pack(r, m, i))
+			continue;
+
+		if (m->packs[i]->pack_keep || m->packs[i]->is_cruft)
+			continue;
+
+		pack_name = xstrdup(m->packs[i]->pack_name);
+		close_pack(m->packs[i]);
+
+		string_list_insert(&packs_to_drop, m->pack_names[i]);
+		unlink_pack_path(pack_name, 0);
+		free(pack_name);
+	}
+	stop_progress(&progress);
+
+	free(count);
+
+	if (packs_to_drop.nr)
+		result = write_midx_internal(object_dir, NULL, &packs_to_drop, NULL, NULL, flags);
+
+	string_list_clear(&packs_to_drop, 0);
+
+	return result;
+}
+
+struct repack_info {
+	timestamp_t mtime;
+	uint32_t referenced_objects;
+	uint32_t pack_int_id;
+};
+
+static int compare_by_mtime(const void *a_, const void *b_)
+{
+	const struct repack_info *a, *b;
+
+	a = (const struct repack_info *)a_;
+	b = (const struct repack_info *)b_;
+
+	if (a->mtime < b->mtime)
+		return -1;
+	if (a->mtime > b->mtime)
+		return 1;
+	return 0;
+}
+
+static int want_included_pack(struct repository *r,
+			      struct multi_pack_index *m,
+			      int pack_kept_objects,
+			      uint32_t pack_int_id)
+{
+	struct packed_git *p;
+	if (prepare_midx_pack(r, m, pack_int_id))
+		return 0;
+	p = m->packs[pack_int_id];
+	if (!pack_kept_objects && p->pack_keep)
+		return 0;
+	if (p->is_cruft)
+		return 0;
+	if (open_pack_index(p) || !p->num_objects)
+		return 0;
+	return 1;
+}
+
+static void fill_included_packs_all(struct repository *r,
+				    struct multi_pack_index *m,
+				    unsigned char *include_pack)
+{
+	uint32_t i;
+	int pack_kept_objects = 0;
+
+	repo_config_get_bool(r, "repack.packkeptobjects", &pack_kept_objects);
+
+	for (i = 0; i < m->num_packs; i++) {
+		if (!want_included_pack(r, m, pack_kept_objects, i))
+			continue;
+
+		include_pack[i] = 1;
+	}
+}
+
+static void fill_included_packs_batch(struct repository *r,
+				      struct multi_pack_index *m,
+				      unsigned char *include_pack,
+				      size_t batch_size)
+{
+	uint32_t i;
+	size_t total_size;
+	struct repack_info *pack_info;
+	int pack_kept_objects = 0;
+
+	CALLOC_ARRAY(pack_info, m->num_packs);
+
+	repo_config_get_bool(r, "repack.packkeptobjects", &pack_kept_objects);
+
+	for (i = 0; i < m->num_packs; i++) {
+		pack_info[i].pack_int_id = i;
+
+		if (prepare_midx_pack(r, m, i))
+			continue;
+
+		pack_info[i].mtime = m->packs[i]->mtime;
+	}
+
+	for (i = 0; i < m->num_objects; i++) {
+		uint32_t pack_int_id = nth_midxed_pack_int_id(m, i);
+		pack_info[pack_int_id].referenced_objects++;
+	}
+
+	QSORT(pack_info, m->num_packs, compare_by_mtime);
+
+	total_size = 0;
+	for (i = 0; total_size < batch_size && i < m->num_packs; i++) {
+		int pack_int_id = pack_info[i].pack_int_id;
+		struct packed_git *p = m->packs[pack_int_id];
+		size_t expected_size;
+
+		if (!want_included_pack(r, m, pack_kept_objects, pack_int_id))
+			continue;
+
+		expected_size = st_mult(p->pack_size,
+					pack_info[i].referenced_objects);
+		expected_size /= p->num_objects;
+
+		if (expected_size >= batch_size)
+			continue;
+
+		total_size += expected_size;
+		include_pack[pack_int_id] = 1;
+	}
+
+	free(pack_info);
+}
+
+int midx_repack(struct repository *r, const char *object_dir, size_t batch_size, unsigned flags)
+{
+	int result = 0;
+	uint32_t i, packs_to_repack = 0;
+	unsigned char *include_pack;
+	struct child_process cmd = CHILD_PROCESS_INIT;
+	FILE *cmd_in;
+	struct multi_pack_index *m = lookup_multi_pack_index(r, object_dir);
+
+	/*
+	 * When updating the default for these configuration
+	 * variables in builtin/repack.c, these must be adjusted
+	 * to match.
+	 */
+	int delta_base_offset = 1;
+	int use_delta_islands = 0;
+
+	if (!m)
+		return 0;
+
+	CALLOC_ARRAY(include_pack, m->num_packs);
+
+	if (batch_size)
+		fill_included_packs_batch(r, m, include_pack, batch_size);
+	else
+		fill_included_packs_all(r, m, include_pack);
+
+	for (i = 0; i < m->num_packs; i++) {
+		if (include_pack[i])
+			packs_to_repack++;
+	}
+	if (packs_to_repack <= 1)
+		goto cleanup;
+
+	repo_config_get_bool(r, "repack.usedeltabaseoffset", &delta_base_offset);
+	repo_config_get_bool(r, "repack.usedeltaislands", &use_delta_islands);
+
+	strvec_pushl(&cmd.args, "pack-objects", "--stdin-packs", "--non-empty",
+		     NULL);
+
+	strvec_pushf(&cmd.args, "%s/pack/pack", object_dir);
+
+	if (delta_base_offset)
+		strvec_push(&cmd.args, "--delta-base-offset");
+	if (use_delta_islands)
+		strvec_push(&cmd.args, "--delta-islands");
+
+	if (flags & MIDX_PROGRESS)
+		strvec_push(&cmd.args, "--progress");
+	else
+		strvec_push(&cmd.args, "-q");
+
+	cmd.git_cmd = 1;
+	cmd.in = cmd.out = -1;
+
+	if (start_command(&cmd)) {
+		error(_("could not start pack-objects"));
+		result = 1;
+		goto cleanup;
+	}
+
+	cmd_in = xfdopen(cmd.in, "w");
+	for (i = 0; i < m->num_packs; i++) {
+		struct packed_git *p = m->packs[i];
+		if (!p)
+			continue;
+
+		if (include_pack[i])
+			fprintf(cmd_in, "%s\n", pack_basename(p));
+		else
+			fprintf(cmd_in, "^%s\n", pack_basename(p));
+	}
+	fclose(cmd_in);
+
+	if (finish_command(&cmd)) {
+		error(_("could not finish pack-objects"));
+		result = 1;
+		goto cleanup;
+	}
+
+	result = write_midx_internal(object_dir, NULL, NULL, NULL, NULL, flags);
+
+cleanup:
+	free(include_pack);
+	return result;
+}
diff --git a/midx.c b/midx.c
index 2f3863c..6f07de3 100644
--- a/midx.c
+++ b/midx.c
@@ -1,49 +1,22 @@
 #include "git-compat-util.h"
-#include "abspath.h"
 #include "config.h"
-#include "csum-file.h"
 #include "dir.h"
-#include "gettext.h"
 #include "hex.h"
-#include "lockfile.h"
 #include "packfile.h"
 #include "object-file.h"
-#include "object-store-ll.h"
 #include "hash-lookup.h"
 #include "midx.h"
 #include "progress.h"
 #include "trace2.h"
-#include "run-command.h"
-#include "repository.h"
 #include "chunk-format.h"
-#include "pack.h"
 #include "pack-bitmap.h"
-#include "refs.h"
-#include "revision.h"
-#include "list-objects.h"
+#include "pack-revindex.h"
 
-#define MIDX_SIGNATURE 0x4d494458 /* "MIDX" */
-#define MIDX_VERSION 1
-#define MIDX_BYTE_FILE_VERSION 4
-#define MIDX_BYTE_HASH_VERSION 5
-#define MIDX_BYTE_NUM_CHUNKS 6
-#define MIDX_BYTE_NUM_PACKS 8
-#define MIDX_HEADER_SIZE 12
-#define MIDX_MIN_SIZE (MIDX_HEADER_SIZE + the_hash_algo->rawsz)
-
-#define MIDX_CHUNK_ALIGNMENT 4
-#define MIDX_CHUNKID_PACKNAMES 0x504e414d /* "PNAM" */
-#define MIDX_CHUNKID_OIDFANOUT 0x4f494446 /* "OIDF" */
-#define MIDX_CHUNKID_OIDLOOKUP 0x4f49444c /* "OIDL" */
-#define MIDX_CHUNKID_OBJECTOFFSETS 0x4f4f4646 /* "OOFF" */
-#define MIDX_CHUNKID_LARGEOFFSETS 0x4c4f4646 /* "LOFF" */
-#define MIDX_CHUNKID_REVINDEX 0x52494458 /* "RIDX" */
-#define MIDX_CHUNK_FANOUT_SIZE (sizeof(uint32_t) * 256)
-#define MIDX_CHUNK_OFFSET_WIDTH (2 * sizeof(uint32_t))
-#define MIDX_CHUNK_LARGE_OFFSET_WIDTH (sizeof(uint64_t))
-#define MIDX_LARGE_OFFSET_NEEDED 0x80000000
-
-#define PACK_EXPIRED UINT_MAX
+int midx_checksum_valid(struct multi_pack_index *m);
+void clear_midx_files_ext(const char *object_dir, const char *ext,
+			  unsigned char *keep_hash);
+int cmp_idx_or_pack_name(const char *idx_or_pack_name,
+			 const char *idx_name);
 
 const unsigned char *get_midx_checksum(struct multi_pack_index *m)
 {
@@ -64,6 +37,7 @@ void get_midx_rev_filename(struct strbuf *out, struct multi_pack_index *m)
 static int midx_read_oid_fanout(const unsigned char *chunk_start,
 				size_t chunk_size, void *data)
 {
+	int i;
 	struct multi_pack_index *m = data;
 	m->chunk_oid_fanout = (uint32_t *)chunk_start;
 
@@ -71,6 +45,16 @@ static int midx_read_oid_fanout(const unsigned char *chunk_start,
 		error(_("multi-pack-index OID fanout is of the wrong size"));
 		return 1;
 	}
+	for (i = 0; i < 255; i++) {
+		uint32_t oid_fanout1 = ntohl(m->chunk_oid_fanout[i]);
+		uint32_t oid_fanout2 = ntohl(m->chunk_oid_fanout[i+1]);
+
+		if (oid_fanout1 > oid_fanout2) {
+			error(_("oid fanout out of order: fanout[%d] = %"PRIx32" > %"PRIx32" = fanout[%d]"),
+			      i, oid_fanout1, oid_fanout2, i + 1);
+			return 1;
+		}
+	}
 	m->num_objects = ntohl(m->chunk_oid_fanout[255]);
 	return 0;
 }
@@ -101,6 +85,8 @@ static int midx_read_object_offsets(const unsigned char *chunk_start,
 	return 0;
 }
 
+#define MIDX_MIN_SIZE (MIDX_HEADER_SIZE + the_hash_algo->rawsz)
+
 struct multi_pack_index *load_multi_pack_index(const char *object_dir, int local)
 {
 	struct multi_pack_index *m = NULL;
@@ -164,6 +150,8 @@ struct multi_pack_index *load_multi_pack_index(const char *object_dir, int local
 
 	m->num_packs = get_be32(m->data + MIDX_BYTE_NUM_PACKS);
 
+	m->preferred_pack_idx = -1;
+
 	cf = init_chunkfile(NULL);
 
 	if (read_table_of_contents(cf, m->data, midx_size,
@@ -182,6 +170,10 @@ struct multi_pack_index *load_multi_pack_index(const char *object_dir, int local
 
 	pair_chunk(cf, MIDX_CHUNKID_LARGEOFFSETS, &m->chunk_large_offsets,
 		   &m->chunk_large_offsets_len);
+	if (git_env_bool("GIT_TEST_MIDX_READ_BTMP", 1))
+		pair_chunk(cf, MIDX_CHUNKID_BITMAPPEDPACKS,
+			   (const unsigned char **)&m->chunk_bitmapped_packs,
+			   &m->chunk_bitmapped_packs_len);
 
 	if (git_env_bool("GIT_TEST_MIDX_READ_RIDX", 1))
 		pair_chunk(cf, MIDX_CHUNKID_REVINDEX, &m->chunk_revindex,
@@ -275,6 +267,28 @@ int prepare_midx_pack(struct repository *r, struct multi_pack_index *m, uint32_t
 	return 0;
 }
 
+#define MIDX_CHUNK_BITMAPPED_PACKS_WIDTH (2 * sizeof(uint32_t))
+
+int nth_bitmapped_pack(struct repository *r, struct multi_pack_index *m,
+		       struct bitmapped_pack *bp, uint32_t pack_int_id)
+{
+	if (!m->chunk_bitmapped_packs)
+		return error(_("MIDX does not contain the BTMP chunk"));
+
+	if (prepare_midx_pack(r, m, pack_int_id))
+		return error(_("could not load bitmapped pack %"PRIu32), pack_int_id);
+
+	bp->p = m->packs[pack_int_id];
+	bp->bitmap_pos = get_be32((char *)m->chunk_bitmapped_packs +
+				  MIDX_CHUNK_BITMAPPED_PACKS_WIDTH * pack_int_id);
+	bp->bitmap_nr = get_be32((char *)m->chunk_bitmapped_packs +
+				 MIDX_CHUNK_BITMAPPED_PACKS_WIDTH * pack_int_id +
+				 sizeof(uint32_t));
+	bp->pack_int_id = pack_int_id;
+
+	return 0;
+}
+
 int bsearch_midx(const struct object_id *oid, struct multi_pack_index *m, uint32_t *result)
 {
 	return bsearch_hash(oid->hash, m->chunk_oid_fanout, m->chunk_oid_lookup,
@@ -361,8 +375,8 @@ int fill_midx_entry(struct repository *r,
 }
 
 /* Match "foo.idx" against either "foo.pack" _or_ "foo.idx". */
-static int cmp_idx_or_pack_name(const char *idx_or_pack_name,
-				const char *idx_name)
+int cmp_idx_or_pack_name(const char *idx_or_pack_name,
+			 const char *idx_name)
 {
 	/* Skip past any initial matching prefix. */
 	while (*idx_name && *idx_name == *idx_or_pack_name) {
@@ -392,7 +406,8 @@ static int cmp_idx_or_pack_name(const char *idx_or_pack_name,
 	return strcmp(idx_or_pack_name, idx_name);
 }
 
-int midx_contains_pack(struct multi_pack_index *m, const char *idx_or_pack_name)
+int midx_locate_pack(struct multi_pack_index *m, const char *idx_or_pack_name,
+		     uint32_t *pos)
 {
 	uint32_t first = 0, last = m->num_packs;
 
@@ -403,8 +418,11 @@ int midx_contains_pack(struct multi_pack_index *m, const char *idx_or_pack_name)
 
 		current = m->pack_names[mid];
 		cmp = cmp_idx_or_pack_name(idx_or_pack_name, current);
-		if (!cmp)
+		if (!cmp) {
+			if (pos)
+				*pos = mid;
 			return 1;
+		}
 		if (cmp > 0) {
 			first = mid + 1;
 			continue;
@@ -415,6 +433,28 @@ int midx_contains_pack(struct multi_pack_index *m, const char *idx_or_pack_name)
 	return 0;
 }
 
+int midx_contains_pack(struct multi_pack_index *m, const char *idx_or_pack_name)
+{
+	return midx_locate_pack(m, idx_or_pack_name, NULL);
+}
+
+int midx_preferred_pack(struct multi_pack_index *m, uint32_t *pack_int_id)
+{
+	if (m->preferred_pack_idx == -1) {
+		if (load_midx_revindex(m) < 0) {
+			m->preferred_pack_idx = -2;
+			return -1;
+		}
+
+		m->preferred_pack_idx =
+			nth_midxed_pack_int_id(m, pack_pos_to_midx(m, 0));
+	} else if (m->preferred_pack_idx == -2)
+		return -1; /* no revindex */
+
+	*pack_int_id = m->preferred_pack_idx;
+	return 0;
+}
+
 int prepare_multi_pack_index_one(struct repository *r, const char *object_dir, int local)
 {
 	struct multi_pack_index *m;
@@ -443,1211 +483,11 @@ int prepare_multi_pack_index_one(struct repository *r, const char *object_dir, i
 	return 0;
 }
 
-static size_t write_midx_header(struct hashfile *f,
-				unsigned char num_chunks,
-				uint32_t num_packs)
-{
-	hashwrite_be32(f, MIDX_SIGNATURE);
-	hashwrite_u8(f, MIDX_VERSION);
-	hashwrite_u8(f, oid_version(the_hash_algo));
-	hashwrite_u8(f, num_chunks);
-	hashwrite_u8(f, 0); /* unused */
-	hashwrite_be32(f, num_packs);
-
-	return MIDX_HEADER_SIZE;
-}
-
-struct pack_info {
-	uint32_t orig_pack_int_id;
-	char *pack_name;
-	struct packed_git *p;
-	unsigned expired : 1;
-};
-
-static int pack_info_compare(const void *_a, const void *_b)
-{
-	struct pack_info *a = (struct pack_info *)_a;
-	struct pack_info *b = (struct pack_info *)_b;
-	return strcmp(a->pack_name, b->pack_name);
-}
-
-static int idx_or_pack_name_cmp(const void *_va, const void *_vb)
-{
-	const char *pack_name = _va;
-	const struct pack_info *compar = _vb;
-
-	return cmp_idx_or_pack_name(pack_name, compar->pack_name);
-}
-
-struct write_midx_context {
-	struct pack_info *info;
-	size_t nr;
-	size_t alloc;
-	struct multi_pack_index *m;
-	struct progress *progress;
-	unsigned pack_paths_checked;
-
-	struct pack_midx_entry *entries;
-	size_t entries_nr;
-
-	uint32_t *pack_perm;
-	uint32_t *pack_order;
-	unsigned large_offsets_needed:1;
-	uint32_t num_large_offsets;
-
-	int preferred_pack_idx;
-
-	struct string_list *to_include;
-};
-
-static void add_pack_to_midx(const char *full_path, size_t full_path_len,
-			     const char *file_name, void *data)
-{
-	struct write_midx_context *ctx = data;
-
-	if (ends_with(file_name, ".idx")) {
-		display_progress(ctx->progress, ++ctx->pack_paths_checked);
-		/*
-		 * Note that at most one of ctx->m and ctx->to_include are set,
-		 * so we are testing midx_contains_pack() and
-		 * string_list_has_string() independently (guarded by the
-		 * appropriate NULL checks).
-		 *
-		 * We could support passing to_include while reusing an existing
-		 * MIDX, but don't currently since the reuse process drags
-		 * forward all packs from an existing MIDX (without checking
-		 * whether or not they appear in the to_include list).
-		 *
-		 * If we added support for that, these next two conditional
-		 * should be performed independently (likely checking
-		 * to_include before the existing MIDX).
-		 */
-		if (ctx->m && midx_contains_pack(ctx->m, file_name))
-			return;
-		else if (ctx->to_include &&
-			 !string_list_has_string(ctx->to_include, file_name))
-			return;
-
-		ALLOC_GROW(ctx->info, ctx->nr + 1, ctx->alloc);
-
-		ctx->info[ctx->nr].p = add_packed_git(full_path,
-						      full_path_len,
-						      0);
-
-		if (!ctx->info[ctx->nr].p) {
-			warning(_("failed to add packfile '%s'"),
-				full_path);
-			return;
-		}
-
-		if (open_pack_index(ctx->info[ctx->nr].p)) {
-			warning(_("failed to open pack-index '%s'"),
-				full_path);
-			close_pack(ctx->info[ctx->nr].p);
-			FREE_AND_NULL(ctx->info[ctx->nr].p);
-			return;
-		}
-
-		ctx->info[ctx->nr].pack_name = xstrdup(file_name);
-		ctx->info[ctx->nr].orig_pack_int_id = ctx->nr;
-		ctx->info[ctx->nr].expired = 0;
-		ctx->nr++;
-	}
-}
-
-struct pack_midx_entry {
-	struct object_id oid;
-	uint32_t pack_int_id;
-	time_t pack_mtime;
-	uint64_t offset;
-	unsigned preferred : 1;
-};
-
-static int midx_oid_compare(const void *_a, const void *_b)
-{
-	const struct pack_midx_entry *a = (const struct pack_midx_entry *)_a;
-	const struct pack_midx_entry *b = (const struct pack_midx_entry *)_b;
-	int cmp = oidcmp(&a->oid, &b->oid);
-
-	if (cmp)
-		return cmp;
-
-	/* Sort objects in a preferred pack first when multiple copies exist. */
-	if (a->preferred > b->preferred)
-		return -1;
-	if (a->preferred < b->preferred)
-		return 1;
-
-	if (a->pack_mtime > b->pack_mtime)
-		return -1;
-	else if (a->pack_mtime < b->pack_mtime)
-		return 1;
-
-	return a->pack_int_id - b->pack_int_id;
-}
-
-static int nth_midxed_pack_midx_entry(struct multi_pack_index *m,
-				      struct pack_midx_entry *e,
-				      uint32_t pos)
-{
-	if (pos >= m->num_objects)
-		return 1;
-
-	nth_midxed_object_oid(&e->oid, m, pos);
-	e->pack_int_id = nth_midxed_pack_int_id(m, pos);
-	e->offset = nth_midxed_offset(m, pos);
-
-	/* consider objects in midx to be from "old" packs */
-	e->pack_mtime = 0;
-	return 0;
-}
-
-static void fill_pack_entry(uint32_t pack_int_id,
-			    struct packed_git *p,
-			    uint32_t cur_object,
-			    struct pack_midx_entry *entry,
-			    int preferred)
-{
-	if (nth_packed_object_id(&entry->oid, p, cur_object) < 0)
-		die(_("failed to locate object %d in packfile"), cur_object);
-
-	entry->pack_int_id = pack_int_id;
-	entry->pack_mtime = p->mtime;
-
-	entry->offset = nth_packed_object_offset(p, cur_object);
-	entry->preferred = !!preferred;
-}
-
-struct midx_fanout {
-	struct pack_midx_entry *entries;
-	size_t nr, alloc;
-};
-
-static void midx_fanout_grow(struct midx_fanout *fanout, size_t nr)
-{
-	if (nr < fanout->nr)
-		BUG("negative growth in midx_fanout_grow() (%"PRIuMAX" < %"PRIuMAX")",
-		    (uintmax_t)nr, (uintmax_t)fanout->nr);
-	ALLOC_GROW(fanout->entries, nr, fanout->alloc);
-}
-
-static void midx_fanout_sort(struct midx_fanout *fanout)
-{
-	QSORT(fanout->entries, fanout->nr, midx_oid_compare);
-}
-
-static void midx_fanout_add_midx_fanout(struct midx_fanout *fanout,
-					struct multi_pack_index *m,
-					uint32_t cur_fanout,
-					int preferred_pack)
-{
-	uint32_t start = 0, end;
-	uint32_t cur_object;
-
-	if (cur_fanout)
-		start = ntohl(m->chunk_oid_fanout[cur_fanout - 1]);
-	end = ntohl(m->chunk_oid_fanout[cur_fanout]);
-
-	for (cur_object = start; cur_object < end; cur_object++) {
-		if ((preferred_pack > -1) &&
-		    (preferred_pack == nth_midxed_pack_int_id(m, cur_object))) {
-			/*
-			 * Objects from preferred packs are added
-			 * separately.
-			 */
-			continue;
-		}
-
-		midx_fanout_grow(fanout, fanout->nr + 1);
-		nth_midxed_pack_midx_entry(m,
-					   &fanout->entries[fanout->nr],
-					   cur_object);
-		fanout->entries[fanout->nr].preferred = 0;
-		fanout->nr++;
-	}
-}
-
-static void midx_fanout_add_pack_fanout(struct midx_fanout *fanout,
-					struct pack_info *info,
-					uint32_t cur_pack,
-					int preferred,
-					uint32_t cur_fanout)
-{
-	struct packed_git *pack = info[cur_pack].p;
-	uint32_t start = 0, end;
-	uint32_t cur_object;
-
-	if (cur_fanout)
-		start = get_pack_fanout(pack, cur_fanout - 1);
-	end = get_pack_fanout(pack, cur_fanout);
-
-	for (cur_object = start; cur_object < end; cur_object++) {
-		midx_fanout_grow(fanout, fanout->nr + 1);
-		fill_pack_entry(cur_pack,
-				info[cur_pack].p,
-				cur_object,
-				&fanout->entries[fanout->nr],
-				preferred);
-		fanout->nr++;
-	}
-}
-
-/*
- * It is possible to artificially get into a state where there are many
- * duplicate copies of objects. That can create high memory pressure if
- * we are to create a list of all objects before de-duplication. To reduce
- * this memory pressure without a significant performance drop, automatically
- * group objects by the first byte of their object id. Use the IDX fanout
- * tables to group the data, copy to a local array, then sort.
- *
- * Copy only the de-duplicated entries (selected by most-recent modified time
- * of a packfile containing the object).
- */
-static struct pack_midx_entry *get_sorted_entries(struct multi_pack_index *m,
-						  struct pack_info *info,
-						  uint32_t nr_packs,
-						  size_t *nr_objects,
-						  int preferred_pack)
-{
-	uint32_t cur_fanout, cur_pack, cur_object;
-	size_t alloc_objects, total_objects = 0;
-	struct midx_fanout fanout = { 0 };
-	struct pack_midx_entry *deduplicated_entries = NULL;
-	uint32_t start_pack = m ? m->num_packs : 0;
-
-	for (cur_pack = start_pack; cur_pack < nr_packs; cur_pack++)
-		total_objects = st_add(total_objects,
-				       info[cur_pack].p->num_objects);
-
-	/*
-	 * As we de-duplicate by fanout value, we expect the fanout
-	 * slices to be evenly distributed, with some noise. Hence,
-	 * allocate slightly more than one 256th.
-	 */
-	alloc_objects = fanout.alloc = total_objects > 3200 ? total_objects / 200 : 16;
-
-	ALLOC_ARRAY(fanout.entries, fanout.alloc);
-	ALLOC_ARRAY(deduplicated_entries, alloc_objects);
-	*nr_objects = 0;
-
-	for (cur_fanout = 0; cur_fanout < 256; cur_fanout++) {
-		fanout.nr = 0;
-
-		if (m)
-			midx_fanout_add_midx_fanout(&fanout, m, cur_fanout,
-						    preferred_pack);
-
-		for (cur_pack = start_pack; cur_pack < nr_packs; cur_pack++) {
-			int preferred = cur_pack == preferred_pack;
-			midx_fanout_add_pack_fanout(&fanout,
-						    info, cur_pack,
-						    preferred, cur_fanout);
-		}
-
-		if (-1 < preferred_pack && preferred_pack < start_pack)
-			midx_fanout_add_pack_fanout(&fanout, info,
-						    preferred_pack, 1,
-						    cur_fanout);
-
-		midx_fanout_sort(&fanout);
-
-		/*
-		 * The batch is now sorted by OID and then mtime (descending).
-		 * Take only the first duplicate.
-		 */
-		for (cur_object = 0; cur_object < fanout.nr; cur_object++) {
-			if (cur_object && oideq(&fanout.entries[cur_object - 1].oid,
-						&fanout.entries[cur_object].oid))
-				continue;
-
-			ALLOC_GROW(deduplicated_entries, st_add(*nr_objects, 1),
-				   alloc_objects);
-			memcpy(&deduplicated_entries[*nr_objects],
-			       &fanout.entries[cur_object],
-			       sizeof(struct pack_midx_entry));
-			(*nr_objects)++;
-		}
-	}
-
-	free(fanout.entries);
-	return deduplicated_entries;
-}
-
-static int write_midx_pack_names(struct hashfile *f, void *data)
-{
-	struct write_midx_context *ctx = data;
-	uint32_t i;
-	unsigned char padding[MIDX_CHUNK_ALIGNMENT];
-	size_t written = 0;
-
-	for (i = 0; i < ctx->nr; i++) {
-		size_t writelen;
-
-		if (ctx->info[i].expired)
-			continue;
-
-		if (i && strcmp(ctx->info[i].pack_name, ctx->info[i - 1].pack_name) <= 0)
-			BUG("incorrect pack-file order: %s before %s",
-			    ctx->info[i - 1].pack_name,
-			    ctx->info[i].pack_name);
-
-		writelen = strlen(ctx->info[i].pack_name) + 1;
-		hashwrite(f, ctx->info[i].pack_name, writelen);
-		written += writelen;
-	}
-
-	/* add padding to be aligned */
-	i = MIDX_CHUNK_ALIGNMENT - (written % MIDX_CHUNK_ALIGNMENT);
-	if (i < MIDX_CHUNK_ALIGNMENT) {
-		memset(padding, 0, sizeof(padding));
-		hashwrite(f, padding, i);
-	}
-
-	return 0;
-}
-
-static int write_midx_oid_fanout(struct hashfile *f,
-				 void *data)
-{
-	struct write_midx_context *ctx = data;
-	struct pack_midx_entry *list = ctx->entries;
-	struct pack_midx_entry *last = ctx->entries + ctx->entries_nr;
-	uint32_t count = 0;
-	uint32_t i;
-
-	/*
-	* Write the first-level table (the list is sorted,
-	* but we use a 256-entry lookup to be able to avoid
-	* having to do eight extra binary search iterations).
-	*/
-	for (i = 0; i < 256; i++) {
-		struct pack_midx_entry *next = list;
-
-		while (next < last && next->oid.hash[0] == i) {
-			count++;
-			next++;
-		}
-
-		hashwrite_be32(f, count);
-		list = next;
-	}
-
-	return 0;
-}
-
-static int write_midx_oid_lookup(struct hashfile *f,
-				 void *data)
-{
-	struct write_midx_context *ctx = data;
-	unsigned char hash_len = the_hash_algo->rawsz;
-	struct pack_midx_entry *list = ctx->entries;
-	uint32_t i;
-
-	for (i = 0; i < ctx->entries_nr; i++) {
-		struct pack_midx_entry *obj = list++;
-
-		if (i < ctx->entries_nr - 1) {
-			struct pack_midx_entry *next = list;
-			if (oidcmp(&obj->oid, &next->oid) >= 0)
-				BUG("OIDs not in order: %s >= %s",
-				    oid_to_hex(&obj->oid),
-				    oid_to_hex(&next->oid));
-		}
-
-		hashwrite(f, obj->oid.hash, (int)hash_len);
-	}
-
-	return 0;
-}
-
-static int write_midx_object_offsets(struct hashfile *f,
-				     void *data)
-{
-	struct write_midx_context *ctx = data;
-	struct pack_midx_entry *list = ctx->entries;
-	uint32_t i, nr_large_offset = 0;
-
-	for (i = 0; i < ctx->entries_nr; i++) {
-		struct pack_midx_entry *obj = list++;
-
-		if (ctx->pack_perm[obj->pack_int_id] == PACK_EXPIRED)
-			BUG("object %s is in an expired pack with int-id %d",
-			    oid_to_hex(&obj->oid),
-			    obj->pack_int_id);
-
-		hashwrite_be32(f, ctx->pack_perm[obj->pack_int_id]);
-
-		if (ctx->large_offsets_needed && obj->offset >> 31)
-			hashwrite_be32(f, MIDX_LARGE_OFFSET_NEEDED | nr_large_offset++);
-		else if (!ctx->large_offsets_needed && obj->offset >> 32)
-			BUG("object %s requires a large offset (%"PRIx64") but the MIDX is not writing large offsets!",
-			    oid_to_hex(&obj->oid),
-			    obj->offset);
-		else
-			hashwrite_be32(f, (uint32_t)obj->offset);
-	}
-
-	return 0;
-}
-
-static int write_midx_large_offsets(struct hashfile *f,
-				    void *data)
-{
-	struct write_midx_context *ctx = data;
-	struct pack_midx_entry *list = ctx->entries;
-	struct pack_midx_entry *end = ctx->entries + ctx->entries_nr;
-	uint32_t nr_large_offset = ctx->num_large_offsets;
-
-	while (nr_large_offset) {
-		struct pack_midx_entry *obj;
-		uint64_t offset;
-
-		if (list >= end)
-			BUG("too many large-offset objects");
-
-		obj = list++;
-		offset = obj->offset;
-
-		if (!(offset >> 31))
-			continue;
-
-		hashwrite_be64(f, offset);
-
-		nr_large_offset--;
-	}
-
-	return 0;
-}
-
-static int write_midx_revindex(struct hashfile *f,
-			       void *data)
-{
-	struct write_midx_context *ctx = data;
-	uint32_t i;
-
-	for (i = 0; i < ctx->entries_nr; i++)
-		hashwrite_be32(f, ctx->pack_order[i]);
-
-	return 0;
-}
-
-struct midx_pack_order_data {
-	uint32_t nr;
-	uint32_t pack;
-	off_t offset;
-};
-
-static int midx_pack_order_cmp(const void *va, const void *vb)
-{
-	const struct midx_pack_order_data *a = va, *b = vb;
-	if (a->pack < b->pack)
-		return -1;
-	else if (a->pack > b->pack)
-		return 1;
-	else if (a->offset < b->offset)
-		return -1;
-	else if (a->offset > b->offset)
-		return 1;
-	else
-		return 0;
-}
-
-static uint32_t *midx_pack_order(struct write_midx_context *ctx)
-{
-	struct midx_pack_order_data *data;
-	uint32_t *pack_order;
-	uint32_t i;
-
-	trace2_region_enter("midx", "midx_pack_order", the_repository);
-
-	ALLOC_ARRAY(data, ctx->entries_nr);
-	for (i = 0; i < ctx->entries_nr; i++) {
-		struct pack_midx_entry *e = &ctx->entries[i];
-		data[i].nr = i;
-		data[i].pack = ctx->pack_perm[e->pack_int_id];
-		if (!e->preferred)
-			data[i].pack |= (1U << 31);
-		data[i].offset = e->offset;
-	}
-
-	QSORT(data, ctx->entries_nr, midx_pack_order_cmp);
-
-	ALLOC_ARRAY(pack_order, ctx->entries_nr);
-	for (i = 0; i < ctx->entries_nr; i++)
-		pack_order[i] = data[i].nr;
-	free(data);
-
-	trace2_region_leave("midx", "midx_pack_order", the_repository);
-
-	return pack_order;
-}
-
-static void write_midx_reverse_index(char *midx_name, unsigned char *midx_hash,
-				     struct write_midx_context *ctx)
-{
-	struct strbuf buf = STRBUF_INIT;
-	const char *tmp_file;
-
-	trace2_region_enter("midx", "write_midx_reverse_index", the_repository);
-
-	strbuf_addf(&buf, "%s-%s.rev", midx_name, hash_to_hex(midx_hash));
-
-	tmp_file = write_rev_file_order(NULL, ctx->pack_order, ctx->entries_nr,
-					midx_hash, WRITE_REV);
-
-	if (finalize_object_file(tmp_file, buf.buf))
-		die(_("cannot store reverse index file"));
-
-	strbuf_release(&buf);
-
-	trace2_region_leave("midx", "write_midx_reverse_index", the_repository);
-}
-
-static void clear_midx_files_ext(const char *object_dir, const char *ext,
-				 unsigned char *keep_hash);
-
-static int midx_checksum_valid(struct multi_pack_index *m)
+int midx_checksum_valid(struct multi_pack_index *m)
 {
 	return hashfile_checksum_valid(m->data, m->data_len);
 }
 
-static void prepare_midx_packing_data(struct packing_data *pdata,
-				      struct write_midx_context *ctx)
-{
-	uint32_t i;
-
-	trace2_region_enter("midx", "prepare_midx_packing_data", the_repository);
-
-	memset(pdata, 0, sizeof(struct packing_data));
-	prepare_packing_data(the_repository, pdata);
-
-	for (i = 0; i < ctx->entries_nr; i++) {
-		struct pack_midx_entry *from = &ctx->entries[ctx->pack_order[i]];
-		struct object_entry *to = packlist_alloc(pdata, &from->oid);
-
-		oe_set_in_pack(pdata, to,
-			       ctx->info[ctx->pack_perm[from->pack_int_id]].p);
-	}
-
-	trace2_region_leave("midx", "prepare_midx_packing_data", the_repository);
-}
-
-static int add_ref_to_pending(const char *refname,
-			      const struct object_id *oid,
-			      int flag, void *cb_data)
-{
-	struct rev_info *revs = (struct rev_info*)cb_data;
-	struct object_id peeled;
-	struct object *object;
-
-	if ((flag & REF_ISSYMREF) && (flag & REF_ISBROKEN)) {
-		warning("symbolic ref is dangling: %s", refname);
-		return 0;
-	}
-
-	if (!peel_iterated_oid(oid, &peeled))
-		oid = &peeled;
-
-	object = parse_object_or_die(oid, refname);
-	if (object->type != OBJ_COMMIT)
-		return 0;
-
-	add_pending_object(revs, object, "");
-	if (bitmap_is_preferred_refname(revs->repo, refname))
-		object->flags |= NEEDS_BITMAP;
-	return 0;
-}
-
-struct bitmap_commit_cb {
-	struct commit **commits;
-	size_t commits_nr, commits_alloc;
-
-	struct write_midx_context *ctx;
-};
-
-static const struct object_id *bitmap_oid_access(size_t index,
-						 const void *_entries)
-{
-	const struct pack_midx_entry *entries = _entries;
-	return &entries[index].oid;
-}
-
-static void bitmap_show_commit(struct commit *commit, void *_data)
-{
-	struct bitmap_commit_cb *data = _data;
-	int pos = oid_pos(&commit->object.oid, data->ctx->entries,
-			  data->ctx->entries_nr,
-			  bitmap_oid_access);
-	if (pos < 0)
-		return;
-
-	ALLOC_GROW(data->commits, data->commits_nr + 1, data->commits_alloc);
-	data->commits[data->commits_nr++] = commit;
-}
-
-static int read_refs_snapshot(const char *refs_snapshot,
-			      struct rev_info *revs)
-{
-	struct strbuf buf = STRBUF_INIT;
-	struct object_id oid;
-	FILE *f = xfopen(refs_snapshot, "r");
-
-	while (strbuf_getline(&buf, f) != EOF) {
-		struct object *object;
-		int preferred = 0;
-		char *hex = buf.buf;
-		const char *end = NULL;
-
-		if (buf.len && *buf.buf == '+') {
-			preferred = 1;
-			hex = &buf.buf[1];
-		}
-
-		if (parse_oid_hex(hex, &oid, &end) < 0)
-			die(_("could not parse line: %s"), buf.buf);
-		if (*end)
-			die(_("malformed line: %s"), buf.buf);
-
-		object = parse_object_or_die(&oid, NULL);
-		if (preferred)
-			object->flags |= NEEDS_BITMAP;
-
-		add_pending_object(revs, object, "");
-	}
-
-	fclose(f);
-	strbuf_release(&buf);
-	return 0;
-}
-
-static struct commit **find_commits_for_midx_bitmap(uint32_t *indexed_commits_nr_p,
-						    const char *refs_snapshot,
-						    struct write_midx_context *ctx)
-{
-	struct rev_info revs;
-	struct bitmap_commit_cb cb = {0};
-
-	trace2_region_enter("midx", "find_commits_for_midx_bitmap",
-			    the_repository);
-
-	cb.ctx = ctx;
-
-	repo_init_revisions(the_repository, &revs, NULL);
-	if (refs_snapshot) {
-		read_refs_snapshot(refs_snapshot, &revs);
-	} else {
-		setup_revisions(0, NULL, &revs, NULL);
-		for_each_ref(add_ref_to_pending, &revs);
-	}
-
-	/*
-	 * Skipping promisor objects here is intentional, since it only excludes
-	 * them from the list of reachable commits that we want to select from
-	 * when computing the selection of MIDX'd commits to receive bitmaps.
-	 *
-	 * Reachability bitmaps do require that their objects be closed under
-	 * reachability, but fetching any objects missing from promisors at this
-	 * point is too late. But, if one of those objects can be reached from
-	 * an another object that is included in the bitmap, then we will
-	 * complain later that we don't have reachability closure (and fail
-	 * appropriately).
-	 */
-	fetch_if_missing = 0;
-	revs.exclude_promisor_objects = 1;
-
-	if (prepare_revision_walk(&revs))
-		die(_("revision walk setup failed"));
-
-	traverse_commit_list(&revs, bitmap_show_commit, NULL, &cb);
-	if (indexed_commits_nr_p)
-		*indexed_commits_nr_p = cb.commits_nr;
-
-	release_revisions(&revs);
-
-	trace2_region_leave("midx", "find_commits_for_midx_bitmap",
-			    the_repository);
-
-	return cb.commits;
-}
-
-static int write_midx_bitmap(const char *midx_name,
-			     const unsigned char *midx_hash,
-			     struct packing_data *pdata,
-			     struct commit **commits,
-			     uint32_t commits_nr,
-			     uint32_t *pack_order,
-			     unsigned flags)
-{
-	int ret, i;
-	uint16_t options = 0;
-	struct pack_idx_entry **index;
-	char *bitmap_name = xstrfmt("%s-%s.bitmap", midx_name,
-					hash_to_hex(midx_hash));
-
-	trace2_region_enter("midx", "write_midx_bitmap", the_repository);
-
-	if (flags & MIDX_WRITE_BITMAP_HASH_CACHE)
-		options |= BITMAP_OPT_HASH_CACHE;
-
-	if (flags & MIDX_WRITE_BITMAP_LOOKUP_TABLE)
-		options |= BITMAP_OPT_LOOKUP_TABLE;
-
-	/*
-	 * Build the MIDX-order index based on pdata.objects (which is already
-	 * in MIDX order; c.f., 'midx_pack_order_cmp()' for the definition of
-	 * this order).
-	 */
-	ALLOC_ARRAY(index, pdata->nr_objects);
-	for (i = 0; i < pdata->nr_objects; i++)
-		index[i] = &pdata->objects[i].idx;
-
-	bitmap_writer_show_progress(flags & MIDX_PROGRESS);
-	bitmap_writer_build_type_index(pdata, index, pdata->nr_objects);
-
-	/*
-	 * bitmap_writer_finish expects objects in lex order, but pack_order
-	 * gives us exactly that. use it directly instead of re-sorting the
-	 * array.
-	 *
-	 * This changes the order of objects in 'index' between
-	 * bitmap_writer_build_type_index and bitmap_writer_finish.
-	 *
-	 * The same re-ordering takes place in the single-pack bitmap code via
-	 * write_idx_file(), which is called by finish_tmp_packfile(), which
-	 * happens between bitmap_writer_build_type_index() and
-	 * bitmap_writer_finish().
-	 */
-	for (i = 0; i < pdata->nr_objects; i++)
-		index[pack_order[i]] = &pdata->objects[i].idx;
-
-	bitmap_writer_select_commits(commits, commits_nr, -1);
-	ret = bitmap_writer_build(pdata);
-	if (ret < 0)
-		goto cleanup;
-
-	bitmap_writer_set_checksum(midx_hash);
-	bitmap_writer_finish(index, pdata->nr_objects, bitmap_name, options);
-
-cleanup:
-	free(index);
-	free(bitmap_name);
-
-	trace2_region_leave("midx", "write_midx_bitmap", the_repository);
-
-	return ret;
-}
-
-static struct multi_pack_index *lookup_multi_pack_index(struct repository *r,
-							const char *object_dir)
-{
-	struct multi_pack_index *result = NULL;
-	struct multi_pack_index *cur;
-	char *obj_dir_real = real_pathdup(object_dir, 1);
-	struct strbuf cur_path_real = STRBUF_INIT;
-
-	/* Ensure the given object_dir is local, or a known alternate. */
-	find_odb(r, obj_dir_real);
-
-	for (cur = get_multi_pack_index(r); cur; cur = cur->next) {
-		strbuf_realpath(&cur_path_real, cur->object_dir, 1);
-		if (!strcmp(obj_dir_real, cur_path_real.buf)) {
-			result = cur;
-			goto cleanup;
-		}
-	}
-
-cleanup:
-	free(obj_dir_real);
-	strbuf_release(&cur_path_real);
-	return result;
-}
-
-static int write_midx_internal(const char *object_dir,
-			       struct string_list *packs_to_include,
-			       struct string_list *packs_to_drop,
-			       const char *preferred_pack_name,
-			       const char *refs_snapshot,
-			       unsigned flags)
-{
-	struct strbuf midx_name = STRBUF_INIT;
-	unsigned char midx_hash[GIT_MAX_RAWSZ];
-	uint32_t i;
-	struct hashfile *f = NULL;
-	struct lock_file lk;
-	struct write_midx_context ctx = { 0 };
-	int pack_name_concat_len = 0;
-	int dropped_packs = 0;
-	int result = 0;
-	struct chunkfile *cf;
-
-	trace2_region_enter("midx", "write_midx_internal", the_repository);
-
-	get_midx_filename(&midx_name, object_dir);
-	if (safe_create_leading_directories(midx_name.buf))
-		die_errno(_("unable to create leading directories of %s"),
-			  midx_name.buf);
-
-	if (!packs_to_include) {
-		/*
-		 * Only reference an existing MIDX when not filtering which
-		 * packs to include, since all packs and objects are copied
-		 * blindly from an existing MIDX if one is present.
-		 */
-		ctx.m = lookup_multi_pack_index(the_repository, object_dir);
-	}
-
-	if (ctx.m && !midx_checksum_valid(ctx.m)) {
-		warning(_("ignoring existing multi-pack-index; checksum mismatch"));
-		ctx.m = NULL;
-	}
-
-	ctx.nr = 0;
-	ctx.alloc = ctx.m ? ctx.m->num_packs : 16;
-	ctx.info = NULL;
-	ALLOC_ARRAY(ctx.info, ctx.alloc);
-
-	if (ctx.m) {
-		for (i = 0; i < ctx.m->num_packs; i++) {
-			ALLOC_GROW(ctx.info, ctx.nr + 1, ctx.alloc);
-
-			ctx.info[ctx.nr].orig_pack_int_id = i;
-			ctx.info[ctx.nr].pack_name = xstrdup(ctx.m->pack_names[i]);
-			ctx.info[ctx.nr].p = ctx.m->packs[i];
-			ctx.info[ctx.nr].expired = 0;
-
-			if (flags & MIDX_WRITE_REV_INDEX) {
-				/*
-				 * If generating a reverse index, need to have
-				 * packed_git's loaded to compare their
-				 * mtimes and object count.
-				 */
-				if (prepare_midx_pack(the_repository, ctx.m, i)) {
-					error(_("could not load pack"));
-					result = 1;
-					goto cleanup;
-				}
-
-				if (open_pack_index(ctx.m->packs[i]))
-					die(_("could not open index for %s"),
-					    ctx.m->packs[i]->pack_name);
-				ctx.info[ctx.nr].p = ctx.m->packs[i];
-			}
-
-			ctx.nr++;
-		}
-	}
-
-	ctx.pack_paths_checked = 0;
-	if (flags & MIDX_PROGRESS)
-		ctx.progress = start_delayed_progress(_("Adding packfiles to multi-pack-index"), 0);
-	else
-		ctx.progress = NULL;
-
-	ctx.to_include = packs_to_include;
-
-	for_each_file_in_pack_dir(object_dir, add_pack_to_midx, &ctx);
-	stop_progress(&ctx.progress);
-
-	if ((ctx.m && ctx.nr == ctx.m->num_packs) &&
-	    !(packs_to_include || packs_to_drop)) {
-		struct bitmap_index *bitmap_git;
-		int bitmap_exists;
-		int want_bitmap = flags & MIDX_WRITE_BITMAP;
-
-		bitmap_git = prepare_midx_bitmap_git(ctx.m);
-		bitmap_exists = bitmap_git && bitmap_is_midx(bitmap_git);
-		free_bitmap_index(bitmap_git);
-
-		if (bitmap_exists || !want_bitmap) {
-			/*
-			 * The correct MIDX already exists, and so does a
-			 * corresponding bitmap (or one wasn't requested).
-			 */
-			if (!want_bitmap)
-				clear_midx_files_ext(object_dir, ".bitmap",
-						     NULL);
-			goto cleanup;
-		}
-	}
-
-	if (preferred_pack_name) {
-		ctx.preferred_pack_idx = -1;
-
-		for (i = 0; i < ctx.nr; i++) {
-			if (!cmp_idx_or_pack_name(preferred_pack_name,
-						  ctx.info[i].pack_name)) {
-				ctx.preferred_pack_idx = i;
-				break;
-			}
-		}
-
-		if (ctx.preferred_pack_idx == -1)
-			warning(_("unknown preferred pack: '%s'"),
-				preferred_pack_name);
-	} else if (ctx.nr &&
-		   (flags & (MIDX_WRITE_REV_INDEX | MIDX_WRITE_BITMAP))) {
-		struct packed_git *oldest = ctx.info[ctx.preferred_pack_idx].p;
-		ctx.preferred_pack_idx = 0;
-
-		if (packs_to_drop && packs_to_drop->nr)
-			BUG("cannot write a MIDX bitmap during expiration");
-
-		/*
-		 * set a preferred pack when writing a bitmap to ensure that
-		 * the pack from which the first object is selected in pseudo
-		 * pack-order has all of its objects selected from that pack
-		 * (and not another pack containing a duplicate)
-		 */
-		for (i = 1; i < ctx.nr; i++) {
-			struct packed_git *p = ctx.info[i].p;
-
-			if (!oldest->num_objects || p->mtime < oldest->mtime) {
-				oldest = p;
-				ctx.preferred_pack_idx = i;
-			}
-		}
-
-		if (!oldest->num_objects) {
-			/*
-			 * If all packs are empty; unset the preferred index.
-			 * This is acceptable since there will be no duplicate
-			 * objects to resolve, so the preferred value doesn't
-			 * matter.
-			 */
-			ctx.preferred_pack_idx = -1;
-		}
-	} else {
-		/*
-		 * otherwise don't mark any pack as preferred to avoid
-		 * interfering with expiration logic below
-		 */
-		ctx.preferred_pack_idx = -1;
-	}
-
-	if (ctx.preferred_pack_idx > -1) {
-		struct packed_git *preferred = ctx.info[ctx.preferred_pack_idx].p;
-		if (!preferred->num_objects) {
-			error(_("cannot select preferred pack %s with no objects"),
-			      preferred->pack_name);
-			result = 1;
-			goto cleanup;
-		}
-	}
-
-	ctx.entries = get_sorted_entries(ctx.m, ctx.info, ctx.nr, &ctx.entries_nr,
-					 ctx.preferred_pack_idx);
-
-	ctx.large_offsets_needed = 0;
-	for (i = 0; i < ctx.entries_nr; i++) {
-		if (ctx.entries[i].offset > 0x7fffffff)
-			ctx.num_large_offsets++;
-		if (ctx.entries[i].offset > 0xffffffff)
-			ctx.large_offsets_needed = 1;
-	}
-
-	QSORT(ctx.info, ctx.nr, pack_info_compare);
-
-	if (packs_to_drop && packs_to_drop->nr) {
-		int drop_index = 0;
-		int missing_drops = 0;
-
-		for (i = 0; i < ctx.nr && drop_index < packs_to_drop->nr; i++) {
-			int cmp = strcmp(ctx.info[i].pack_name,
-					 packs_to_drop->items[drop_index].string);
-
-			if (!cmp) {
-				drop_index++;
-				ctx.info[i].expired = 1;
-			} else if (cmp > 0) {
-				error(_("did not see pack-file %s to drop"),
-				      packs_to_drop->items[drop_index].string);
-				drop_index++;
-				missing_drops++;
-				i--;
-			} else {
-				ctx.info[i].expired = 0;
-			}
-		}
-
-		if (missing_drops) {
-			result = 1;
-			goto cleanup;
-		}
-	}
-
-	/*
-	 * pack_perm stores a permutation between pack-int-ids from the
-	 * previous multi-pack-index to the new one we are writing:
-	 *
-	 * pack_perm[old_id] = new_id
-	 */
-	ALLOC_ARRAY(ctx.pack_perm, ctx.nr);
-	for (i = 0; i < ctx.nr; i++) {
-		if (ctx.info[i].expired) {
-			dropped_packs++;
-			ctx.pack_perm[ctx.info[i].orig_pack_int_id] = PACK_EXPIRED;
-		} else {
-			ctx.pack_perm[ctx.info[i].orig_pack_int_id] = i - dropped_packs;
-		}
-	}
-
-	for (i = 0; i < ctx.nr; i++) {
-		if (!ctx.info[i].expired)
-			pack_name_concat_len += strlen(ctx.info[i].pack_name) + 1;
-	}
-
-	/* Check that the preferred pack wasn't expired (if given). */
-	if (preferred_pack_name) {
-		struct pack_info *preferred = bsearch(preferred_pack_name,
-						      ctx.info, ctx.nr,
-						      sizeof(*ctx.info),
-						      idx_or_pack_name_cmp);
-		if (preferred) {
-			uint32_t perm = ctx.pack_perm[preferred->orig_pack_int_id];
-			if (perm == PACK_EXPIRED)
-				warning(_("preferred pack '%s' is expired"),
-					preferred_pack_name);
-		}
-	}
-
-	if (pack_name_concat_len % MIDX_CHUNK_ALIGNMENT)
-		pack_name_concat_len += MIDX_CHUNK_ALIGNMENT -
-					(pack_name_concat_len % MIDX_CHUNK_ALIGNMENT);
-
-	hold_lock_file_for_update(&lk, midx_name.buf, LOCK_DIE_ON_ERROR);
-	f = hashfd(get_lock_file_fd(&lk), get_lock_file_path(&lk));
-
-	if (ctx.nr - dropped_packs == 0) {
-		error(_("no pack files to index."));
-		result = 1;
-		goto cleanup;
-	}
-
-	if (!ctx.entries_nr) {
-		if (flags & MIDX_WRITE_BITMAP)
-			warning(_("refusing to write multi-pack .bitmap without any objects"));
-		flags &= ~(MIDX_WRITE_REV_INDEX | MIDX_WRITE_BITMAP);
-	}
-
-	cf = init_chunkfile(f);
-
-	add_chunk(cf, MIDX_CHUNKID_PACKNAMES, pack_name_concat_len,
-		  write_midx_pack_names);
-	add_chunk(cf, MIDX_CHUNKID_OIDFANOUT, MIDX_CHUNK_FANOUT_SIZE,
-		  write_midx_oid_fanout);
-	add_chunk(cf, MIDX_CHUNKID_OIDLOOKUP,
-		  st_mult(ctx.entries_nr, the_hash_algo->rawsz),
-		  write_midx_oid_lookup);
-	add_chunk(cf, MIDX_CHUNKID_OBJECTOFFSETS,
-		  st_mult(ctx.entries_nr, MIDX_CHUNK_OFFSET_WIDTH),
-		  write_midx_object_offsets);
-
-	if (ctx.large_offsets_needed)
-		add_chunk(cf, MIDX_CHUNKID_LARGEOFFSETS,
-			st_mult(ctx.num_large_offsets,
-				MIDX_CHUNK_LARGE_OFFSET_WIDTH),
-			write_midx_large_offsets);
-
-	if (flags & (MIDX_WRITE_REV_INDEX | MIDX_WRITE_BITMAP)) {
-		ctx.pack_order = midx_pack_order(&ctx);
-		add_chunk(cf, MIDX_CHUNKID_REVINDEX,
-			  st_mult(ctx.entries_nr, sizeof(uint32_t)),
-			  write_midx_revindex);
-	}
-
-	write_midx_header(f, get_num_chunks(cf), ctx.nr - dropped_packs);
-	write_chunkfile(cf, &ctx);
-
-	finalize_hashfile(f, midx_hash, FSYNC_COMPONENT_PACK_METADATA,
-			  CSUM_FSYNC | CSUM_HASH_IN_STREAM);
-	free_chunkfile(cf);
-
-	if (flags & MIDX_WRITE_REV_INDEX &&
-	    git_env_bool("GIT_TEST_MIDX_WRITE_REV", 0))
-		write_midx_reverse_index(midx_name.buf, midx_hash, &ctx);
-
-	if (flags & MIDX_WRITE_BITMAP) {
-		struct packing_data pdata;
-		struct commit **commits;
-		uint32_t commits_nr;
-
-		if (!ctx.entries_nr)
-			BUG("cannot write a bitmap without any objects");
-
-		prepare_midx_packing_data(&pdata, &ctx);
-
-		commits = find_commits_for_midx_bitmap(&commits_nr, refs_snapshot, &ctx);
-
-		/*
-		 * The previous steps translated the information from
-		 * 'entries' into information suitable for constructing
-		 * bitmaps. We no longer need that array, so clear it to
-		 * reduce memory pressure.
-		 */
-		FREE_AND_NULL(ctx.entries);
-		ctx.entries_nr = 0;
-
-		if (write_midx_bitmap(midx_name.buf, midx_hash, &pdata,
-				      commits, commits_nr, ctx.pack_order,
-				      flags) < 0) {
-			error(_("could not write multi-pack bitmap"));
-			result = 1;
-			goto cleanup;
-		}
-	}
-	/*
-	 * NOTE: Do not use ctx.entries beyond this point, since it might
-	 * have been freed in the previous if block.
-	 */
-
-	if (ctx.m)
-		close_object_store(the_repository->objects);
-
-	if (commit_lock_file(&lk) < 0)
-		die_errno(_("could not write multi-pack-index"));
-
-	clear_midx_files_ext(object_dir, ".bitmap", midx_hash);
-	clear_midx_files_ext(object_dir, ".rev", midx_hash);
-
-cleanup:
-	for (i = 0; i < ctx.nr; i++) {
-		if (ctx.info[i].p) {
-			close_pack(ctx.info[i].p);
-			free(ctx.info[i].p);
-		}
-		free(ctx.info[i].pack_name);
-	}
-
-	free(ctx.info);
-	free(ctx.entries);
-	free(ctx.pack_perm);
-	free(ctx.pack_order);
-	strbuf_release(&midx_name);
-
-	trace2_region_leave("midx", "write_midx_internal", the_repository);
-
-	return result;
-}
-
-int write_midx_file(const char *object_dir,
-		    const char *preferred_pack_name,
-		    const char *refs_snapshot,
-		    unsigned flags)
-{
-	return write_midx_internal(object_dir, NULL, NULL, preferred_pack_name,
-				   refs_snapshot, flags);
-}
-
-int write_midx_file_only(const char *object_dir,
-			 struct string_list *packs_to_include,
-			 const char *preferred_pack_name,
-			 const char *refs_snapshot,
-			 unsigned flags)
-{
-	return write_midx_internal(object_dir, packs_to_include, NULL,
-				   preferred_pack_name, refs_snapshot, flags);
-}
-
 struct clear_midx_data {
 	char *keep;
 	const char *ext;
@@ -1668,8 +508,8 @@ static void clear_midx_file_ext(const char *full_path, size_t full_path_len UNUS
 		die_errno(_("failed to remove %s"), full_path);
 }
 
-static void clear_midx_files_ext(const char *object_dir, const char *ext,
-				 unsigned char *keep_hash)
+void clear_midx_files_ext(const char *object_dir, const char *ext,
+			  unsigned char *keep_hash)
 {
 	struct clear_midx_data data;
 	memset(&data, 0, sizeof(struct clear_midx_data));
@@ -1782,15 +622,6 @@ int verify_midx_file(struct repository *r, const char *object_dir, unsigned flag
 	}
 	stop_progress(&progress);
 
-	for (i = 0; i < 255; i++) {
-		uint32_t oid_fanout1 = ntohl(m->chunk_oid_fanout[i]);
-		uint32_t oid_fanout2 = ntohl(m->chunk_oid_fanout[i + 1]);
-
-		if (oid_fanout1 > oid_fanout2)
-			midx_report(_("oid fanout out of order: fanout[%d] = %"PRIx32" > %"PRIx32" = fanout[%d]"),
-				    i, oid_fanout1, oid_fanout2, i + 1);
-	}
-
 	if (m->num_objects == 0) {
 		midx_report(_("the midx contains no oid"));
 		/*
@@ -1881,256 +712,3 @@ int verify_midx_file(struct repository *r, const char *object_dir, unsigned flag
 
 	return verify_midx_error;
 }
-
-int expire_midx_packs(struct repository *r, const char *object_dir, unsigned flags)
-{
-	uint32_t i, *count, result = 0;
-	struct string_list packs_to_drop = STRING_LIST_INIT_DUP;
-	struct multi_pack_index *m = lookup_multi_pack_index(r, object_dir);
-	struct progress *progress = NULL;
-
-	if (!m)
-		return 0;
-
-	CALLOC_ARRAY(count, m->num_packs);
-
-	if (flags & MIDX_PROGRESS)
-		progress = start_delayed_progress(_("Counting referenced objects"),
-					  m->num_objects);
-	for (i = 0; i < m->num_objects; i++) {
-		int pack_int_id = nth_midxed_pack_int_id(m, i);
-		count[pack_int_id]++;
-		display_progress(progress, i + 1);
-	}
-	stop_progress(&progress);
-
-	if (flags & MIDX_PROGRESS)
-		progress = start_delayed_progress(_("Finding and deleting unreferenced packfiles"),
-					  m->num_packs);
-	for (i = 0; i < m->num_packs; i++) {
-		char *pack_name;
-		display_progress(progress, i + 1);
-
-		if (count[i])
-			continue;
-
-		if (prepare_midx_pack(r, m, i))
-			continue;
-
-		if (m->packs[i]->pack_keep || m->packs[i]->is_cruft)
-			continue;
-
-		pack_name = xstrdup(m->packs[i]->pack_name);
-		close_pack(m->packs[i]);
-
-		string_list_insert(&packs_to_drop, m->pack_names[i]);
-		unlink_pack_path(pack_name, 0);
-		free(pack_name);
-	}
-	stop_progress(&progress);
-
-	free(count);
-
-	if (packs_to_drop.nr)
-		result = write_midx_internal(object_dir, NULL, &packs_to_drop, NULL, NULL, flags);
-
-	string_list_clear(&packs_to_drop, 0);
-
-	return result;
-}
-
-struct repack_info {
-	timestamp_t mtime;
-	uint32_t referenced_objects;
-	uint32_t pack_int_id;
-};
-
-static int compare_by_mtime(const void *a_, const void *b_)
-{
-	const struct repack_info *a, *b;
-
-	a = (const struct repack_info *)a_;
-	b = (const struct repack_info *)b_;
-
-	if (a->mtime < b->mtime)
-		return -1;
-	if (a->mtime > b->mtime)
-		return 1;
-	return 0;
-}
-
-static int fill_included_packs_all(struct repository *r,
-				   struct multi_pack_index *m,
-				   unsigned char *include_pack)
-{
-	uint32_t i, count = 0;
-	int pack_kept_objects = 0;
-
-	repo_config_get_bool(r, "repack.packkeptobjects", &pack_kept_objects);
-
-	for (i = 0; i < m->num_packs; i++) {
-		if (prepare_midx_pack(r, m, i))
-			continue;
-		if (!pack_kept_objects && m->packs[i]->pack_keep)
-			continue;
-		if (m->packs[i]->is_cruft)
-			continue;
-
-		include_pack[i] = 1;
-		count++;
-	}
-
-	return count < 2;
-}
-
-static int fill_included_packs_batch(struct repository *r,
-				     struct multi_pack_index *m,
-				     unsigned char *include_pack,
-				     size_t batch_size)
-{
-	uint32_t i, packs_to_repack;
-	size_t total_size;
-	struct repack_info *pack_info;
-	int pack_kept_objects = 0;
-
-	CALLOC_ARRAY(pack_info, m->num_packs);
-
-	repo_config_get_bool(r, "repack.packkeptobjects", &pack_kept_objects);
-
-	for (i = 0; i < m->num_packs; i++) {
-		pack_info[i].pack_int_id = i;
-
-		if (prepare_midx_pack(r, m, i))
-			continue;
-
-		pack_info[i].mtime = m->packs[i]->mtime;
-	}
-
-	for (i = 0; i < m->num_objects; i++) {
-		uint32_t pack_int_id = nth_midxed_pack_int_id(m, i);
-		pack_info[pack_int_id].referenced_objects++;
-	}
-
-	QSORT(pack_info, m->num_packs, compare_by_mtime);
-
-	total_size = 0;
-	packs_to_repack = 0;
-	for (i = 0; total_size < batch_size && i < m->num_packs; i++) {
-		int pack_int_id = pack_info[i].pack_int_id;
-		struct packed_git *p = m->packs[pack_int_id];
-		size_t expected_size;
-
-		if (!p)
-			continue;
-		if (!pack_kept_objects && p->pack_keep)
-			continue;
-		if (p->is_cruft)
-			continue;
-		if (open_pack_index(p) || !p->num_objects)
-			continue;
-
-		expected_size = st_mult(p->pack_size,
-					pack_info[i].referenced_objects);
-		expected_size /= p->num_objects;
-
-		if (expected_size >= batch_size)
-			continue;
-
-		packs_to_repack++;
-		total_size += expected_size;
-		include_pack[pack_int_id] = 1;
-	}
-
-	free(pack_info);
-
-	if (packs_to_repack < 2)
-		return 1;
-
-	return 0;
-}
-
-int midx_repack(struct repository *r, const char *object_dir, size_t batch_size, unsigned flags)
-{
-	int result = 0;
-	uint32_t i;
-	unsigned char *include_pack;
-	struct child_process cmd = CHILD_PROCESS_INIT;
-	FILE *cmd_in;
-	struct strbuf base_name = STRBUF_INIT;
-	struct multi_pack_index *m = lookup_multi_pack_index(r, object_dir);
-
-	/*
-	 * When updating the default for these configuration
-	 * variables in builtin/repack.c, these must be adjusted
-	 * to match.
-	 */
-	int delta_base_offset = 1;
-	int use_delta_islands = 0;
-
-	if (!m)
-		return 0;
-
-	CALLOC_ARRAY(include_pack, m->num_packs);
-
-	if (batch_size) {
-		if (fill_included_packs_batch(r, m, include_pack, batch_size))
-			goto cleanup;
-	} else if (fill_included_packs_all(r, m, include_pack))
-		goto cleanup;
-
-	repo_config_get_bool(r, "repack.usedeltabaseoffset", &delta_base_offset);
-	repo_config_get_bool(r, "repack.usedeltaislands", &use_delta_islands);
-
-	strvec_push(&cmd.args, "pack-objects");
-
-	strbuf_addstr(&base_name, object_dir);
-	strbuf_addstr(&base_name, "/pack/pack");
-	strvec_push(&cmd.args, base_name.buf);
-
-	if (delta_base_offset)
-		strvec_push(&cmd.args, "--delta-base-offset");
-	if (use_delta_islands)
-		strvec_push(&cmd.args, "--delta-islands");
-
-	if (flags & MIDX_PROGRESS)
-		strvec_push(&cmd.args, "--progress");
-	else
-		strvec_push(&cmd.args, "-q");
-
-	strbuf_release(&base_name);
-
-	cmd.git_cmd = 1;
-	cmd.in = cmd.out = -1;
-
-	if (start_command(&cmd)) {
-		error(_("could not start pack-objects"));
-		result = 1;
-		goto cleanup;
-	}
-
-	cmd_in = xfdopen(cmd.in, "w");
-
-	for (i = 0; i < m->num_objects; i++) {
-		struct object_id oid;
-		uint32_t pack_int_id = nth_midxed_pack_int_id(m, i);
-
-		if (!include_pack[pack_int_id])
-			continue;
-
-		nth_midxed_object_oid(&oid, m, i);
-		fprintf(cmd_in, "%s\n", oid_to_hex(&oid));
-	}
-	fclose(cmd_in);
-
-	if (finish_command(&cmd)) {
-		error(_("could not finish pack-objects"));
-		result = 1;
-		goto cleanup;
-	}
-
-	result = write_midx_internal(object_dir, NULL, NULL, NULL, NULL, flags);
-
-cleanup:
-	free(include_pack);
-	return result;
-}
diff --git a/midx.h b/midx.h
index eb57a37..dc477df 100644
--- a/midx.h
+++ b/midx.h
@@ -6,6 +6,26 @@
 struct object_id;
 struct pack_entry;
 struct repository;
+struct bitmapped_pack;
+
+#define MIDX_SIGNATURE 0x4d494458 /* "MIDX" */
+#define MIDX_VERSION 1
+#define MIDX_BYTE_FILE_VERSION 4
+#define MIDX_BYTE_HASH_VERSION 5
+#define MIDX_BYTE_NUM_CHUNKS 6
+#define MIDX_BYTE_NUM_PACKS 8
+#define MIDX_HEADER_SIZE 12
+
+#define MIDX_CHUNK_ALIGNMENT 4
+#define MIDX_CHUNKID_PACKNAMES 0x504e414d /* "PNAM" */
+#define MIDX_CHUNKID_BITMAPPEDPACKS 0x42544d50 /* "BTMP" */
+#define MIDX_CHUNKID_OIDFANOUT 0x4f494446 /* "OIDF" */
+#define MIDX_CHUNKID_OIDLOOKUP 0x4f49444c /* "OIDL" */
+#define MIDX_CHUNKID_OBJECTOFFSETS 0x4f4f4646 /* "OOFF" */
+#define MIDX_CHUNKID_LARGEOFFSETS 0x4c4f4646 /* "LOFF" */
+#define MIDX_CHUNKID_REVINDEX 0x52494458 /* "RIDX" */
+#define MIDX_CHUNK_OFFSET_WIDTH (2 * sizeof(uint32_t))
+#define MIDX_LARGE_OFFSET_NEEDED 0x80000000
 
 #define GIT_TEST_MULTI_PACK_INDEX "GIT_TEST_MULTI_PACK_INDEX"
 #define GIT_TEST_MULTI_PACK_INDEX_WRITE_BITMAP \
@@ -27,11 +47,14 @@ struct multi_pack_index {
 	unsigned char num_chunks;
 	uint32_t num_packs;
 	uint32_t num_objects;
+	int preferred_pack_idx;
 
 	int local;
 
 	const unsigned char *chunk_pack_names;
 	size_t chunk_pack_names_len;
+	const uint32_t *chunk_bitmapped_packs;
+	size_t chunk_bitmapped_packs_len;
 	const uint32_t *chunk_oid_fanout;
 	const unsigned char *chunk_oid_lookup;
 	const unsigned char *chunk_object_offsets;
@@ -57,6 +80,8 @@ void get_midx_rev_filename(struct strbuf *out, struct multi_pack_index *m);
 
 struct multi_pack_index *load_multi_pack_index(const char *object_dir, int local);
 int prepare_midx_pack(struct repository *r, struct multi_pack_index *m, uint32_t pack_int_id);
+int nth_bitmapped_pack(struct repository *r, struct multi_pack_index *m,
+		       struct bitmapped_pack *bp, uint32_t pack_int_id);
 int bsearch_midx(const struct object_id *oid, struct multi_pack_index *m, uint32_t *result);
 off_t nth_midxed_offset(struct multi_pack_index *m, uint32_t pos);
 uint32_t nth_midxed_pack_int_id(struct multi_pack_index *m, uint32_t pos);
@@ -64,7 +89,11 @@ struct object_id *nth_midxed_object_oid(struct object_id *oid,
 					struct multi_pack_index *m,
 					uint32_t n);
 int fill_midx_entry(struct repository *r, const struct object_id *oid, struct pack_entry *e, struct multi_pack_index *m);
-int midx_contains_pack(struct multi_pack_index *m, const char *idx_or_pack_name);
+int midx_contains_pack(struct multi_pack_index *m,
+		       const char *idx_or_pack_name);
+int midx_locate_pack(struct multi_pack_index *m, const char *idx_or_pack_name,
+		     uint32_t *pos);
+int midx_preferred_pack(struct multi_pack_index *m, uint32_t *pack_int_id);
 int prepare_multi_pack_index_one(struct repository *r, const char *object_dir, int local);
 
 /*
diff --git a/name-hash.c b/name-hash.c
index 251f036..3a58ce0 100644
--- a/name-hash.c
+++ b/name-hash.c
@@ -685,13 +685,20 @@ static int same_name(const struct cache_entry *ce, const char *name, int namelen
 	return slow_same_name(name, namelen, ce->name, len);
 }
 
-int index_dir_exists(struct index_state *istate, const char *name, int namelen)
+int index_dir_find(struct index_state *istate, const char *name, int namelen,
+		   struct strbuf *canonical_path)
 {
 	struct dir_entry *dir;
 
 	lazy_init_name_hash(istate);
 	expand_to_path(istate, name, namelen, 0);
 	dir = find_dir_entry(istate, name, namelen);
+
+	if (canonical_path && dir && dir->nr) {
+		strbuf_reset(canonical_path);
+		strbuf_add(canonical_path, dir->name, dir->namelen);
+	}
+
 	return dir && dir->nr;
 }
 
diff --git a/name-hash.h b/name-hash.h
index b1b4b0f..0cbfc42 100644
--- a/name-hash.h
+++ b/name-hash.h
@@ -4,7 +4,12 @@
 struct cache_entry;
 struct index_state;
 
-int index_dir_exists(struct index_state *istate, const char *name, int namelen);
+
+int index_dir_find(struct index_state *istate, const char *name, int namelen,
+		   struct strbuf *canonical_path);
+
+#define index_dir_exists(i, n, l) index_dir_find((i), (n), (l), NULL)
+
 void adjust_dirname_case(struct index_state *istate, char *name);
 struct cache_entry *index_file_exists(struct index_state *istate, const char *name, int namelen, int igncase);
 
diff --git a/notes-merge.c b/notes-merge.c
index 8799b52..5128293 100644
--- a/notes-merge.c
+++ b/notes-merge.c
@@ -607,7 +607,8 @@ int notes_merge(struct notes_merge_options *o,
 	assert(local && remote);
 
 	/* Find merge bases */
-	bases = repo_get_merge_bases(the_repository, local, remote);
+	if (repo_get_merge_bases(the_repository, local, remote, &bases) < 0)
+		exit(128);
 	if (!bases) {
 		base_oid = null_oid();
 		base_tree_oid = the_hash_algo->empty_tree;
diff --git a/object-file-convert.c b/object-file-convert.c
new file mode 100644
index 0000000..4f61890
--- /dev/null
+++ b/object-file-convert.c
@@ -0,0 +1,277 @@
+#include "git-compat-util.h"
+#include "gettext.h"
+#include "strbuf.h"
+#include "hex.h"
+#include "repository.h"
+#include "hash-ll.h"
+#include "hash.h"
+#include "object.h"
+#include "loose.h"
+#include "commit.h"
+#include "gpg-interface.h"
+#include "object-file-convert.h"
+
+int repo_oid_to_algop(struct repository *repo, const struct object_id *src,
+		      const struct git_hash_algo *to, struct object_id *dest)
+{
+	/*
+	 * If the source algorithm is not set, then we're using the
+	 * default hash algorithm for that object.
+	 */
+	const struct git_hash_algo *from =
+		src->algo ? &hash_algos[src->algo] : repo->hash_algo;
+
+	if (from == to) {
+		if (src != dest)
+			oidcpy(dest, src);
+		return 0;
+	}
+	if (repo_loose_object_map_oid(repo, src, to, dest)) {
+		/*
+		 * We may have loaded the object map at repo initialization but
+		 * another process (perhaps upstream of a pipe from us) may have
+		 * written a new object into the map.  If the object is missing,
+		 * let's reload the map to see if the object has appeared.
+		 */
+		repo_read_loose_object_map(repo);
+		if (repo_loose_object_map_oid(repo, src, to, dest))
+			return -1;
+	}
+	return 0;
+}
+
+static int decode_tree_entry_raw(struct object_id *oid, const char **path,
+				 size_t *len, const struct git_hash_algo *algo,
+				 const char *buf, unsigned long size)
+{
+	uint16_t mode;
+	const unsigned hashsz = algo->rawsz;
+
+	if (size < hashsz + 3 || buf[size - (hashsz + 1)]) {
+		return -1;
+	}
+
+	*path = parse_mode(buf, &mode);
+	if (!*path || !**path)
+		return -1;
+	*len = strlen(*path) + 1;
+
+	oidread_algop(oid, (const unsigned char *)*path + *len, algo);
+	return 0;
+}
+
+static int convert_tree_object(struct strbuf *out,
+			       const struct git_hash_algo *from,
+			       const struct git_hash_algo *to,
+			       const char *buffer, size_t size)
+{
+	const char *p = buffer, *end = buffer + size;
+
+	while (p < end) {
+		struct object_id entry_oid, mapped_oid;
+		const char *path = NULL;
+		size_t pathlen;
+
+		if (decode_tree_entry_raw(&entry_oid, &path, &pathlen, from, p,
+					  end - p))
+			return error(_("failed to decode tree entry"));
+		if (repo_oid_to_algop(the_repository, &entry_oid, to, &mapped_oid))
+			return error(_("failed to map tree entry for %s"), oid_to_hex(&entry_oid));
+		strbuf_add(out, p, path - p);
+		strbuf_add(out, path, pathlen);
+		strbuf_add(out, mapped_oid.hash, to->rawsz);
+		p = path + pathlen + from->rawsz;
+	}
+	return 0;
+}
+
+static int convert_tag_object(struct strbuf *out,
+			      const struct git_hash_algo *from,
+			      const struct git_hash_algo *to,
+			      const char *buffer, size_t size)
+{
+	struct strbuf payload = STRBUF_INIT, oursig = STRBUF_INIT, othersig = STRBUF_INIT;
+	const int entry_len = from->hexsz + 7;
+	size_t payload_size;
+	struct object_id oid, mapped_oid;
+	const char *p;
+
+	/* Consume the object line */
+	if ((entry_len >= size) ||
+	    memcmp(buffer, "object ", 7) || buffer[entry_len] != '\n')
+		return error("bogus tag object");
+	if (parse_oid_hex_algop(buffer + 7, &oid, &p, from) < 0)
+		return error("bad tag object ID");
+	if (repo_oid_to_algop(the_repository, &oid, to, &mapped_oid))
+		return error("unable to map tree %s in tag object",
+			     oid_to_hex(&oid));
+	size -= ((p + 1) - buffer);
+	buffer = p + 1;
+
+	/* Is there a signature for our algorithm? */
+	payload_size = parse_signed_buffer(buffer, size);
+	if (payload_size != size) {
+		/* Yes, there is. */
+		strbuf_add(&oursig, buffer + payload_size, size - payload_size);
+	}
+
+	/* Now, is there a signature for the other algorithm? */
+	parse_buffer_signed_by_header(buffer, payload_size, &payload, &othersig, to);
+	/*
+	 * Our payload is now in payload and we may have up to two signatrures
+	 * in oursig and othersig.
+	 */
+
+	/* Add some slop for longer signature header in the new algorithm. */
+	strbuf_grow(out, (7 + to->hexsz + 1) + size + 7);
+	strbuf_addf(out, "object %s\n", oid_to_hex(&mapped_oid));
+	strbuf_addbuf(out, &payload);
+	if (oursig.len)
+		add_header_signature(out, &oursig, from);
+	strbuf_addbuf(out, &othersig);
+
+	strbuf_release(&payload);
+	strbuf_release(&othersig);
+	strbuf_release(&oursig);
+	return 0;
+}
+
+static int convert_commit_object(struct strbuf *out,
+				 const struct git_hash_algo *from,
+				 const struct git_hash_algo *to,
+				 const char *buffer, size_t size)
+{
+	const char *tail = buffer;
+	const char *bufptr = buffer;
+	const int tree_entry_len = from->hexsz + 5;
+	const int parent_entry_len = from->hexsz + 7;
+	struct object_id oid, mapped_oid;
+	const char *p, *eol;
+
+	tail += size;
+
+	while ((bufptr < tail) && (*bufptr != '\n')) {
+		eol = memchr(bufptr, '\n', tail - bufptr);
+		if (!eol)
+			return error(_("bad %s in commit"), "line");
+
+		if (((bufptr + 5) < eol) && !memcmp(bufptr, "tree ", 5))
+		{
+			if (((bufptr + tree_entry_len) != eol) ||
+			    parse_oid_hex_algop(bufptr + 5, &oid, &p, from) ||
+			    (p != eol))
+				return error(_("bad %s in commit"), "tree");
+
+			if (repo_oid_to_algop(the_repository, &oid, to, &mapped_oid))
+				return error(_("unable to map %s %s in commit object"),
+					     "tree", oid_to_hex(&oid));
+			strbuf_addf(out, "tree %s\n", oid_to_hex(&mapped_oid));
+		}
+		else if (((bufptr + 7) < eol) && !memcmp(bufptr, "parent ", 7))
+		{
+			if (((bufptr + parent_entry_len) != eol) ||
+			    parse_oid_hex_algop(bufptr + 7, &oid, &p, from) ||
+			    (p != eol))
+				return error(_("bad %s in commit"), "parent");
+
+			if (repo_oid_to_algop(the_repository, &oid, to, &mapped_oid))
+				return error(_("unable to map %s %s in commit object"),
+					     "parent", oid_to_hex(&oid));
+
+			strbuf_addf(out, "parent %s\n", oid_to_hex(&mapped_oid));
+		}
+		else if (((bufptr + 9) < eol) && !memcmp(bufptr, "mergetag ", 9))
+		{
+			struct strbuf tag = STRBUF_INIT, new_tag = STRBUF_INIT;
+
+			/* Recover the tag object from the mergetag */
+			strbuf_add(&tag, bufptr + 9, (eol - (bufptr + 9)) + 1);
+
+			bufptr = eol + 1;
+			while ((bufptr < tail) && (*bufptr == ' ')) {
+				eol = memchr(bufptr, '\n', tail - bufptr);
+				if (!eol) {
+					strbuf_release(&tag);
+					return error(_("bad %s in commit"), "mergetag continuation");
+				}
+				strbuf_add(&tag, bufptr + 1, (eol - (bufptr + 1)) + 1);
+				bufptr = eol + 1;
+			}
+
+			/* Compute the new tag object */
+			if (convert_tag_object(&new_tag, from, to, tag.buf, tag.len)) {
+				strbuf_release(&tag);
+				strbuf_release(&new_tag);
+				return -1;
+			}
+
+			/* Write the new mergetag */
+			strbuf_addstr(out, "mergetag");
+			strbuf_add_lines(out, " ", new_tag.buf, new_tag.len);
+			strbuf_release(&tag);
+			strbuf_release(&new_tag);
+		}
+		else if (((bufptr + 7) < tail) && !memcmp(bufptr, "author ", 7))
+			strbuf_add(out, bufptr, (eol - bufptr) + 1);
+		else if (((bufptr + 10) < tail) && !memcmp(bufptr, "committer ", 10))
+			strbuf_add(out, bufptr, (eol - bufptr) + 1);
+		else if (((bufptr + 9) < tail) && !memcmp(bufptr, "encoding ", 9))
+			strbuf_add(out, bufptr, (eol - bufptr) + 1);
+		else if (((bufptr + 6) < tail) && !memcmp(bufptr, "gpgsig", 6))
+			strbuf_add(out, bufptr, (eol - bufptr) + 1);
+		else {
+			/* Unknown line fail it might embed an oid */
+			return -1;
+		}
+		/* Consume any trailing continuation lines */
+		bufptr = eol + 1;
+		while ((bufptr < tail) && (*bufptr == ' ')) {
+			eol = memchr(bufptr, '\n', tail - bufptr);
+			if (!eol)
+				return error(_("bad %s in commit"), "continuation");
+			strbuf_add(out, bufptr, (eol - bufptr) + 1);
+			bufptr = eol + 1;
+		}
+	}
+	if (bufptr < tail)
+		strbuf_add(out, bufptr, tail - bufptr);
+	return 0;
+}
+
+int convert_object_file(struct strbuf *outbuf,
+			const struct git_hash_algo *from,
+			const struct git_hash_algo *to,
+			const void *buf, size_t len,
+			enum object_type type,
+			int gentle)
+{
+	int ret;
+
+	/* Don't call this function when no conversion is necessary */
+	if ((from == to) || (type == OBJ_BLOB))
+		BUG("Refusing noop object file conversion");
+
+	switch (type) {
+	case OBJ_COMMIT:
+		ret = convert_commit_object(outbuf, from, to, buf, len);
+		break;
+	case OBJ_TREE:
+		ret = convert_tree_object(outbuf, from, to, buf, len);
+		break;
+	case OBJ_TAG:
+		ret = convert_tag_object(outbuf, from, to, buf, len);
+		break;
+	default:
+		/* Not implemented yet, so fail. */
+		ret = -1;
+		break;
+	}
+	if (!ret)
+		return 0;
+	if (gentle) {
+		strbuf_release(outbuf);
+		return ret;
+	}
+	die(_("Failed to convert object from %s to %s"),
+		from->name, to->name);
+}
diff --git a/object-file-convert.h b/object-file-convert.h
new file mode 100644
index 0000000..a4f802a
--- /dev/null
+++ b/object-file-convert.h
@@ -0,0 +1,24 @@
+#ifndef OBJECT_CONVERT_H
+#define OBJECT_CONVERT_H
+
+struct repository;
+struct object_id;
+struct git_hash_algo;
+struct strbuf;
+#include "object.h"
+
+int repo_oid_to_algop(struct repository *repo, const struct object_id *src,
+		      const struct git_hash_algo *to, struct object_id *dest);
+
+/*
+ * Convert an object file from one hash algorithm to another algorithm.
+ * Return -1 on failure, 0 on success.
+ */
+int convert_object_file(struct strbuf *outbuf,
+			const struct git_hash_algo *from,
+			const struct git_hash_algo *to,
+			const void *buf, size_t len,
+			enum object_type type,
+			int gentle);
+
+#endif /* OBJECT_CONVERT_H */
diff --git a/object-file.c b/object-file.c
index 619f039..610b1f4 100644
--- a/object-file.c
+++ b/object-file.c
@@ -35,6 +35,8 @@
 #include "setup.h"
 #include "submodule.h"
 #include "fsck.h"
+#include "loose.h"
+#include "object-file-convert.h"
 
 /* The maximum size for an object header. */
 #define MAX_HEADER_LEN 32
@@ -1084,9 +1086,11 @@ int check_object_signature(struct repository *r, const struct object_id *oid,
 			   void *buf, unsigned long size,
 			   enum object_type type)
 {
+	const struct git_hash_algo *algo =
+		oid->algo ? &hash_algos[oid->algo] : r->hash_algo;
 	struct object_id real_oid;
 
-	hash_object_file(r->hash_algo, buf, size, type, &real_oid);
+	hash_object_file(algo, buf, size, type, &real_oid);
 
 	return !oideq(oid, &real_oid) ? -1 : 0;
 }
@@ -1652,10 +1656,101 @@ static int do_oid_object_info_extended(struct repository *r,
 	return 0;
 }
 
+static int oid_object_info_convert(struct repository *r,
+				   const struct object_id *input_oid,
+				   struct object_info *input_oi, unsigned flags)
+{
+	const struct git_hash_algo *input_algo = &hash_algos[input_oid->algo];
+	int do_die = flags & OBJECT_INFO_DIE_IF_CORRUPT;
+	struct strbuf type_name = STRBUF_INIT;
+	struct object_id oid, delta_base_oid;
+	struct object_info new_oi, *oi;
+	unsigned long size;
+	void *content;
+	int ret;
+
+	if (repo_oid_to_algop(r, input_oid, the_hash_algo, &oid)) {
+		if (do_die)
+			die(_("missing mapping of %s to %s"),
+			    oid_to_hex(input_oid), the_hash_algo->name);
+		return -1;
+	}
+
+	/* Is new_oi needed? */
+	oi = input_oi;
+	if (input_oi && (input_oi->delta_base_oid || input_oi->sizep ||
+			 input_oi->contentp)) {
+		new_oi = *input_oi;
+		/* Does delta_base_oid need to be converted? */
+		if (input_oi->delta_base_oid)
+			new_oi.delta_base_oid = &delta_base_oid;
+		/* Will the attributes differ when converted? */
+		if (input_oi->sizep || input_oi->contentp) {
+			new_oi.contentp = &content;
+			new_oi.sizep = &size;
+			new_oi.type_name = &type_name;
+		}
+		oi = &new_oi;
+	}
+
+	ret = oid_object_info_extended(r, &oid, oi, flags);
+	if (ret)
+		return -1;
+	if (oi == input_oi)
+		return ret;
+
+	if (new_oi.contentp) {
+		struct strbuf outbuf = STRBUF_INIT;
+		enum object_type type;
+
+		type = type_from_string_gently(type_name.buf, type_name.len,
+					       !do_die);
+		if (type == -1)
+			return -1;
+		if (type != OBJ_BLOB) {
+			ret = convert_object_file(&outbuf,
+						  the_hash_algo, input_algo,
+						  content, size, type, !do_die);
+			if (ret == -1)
+				return -1;
+			free(content);
+			size = outbuf.len;
+			content = strbuf_detach(&outbuf, NULL);
+		}
+		if (input_oi->sizep)
+			*input_oi->sizep = size;
+		if (input_oi->contentp)
+			*input_oi->contentp = content;
+		else
+			free(content);
+		if (input_oi->type_name)
+			*input_oi->type_name = type_name;
+		else
+			strbuf_release(&type_name);
+	}
+	if (new_oi.delta_base_oid == &delta_base_oid) {
+		if (repo_oid_to_algop(r, &delta_base_oid, input_algo,
+				 input_oi->delta_base_oid)) {
+			if (do_die)
+				die(_("missing mapping of %s to %s"),
+				    oid_to_hex(&delta_base_oid),
+				    input_algo->name);
+			return -1;
+		}
+	}
+	input_oi->whence = new_oi.whence;
+	input_oi->u = new_oi.u;
+	return ret;
+}
+
 int oid_object_info_extended(struct repository *r, const struct object_id *oid,
 			     struct object_info *oi, unsigned flags)
 {
 	int ret;
+
+	if (oid->algo && (hash_algo_by_ptr(r->hash_algo) != oid->algo))
+		return oid_object_info_convert(r, oid, oi, flags);
+
 	obj_read_lock();
 	ret = do_oid_object_info_extended(r, oid, oi, flags);
 	obj_read_unlock();
@@ -1944,9 +2039,12 @@ static int start_loose_object_common(struct strbuf *tmp_file,
 				     const char *filename, unsigned flags,
 				     git_zstream *stream,
 				     unsigned char *buf, size_t buflen,
-				     git_hash_ctx *c,
+				     git_hash_ctx *c, git_hash_ctx *compat_c,
 				     char *hdr, int hdrlen)
 {
+	struct repository *repo = the_repository;
+	const struct git_hash_algo *algo = repo->hash_algo;
+	const struct git_hash_algo *compat = repo->compat_hash_algo;
 	int fd;
 
 	fd = create_tmpfile(tmp_file, filename);
@@ -1966,14 +2064,18 @@ static int start_loose_object_common(struct strbuf *tmp_file,
 	git_deflate_init(stream, zlib_compression_level);
 	stream->next_out = buf;
 	stream->avail_out = buflen;
-	the_hash_algo->init_fn(c);
+	algo->init_fn(c);
+	if (compat && compat_c)
+		compat->init_fn(compat_c);
 
 	/*  Start to feed header to zlib stream */
 	stream->next_in = (unsigned char *)hdr;
 	stream->avail_in = hdrlen;
 	while (git_deflate(stream, 0) == Z_OK)
 		; /* nothing */
-	the_hash_algo->update_fn(c, hdr, hdrlen);
+	algo->update_fn(c, hdr, hdrlen);
+	if (compat && compat_c)
+		compat->update_fn(compat_c, hdr, hdrlen);
 
 	return fd;
 }
@@ -1982,16 +2084,21 @@ static int start_loose_object_common(struct strbuf *tmp_file,
  * Common steps for the inner git_deflate() loop for writing loose
  * objects. Returns what git_deflate() returns.
  */
-static int write_loose_object_common(git_hash_ctx *c,
+static int write_loose_object_common(git_hash_ctx *c, git_hash_ctx *compat_c,
 				     git_zstream *stream, const int flush,
 				     unsigned char *in0, const int fd,
 				     unsigned char *compressed,
 				     const size_t compressed_len)
 {
+	struct repository *repo = the_repository;
+	const struct git_hash_algo *algo = repo->hash_algo;
+	const struct git_hash_algo *compat = repo->compat_hash_algo;
 	int ret;
 
 	ret = git_deflate(stream, flush ? Z_FINISH : 0);
-	the_hash_algo->update_fn(c, in0, stream->next_in - in0);
+	algo->update_fn(c, in0, stream->next_in - in0);
+	if (compat && compat_c)
+		compat->update_fn(compat_c, in0, stream->next_in - in0);
 	if (write_in_full(fd, compressed, stream->next_out - compressed) < 0)
 		die_errno(_("unable to write loose object file"));
 	stream->next_out = compressed;
@@ -2006,15 +2113,21 @@ static int write_loose_object_common(git_hash_ctx *c,
  * - End the compression of zlib stream.
  * - Get the calculated oid to "oid".
  */
-static int end_loose_object_common(git_hash_ctx *c, git_zstream *stream,
-				   struct object_id *oid)
+static int end_loose_object_common(git_hash_ctx *c, git_hash_ctx *compat_c,
+				   git_zstream *stream, struct object_id *oid,
+				   struct object_id *compat_oid)
 {
+	struct repository *repo = the_repository;
+	const struct git_hash_algo *algo = repo->hash_algo;
+	const struct git_hash_algo *compat = repo->compat_hash_algo;
 	int ret;
 
 	ret = git_deflate_end_gently(stream);
 	if (ret != Z_OK)
 		return ret;
-	the_hash_algo->final_oid_fn(oid, c);
+	algo->final_oid_fn(oid, c);
+	if (compat && compat_c)
+		compat->final_oid_fn(compat_oid, compat_c);
 
 	return Z_OK;
 }
@@ -2038,7 +2151,7 @@ static int write_loose_object(const struct object_id *oid, char *hdr,
 
 	fd = start_loose_object_common(&tmp_file, filename.buf, flags,
 				       &stream, compressed, sizeof(compressed),
-				       &c, hdr, hdrlen);
+				       &c, NULL, hdr, hdrlen);
 	if (fd < 0)
 		return -1;
 
@@ -2048,14 +2161,14 @@ static int write_loose_object(const struct object_id *oid, char *hdr,
 	do {
 		unsigned char *in0 = stream.next_in;
 
-		ret = write_loose_object_common(&c, &stream, 1, in0, fd,
+		ret = write_loose_object_common(&c, NULL, &stream, 1, in0, fd,
 						compressed, sizeof(compressed));
 	} while (ret == Z_OK);
 
 	if (ret != Z_STREAM_END)
 		die(_("unable to deflate new object %s (%d)"), oid_to_hex(oid),
 		    ret);
-	ret = end_loose_object_common(&c, &stream, &parano_oid);
+	ret = end_loose_object_common(&c, NULL, &stream, &parano_oid, NULL);
 	if (ret != Z_OK)
 		die(_("deflateEnd on object %s failed (%d)"), oid_to_hex(oid),
 		    ret);
@@ -2100,10 +2213,12 @@ static int freshen_packed_object(const struct object_id *oid)
 int stream_loose_object(struct input_stream *in_stream, size_t len,
 			struct object_id *oid)
 {
+	const struct git_hash_algo *compat = the_repository->compat_hash_algo;
+	struct object_id compat_oid;
 	int fd, ret, err = 0, flush = 0;
 	unsigned char compressed[4096];
 	git_zstream stream;
-	git_hash_ctx c;
+	git_hash_ctx c, compat_c;
 	struct strbuf tmp_file = STRBUF_INIT;
 	struct strbuf filename = STRBUF_INIT;
 	int dirlen;
@@ -2127,7 +2242,7 @@ int stream_loose_object(struct input_stream *in_stream, size_t len,
 	 */
 	fd = start_loose_object_common(&tmp_file, filename.buf, 0,
 				       &stream, compressed, sizeof(compressed),
-				       &c, hdr, hdrlen);
+				       &c, &compat_c, hdr, hdrlen);
 	if (fd < 0) {
 		err = -1;
 		goto cleanup;
@@ -2145,7 +2260,7 @@ int stream_loose_object(struct input_stream *in_stream, size_t len,
 			if (in_stream->is_finished)
 				flush = 1;
 		}
-		ret = write_loose_object_common(&c, &stream, flush, in0, fd,
+		ret = write_loose_object_common(&c, &compat_c, &stream, flush, in0, fd,
 						compressed, sizeof(compressed));
 		/*
 		 * Unlike write_loose_object(), we do not have the entire
@@ -2168,7 +2283,7 @@ int stream_loose_object(struct input_stream *in_stream, size_t len,
 	 */
 	if (ret != Z_STREAM_END)
 		die(_("unable to stream deflate new object (%d)"), ret);
-	ret = end_loose_object_common(&c, &stream, oid);
+	ret = end_loose_object_common(&c, &compat_c, &stream, oid, &compat_oid);
 	if (ret != Z_OK)
 		die(_("deflateEnd on stream object failed (%d)"), ret);
 	close_loose_object(fd, tmp_file.buf);
@@ -2195,6 +2310,8 @@ int stream_loose_object(struct input_stream *in_stream, size_t len,
 	}
 
 	err = finalize_object_file(tmp_file.buf, filename.buf);
+	if (!err && compat)
+		err = repo_add_loose_object_map(the_repository, oid, &compat_oid);
 cleanup:
 	strbuf_release(&tmp_file);
 	strbuf_release(&filename);
@@ -2203,19 +2320,42 @@ int stream_loose_object(struct input_stream *in_stream, size_t len,
 
 int write_object_file_flags(const void *buf, unsigned long len,
 			    enum object_type type, struct object_id *oid,
-			    unsigned flags)
+			    struct object_id *compat_oid_in, unsigned flags)
 {
+	struct repository *repo = the_repository;
+	const struct git_hash_algo *algo = repo->hash_algo;
+	const struct git_hash_algo *compat = repo->compat_hash_algo;
+	struct object_id compat_oid;
 	char hdr[MAX_HEADER_LEN];
 	int hdrlen = sizeof(hdr);
 
+	/* Generate compat_oid */
+	if (compat) {
+		if (compat_oid_in)
+			oidcpy(&compat_oid, compat_oid_in);
+		else if (type == OBJ_BLOB)
+			hash_object_file(compat, buf, len, type, &compat_oid);
+		else {
+			struct strbuf converted = STRBUF_INIT;
+			convert_object_file(&converted, algo, compat,
+					    buf, len, type, 0);
+			hash_object_file(compat, converted.buf, converted.len,
+					 type, &compat_oid);
+			strbuf_release(&converted);
+		}
+	}
+
 	/* Normally if we have it in the pack then we do not bother writing
 	 * it out into .git/objects/??/?{38} file.
 	 */
-	write_object_file_prepare(the_hash_algo, buf, len, type, oid, hdr,
-				  &hdrlen);
+	write_object_file_prepare(algo, buf, len, type, oid, hdr, &hdrlen);
 	if (freshen_packed_object(oid) || freshen_loose_object(oid))
 		return 0;
-	return write_loose_object(oid, hdr, hdrlen, buf, len, 0, flags);
+	if (write_loose_object(oid, hdr, hdrlen, buf, len, 0, flags))
+		return -1;
+	if (compat)
+		return repo_add_loose_object_map(repo, oid, &compat_oid);
+	return 0;
 }
 
 int write_object_file_literally(const void *buf, unsigned long len,
@@ -2223,7 +2363,27 @@ int write_object_file_literally(const void *buf, unsigned long len,
 				unsigned flags)
 {
 	char *header;
+	struct repository *repo = the_repository;
+	const struct git_hash_algo *algo = repo->hash_algo;
+	const struct git_hash_algo *compat = repo->compat_hash_algo;
+	struct object_id compat_oid;
 	int hdrlen, status = 0;
+	int compat_type = -1;
+
+	if (compat) {
+		compat_type = type_from_string_gently(type, -1, 1);
+		if (compat_type == OBJ_BLOB)
+			hash_object_file(compat, buf, len, compat_type,
+					 &compat_oid);
+		else if (compat_type != -1) {
+			struct strbuf converted = STRBUF_INIT;
+			convert_object_file(&converted, algo, compat,
+					    buf, len, compat_type, 0);
+			hash_object_file(compat, converted.buf, converted.len,
+					 compat_type, &compat_oid);
+			strbuf_release(&converted);
+		}
+	}
 
 	/* type string, SP, %lu of the length plus NUL must fit this */
 	hdrlen = strlen(type) + MAX_HEADER_LEN;
@@ -2236,6 +2396,8 @@ int write_object_file_literally(const void *buf, unsigned long len,
 	if (freshen_packed_object(oid) || freshen_loose_object(oid))
 		goto cleanup;
 	status = write_loose_object(oid, header, hdrlen, buf, len, 0, 0);
+	if (compat_type != -1)
+		return repo_add_loose_object_map(repo, oid, &compat_oid);
 
 cleanup:
 	free(header);
@@ -2244,9 +2406,12 @@ int write_object_file_literally(const void *buf, unsigned long len,
 
 int force_object_loose(const struct object_id *oid, time_t mtime)
 {
+	struct repository *repo = the_repository;
+	const struct git_hash_algo *compat = repo->compat_hash_algo;
 	void *buf;
 	unsigned long len;
 	struct object_info oi = OBJECT_INFO_INIT;
+	struct object_id compat_oid;
 	enum object_type type;
 	char hdr[MAX_HEADER_LEN];
 	int hdrlen;
@@ -2259,8 +2424,15 @@ int force_object_loose(const struct object_id *oid, time_t mtime)
 	oi.contentp = &buf;
 	if (oid_object_info_extended(the_repository, oid, &oi, 0))
 		return error(_("cannot read object for %s"), oid_to_hex(oid));
+	if (compat) {
+		if (repo_oid_to_algop(repo, oid, compat, &compat_oid))
+			return error(_("cannot map object %s to %s"),
+				     oid_to_hex(oid), compat->name);
+	}
 	hdrlen = format_object_header(hdr, sizeof(hdr), type, len);
 	ret = write_loose_object(oid, hdr, hdrlen, buf, len, mtime, 0);
+	if (!ret && compat)
+		ret = repo_add_loose_object_map(the_repository, oid, &compat_oid);
 	free(buf);
 
 	return ret;
diff --git a/object-name.c b/object-name.c
index 3a2ef5d..523af6f 100644
--- a/object-name.c
+++ b/object-name.c
@@ -23,6 +23,7 @@
 #include "midx.h"
 #include "commit-reach.h"
 #include "date.h"
+#include "object-file-convert.h"
 
 static int get_oid_oneline(struct repository *r, const char *, struct object_id *, struct commit_list *);
 
@@ -47,6 +48,7 @@ struct disambiguate_state {
 
 static void update_candidates(struct disambiguate_state *ds, const struct object_id *current)
 {
+	/* The hash algorithm of current has already been filtered */
 	if (ds->always_call_fn) {
 		ds->ambiguous = ds->fn(ds->repo, current, ds->cb_data) ? 1 : 0;
 		return;
@@ -132,6 +134,8 @@ static void unique_in_midx(struct multi_pack_index *m,
 {
 	uint32_t num, i, first = 0;
 	const struct object_id *current = NULL;
+	int len = ds->len > ds->repo->hash_algo->hexsz ?
+		ds->repo->hash_algo->hexsz : ds->len;
 	num = m->num_objects;
 
 	if (!num)
@@ -147,7 +151,7 @@ static void unique_in_midx(struct multi_pack_index *m,
 	for (i = first; i < num && !ds->ambiguous; i++) {
 		struct object_id oid;
 		current = nth_midxed_object_oid(&oid, m, i);
-		if (!match_hash(ds->len, ds->bin_pfx.hash, current->hash))
+		if (!match_hash(len, ds->bin_pfx.hash, current->hash))
 			break;
 		update_candidates(ds, current);
 	}
@@ -157,6 +161,8 @@ static void unique_in_pack(struct packed_git *p,
 			   struct disambiguate_state *ds)
 {
 	uint32_t num, i, first = 0;
+	int len = ds->len > ds->repo->hash_algo->hexsz ?
+		ds->repo->hash_algo->hexsz : ds->len;
 
 	if (p->multi_pack_index)
 		return;
@@ -175,7 +181,7 @@ static void unique_in_pack(struct packed_git *p,
 	for (i = first; i < num && !ds->ambiguous; i++) {
 		struct object_id oid;
 		nth_packed_object_id(&oid, p, i);
-		if (!match_hash(ds->len, ds->bin_pfx.hash, oid.hash))
+		if (!match_hash(len, ds->bin_pfx.hash, oid.hash))
 			break;
 		update_candidates(ds, &oid);
 	}
@@ -186,6 +192,10 @@ static void find_short_packed_object(struct disambiguate_state *ds)
 	struct multi_pack_index *m;
 	struct packed_git *p;
 
+	/* Skip, unless oids from the storage hash algorithm are wanted */
+	if (ds->bin_pfx.algo && (&hash_algos[ds->bin_pfx.algo] != ds->repo->hash_algo))
+		return;
+
 	for (m = get_multi_pack_index(ds->repo); m && !ds->ambiguous;
 	     m = m->next)
 		unique_in_midx(m, ds);
@@ -324,11 +334,12 @@ int set_disambiguate_hint_config(const char *var, const char *value)
 
 static int init_object_disambiguation(struct repository *r,
 				      const char *name, int len,
+				      const struct git_hash_algo *algo,
 				      struct disambiguate_state *ds)
 {
 	int i;
 
-	if (len < MINIMUM_ABBREV || len > the_hash_algo->hexsz)
+	if (len < MINIMUM_ABBREV || len > GIT_MAX_HEXSZ)
 		return -1;
 
 	memset(ds, 0, sizeof(*ds));
@@ -355,6 +366,7 @@ static int init_object_disambiguation(struct repository *r,
 	ds->len = len;
 	ds->hex_pfx[len] = '\0';
 	ds->repo = r;
+	ds->bin_pfx.algo = algo ? hash_algo_by_ptr(algo) : GIT_HASH_UNKNOWN;
 	prepare_alt_odb(r);
 	return 0;
 }
@@ -489,9 +501,10 @@ static int repo_collect_ambiguous(struct repository *r UNUSED,
 	return collect_ambiguous(oid, data);
 }
 
-static int sort_ambiguous(const void *a, const void *b, void *ctx)
+static int sort_ambiguous(const void *va, const void *vb, void *ctx)
 {
 	struct repository *sort_ambiguous_repo = ctx;
+	const struct object_id *a = va, *b = vb;
 	int a_type = oid_object_info(sort_ambiguous_repo, a, NULL);
 	int b_type = oid_object_info(sort_ambiguous_repo, b, NULL);
 	int a_type_sort;
@@ -501,8 +514,12 @@ static int sort_ambiguous(const void *a, const void *b, void *ctx)
 	 * Sorts by hash within the same object type, just as
 	 * oid_array_for_each_unique() would do.
 	 */
-	if (a_type == b_type)
-		return oidcmp(a, b);
+	if (a_type == b_type) {
+		if (a->algo == b->algo)
+			return oidcmp(a, b);
+		else
+			return a->algo > b->algo ? 1 : -1;
+	}
 
 	/*
 	 * Between object types show tags, then commits, and finally
@@ -531,8 +548,12 @@ static enum get_oid_result get_short_oid(struct repository *r,
 	int status;
 	struct disambiguate_state ds;
 	int quietly = !!(flags & GET_OID_QUIETLY);
+	const struct git_hash_algo *algo = r->hash_algo;
 
-	if (init_object_disambiguation(r, name, len, &ds) < 0)
+	if (flags & GET_OID_HASH_ANY)
+		algo = NULL;
+
+	if (init_object_disambiguation(r, name, len, algo, &ds) < 0)
 		return -1;
 
 	if (HAS_MULTI_BITS(flags & GET_OID_DISAMBIGUATORS))
@@ -586,7 +607,7 @@ static enum get_oid_result get_short_oid(struct repository *r,
 		if (!ds.ambiguous)
 			ds.fn = NULL;
 
-		repo_for_each_abbrev(r, ds.hex_pfx, collect_ambiguous, &collect);
+		repo_for_each_abbrev(r, ds.hex_pfx, algo, collect_ambiguous, &collect);
 		sort_ambiguous_oid_array(r, &collect);
 
 		if (oid_array_for_each(&collect, show_ambiguous_object, &out))
@@ -608,13 +629,14 @@ static enum get_oid_result get_short_oid(struct repository *r,
 }
 
 int repo_for_each_abbrev(struct repository *r, const char *prefix,
+			 const struct git_hash_algo *algo,
 			 each_abbrev_fn fn, void *cb_data)
 {
 	struct oid_array collect = OID_ARRAY_INIT;
 	struct disambiguate_state ds;
 	int ret;
 
-	if (init_object_disambiguation(r, prefix, strlen(prefix), &ds) < 0)
+	if (init_object_disambiguation(r, prefix, strlen(prefix), algo, &ds) < 0)
 		return -1;
 
 	ds.always_call_fn = 1;
@@ -785,10 +807,12 @@ void strbuf_add_unique_abbrev(struct strbuf *sb, const struct object_id *oid,
 int repo_find_unique_abbrev_r(struct repository *r, char *hex,
 			      const struct object_id *oid, int len)
 {
+	const struct git_hash_algo *algo =
+		oid->algo ? &hash_algos[oid->algo] : r->hash_algo;
 	struct disambiguate_state ds;
 	struct min_abbrev_data mad;
 	struct object_id oid_ret;
-	const unsigned hexsz = r->hash_algo->hexsz;
+	const unsigned hexsz = algo->hexsz;
 
 	if (len < 0) {
 		unsigned long count = repo_approximate_object_count(r);
@@ -824,7 +848,7 @@ int repo_find_unique_abbrev_r(struct repository *r, char *hex,
 
 	find_abbrev_len_packed(&mad);
 
-	if (init_object_disambiguation(r, hex, mad.cur_len, &ds) < 0)
+	if (init_object_disambiguation(r, hex, mad.cur_len, algo, &ds) < 0)
 		return -1;
 
 	ds.fn = repo_extend_abbrev_len;
@@ -1034,6 +1058,15 @@ static int get_oid_basic(struct repository *r, const char *str, int len,
 						len, str,
 						show_date(co_time, co_tz, DATE_MODE(RFC2822)));
 				}
+			} else if (nth == co_cnt && !is_null_oid(oid)) {
+				/*
+				 * We were asked for the Nth reflog (counting
+				 * from 0), but there were only N entries.
+				 * read_ref_at() will have returned "1" to tell
+				 * us it did not find an entry, but it did
+				 * still fill in the oid with the "old" value,
+				 * which we can use.
+				 */
 			} else {
 				if (flags & GET_OID_QUIETLY) {
 					exit(128);
@@ -1479,7 +1512,7 @@ int repo_get_oid_mb(struct repository *r,
 		    struct object_id *oid)
 {
 	struct commit *one, *two;
-	struct commit_list *mbs;
+	struct commit_list *mbs = NULL;
 	struct object_id oid_tmp;
 	const char *dots;
 	int st;
@@ -1507,7 +1540,10 @@ int repo_get_oid_mb(struct repository *r,
 	two = lookup_commit_reference_gently(r, &oid_tmp, 0);
 	if (!two)
 		return -1;
-	mbs = repo_get_merge_bases(r, one, two);
+	if (repo_get_merge_bases(r, one, two, &mbs) < 0) {
+		free_commit_list(mbs);
+		return -1;
+	}
 	if (!mbs || mbs->next)
 		st = -1;
 	else {
diff --git a/object-name.h b/object-name.h
index 9ae5223..064ddc9 100644
--- a/object-name.h
+++ b/object-name.h
@@ -67,7 +67,8 @@ enum get_oid_result get_oid_with_context(struct repository *repo, const char *st
 
 
 typedef int each_abbrev_fn(const struct object_id *oid, void *);
-int repo_for_each_abbrev(struct repository *r, const char *prefix, each_abbrev_fn, void *);
+int repo_for_each_abbrev(struct repository *r, const char *prefix,
+			 const struct git_hash_algo *algo, each_abbrev_fn, void *);
 
 int set_disambiguate_hint_config(const char *var, const char *value);
 
diff --git a/object-store-ll.h b/object-store-ll.h
index 26a3895..c5f2bb2 100644
--- a/object-store-ll.h
+++ b/object-store-ll.h
@@ -26,6 +26,9 @@ struct object_directory {
 	uint32_t loose_objects_subdir_seen[8]; /* 256 bits */
 	struct oidtree *loose_objects_cache;
 
+	/* Map between object IDs for loose objects. */
+	struct loose_object_map *loose_map;
+
 	/*
 	 * This is a temporary object store created by the tmp_objdir
 	 * facility. Disable ref updates since the objects in the store
@@ -252,11 +255,11 @@ void hash_object_file(const struct git_hash_algo *algo, const void *buf,
 
 int write_object_file_flags(const void *buf, unsigned long len,
 			    enum object_type type, struct object_id *oid,
-			    unsigned flags);
+			    struct object_id *comapt_oid_in, unsigned flags);
 static inline int write_object_file(const void *buf, unsigned long len,
 				    enum object_type type, struct object_id *oid)
 {
-	return write_object_file_flags(buf, len, type, oid, 0);
+	return write_object_file_flags(buf, len, type, oid, NULL, 0);
 }
 
 int write_object_file_literally(const void *buf, unsigned long len,
diff --git a/object.c b/object.c
index 2c61e4c..51e3848 100644
--- a/object.c
+++ b/object.c
@@ -13,6 +13,7 @@
 #include "alloc.h"
 #include "packfile.h"
 #include "commit-graph.h"
+#include "loose.h"
 
 unsigned int get_max_object_index(void)
 {
@@ -47,8 +48,7 @@ int type_from_string_gently(const char *str, ssize_t len, int gentle)
 		len = strlen(str);
 
 	for (i = 1; i < ARRAY_SIZE(object_type_strings); i++)
-		if (!strncmp(str, object_type_strings[i], len) &&
-		    object_type_strings[i][len] == '\0')
+		if (!xstrncmpz(object_type_strings[i], str, len))
 			return i;
 
 	if (gentle)
@@ -272,6 +272,7 @@ struct object *parse_object_with_flags(struct repository *r,
 				       enum parse_object_flags flags)
 {
 	int skip_hash = !!(flags & PARSE_OBJECT_SKIP_HASH_CHECK);
+	int discard_tree = !!(flags & PARSE_OBJECT_DISCARD_TREE);
 	unsigned long size;
 	enum object_type type;
 	int eaten;
@@ -299,6 +300,17 @@ struct object *parse_object_with_flags(struct repository *r,
 		return lookup_object(r, oid);
 	}
 
+	/*
+	 * If the caller does not care about the tree buffer and does not
+	 * care about checking the hash, we can simply verify that we
+	 * have the on-disk object with the correct type.
+	 */
+	if (skip_hash && discard_tree &&
+	    (!obj || obj->type == OBJ_TREE) &&
+	    oid_object_info(r, oid, NULL) == OBJ_TREE) {
+		return &lookup_tree(r, oid)->object;
+	}
+
 	buffer = repo_read_object_file(r, oid, &type, &size);
 	if (buffer) {
 		if (!skip_hash &&
@@ -312,6 +324,8 @@ struct object *parse_object_with_flags(struct repository *r,
 					  buffer, &eaten);
 		if (!eaten)
 			free(buffer);
+		if (discard_tree && type == OBJ_TREE)
+			free_tree_buffer((struct tree *)obj);
 		return obj;
 	}
 	return NULL;
@@ -540,6 +554,7 @@ void free_object_directory(struct object_directory *odb)
 {
 	free(odb->path);
 	odb_clear_loose_cache(odb);
+	loose_object_map_clear(&odb->loose_map);
 	free(odb);
 }
 
diff --git a/object.h b/object.h
index 114d459..9293e70 100644
--- a/object.h
+++ b/object.h
@@ -190,6 +190,24 @@ void *create_object(struct repository *r, const struct object_id *oid, void *obj
 
 void *object_as_type(struct object *obj, enum object_type type, int quiet);
 
+
+static inline const char *parse_mode(const char *str, uint16_t *modep)
+{
+	unsigned char c;
+	unsigned int mode = 0;
+
+	if (*str == ' ')
+		return NULL;
+
+	while ((c = *str++) != ' ') {
+		if (c < '0' || c > '7')
+			return NULL;
+		mode = (mode << 3) + (c - '0');
+	}
+	*modep = mode;
+	return str;
+}
+
 /*
  * Returns the object, having parsed it to find out what it is.
  *
@@ -197,6 +215,7 @@ void *object_as_type(struct object *obj, enum object_type type, int quiet);
  */
 enum parse_object_flags {
 	PARSE_OBJECT_SKIP_HASH_CHECK = 1 << 0,
+	PARSE_OBJECT_DISCARD_TREE = 1 << 1,
 };
 struct object *parse_object(struct repository *r, const struct object_id *oid);
 struct object *parse_object_with_flags(struct repository *r,
diff --git a/oid-array.c b/oid-array.c
index 8e47177..1f36651 100644
--- a/oid-array.c
+++ b/oid-array.c
@@ -6,12 +6,20 @@ void oid_array_append(struct oid_array *array, const struct object_id *oid)
 {
 	ALLOC_GROW(array->oid, array->nr + 1, array->alloc);
 	oidcpy(&array->oid[array->nr++], oid);
+	if (!oid->algo)
+		oid_set_algo(&array->oid[array->nr - 1], the_hash_algo);
 	array->sorted = 0;
 }
 
-static int void_hashcmp(const void *a, const void *b)
+static int void_hashcmp(const void *va, const void *vb)
 {
-	return oidcmp(a, b);
+	const struct object_id *a = va, *b = vb;
+	int ret;
+	if (a->algo == b->algo)
+		ret = oidcmp(a, b);
+	else
+		ret = a->algo > b->algo ? 1 : -1;
+	return ret;
 }
 
 void oid_array_sort(struct oid_array *array)
diff --git a/oidset.c b/oidset.c
index d1e5376..91d1385 100644
--- a/oidset.c
+++ b/oidset.c
@@ -23,6 +23,16 @@ int oidset_insert(struct oidset *set, const struct object_id *oid)
 	return !added;
 }
 
+void oidset_insert_from_set(struct oidset *dest, struct oidset *src)
+{
+	struct oidset_iter iter;
+	struct object_id *src_oid;
+
+	oidset_iter_init(src, &iter);
+	while ((src_oid = oidset_iter_next(&iter)))
+		oidset_insert(dest, src_oid);
+}
+
 int oidset_remove(struct oidset *set, const struct object_id *oid)
 {
 	khiter_t pos = kh_get_oid_set(&set->set, *oid);
diff --git a/oidset.h b/oidset.h
index ba4a5a2..262f425 100644
--- a/oidset.h
+++ b/oidset.h
@@ -48,6 +48,12 @@ int oidset_contains(const struct oidset *set, const struct object_id *oid);
 int oidset_insert(struct oidset *set, const struct object_id *oid);
 
 /**
+ * Insert all the oids that are in set 'src' into set 'dest'; a copy
+ * is made of each oid inserted into set 'dest'.
+ */
+void oidset_insert_from_set(struct oidset *dest, struct oidset *src);
+
+/**
  * Remove the oid from the set.
  *
  * Returns 1 if the oid was present in the set, 0 otherwise.
diff --git a/oss-fuzz/.gitignore b/oss-fuzz/.gitignore
index 9acb744..a877c11 100644
--- a/oss-fuzz/.gitignore
+++ b/oss-fuzz/.gitignore
@@ -1,3 +1,5 @@
 fuzz-commit-graph
+fuzz-config
+fuzz-date
 fuzz-pack-headers
 fuzz-pack-idx
diff --git a/oss-fuzz/dummy-cmd-main.c b/oss-fuzz/dummy-cmd-main.c
new file mode 100644
index 0000000..071cb23
--- /dev/null
+++ b/oss-fuzz/dummy-cmd-main.c
@@ -0,0 +1,14 @@
+#include "git-compat-util.h"
+
+/*
+ * When linking the fuzzers, we link against common-main.o to pick up some
+ * symbols. However, even though we ignore common-main:main(), we still need to
+ * provide all the symbols it references. In the fuzzers' case, we need to
+ * provide a dummy cmd_main() for the linker to be happy. It will never be
+ * executed.
+ */
+
+int cmd_main(int argc, const char **argv) {
+	BUG("We should not execute cmd_main() from a fuzz target");
+	return 1;
+}
diff --git a/oss-fuzz/fuzz-config.c b/oss-fuzz/fuzz-config.c
new file mode 100644
index 0000000..94027f5
--- /dev/null
+++ b/oss-fuzz/fuzz-config.c
@@ -0,0 +1,33 @@
+#include "git-compat-util.h"
+#include "config.h"
+
+int LLVMFuzzerTestOneInput(const uint8_t *, size_t);
+static int config_parser_callback(const char *, const char *,
+					const struct config_context *, void *);
+
+static int config_parser_callback(const char *key, const char *value,
+					const struct config_context *ctx UNUSED,
+					void *data UNUSED)
+{
+	/*
+	 * Visit every byte of memory we are given to make sure the parser
+	 * gave it to us appropriately. We need to unconditionally return 0,
+	 * but we also want to prevent the strlen from being optimized away.
+	 */
+	size_t c = strlen(key);
+
+	if (value)
+		c += strlen(value);
+	return c == SIZE_MAX;
+}
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, const size_t size)
+{
+	struct config_options config_opts = { 0 };
+
+	config_opts.error_action = CONFIG_ERROR_SILENT;
+	git_config_from_mem(config_parser_callback, CONFIG_ORIGIN_BLOB,
+				"fuzztest-config", (const char *)data, size, NULL,
+				CONFIG_SCOPE_UNKNOWN, &config_opts);
+	return 0;
+}
diff --git a/oss-fuzz/fuzz-date.c b/oss-fuzz/fuzz-date.c
new file mode 100644
index 0000000..9619dae
--- /dev/null
+++ b/oss-fuzz/fuzz-date.c
@@ -0,0 +1,49 @@
+#include "git-compat-util.h"
+#include "date.h"
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
+{
+	int local;
+	int num;
+	char *str;
+	int16_t tz;
+	timestamp_t ts;
+	enum date_mode_type dmtype;
+	struct date_mode dm;
+
+	if (size <= 4)
+		/*
+		 * we use the first byte to fuzz dmtype and the
+		 * second byte to fuzz local, then the next two
+		 * bytes to fuzz tz offset. The remainder
+		 * (at least one byte) is fed as input to
+		 * approxidate_careful().
+		 */
+		return 0;
+
+	local = !!(*data++ & 0x10);
+	num = *data++ % DATE_UNIX;
+	if (num >= DATE_STRFTIME)
+		num++;
+	dmtype = (enum date_mode_type)num;
+	size -= 2;
+
+	tz = *data++;
+	tz = (tz << 8) | *data++;
+	size -= 2;
+
+	str = xmemdupz(data, size);
+
+	ts = approxidate_careful(str, &num);
+	free(str);
+
+	dm = date_mode_from_type(dmtype);
+	dm.local = local;
+	show_date(ts, (int)tz, dm);
+
+	date_mode_release(&dm);
+
+	return 0;
+}
diff --git a/pack-bitmap-write.c b/pack-bitmap-write.c
index be4733e..c6c8f94 100644
--- a/pack-bitmap-write.c
+++ b/pack-bitmap-write.c
@@ -195,6 +195,13 @@ struct bb_commit {
 	unsigned idx; /* within selected array */
 };
 
+static void clear_bb_commit(struct bb_commit *commit)
+{
+	free_commit_list(commit->reverse_edges);
+	bitmap_free(commit->commit_mask);
+	bitmap_free(commit->bitmap);
+}
+
 define_commit_slab(bb_data, struct bb_commit);
 
 struct bitmap_builder {
@@ -336,7 +343,7 @@ static void bitmap_builder_init(struct bitmap_builder *bb,
 
 static void bitmap_builder_clear(struct bitmap_builder *bb)
 {
-	clear_bb_data(&bb->data);
+	deep_clear_bb_data(&bb->data, clear_bb_commit);
 	free(bb->commits);
 	bb->commits_nr = bb->commits_alloc = 0;
 }
@@ -363,7 +370,7 @@ static int fill_bitmap_tree(struct bitmap *bitmap,
 	if (parse_tree(tree) < 0)
 		die("unable to load tree object %s",
 		    oid_to_hex(&tree->object.oid));
-	init_tree_desc(&desc, tree->buffer, tree->size);
+	init_tree_desc(&desc, &tree->object.oid, tree->buffer, tree->size);
 
 	while (tree_entry(&desc, &entry)) {
 		switch (object_type(entry.mode)) {
diff --git a/pack-bitmap.c b/pack-bitmap.c
index c88dd35..35c5ef9 100644
--- a/pack-bitmap.c
+++ b/pack-bitmap.c
@@ -331,7 +331,7 @@ static int open_midx_bitmap_1(struct bitmap_index *bitmap_git,
 	struct stat st;
 	char *bitmap_name = midx_bitmap_filename(midx);
 	int fd = git_open(bitmap_name);
-	uint32_t i;
+	uint32_t i, preferred_pack;
 	struct packed_git *preferred;
 
 	if (fd < 0) {
@@ -386,7 +386,12 @@ static int open_midx_bitmap_1(struct bitmap_index *bitmap_git,
 		}
 	}
 
-	preferred = bitmap_git->midx->packs[midx_preferred_pack(bitmap_git)];
+	if (midx_preferred_pack(bitmap_git->midx, &preferred_pack) < 0) {
+		warning(_("could not determine MIDX preferred pack"));
+		goto cleanup;
+	}
+
+	preferred = bitmap_git->midx->packs[preferred_pack];
 	if (!is_pack_valid(preferred)) {
 		warning(_("preferred pack (%s) is invalid"),
 			preferred->pack_name);
@@ -1273,6 +1278,8 @@ static struct bitmap *find_objects(struct bitmap_index *bitmap_git,
 		base = fill_in_bitmap(bitmap_git, revs, base, seen);
 	}
 
+	object_list_free(&not_mapped);
+
 	return base;
 }
 
@@ -1827,8 +1834,10 @@ struct bitmap_index *prepare_bitmap_walk(struct rev_info *revs,
  * -1 means "stop trying further objects"; 0 means we may or may not have
  * reused, but you can keep feeding bits.
  */
-static int try_partial_reuse(struct packed_git *pack,
-			     size_t pos,
+static int try_partial_reuse(struct bitmap_index *bitmap_git,
+			     struct bitmapped_pack *pack,
+			     size_t bitmap_pos,
+			     uint32_t pack_pos,
 			     struct bitmap *reuse,
 			     struct pack_window **w_curs)
 {
@@ -1836,40 +1845,18 @@ static int try_partial_reuse(struct packed_git *pack,
 	enum object_type type;
 	unsigned long size;
 
-	/*
-	 * try_partial_reuse() is called either on (a) objects in the
-	 * bitmapped pack (in the case of a single-pack bitmap) or (b)
-	 * objects in the preferred pack of a multi-pack bitmap.
-	 * Importantly, the latter can pretend as if only a single pack
-	 * exists because:
-	 *
-	 *   - The first pack->num_objects bits of a MIDX bitmap are
-	 *     reserved for the preferred pack, and
-	 *
-	 *   - Ties due to duplicate objects are always resolved in
-	 *     favor of the preferred pack.
-	 *
-	 * Therefore we do not need to ever ask the MIDX for its copy of
-	 * an object by OID, since it will always select it from the
-	 * preferred pack. Likewise, the selected copy of the base
-	 * object for any deltas will reside in the same pack.
-	 *
-	 * This means that we can reuse pos when looking up the bit in
-	 * the reuse bitmap, too, since bits corresponding to the
-	 * preferred pack precede all bits from other packs.
-	 */
+	if (pack_pos >= pack->p->num_objects)
+		return -1; /* not actually in the pack */
 
-	if (pos >= pack->num_objects)
-		return -1; /* not actually in the pack or MIDX preferred pack */
-
-	offset = delta_obj_offset = pack_pos_to_offset(pack, pos);
-	type = unpack_object_header(pack, w_curs, &offset, &size);
+	offset = delta_obj_offset = pack_pos_to_offset(pack->p, pack_pos);
+	type = unpack_object_header(pack->p, w_curs, &offset, &size);
 	if (type < 0)
 		return -1; /* broken packfile, punt */
 
 	if (type == OBJ_REF_DELTA || type == OBJ_OFS_DELTA) {
 		off_t base_offset;
 		uint32_t base_pos;
+		uint32_t base_bitmap_pos;
 
 		/*
 		 * Find the position of the base object so we can look it up
@@ -1879,24 +1866,48 @@ static int try_partial_reuse(struct packed_git *pack,
 		 * and the normal slow path will complain about it in
 		 * more detail.
 		 */
-		base_offset = get_delta_base(pack, w_curs, &offset, type,
+		base_offset = get_delta_base(pack->p, w_curs, &offset, type,
 					     delta_obj_offset);
 		if (!base_offset)
 			return 0;
-		if (offset_to_pack_pos(pack, base_offset, &base_pos) < 0)
-			return 0;
 
-		/*
-		 * We assume delta dependencies always point backwards. This
-		 * lets us do a single pass, and is basically always true
-		 * due to the way OFS_DELTAs work. You would not typically
-		 * find REF_DELTA in a bitmapped pack, since we only bitmap
-		 * packs we write fresh, and OFS_DELTA is the default). But
-		 * let's double check to make sure the pack wasn't written with
-		 * odd parameters.
-		 */
-		if (base_pos >= pos)
-			return 0;
+		offset_to_pack_pos(pack->p, base_offset, &base_pos);
+
+		if (bitmap_is_midx(bitmap_git)) {
+			/*
+			 * Cross-pack deltas are rejected for now, but could
+			 * theoretically be supported in the future.
+			 *
+			 * We would need to ensure that we're sending both
+			 * halves of the delta/base pair, regardless of whether
+			 * or not the two cross a pack boundary. If they do,
+			 * then we must convert the delta to an REF_DELTA to
+			 * refer back to the base in the other pack.
+			 * */
+			if (midx_pair_to_pack_pos(bitmap_git->midx,
+						  pack->pack_int_id,
+						  base_offset,
+						  &base_bitmap_pos) < 0) {
+				return 0;
+			}
+		} else {
+			if (offset_to_pack_pos(pack->p, base_offset,
+					       &base_pos) < 0)
+				return 0;
+			/*
+			 * We assume delta dependencies always point backwards.
+			 * This lets us do a single pass, and is basically
+			 * always true due to the way OFS_DELTAs work. You would
+			 * not typically find REF_DELTA in a bitmapped pack,
+			 * since we only bitmap packs we write fresh, and
+			 * OFS_DELTA is the default). But let's double check to
+			 * make sure the pack wasn't written with odd
+			 * parameters.
+			 */
+			if (base_pos >= pack_pos)
+				return 0;
+			base_bitmap_pos = pack->bitmap_pos + base_pos;
+		}
 
 		/*
 		 * And finally, if we're not sending the base as part of our
@@ -1906,77 +1917,89 @@ static int try_partial_reuse(struct packed_git *pack,
 		 * to REF_DELTA on the fly. Better to just let the normal
 		 * object_entry code path handle it.
 		 */
-		if (!bitmap_get(reuse, base_pos))
+		if (!bitmap_get(reuse, base_bitmap_pos))
 			return 0;
 	}
 
 	/*
 	 * If we got here, then the object is OK to reuse. Mark it.
 	 */
-	bitmap_set(reuse, pos);
+	bitmap_set(reuse, bitmap_pos);
 	return 0;
 }
 
-uint32_t midx_preferred_pack(struct bitmap_index *bitmap_git)
+static void reuse_partial_packfile_from_bitmap_1(struct bitmap_index *bitmap_git,
+						 struct bitmapped_pack *pack,
+						 struct bitmap *reuse)
 {
-	struct multi_pack_index *m = bitmap_git->midx;
-	if (!m)
-		BUG("midx_preferred_pack: requires non-empty MIDX");
-	return nth_midxed_pack_int_id(m, pack_pos_to_midx(bitmap_git->midx, 0));
-}
-
-int reuse_partial_packfile_from_bitmap(struct bitmap_index *bitmap_git,
-				       struct packed_git **packfile_out,
-				       uint32_t *entries,
-				       struct bitmap **reuse_out)
-{
-	struct repository *r = the_repository;
-	struct packed_git *pack;
 	struct bitmap *result = bitmap_git->result;
-	struct bitmap *reuse;
 	struct pack_window *w_curs = NULL;
-	size_t i = 0;
-	uint32_t offset;
-	uint32_t objects_nr;
+	size_t pos = pack->bitmap_pos / BITS_IN_EWORD;
 
-	assert(result);
+	if (!pack->bitmap_pos) {
+		/*
+		 * If we're processing the first (in the case of a MIDX, the
+		 * preferred pack) or the only (in the case of single-pack
+		 * bitmaps) pack, then we can reuse whole words at a time.
+		 *
+		 * This is because we know that any deltas in this range *must*
+		 * have their bases chosen from the same pack, since:
+		 *
+		 * - In the single pack case, there is no other pack to choose
+		 *   them from.
+		 *
+		 * - In the MIDX case, the first pack is the preferred pack, so
+		 *   all ties are broken in favor of that pack (i.e. the one
+		 *   we're currently processing). So any duplicate bases will be
+		 *   resolved in favor of the pack we're processing.
+		 */
+		while (pos < result->word_alloc &&
+		       pos < pack->bitmap_nr / BITS_IN_EWORD &&
+		       result->words[pos] == (eword_t)~0)
+			pos++;
+		memset(reuse->words, 0xFF, pos * sizeof(eword_t));
+	}
 
-	load_reverse_index(r, bitmap_git);
+	for (; pos < result->word_alloc; pos++) {
+		eword_t word = result->words[pos];
+		size_t offset;
 
-	if (bitmap_is_midx(bitmap_git))
-		pack = bitmap_git->midx->packs[midx_preferred_pack(bitmap_git)];
-	else
-		pack = bitmap_git->pack;
-	objects_nr = pack->num_objects;
+		for (offset = 0; offset < BITS_IN_EWORD; offset++) {
+			size_t bit_pos;
+			uint32_t pack_pos;
 
-	while (i < result->word_alloc && result->words[i] == (eword_t)~0)
-		i++;
-
-	/*
-	 * Don't mark objects not in the packfile or preferred pack. This bitmap
-	 * marks objects eligible for reuse, but the pack-reuse code only
-	 * understands how to reuse a single pack. Since the preferred pack is
-	 * guaranteed to have all bases for its deltas (in a multi-pack bitmap),
-	 * we use it instead of another pack. In single-pack bitmaps, the choice
-	 * is made for us.
-	 */
-	if (i > objects_nr / BITS_IN_EWORD)
-		i = objects_nr / BITS_IN_EWORD;
-
-	reuse = bitmap_word_alloc(i);
-	memset(reuse->words, 0xFF, i * sizeof(eword_t));
-
-	for (; i < result->word_alloc; ++i) {
-		eword_t word = result->words[i];
-		size_t pos = (i * BITS_IN_EWORD);
-
-		for (offset = 0; offset < BITS_IN_EWORD; ++offset) {
-			if ((word >> offset) == 0)
+			if (word >> offset == 0)
 				break;
 
 			offset += ewah_bit_ctz64(word >> offset);
-			if (try_partial_reuse(pack, pos + offset,
-					      reuse, &w_curs) < 0) {
+
+			bit_pos = pos * BITS_IN_EWORD + offset;
+			if (bit_pos < pack->bitmap_pos)
+				continue;
+			if (bit_pos >= pack->bitmap_pos + pack->bitmap_nr)
+				goto done;
+
+			if (bitmap_is_midx(bitmap_git)) {
+				uint32_t midx_pos;
+				off_t ofs;
+
+				midx_pos = pack_pos_to_midx(bitmap_git->midx, bit_pos);
+				ofs = nth_midxed_offset(bitmap_git->midx, midx_pos);
+
+				if (offset_to_pack_pos(pack->p, ofs, &pack_pos) < 0)
+					BUG("could not find object in pack %s "
+					    "at offset %"PRIuMAX" in MIDX",
+					    pack_basename(pack->p), (uintmax_t)ofs);
+			} else {
+				pack_pos = cast_size_t_to_uint32_t(st_sub(bit_pos, pack->bitmap_pos));
+				if (pack_pos >= pack->p->num_objects)
+					BUG("advanced beyond the end of pack %s (%"PRIuMAX" > %"PRIu32")",
+					    pack_basename(pack->p), (uintmax_t)pack_pos,
+					    pack->p->num_objects);
+			}
+
+			if (try_partial_reuse(bitmap_git, pack, bit_pos,
+					      pack_pos, reuse, &w_curs) < 0) {
 				/*
 				 * try_partial_reuse indicated we couldn't reuse
 				 * any bits, so there is no point in trying more
@@ -1993,11 +2016,98 @@ int reuse_partial_packfile_from_bitmap(struct bitmap_index *bitmap_git,
 
 done:
 	unuse_pack(&w_curs);
+}
 
-	*entries = bitmap_popcount(reuse);
-	if (!*entries) {
-		bitmap_free(reuse);
+static int bitmapped_pack_cmp(const void *va, const void *vb)
+{
+	const struct bitmapped_pack *a = va;
+	const struct bitmapped_pack *b = vb;
+
+	if (a->bitmap_pos < b->bitmap_pos)
 		return -1;
+	if (a->bitmap_pos > b->bitmap_pos)
+		return 1;
+	return 0;
+}
+
+void reuse_partial_packfile_from_bitmap(struct bitmap_index *bitmap_git,
+					struct bitmapped_pack **packs_out,
+					size_t *packs_nr_out,
+					struct bitmap **reuse_out,
+					int multi_pack_reuse)
+{
+	struct repository *r = the_repository;
+	struct bitmapped_pack *packs = NULL;
+	struct bitmap *result = bitmap_git->result;
+	struct bitmap *reuse;
+	size_t i;
+	size_t packs_nr = 0, packs_alloc = 0;
+	size_t word_alloc;
+	uint32_t objects_nr = 0;
+
+	assert(result);
+
+	load_reverse_index(r, bitmap_git);
+
+	if (!bitmap_is_midx(bitmap_git) || !bitmap_git->midx->chunk_bitmapped_packs)
+		multi_pack_reuse = 0;
+
+	if (multi_pack_reuse) {
+		for (i = 0; i < bitmap_git->midx->num_packs; i++) {
+			struct bitmapped_pack pack;
+			if (nth_bitmapped_pack(r, bitmap_git->midx, &pack, i) < 0) {
+				warning(_("unable to load pack: '%s', disabling pack-reuse"),
+					bitmap_git->midx->pack_names[i]);
+				free(packs);
+				return;
+			}
+
+			if (!pack.bitmap_nr)
+				continue;
+
+			ALLOC_GROW(packs, packs_nr + 1, packs_alloc);
+			memcpy(&packs[packs_nr++], &pack, sizeof(pack));
+
+			objects_nr += pack.p->num_objects;
+		}
+
+		QSORT(packs, packs_nr, bitmapped_pack_cmp);
+	} else {
+		struct packed_git *pack;
+
+		if (bitmap_is_midx(bitmap_git)) {
+			uint32_t preferred_pack_pos;
+
+			if (midx_preferred_pack(bitmap_git->midx, &preferred_pack_pos) < 0) {
+				warning(_("unable to compute preferred pack, disabling pack-reuse"));
+				return;
+			}
+
+			pack = bitmap_git->midx->packs[preferred_pack_pos];
+		} else {
+			pack = bitmap_git->pack;
+		}
+
+		ALLOC_GROW(packs, packs_nr + 1, packs_alloc);
+		packs[packs_nr].p = pack;
+		packs[packs_nr].bitmap_nr = pack->num_objects;
+		packs[packs_nr].bitmap_pos = 0;
+
+		objects_nr = packs[packs_nr++].bitmap_nr;
+	}
+
+	word_alloc = objects_nr / BITS_IN_EWORD;
+	if (objects_nr % BITS_IN_EWORD)
+		word_alloc++;
+	reuse = bitmap_word_alloc(word_alloc);
+
+	for (i = 0; i < packs_nr; i++)
+		reuse_partial_packfile_from_bitmap_1(bitmap_git, &packs[i], reuse);
+
+	if (bitmap_is_empty(reuse)) {
+		free(packs);
+		bitmap_free(reuse);
+		return;
 	}
 
 	/*
@@ -2005,9 +2115,9 @@ int reuse_partial_packfile_from_bitmap(struct bitmap_index *bitmap_git,
 	 * need to be handled separately.
 	 */
 	bitmap_and_not(result, reuse);
-	*packfile_out = pack;
+	*packs_out = packs;
+	*packs_nr_out = packs_nr;
 	*reuse_out = reuse;
-	return 0;
 }
 
 int bitmap_walk_contains(struct bitmap_index *bitmap_git,
diff --git a/pack-bitmap.h b/pack-bitmap.h
index 5273a6a..c7dea13 100644
--- a/pack-bitmap.h
+++ b/pack-bitmap.h
@@ -52,6 +52,15 @@ typedef int (*show_reachable_fn)(
 
 struct bitmap_index;
 
+struct bitmapped_pack {
+	struct packed_git *p;
+
+	uint32_t bitmap_pos;
+	uint32_t bitmap_nr;
+
+	uint32_t pack_int_id; /* MIDX only */
+};
+
 struct bitmap_index *prepare_bitmap_git(struct repository *r);
 struct bitmap_index *prepare_midx_bitmap_git(struct multi_pack_index *midx);
 void count_bitmap_commit_list(struct bitmap_index *, uint32_t *commits,
@@ -68,11 +77,11 @@ int test_bitmap_hashes(struct repository *r);
 
 struct bitmap_index *prepare_bitmap_walk(struct rev_info *revs,
 					 int filter_provided_objects);
-uint32_t midx_preferred_pack(struct bitmap_index *bitmap_git);
-int reuse_partial_packfile_from_bitmap(struct bitmap_index *,
-				       struct packed_git **packfile,
-				       uint32_t *entries,
-				       struct bitmap **reuse_out);
+void reuse_partial_packfile_from_bitmap(struct bitmap_index *bitmap_git,
+					struct bitmapped_pack **packs_out,
+					size_t *packs_nr_out,
+					struct bitmap **reuse_out,
+					int multi_pack_reuse);
 int rebuild_existing_bitmaps(struct bitmap_index *, struct packing_data *mapping,
 			     kh_oid_map_t *reused_bitmaps, int show_progress);
 void free_bitmap_index(struct bitmap_index *);
diff --git a/pack-objects.c b/pack-objects.c
index f403ca6..a9d9855 100644
--- a/pack-objects.c
+++ b/pack-objects.c
@@ -151,6 +151,21 @@ void prepare_packing_data(struct repository *r, struct packing_data *pdata)
 	init_recursive_mutex(&pdata->odb_lock);
 }
 
+void clear_packing_data(struct packing_data *pdata)
+{
+	if (!pdata)
+		return;
+
+	free(pdata->cruft_mtime);
+	free(pdata->in_pack);
+	free(pdata->in_pack_by_idx);
+	free(pdata->in_pack_pos);
+	free(pdata->index);
+	free(pdata->layer);
+	free(pdata->objects);
+	free(pdata->tree_depth);
+}
+
 struct object_entry *packlist_alloc(struct packing_data *pdata,
 				    const struct object_id *oid)
 {
diff --git a/pack-objects.h b/pack-objects.h
index 0d78db4..b9898a4 100644
--- a/pack-objects.h
+++ b/pack-objects.h
@@ -169,6 +169,7 @@ struct packing_data {
 };
 
 void prepare_packing_data(struct repository *r, struct packing_data *pdata);
+void clear_packing_data(struct packing_data *pdata);
 
 /* Protect access to object database */
 static inline void packing_data_lock(struct packing_data *pdata)
diff --git a/pack-revindex.c b/pack-revindex.c
index acf1dd9..a7624d8 100644
--- a/pack-revindex.c
+++ b/pack-revindex.c
@@ -520,19 +520,12 @@ static int midx_pack_order_cmp(const void *va, const void *vb)
 	return 0;
 }
 
-int midx_to_pack_pos(struct multi_pack_index *m, uint32_t at, uint32_t *pos)
+static int midx_key_to_pack_pos(struct multi_pack_index *m,
+				struct midx_pack_key *key,
+				uint32_t *pos)
 {
-	struct midx_pack_key key;
 	uint32_t *found;
 
-	if (!m->revindex_data)
-		BUG("midx_to_pack_pos: reverse index not yet loaded");
-	if (m->num_objects <= at)
-		BUG("midx_to_pack_pos: out-of-bounds object at %"PRIu32, at);
-
-	key.pack = nth_midxed_pack_int_id(m, at);
-	key.offset = nth_midxed_offset(m, at);
-	key.midx = m;
 	/*
 	 * The preferred pack sorts first, so determine its identifier by
 	 * looking at the first object in pseudo-pack order.
@@ -542,14 +535,43 @@ int midx_to_pack_pos(struct multi_pack_index *m, uint32_t at, uint32_t *pos)
 	 * implicitly is preferred (and includes all its objects, since ties are
 	 * broken first by pack identifier).
 	 */
-	key.preferred_pack = nth_midxed_pack_int_id(m, pack_pos_to_midx(m, 0));
+	if (midx_preferred_pack(key->midx, &key->preferred_pack) < 0)
+		return error(_("could not determine preferred pack"));
 
-	found = bsearch(&key, m->revindex_data, m->num_objects,
-			sizeof(*m->revindex_data), midx_pack_order_cmp);
+	found = bsearch(key, m->revindex_data, m->num_objects,
+			sizeof(*m->revindex_data),
+			midx_pack_order_cmp);
 
 	if (!found)
-		return error("bad offset for revindex");
+		return -1;
 
 	*pos = found - m->revindex_data;
 	return 0;
 }
+
+int midx_to_pack_pos(struct multi_pack_index *m, uint32_t at, uint32_t *pos)
+{
+	struct midx_pack_key key;
+
+	if (!m->revindex_data)
+		BUG("midx_to_pack_pos: reverse index not yet loaded");
+	if (m->num_objects <= at)
+		BUG("midx_to_pack_pos: out-of-bounds object at %"PRIu32, at);
+
+	key.pack = nth_midxed_pack_int_id(m, at);
+	key.offset = nth_midxed_offset(m, at);
+	key.midx = m;
+
+	return midx_key_to_pack_pos(m, &key, pos);
+}
+
+int midx_pair_to_pack_pos(struct multi_pack_index *m, uint32_t pack_int_id,
+			  off_t ofs, uint32_t *pos)
+{
+	struct midx_pack_key key = {
+		.pack = pack_int_id,
+		.offset = ofs,
+		.midx = m,
+	};
+	return midx_key_to_pack_pos(m, &key, pos);
+}
diff --git a/pack-revindex.h b/pack-revindex.h
index 6dd47ef..422c248 100644
--- a/pack-revindex.h
+++ b/pack-revindex.h
@@ -142,4 +142,7 @@ uint32_t pack_pos_to_midx(struct multi_pack_index *m, uint32_t pos);
  */
 int midx_to_pack_pos(struct multi_pack_index *midx, uint32_t at, uint32_t *pos);
 
+int midx_pair_to_pack_pos(struct multi_pack_index *midx, uint32_t pack_id,
+			  off_t ofs, uint32_t *pos);
+
 #endif
diff --git a/packfile.c b/packfile.c
index 84a0056..d4df7fd 100644
--- a/packfile.c
+++ b/packfile.c
@@ -2249,7 +2249,8 @@ static int add_promisor_object(const struct object_id *oid,
 		struct tree *tree = (struct tree *)obj;
 		struct tree_desc desc;
 		struct name_entry entry;
-		if (init_tree_desc_gently(&desc, tree->buffer, tree->size, 0))
+		if (init_tree_desc_gently(&desc, &tree->object.oid,
+					  tree->buffer, tree->size, 0))
 			/*
 			 * Error messages are given when packs are
 			 * verified, so do not print any here.
diff --git a/parse-options.c b/parse-options.c
index 63a99de..30b9e68 100644
--- a/parse-options.c
+++ b/parse-options.c
@@ -350,98 +350,107 @@ static int is_alias(struct parse_opt_ctx_t *ctx,
 	return 0;
 }
 
+struct parsed_option {
+	const struct option *option;
+	enum opt_parsed flags;
+};
+
+static void register_abbrev(struct parse_opt_ctx_t *p,
+			    const struct option *option, enum opt_parsed flags,
+			    struct parsed_option *abbrev,
+			    struct parsed_option *ambiguous)
+{
+	if (p->flags & PARSE_OPT_KEEP_UNKNOWN_OPT)
+		return;
+	if (abbrev->option &&
+	    !(abbrev->flags == flags && is_alias(p, abbrev->option, option))) {
+		/*
+		 * If this is abbreviated, it is
+		 * ambiguous. So when there is no
+		 * exact match later, we need to
+		 * error out.
+		 */
+		ambiguous->option = abbrev->option;
+		ambiguous->flags = abbrev->flags;
+	}
+	abbrev->option = option;
+	abbrev->flags = flags;
+}
+
 static enum parse_opt_result parse_long_opt(
 	struct parse_opt_ctx_t *p, const char *arg,
 	const struct option *options)
 {
 	const char *arg_end = strchrnul(arg, '=');
-	const struct option *abbrev_option = NULL, *ambiguous_option = NULL;
-	enum opt_parsed abbrev_flags = OPT_LONG, ambiguous_flags = OPT_LONG;
-	int allow_abbrev = !(p->flags & PARSE_OPT_KEEP_UNKNOWN_OPT);
+	const char *arg_start = arg;
+	enum opt_parsed flags = OPT_LONG;
+	int arg_starts_with_no_no = 0;
+	struct parsed_option abbrev = { .option = NULL, .flags = OPT_LONG };
+	struct parsed_option ambiguous = { .option = NULL, .flags = OPT_LONG };
+
+	if (skip_prefix(arg_start, "no-", &arg_start)) {
+		if (skip_prefix(arg_start, "no-", &arg_start))
+			arg_starts_with_no_no = 1;
+		else
+			flags |= OPT_UNSET;
+	}
 
 	for (; options->type != OPTION_END; options++) {
 		const char *rest, *long_name = options->long_name;
-		enum opt_parsed flags = OPT_LONG, opt_flags = OPT_LONG;
+		enum opt_parsed opt_flags = OPT_LONG;
+		int allow_unset = !(options->flags & PARSE_OPT_NONEG);
 
 		if (options->type == OPTION_SUBCOMMAND)
 			continue;
 		if (!long_name)
 			continue;
 
-		if (!starts_with(arg, "no-") &&
-		    !(options->flags & PARSE_OPT_NONEG) &&
-		    skip_prefix(long_name, "no-", &long_name))
+		if (skip_prefix(long_name, "no-", &long_name))
 			opt_flags |= OPT_UNSET;
+		else if (arg_starts_with_no_no)
+			continue;
 
-		if (!skip_prefix(arg, long_name, &rest))
-			rest = NULL;
-		if (!rest) {
-			/* abbreviated? */
-			if (allow_abbrev &&
-			    !strncmp(long_name, arg, arg_end - arg)) {
-is_abbreviated:
-				if (abbrev_option &&
-				    !is_alias(p, abbrev_option, options)) {
-					/*
-					 * If this is abbreviated, it is
-					 * ambiguous. So when there is no
-					 * exact match later, we need to
-					 * error out.
-					 */
-					ambiguous_option = abbrev_option;
-					ambiguous_flags = abbrev_flags;
-				}
-				if (!(flags & OPT_UNSET) && *arg_end)
-					p->opt = arg_end + 1;
-				abbrev_option = options;
-				abbrev_flags = flags ^ opt_flags;
+		if (((flags ^ opt_flags) & OPT_UNSET) && !allow_unset)
+			continue;
+
+		if (skip_prefix(arg_start, long_name, &rest)) {
+			if (*rest == '=')
+				p->opt = rest + 1;
+			else if (*rest)
 				continue;
-			}
-			/* negation allowed? */
-			if (options->flags & PARSE_OPT_NONEG)
-				continue;
-			/* negated and abbreviated very much? */
-			if (allow_abbrev && starts_with("no-", arg)) {
-				flags |= OPT_UNSET;
-				goto is_abbreviated;
-			}
-			/* negated? */
-			if (!starts_with(arg, "no-"))
-				continue;
-			flags |= OPT_UNSET;
-			if (!skip_prefix(arg + 3, long_name, &rest)) {
-				/* abbreviated and negated? */
-				if (allow_abbrev &&
-				    starts_with(long_name, arg + 3))
-					goto is_abbreviated;
-				else
-					continue;
-			}
+			return get_value(p, options, flags ^ opt_flags);
 		}
-		if (*rest) {
-			if (*rest != '=')
-				continue;
-			p->opt = rest + 1;
-		}
-		return get_value(p, options, flags ^ opt_flags);
+
+		/* abbreviated? */
+		if (!strncmp(long_name, arg_start, arg_end - arg_start))
+			register_abbrev(p, options, flags ^ opt_flags,
+					&abbrev, &ambiguous);
+
+		/* negated and abbreviated very much? */
+		if (allow_unset && starts_with("no-", arg))
+			register_abbrev(p, options, OPT_UNSET ^ opt_flags,
+					&abbrev, &ambiguous);
 	}
 
-	if (disallow_abbreviated_options && (ambiguous_option || abbrev_option))
+	if (disallow_abbreviated_options && (ambiguous.option || abbrev.option))
 		die("disallowed abbreviated or ambiguous option '%.*s'",
 		    (int)(arg_end - arg), arg);
 
-	if (ambiguous_option) {
+	if (ambiguous.option) {
 		error(_("ambiguous option: %s "
 			"(could be --%s%s or --%s%s)"),
 			arg,
-			(ambiguous_flags & OPT_UNSET) ?  "no-" : "",
-			ambiguous_option->long_name,
-			(abbrev_flags & OPT_UNSET) ?  "no-" : "",
-			abbrev_option->long_name);
+			(ambiguous.flags & OPT_UNSET) ?  "no-" : "",
+			ambiguous.option->long_name,
+			(abbrev.flags & OPT_UNSET) ?  "no-" : "",
+			abbrev.option->long_name);
 		return PARSE_OPT_HELP;
 	}
-	if (abbrev_option)
-		return get_value(p, abbrev_option, abbrev_flags);
+	if (abbrev.option) {
+		if (*arg_end)
+			p->opt = arg_end + 1;
+		return get_value(p, abbrev.option, abbrev.flags);
+	}
 	return PARSE_OPT_UNKNOWN;
 }
 
diff --git a/path.c b/path.c
index 67e2690..d838d4b 100644
--- a/path.c
+++ b/path.c
@@ -28,8 +28,6 @@ static int get_st_mode_bits(const char *path, int *mode)
 	return 0;
 }
 
-static char bad_path[] = "/bad-path/";
-
 static struct strbuf *get_pathname(void)
 {
 	static struct strbuf pathname_array[4] = {
@@ -59,21 +57,6 @@ static void strbuf_cleanup_path(struct strbuf *sb)
 		strbuf_remove(sb, 0, path - sb->buf);
 }
 
-char *mksnpath(char *buf, size_t n, const char *fmt, ...)
-{
-	va_list args;
-	unsigned len;
-
-	va_start(args, fmt);
-	len = vsnprintf(buf, n, fmt, args);
-	va_end(args);
-	if (len >= n) {
-		strlcpy(buf, bad_path, n);
-		return buf;
-	}
-	return (char *)cleanup_path(buf);
-}
-
 static int dir_prefix(const char *buf, const char *dir)
 {
 	int len = strlen(dir);
@@ -846,6 +829,7 @@ const char *enter_repo(const char *path, int strict)
 		if (!suffix[i])
 			return NULL;
 		gitfile = read_gitfile(used_path.buf);
+		die_upon_dubious_ownership(gitfile, NULL, used_path.buf);
 		if (gitfile) {
 			strbuf_reset(&used_path);
 			strbuf_addstr(&used_path, gitfile);
@@ -856,6 +840,7 @@ const char *enter_repo(const char *path, int strict)
 	}
 	else {
 		const char *gitfile = read_gitfile(path);
+		die_upon_dubious_ownership(gitfile, NULL, path);
 		if (gitfile)
 			path = gitfile;
 		if (chdir(path))
@@ -871,7 +856,7 @@ const char *enter_repo(const char *path, int strict)
 	return NULL;
 }
 
-static int calc_shared_perm(int mode)
+int calc_shared_perm(int mode)
 {
 	int tweak;
 
@@ -1588,7 +1573,5 @@ REPO_GIT_PATH_FUNC(merge_msg, "MERGE_MSG")
 REPO_GIT_PATH_FUNC(merge_rr, "MERGE_RR")
 REPO_GIT_PATH_FUNC(merge_mode, "MERGE_MODE")
 REPO_GIT_PATH_FUNC(merge_head, "MERGE_HEAD")
-REPO_GIT_PATH_FUNC(merge_autostash, "MERGE_AUTOSTASH")
-REPO_GIT_PATH_FUNC(auto_merge, "AUTO_MERGE")
 REPO_GIT_PATH_FUNC(fetch_head, "FETCH_HEAD")
 REPO_GIT_PATH_FUNC(shallow, "shallow")
diff --git a/path.h b/path.h
index 639372e..ea96487 100644
--- a/path.h
+++ b/path.h
@@ -24,12 +24,6 @@ char *mkpathdup(const char *fmt, ...)
 	__attribute__((format (printf, 1, 2)));
 
 /*
- * Construct a path and place the result in the provided buffer `buf`.
- */
-char *mksnpath(char *buf, size_t n, const char *fmt, ...)
-	__attribute__((format (printf, 3, 4)));
-
-/*
  * The `git_common_path` family of functions will construct a path into a
  * repository's common git directory, which is shared by all worktrees.
  */
@@ -175,14 +169,13 @@ const char *git_path_merge_msg(struct repository *r);
 const char *git_path_merge_rr(struct repository *r);
 const char *git_path_merge_mode(struct repository *r);
 const char *git_path_merge_head(struct repository *r);
-const char *git_path_merge_autostash(struct repository *r);
-const char *git_path_auto_merge(struct repository *r);
 const char *git_path_fetch_head(struct repository *r);
 const char *git_path_shallow(struct repository *r);
 
 int ends_with_path_components(const char *path, const char *components);
 int validate_headref(const char *ref);
 
+int calc_shared_perm(int mode);
 int adjust_shared_perm(const char *path);
 
 char *interpolate_path(const char *path, int real_home);
diff --git a/pathspec.c b/pathspec.c
index bb1efe1..2133b9f 100644
--- a/pathspec.c
+++ b/pathspec.c
@@ -109,16 +109,37 @@ static struct pathspec_magic {
 	{ PATHSPEC_ATTR,    '\0', "attr" },
 };
 
-static void prefix_magic(struct strbuf *sb, int prefixlen, unsigned magic)
+static void prefix_magic(struct strbuf *sb, int prefixlen,
+			 unsigned magic, const char *element)
 {
-	int i;
-	strbuf_addstr(sb, ":(");
-	for (i = 0; i < ARRAY_SIZE(pathspec_magic); i++)
-		if (magic & pathspec_magic[i].bit) {
-			if (sb->buf[sb->len - 1] != '(')
-				strbuf_addch(sb, ',');
-			strbuf_addstr(sb, pathspec_magic[i].name);
+	/* No magic was found in element, just add prefix magic */
+	if (!magic) {
+		strbuf_addf(sb, ":(prefix:%d)", prefixlen);
+		return;
+	}
+
+	/*
+	 * At this point, we know that parse_element_magic() was able
+	 * to extract some pathspec magic from element. So we know
+	 * element is correctly formatted in either shorthand or
+	 * longhand form
+	 */
+	if (element[1] != '(') {
+		/* Process an element in shorthand form (e.g. ":!/<match>") */
+		strbuf_addstr(sb, ":(");
+		for (int i = 0; i < ARRAY_SIZE(pathspec_magic); i++) {
+			if ((magic & pathspec_magic[i].bit) &&
+			    pathspec_magic[i].mnemonic) {
+				if (sb->buf[sb->len - 1] != '(')
+					strbuf_addch(sb, ',');
+				strbuf_addstr(sb, pathspec_magic[i].name);
+			}
 		}
+	} else {
+		/* For the longhand form, we copy everything up to the final ')' */
+		size_t len = strchr(element, ')') - element;
+		strbuf_add(sb, element, len);
+	}
 	strbuf_addf(sb, ",prefix:%d)", prefixlen);
 }
 
@@ -493,7 +514,7 @@ static void init_pathspec_item(struct pathspec_item *item, unsigned flags,
 		struct strbuf sb = STRBUF_INIT;
 
 		/* Preserve the actual prefix length of each pattern */
-		prefix_magic(&sb, prefixlen, element_magic);
+		prefix_magic(&sb, prefixlen, element_magic, elt);
 
 		strbuf_addstr(&sb, match);
 		item->original = strbuf_detach(&sb, NULL);
diff --git a/po/TEAMS b/po/TEAMS
index 87df7c6..2775a97 100644
--- a/po/TEAMS
+++ b/po/TEAMS
@@ -18,11 +18,11 @@
 
 Language:	el (Greek)
 Repository:	https://github.com/vyruss/git-po-el
-Leader:		Jimmy Angelakos <vyruss@hellug.gr>
+Members:	Jimmy Angelakos <vyruss@hellug.gr>
 
 Language:	es (Spanish)
 Repository:	https://github.com/ChrisADR/git-po
-Leader:		Christopher Díaz <christopher.diaz.riv@gmail.com>
+Members:	Christopher Díaz <christopher.diaz.riv@gmail.com>
 
 Language:	fr (French)
 Repository:	https://github.com/jnavila/git
@@ -34,25 +34,25 @@
 Leader:		Bagas Sanjaya <bagasdotme@gmail.com>
 
 Language:	is (Icelandic)
-Leader:		Ævar Arnfjörð Bjarmason <avarab@gmail.com>
+Members:	Ævar Arnfjörð Bjarmason <avarab@gmail.com>
 
 Language:	it (Italian)
 Repository:	https://github.com/AlessandroMenti/git-po
-Leader:		Alessandro Menti <alessandro.menti@alessandromenti.it>
+Members:	Alessandro Menti <alessandro.menti@alessandromenti.it>
 
 Language:	ko (Korean)
 Repository:	https://github.com/git-l10n-ko/git-l10n-ko/
-Leader:		Gwan-gyeong Mun <elongbug@gmail.com>
-Members:	Changwoo Ryu <cwryu@debian.org>
+Members:	Gwan-gyeong Mun <elongbug@gmail.com>
+		Changwoo Ryu <cwryu@debian.org>
 		Sihyeon Jang <uneedsihyeon@gmail.com>
 
 Language:	pl (Polish)
 Repository:	https://github.com/Arusekk/git-po
-Leader:		Arusekk <arek_koz@o2.pl>
+Members:	Arusekk <arek_koz@o2.pl>
 
 Language:	pt_PT (Portuguese - Portugal)
 Repository:	https://gitlab.com/alexandre1985/git-pt/
-Leader:		Daniel Santos <dacs.git@brilhante.top>
+Members:	Daniel Santos <dacs.git@brilhante.top>
 
 Language:	ru (Russian)
 Repository:	https://github.com/DJm00n/git-po-ru/
@@ -73,9 +73,10 @@
 Members:	Kateryna Golovanova <kate@kgthreads.com>
 
 Language:	vi (Vietnamese)
-Repository:	https://github.com/vnwildman/git/
-Leader:		Trần Ngọc Quân <vnwildman AT gmail.com>
-Members:	Nguyễn Thái Ngọc Duy <pclouds AT gmail.com>
+Repository:	https://github.com/Nekosha/git-po/
+Leader:		Vũ Tiến Hưng <newcomerminecraft@gmail.com>
+Members:	Trần Ngọc Quân <vnwildman AT gmail.com>
+		Nguyễn Thái Ngọc Duy <pclouds AT gmail.com>
 
 Language:	zh_CN (Simplified Chinese)
 Repository:	https://github.com/dyrone/git/
diff --git a/po/bg.po b/po/bg.po
index a3fc5b7..a7cbc61 100644
--- a/po/bg.po
+++ b/po/bg.po
@@ -1,7 +1,7 @@
 # Bulgarian translation of git po-file.
-# Copyright (C) 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023 Alexander Shopov <ash@kambanaria.org>.
+# Copyright (C) 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024 Alexander Shopov <ash@kambanaria.org>.
 # This file is distributed under the same license as the git package.
-# Alexander Shopov <ash@kambanaria.org>, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023.
+# Alexander Shopov <ash@kambanaria.org>, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024.
 # ========================
 # DICTIONARY TO MERGE IN GIT GUI
 # ------------------------
@@ -141,6 +141,8 @@
 # midx, multi-pack index - файл с индекса за множество пакети
 # overlay mode - припокриващ режим (при изтеглянe)
 # incremental file нарастващ файл
+# commit-graph граф с подавания
+# commit-graph chain верига на гра̀фа с подавания
 # split (commit-graphr) раздробен (граф с подавания)
 # clobber (a tag) презаписвам (етикет)
 # blame извеждане на авторство
@@ -189,7 +191,7 @@
 # resolve-undo отмяна на разрешените подавания
 # resolve conflict коригирам конфликт
 # resolve reference установяване на обекта, сочен от указателя, проследяване на указателя
-# cannot resolve reference  не може да сее открие към какво сочи указателят
+# cannot resolve reference  не може да се открие към какво сочи указателят
 # maintenance задачи по поддръжка
 # GLE последна грешка в нишката - от GetLatError: https://learn.microsoft.com/en-us/windows/win32/api/errhandlingapi/nf-errhandlingapi-getlasterror
 # lookup table таблица със съответствия
@@ -207,6 +209,18 @@
 # master/main branch основен клон
 # unborn/orphan branch неродѐн клон (а не несъздаден) - клон без никакви подавания, включително и началното
 # parse анализ, анализирам
+# reinitialize repository зануляване на хранилището и инициализиране
+# replay изпълняване/прилагане наново
+# BTMP chunk откъс за побитова маска
+# OID fanout chunk откъс за разпределянето
+# OID lookup chunk  откъс за търсенето
+# autostash автоматично скатано
+# symref файл с указател (regular file that stores a string that begins with ref: refs/)
+# human-readable четим от хора
+# pseudoref псевдоуказател, напр. MERGE_HEAD, CHERRY_PICK_HEAD, REVERT_HEAD или REBASE_HEAD
+# reftable таблица с указатели
+# its referent '%s' сочещия го „%s“
+#
 #
 # ------------------------
 # „$var“ - може да не сработва за shell има gettext и eval_gettext - проверка - намират се лесно по „$
@@ -233,10 +247,10 @@
 # for i in `sort -u FILES`; do cnt=`grep $i FILES | wc -l`; echo $cnt $i ;done | sort -n
 msgid ""
 msgstr ""
-"Project-Id-Version: git 2.43\n"
+"Project-Id-Version: git 2.45\n"
 "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2023-11-17 15:49+0100\n"
-"PO-Revision-Date: 2023-11-18 13:23+0100\n"
+"POT-Creation-Date: 2024-04-21 16:59+0200\n"
+"PO-Revision-Date: 2024-04-21 17:00+0200\n"
 "Last-Translator: Alexander Shopov <ash@kambanaria.org>\n"
 "Language-Team: Bulgarian <dict@fsa-bg.org>\n"
 "Language: bg\n"
@@ -738,13 +752,13 @@
 "---\n"
 "To remove '%c' lines, make them ' ' lines (context).\n"
 "To remove '%c' lines, delete them.\n"
-"Lines starting with %c will be removed.\n"
+"Lines starting with %s will be removed.\n"
 msgstr ""
 "———\n"
 "За да пропуснете редовете, започващи с „%c“: заменете знака с „ “ (стават "
 "контекст)\n"
 "За да пропуснете редовете, започващи с „%c“: изтрийте ги.\n"
-"Редовете, които започват с „%c“ ще се пропуснат.\n"
+"Редовете, които започват с „%s“ ще се пропуснат.\n"
 
 msgid ""
 "If it does not apply cleanly, you will be given an opportunity to\n"
@@ -771,8 +785,8 @@
 "Your edited hunk does not apply. Edit again (saying \"no\" discards!) [y/n]? "
 msgstr ""
 "Редактираното парче не може да се приложи.  Да се продължи ли с "
-"редактирането? (текущите редакции ще се отменят при отказ!): „y“ (да)/ "
-"„n“ (не)? "
+"редактирането? (текущите редакции ще се отменят при отказ!): „y“ (да)/ „n“ "
+"(не)? "
 
 msgid "The selected hunks do not apply to the index!"
 msgstr "Избраните парчета не може да се добавят в индекса!"
@@ -792,6 +806,7 @@
 "/ - search for a hunk matching the given regex\n"
 "s - split the current hunk into smaller hunks\n"
 "e - manually edit the current hunk\n"
+"p - print the current hunk\n"
 "? - print help\n"
 msgstr ""
 "j — без решение за парчето, към следващото парче без решение\n"
@@ -802,7 +817,8 @@
 "/ — търсене на парче, напасващо към даден регулярен израз\n"
 "s — разделяне на текущото парче на по-малки\n"
 "e — ръчно редактиране на текущото парче\n"
-"? — извеждане не помощта\n"
+"p — извеждане на текущото парче\n"
+"? — извеждане на помощта\n"
 
 msgid "No previous hunk"
 msgstr "Няма друго парче преди това"
@@ -866,8 +882,8 @@
 "    git config advice.%s false"
 
 #, c-format
-msgid "%shint: %.*s%s\n"
-msgstr "%sподсказка: %.*s%s\n"
+msgid "%shint:%s%.*s%s\n"
+msgstr "%sподсказка:%s%.*s%s\n"
 
 msgid "Cherry-picking is not possible because you have unmerged files."
 msgstr "Отбирането на подавания е блокирано от неслети файлове."
@@ -1691,6 +1707,10 @@
 msgstr "Неочаквана опция „--output“"
 
 #, c-format
+msgid "extra command line parameter '%s'"
+msgstr "излишна опция или стойност на командния ред: „%s“"
+
+#, c-format
 msgid "Unknown archive format '%s'"
 msgstr "Непознат формат на архив: „%s“"
 
@@ -1738,6 +1758,14 @@
 "„GIT_ATTR_SOURCE“"
 
 #, c-format
+msgid "unable to stat '%s'"
+msgstr "„stat“ не може да се изпълни върху „%s“"
+
+#, c-format
+msgid "unable to read %s"
+msgstr "обектът „%s“ не може да бъде прочетен"
+
+#, c-format
 msgid "Badly quoted content in file '%s': %s"
 msgstr "Неправилно цитирано съдържание във файла „%s“: %s"
 
@@ -1958,6 +1986,12 @@
 msgid "'%s' is not a valid branch name"
 msgstr "„%s“ не е позволено име за клон"
 
+msgid "See `man git check-ref-format`"
+msgstr ""
+"Вижте страницата в ръководството:\n"
+"\n"
+"    git check-ref-format"
+
 #, c-format
 msgid "a branch named '%s' already exists"
 msgstr "вече съществува клон с име „%s“."
@@ -2156,15 +2190,8 @@
 msgid "adding embedded git repository: %s"
 msgstr "добавяне на вградено хранилище: %s"
 
-msgid ""
-"Use -f if you really want to add them.\n"
-"Turn this message off by running\n"
-"\"git config advice.addIgnoredFile false\""
-msgstr ""
-"Ползвайте опцията „-f“, ако наистина искате да ги добавите.\n"
-"За да изключите това съобщение, изпълнете:\n"
-"\n"
-"    git config advice.addIgnoredFile false"
+msgid "Use -f if you really want to add them."
+msgstr "Използвайте „-f“, за да ги добавите"
 
 msgid "adding files failed"
 msgstr "неуспешно добавяне на файлове"
@@ -2181,15 +2208,8 @@
 msgid "Nothing specified, nothing added.\n"
 msgstr "Нищо не е зададено и нищо не е добавено.\n"
 
-msgid ""
-"Maybe you wanted to say 'git add .'?\n"
-"Turn this message off by running\n"
-"\"git config advice.addEmptyPathspec false\""
-msgstr ""
-"„git add .“ ли искахте да изпълните?\n"
-"За да изключите това съобщение, изпълнете:\n"
-"\n"
-"    git config advice.addEmptyPathspec false"
+msgid "Maybe you wanted to say 'git add .'?"
+msgstr "Вероятно искахте да използвате „git add .“?"
 
 msgid "index file corrupt"
 msgstr "файлът с индекса е повреден"
@@ -2267,25 +2287,26 @@
 msgstr "Кръпките не може да се разделят."
 
 #, c-format
-msgid "When you have resolved this problem, run \"%s --continue\"."
+msgid "When you have resolved this problem, run \"%s --continue\".\n"
 msgstr ""
 "След коригирането на този проблем изпълнете:\n"
 "\n"
-"    %s --continue“"
+"    %s --continue“\n"
 
 #, c-format
-msgid "If you prefer to skip this patch, run \"%s --skip\" instead."
+msgid "If you prefer to skip this patch, run \"%s --skip\" instead.\n"
 msgstr ""
 "Ако предпочитате да прескочите тази кръпка, изпълнете:\n"
 "\n"
-"    %s --skip"
+"    %s --skip\n"
 
 #, c-format
-msgid "To record the empty patch as an empty commit, run \"%s --allow-empty\"."
+msgid ""
+"To record the empty patch as an empty commit, run \"%s --allow-empty\".\n"
 msgstr ""
 "За да включите празната кръпка като празно подаване, изпълнете:\n"
 "\n"
-"    %s --allow-empty"
+"    %s --allow-empty\n"
 
 #, c-format
 msgid "To restore the original branch and stop patching, run \"%s --abort\"."
@@ -3074,12 +3095,13 @@
 msgstr "обектът-подаване за „%s“ не може да се открие"
 
 #, c-format
-msgid ""
-"the branch '%s' is not fully merged.\n"
-"If you are sure you want to delete it, run 'git branch -D %s'"
+msgid "the branch '%s' is not fully merged"
+msgstr "клонът „%s“ не е слят напълно"
+
+#, c-format
+msgid "If you are sure you want to delete it, run 'git branch -D %s'"
 msgstr ""
-"клонът „%s“ не е слят напълно.  Ако сте сигурни, че искате\n"
-"да го изтриете, изпълнете:\n"
+"Ако сте сигурни, че искате да го изтриете, изпълнете:\n"
 "\n"
 "    git branch -D %s"
 
@@ -3126,7 +3148,7 @@
 
 #, c-format
 msgid "HEAD (%s) points outside of refs/heads/"
-msgstr "„HEAD“ (%s) сочи извън директорията „refs/heads“"
+msgstr "„HEAD“ (%s) сочи извън директорията „refs/heads/“"
 
 #, c-format
 msgid "branch %s is being rebased at %s"
@@ -3180,11 +3202,11 @@
 msgid ""
 "Please edit the description for the branch\n"
 "  %s\n"
-"Lines starting with '%c' will be stripped.\n"
+"Lines starting with '%s' will be stripped.\n"
 msgstr ""
 "Въведете описание на клона.\n"
 "    %s\n"
-"Редовете, които започват с „%c“, ще бъдат пропуснати.\n"
+"Редовете, които започват с „%s“, ще бъдат пропуснати.\n"
 
 msgid "Generic options"
 msgstr "Общи настройки"
@@ -3389,10 +3411,12 @@
 msgstr "командата е стартирана извън хранилище на Git, затова няма куки\n"
 
 msgid ""
-"git bugreport [(-o | --output-directory) <path>] [(-s | --suffix) <format>]\n"
+"git bugreport [(-o | --output-directory) <path>]\n"
+"              [(-s | --suffix) <format> | --no-suffix]\n"
 "              [--diagnose[=<mode>]]"
 msgstr ""
-"git bugreport [(-o|--output-directory) ПЪТ] [(-s|--suffix) ФОРМАТ]\n"
+"git bugreport [(-o|--output-directory) ПЪТ]\n"
+"              [(-s|--suffix) ФОРМАТ|--no-suffix]\n"
 "              [--diagnose[=РЕЖИМ]]"
 
 msgid ""
@@ -3586,8 +3610,8 @@
 
 msgid "show object type (one of 'blob', 'tree', 'commit', 'tag', ...)"
 msgstr ""
-"показване на обекти от този ВИД: „blob“ (BLOB), „tree“ (дърво), "
-"„commit“ (подаване), „tag“ (етикет и т.н.…)"
+"показване на обекти от този ВИД: „blob“ (BLOB), „tree“ (дърво), „commit“ "
+"(подаване), „tag“ (етикет и т.н.…)"
 
 msgid "show object size"
 msgstr "извеждане на размера на обект"
@@ -3883,6 +3907,10 @@
 msgid "path '%s' is unmerged"
 msgstr "пътят „%s“ не е слят"
 
+#, c-format
+msgid "unable to read tree (%s)"
+msgstr "дървото не може да бъде прочетено (%s)"
+
 msgid "you need to resolve your current index first"
 msgstr "първо трябва да коригирате индекса си"
 
@@ -4118,6 +4146,10 @@
 msgid "missing branch or commit argument"
 msgstr "липсва аргумент — клон или подаване"
 
+#, c-format
+msgid "unknown conflict style '%s'"
+msgstr "непознат вид конфликт „%s“"
+
 msgid "perform a 3-way merge with the new branch"
 msgstr "извършване на тройно сливане с новия клон"
 
@@ -4138,8 +4170,8 @@
 msgid "new-branch"
 msgstr "НОВ_КЛОН"
 
-msgid "new unparented branch"
-msgstr "нов клон без родител"
+msgid "new unborn branch"
+msgstr "нов неродѐн клон"
 
 msgid "update ignored files (default)"
 msgstr "обновяване на игнорираните файлове (стандартно)"
@@ -4377,23 +4409,10 @@
 msgid "remove only ignored files"
 msgstr "изтриване само на игнорирани файлове"
 
-msgid ""
-"clean.requireForce set to true and neither -i, -n, nor -f given; refusing to "
-"clean"
+msgid "clean.requireForce is true and -f not given: refusing to clean"
 msgstr ""
-"Настройката „clean.requireForce“ е зададена като истина, което изисква някоя "
-"от опциите „-i“, „-n“ или „-f“.  Няма да се извърши изчистване"
-
-msgid ""
-"clean.requireForce defaults to true and neither -i, -n, nor -f given; "
-"refusing to clean"
-msgstr ""
-"Настройката „clean.requireForce“ не е зададена, но стандартно е истина, "
-"което изисква някоя от опциите „-i“, „-n“ или „-f“.  Няма да се извърши "
-"изчистване"
-
-msgid "-x and -X cannot be used together"
-msgstr "опциите „-x“ и „-X“ са несъвместими"
+"Настройката „clean.requireForce“ е зададена, което изисква опциията „-f“.  "
+"Няма да се извърши изчистване"
 
 msgid "git clone [<options>] [--] <repo> [<dir>]"
 msgstr "git clone [ОПЦИЯ…] [--] ХРАНИЛИЩЕ [ДИРЕКТОРИЯ]"
@@ -4407,7 +4426,7 @@
 msgid "create a bare repository"
 msgstr "създаване на голо хранилище"
 
-msgid "create a mirror repository (implies bare)"
+msgid "create a mirror repository (implies --bare)"
 msgstr ""
 "създаване на хранилище-огледало (включва опцията „--bare“ за голо хранилище)"
 
@@ -4486,6 +4505,9 @@
 msgid "separate git dir from working tree"
 msgstr "отделна СЛУЖЕБНА_ДИРЕКТОРИЯ за git извън работното дърво"
 
+msgid "specify the reference format to use"
+msgstr "указване на форма̀та за указател"
+
 msgid "key=value"
 msgstr "КЛЮЧ=СТОЙНОСТ"
 
@@ -4613,12 +4635,9 @@
 msgid "You must specify a repository to clone."
 msgstr "Трябва да укажете кое хранилище искате да клонирате."
 
-msgid ""
-"--bundle-uri is incompatible with --depth, --shallow-since, and --shallow-"
-"exclude"
-msgstr ""
-"опцията „--bundle-uri“ е несъвместима с „--depth“, „--shallow-since“ и „--"
-"shallow-exclude“"
+#, c-format
+msgid "unknown ref storage format '%s'"
+msgstr "непознат формат на съхранение: „%s“"
 
 #, c-format
 msgid "repository '%s' does not exist"
@@ -4741,6 +4760,10 @@
 msgid "padding space between columns"
 msgstr "поле в знаци между колоните"
 
+#, c-format
+msgid "%s must be non-negative"
+msgstr "%s трябва да е неотрицателно"
+
 msgid "--command must be the first argument"
 msgstr "опцията „--command“ трябва да е първият аргумент"
 
@@ -4756,7 +4779,7 @@
 "--stdin-commits]\n"
 "                       [--changed-paths] [--[no-]max-new-filters <n>] [--"
 "[no-]progress]\n"
-"                       <split options>"
+"                       <split-options>"
 msgstr ""
 "git commit-graph write [--object-dir ДИРЕКТОРИЯ] [--append]\n"
 "                       [--split[=СТРАТЕГИЯ]] [--reachable|--stdin-packs|--"
@@ -5067,35 +5090,35 @@
 #, c-format
 msgid ""
 "Please enter the commit message for your changes. Lines starting\n"
-"with '%c' will be ignored.\n"
+"with '%s' will be ignored.\n"
 msgstr ""
 "Въведете съобщението за подаване на промѐните.  Редовете, които започват\n"
-"с „%c“, ще бъдат пропуснати.\n"
+"с „%s“, ще бъдат пропуснати.\n"
 
 #, 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"
+"with '%s' will be ignored, and an empty message aborts the commit.\n"
 msgstr ""
 "Въведете съобщението за подаване на промѐните.  Редовете, които започват\n"
-"с „%c“, ще бъдат пропуснати, а празно съобщение преустановява подаването.\n"
+"с „%s“, ще бъдат пропуснати, а празно съобщение преустановява подаването.\n"
 
 #, 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"
+"with '%s' will be kept; you may remove them yourself if you want to.\n"
 msgstr ""
 "Въведете съобщението за подаване на промѐните.  Редовете, които започват\n"
-"с „%c“, също ще бъдат включени — може да ги изтриете вие.\n"
+"с „%s“, също ще бъдат включени — може да ги изтриете вие.\n"
 
 #, 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"
+"with '%s' will be kept; you may remove them yourself if you want to.\n"
 "An empty message aborts the commit.\n"
 msgstr ""
 "Въведете съобщението за подаване на промѐните.  Редовете, които започват\n"
-"с „%c“, също ще бъдат включени — може да ги изтриете вие.  Празно \n"
+"с „%s“, също ще бъдат включени — може да ги изтриете вие.  Празно \n"
 "съобщение преустановява подаването.\n"
 
 msgid ""
@@ -5241,9 +5264,9 @@
 "show ignored files, optional modes: traditional, matching, no. (Default: "
 "traditional)"
 msgstr ""
-"извеждане на игнорираните файлове.  Възможните РЕЖИМи са "
-"„traditional“ (традиционен), „matching“ (напасващи), „no“ (без игнорираните "
-"файлове).  Стандартният РЕЖИМ е: „traditional“."
+"извеждане на игнорираните файлове.  Възможните РЕЖИМи са „traditional“ "
+"(традиционен), „matching“ (напасващи), „no“ (без игнорираните файлове).  "
+"Стандартният РЕЖИМ е: „traditional“."
 
 msgid "when"
 msgstr "КОГА"
@@ -5253,8 +5276,8 @@
 "(Default: all)"
 msgstr ""
 "игнориране на промѐните в подмодулите.  Опция с незадължителна стойност — "
-"една от „all“ (всички), „dirty“ (тези с неподадени промѐни), "
-"„untracked“ (неследени)"
+"една от „all“ (всички), „dirty“ (тези с неподадени промѐни), „untracked“ "
+"(неследени)"
 
 msgid "list untracked files in columns"
 msgstr "извеждане на неследените файлове в колони"
@@ -5547,9 +5570,8 @@
 
 msgid "show scope of config (worktree, local, global, system, command)"
 msgstr ""
-"извеждане на обхвата на настройката „worktree“ (работно дърво), "
-"„local“ (хранилище), „global“ (потребител), „system“ (система), "
-"„command“ (команда)"
+"извеждане на обхвата на настройката „worktree“ (работно дърво), „local“ "
+"(хранилище), „global“ (потребител), „system“ (система), „command“ (команда)"
 
 msgid "value"
 msgstr "СТОЙНОСТ"
@@ -5557,6 +5579,9 @@
 msgid "with --get, use default value when missing entry"
 msgstr "с „--get“ се използва стандартна СТОЙНОСТ при липсваща"
 
+msgid "human-readable comment string (# will be prepended as needed)"
+msgstr "низ за подаване четим от хора (при нужда отпред се добавя „#“)"
+
 #, c-format
 msgid "wrong number of arguments, should be %d"
 msgstr "неправилен брой аргументи, трябва да е точно %d"
@@ -5652,6 +5677,11 @@
 msgid "--default is only applicable to --get"
 msgstr "опцията „--default“ е приложима само към опцията „--get“"
 
+msgid "--comment is only applicable to add/set/replace operations"
+msgstr ""
+"опцията „--comment“ е съвместима само с действията „add“ (добавяне)/„set“ "
+"(задаване)/„replace“ (замяна)"
+
 msgid "--fixed-value only applies with 'value-pattern'"
 msgstr "опцията „--fixed-value“ е приложима само със ШАБЛОН_ЗА_СТОЙНОСТ"
 
@@ -5686,7 +5716,7 @@
 msgstr "такъв раззел няма: %s"
 
 msgid "print sizes in human readable format"
-msgstr "извеждане на размерите на обектите във формат лесно четим от хора"
+msgstr "извеждане на размерите на обектите във формат четим от хора"
 
 #, c-format
 msgid ""
@@ -6514,6 +6544,9 @@
 msgid "read reference patterns from stdin"
 msgstr "изчитане на шаблоните за указатели от стандартния вход"
 
+msgid "also include HEAD ref and pseudorefs"
+msgstr "включване и на указателя „HEAD“ както и псевдоуказателите"
+
 msgid "unknown arguments supplied with --stdin"
 msgstr "непознат аргумент към опцията „--stdin“"
 
@@ -7141,8 +7174,8 @@
 msgstr "липсва поддръжка за нишки.  „%s“ ще се пренебрегне"
 
 #, c-format
-msgid "unable to read tree (%s)"
-msgstr "дървото не може да бъде прочетено (%s)"
+msgid "unable to read tree %s"
+msgstr "дървото не може да бъде прочетено: %s"
 
 #, c-format
 msgid "unable to grep from object of type %s"
@@ -7566,10 +7599,6 @@
 "СЪВПАДЕНИЕ НА СТОЙНОСТИТЕ ЗА СУМИТЕ ЗА SHA1: „%s“ НА ДВА РАЗЛИЧНИ ОБЕКТА!"
 
 #, c-format
-msgid "unable to read %s"
-msgstr "обектът „%s“ не може да бъде прочетен"
-
-#, c-format
 msgid "cannot read existing object info %s"
 msgstr "съществуващият обект в „%s“ не може да бъде прочетен"
 
@@ -7711,6 +7740,7 @@
 msgid ""
 "git init [-q | --quiet] [--bare] [--template=<template-directory>]\n"
 "         [--separate-git-dir <git-dir>] [--object-format=<format>]\n"
+"         [--ref-format=<format>]\n"
 "         [-b <branch-name> | --initial-branch=<branch-name>]\n"
 "         [--shared[=<permissions>]] [<directory>]"
 msgstr ""
@@ -7761,13 +7791,39 @@
 
 msgid ""
 "git interpret-trailers [--in-place] [--trim-empty]\n"
-"                       [(--trailer (<key>|<keyAlias>)[(=|:)<value>])...]\n"
+"                       [(--trailer (<key>|<key-alias>)[(=|:)<value>])...]\n"
 "                       [--parse] [<file>...]"
 msgstr ""
 "git interpret-trailers [--in-place] [--trim-empty]\n"
 "                       [(--trailer (КЛЮЧ|СИНОНИМ)[(=|:)СТОЙНОСТ])…]\n"
 "                       [--parse] [ФАЙЛ…]"
 
+#, c-format
+msgid "could not stat %s"
+msgstr "Не може да се получи информация чрез „stat“ за „%s“"
+
+#, c-format
+msgid "file %s is not a regular file"
+msgstr "„%s“ не е обикновен файл"
+
+#, c-format
+msgid "file %s is not writable by user"
+msgstr "„%s“: няма права̀ за записване на файла"
+
+msgid "could not open temporary file"
+msgstr "временният файл не може да се отвори"
+
+#, c-format
+msgid "could not read input file '%s'"
+msgstr "входният файл „%s“ не може да бъде прочетен"
+
+msgid "could not read from stdin"
+msgstr "от стандартния вход не може да се чете"
+
+#, c-format
+msgid "could not rename temporary file to %s"
+msgstr "временният файл не може да се преименува на „%s“"
+
 msgid "edit files in place"
 msgstr "директно редактиране на файловете"
 
@@ -8066,8 +8122,8 @@
 
 msgid "enable message threading, styles: shallow, deep"
 msgstr ""
-"използване на нишки за съобщенията.  СТИЛът е „shallow“ (плитък) или "
-"„deep“ (дълбок)"
+"използване на нишки за съобщенията.  СТИЛът е „shallow“ (плитък) или „deep“ "
+"(дълбок)"
 
 msgid "signature"
 msgstr "подпис"
@@ -8174,18 +8230,6 @@
 msgid "could not get object info about '%s'"
 msgstr "не може да се получи информация за обекта „%s“"
 
-#, c-format
-msgid "bad ls-files format: element '%s' does not start with '('"
-msgstr "неправилен формат за „ls-tree“: елементът „%s“ не започва с „(“"
-
-#, c-format
-msgid "bad ls-files format: element '%s' does not end in ')'"
-msgstr "неправилен формат за „ls-tree“: елементът „%s“ не завършва с „)“"
-
-#, c-format
-msgid "bad ls-files format: %%%.*s"
-msgstr "неправилен формат за „ls-tree“: %%%.*s"
-
 msgid "git ls-files [<options>] [<file>...]"
 msgstr "git ls-files [ОПЦИЯ…] [ФАЙЛ…]"
 
@@ -8319,18 +8363,6 @@
 msgid "git ls-tree [<options>] <tree-ish> [<path>...]"
 msgstr "git ls-tree [ОПЦИЯ…] УКАЗАТЕЛ_КЪМ_ДЪРВО [ПЪТ…]"
 
-#, c-format
-msgid "bad ls-tree format: element '%s' does not start with '('"
-msgstr "неправилен формат за „ls-tree“: елементът „%s“ не започва с „(“"
-
-#, c-format
-msgid "bad ls-tree format: element '%s' does not end in ')'"
-msgstr "неправилен формат за „ls-tree“: елементът „%s“ не завършва с „(“"
-
-#, c-format
-msgid "bad ls-tree format: %%%.*s"
-msgstr "неправилен формат за „ls-tree“: %%%.*s"
-
 msgid "only show trees"
 msgstr "извеждане само на дървета"
 
@@ -8449,6 +8481,14 @@
 "git merge-file [ОПЦИЯ…] [-L ИМЕ_1 [-L ОРИГИНАЛ [-L ИМЕ_2]]] ФАЙЛ_1 ОРИГ_ФАЙЛ "
 "ФАЙЛ_2"
 
+msgid ""
+"option diff-algorithm accepts \"myers\", \"minimal\", \"patience\" and "
+"\"histogram\""
+msgstr ""
+"опцията приема следните варианти за алгоритъм за разлики: „myers“ (по "
+"Майерс), „minimal“ (минимизиране на разликите), „patience“ (пасианс) и "
+"„histogram“ (хистограмен)"
+
 msgid "send results to standard output"
 msgstr "извеждане на резултатите на стандартния изход"
 
@@ -8470,6 +8510,12 @@
 msgid "for conflicts, use a union version"
 msgstr "при конфликти да се ползва обединена версия"
 
+msgid "<algorithm>"
+msgstr "АЛГОРИТЪМ"
+
+msgid "choose a diff algorithm"
+msgstr "избор на АЛГОРИТЪМа за разлики"
+
 msgid "for conflicts, use this marker size"
 msgstr "при конфликти да се ползва маркер с такъв БРОЙ знаци"
 
@@ -8511,6 +8557,10 @@
 msgid "Merging %s with %s\n"
 msgstr "Сливане на „%s“ с „%s“\n"
 
+#, c-format
+msgid "could not parse as tree '%s'"
+msgstr "„%s“ не може да се анализира като дърво"
+
 msgid "not something we can merge"
 msgstr "не може да се слее"
 
@@ -8561,9 +8611,6 @@
 msgid "unknown strategy option: -X%s"
 msgstr "непозната опция за стратегия: -X%s"
 
-msgid "--merge-base is incompatible with --stdin"
-msgstr "опциите „--merge-base“ и „--stdin“ са несъвместими"
-
 #, c-format
 msgid "malformed input line: '%s'."
 msgstr "входен ред с неправилен формат: „%s“."
@@ -8606,7 +8653,7 @@
 msgid "add (at most <n>) entries from shortlog to merge commit message"
 msgstr ""
 "добавяне (на максимум такъв БРОЙ) записи от съкратения журнал в съобщението "
-"за подаване"
+"за подаване със сливане"
 
 msgid "create a single commit instead of doing a merge"
 msgstr "създаване на едно подаване вместо извършване на сливане"
@@ -8721,10 +8768,10 @@
 
 #, c-format
 msgid ""
-"Lines starting with '%c' will be ignored, and an empty message aborts\n"
+"Lines starting with '%s' will be ignored, and an empty message aborts\n"
 "the commit.\n"
 msgstr ""
-"Редовете, които започват с „%c“, ще бъдат пропуснати, а празно\n"
+"Редовете, които започват с „%s“, ще бъдат пропуснати, а празно\n"
 "съобщение преустановява подаването.\n"
 
 msgid "Empty commit message."
@@ -8890,9 +8937,6 @@
 msgid "object '%s' tagged as '%s', but is a '%s' type"
 msgstr "обектът „%s“ е с етикет за %s, но е %s"
 
-msgid "could not read from stdin"
-msgstr "от стандартния вход не може да се чете"
-
 msgid "tag on stdin did not pass our strict fsck check"
 msgstr "етикетът на стандартния вход не преминава строгата проверка с „fsck“"
 
@@ -9332,9 +9376,8 @@
 "cat_sort_uniq)"
 msgstr ""
 "коригиране на конфликтите при сливане на бележките чрез тази СТРАТЕГИЯ — "
-"„manual“ (ръчно), „ours“ (вашата версия), „theirs“ (чуждата версия), "
-"„union“ (обединяване), „cat_sort_uniq“ (обединяване, подреждане, уникални "
-"резултати)"
+"„manual“ (ръчно), „ours“ (вашата версия), „theirs“ (чуждата версия), „union“ "
+"(обединяване), „cat_sort_uniq“ (обединяване, подреждане, уникални резултати)"
 
 msgid "Committing unmerged notes"
 msgstr "Подаване на неслети бележки"
@@ -9523,6 +9566,11 @@
 msgstr "неправилен брой разлики"
 
 #, c-format
+msgid "invalid pack.allowPackReuse value: '%s'"
+msgstr ""
+"неправилна стойност за преизползването на пакети „pack.allowPackReuse“: „%s“"
+
+#, c-format
 msgid ""
 "value of uploadpack.blobpackfileuri must be of the form '<object-hash> <pack-"
 "hash> <uri>' (got '%s')"
@@ -9534,8 +9582,8 @@
 msgid ""
 "object already configured in another uploadpack.blobpackfileuri (got '%s')"
 msgstr ""
-"вече има настройка за обекта в друг ред „uploadpack."
-"blobpackfileuri“ (получена е „%s“)"
+"вече има настройка за обекта в друг ред „uploadpack.blobpackfileuri“ "
+"(получена е „%s“)"
 
 #, c-format
 msgid "could not get type of object %s in pack %s"
@@ -9795,10 +9843,10 @@
 #, c-format
 msgid ""
 "Total %<PRIu32> (delta %<PRIu32>), reused %<PRIu32> (delta %<PRIu32>), pack-"
-"reused %<PRIu32>"
+"reused %<PRIu32> (from %<PRIuMAX>)"
 msgstr ""
 "Общо: %<PRIu32> (разлики: %<PRIu32>), преизползвани: %<PRIu32> (разлики: "
-"%<PRIu32>), преизползвани при пакетиране: %<PRIu32>"
+"%<PRIu32>), преизползвани при пакетиране: %<PRIu32> (от %<PRIuMAX>)"
 
 msgid ""
 "'git pack-redundant' is nominated for removal.\n"
@@ -9817,10 +9865,11 @@
 msgstr "трябва да добавите и опцията „--i-still-use-this“"
 
 msgid ""
-"git pack-refs [--all] [--no-prune] [--include <pattern>] [--exclude "
+"git pack-refs [--all] [--no-prune] [--auto] [--include <pattern>] [--exclude "
 "<pattern>]"
 msgstr ""
-"git pack-refs [--all] [--no-prune] [--include ШАБЛОН] [--exclude ШАБЛОН]"
+"git pack-refs [--all] [--no-prune] [--auto] [--include ШАБЛОН] [--exclude "
+"ШАБЛОН]"
 
 msgid "pack everything"
 msgstr "пакетиране на всичко"
@@ -9828,6 +9877,9 @@
 msgid "prune loose refs (default)"
 msgstr "окастряне на недостижимите указатели (стандартно)"
 
+msgid "auto-pack refs as needed"
+msgstr "автоматично пакетиране на указателите при нужда"
+
 msgid "references to include"
 msgstr "кои указатели да се включат"
 
@@ -10148,8 +10200,8 @@
 msgid ""
 "You didn't specify any refspecs to push, and push.default is \"nothing\"."
 msgstr ""
-"Не сте указали версия за подаване, а настройката „push.default“ е "
-"„nothing“ (нищо без изрично указана версия да не се изтласква)"
+"Не сте указали версия за подаване, а настройката „push.default“ е „nothing“ "
+"(нищо без изрично указана версия да не се изтласква)"
 
 #, c-format
 msgid ""
@@ -10504,19 +10556,6 @@
 msgid "could not remove '%s'"
 msgstr "„%s“ не може да бъде изтрит"
 
-msgid ""
-"Resolve all conflicts manually, mark them as resolved with\n"
-"\"git add/rm <conflicted_files>\", then run \"git rebase --continue\".\n"
-"You can instead skip this commit: run \"git rebase --skip\".\n"
-"To abort and get back to the state before \"git rebase\", run \"git rebase --"
-"abort\"."
-msgstr ""
-"След коригирането на конфликтите отбележете решаването им чрез:\n"
-"„git add/rm ФАЙЛ_С_КОНФЛИКТ…“ и изпълнете „git rebase --continue“.\n"
-"Ако предпочитате да прескочите тази кръпка, изпълнете „git rebase --skip“.\n"
-"За да откажете пребазирането и да се върнете към първоначалното състояние,\n"
-"изпълнете „git rebase --abort“."
-
 #, c-format
 msgid ""
 "\n"
@@ -10545,13 +10584,17 @@
 msgid "apply options and merge options cannot be used together"
 msgstr "опциите за прилагане и сливане са несъвместими"
 
+msgid "--empty=ask is deprecated; use '--empty=stop' instead."
+msgstr ""
+"комбинацията „--empty=ask“ е остаряла.  Вместо нея ползвайте „--empty=stop“."
+
 #, c-format
 msgid ""
 "unrecognized empty type '%s'; valid values are \"drop\", \"keep\", and "
-"\"ask\"."
+"\"stop\"."
 msgstr ""
-"неправилна стойност „%s“: вариантите са „drop“ (прескачане), "
-"„keep“ (запазване) и „ask“ (питане)"
+"неправилна празна стойност „%s“: вариантите са „drop“ (прескачане), „keep“ "
+"(запазване) и „stop“ (спиране)"
 
 msgid ""
 "--rebase-merges with an empty string argument is deprecated and will stop "
@@ -10744,8 +10787,8 @@
 "„preserve“.\n"
 "Тази стойност вече не се поддържа, заменете я с „merges“."
 
-msgid "No rebase in progress?"
-msgstr "Изглежда в момента не тече пребазиране"
+msgid "no rebase in progress"
+msgstr "изглежда в момента не тече пребазиране"
 
 msgid "The --edit-todo action can only be used during interactive rebase."
 msgstr ""
@@ -10792,13 +10835,6 @@
 msgstr "опцията „C“ очаква число за аргумент"
 
 msgid ""
-"apply options are incompatible with rebase.autoSquash.  Consider adding --no-"
-"autosquash"
-msgstr ""
-"опциите за прилагане са несъвместими с „rebase.autoSquash“.  Пробвайте да "
-"добавите опцията „--no-autosquash“"
-
-msgid ""
 "apply options are incompatible with rebase.rebaseMerges.  Consider adding --"
 "no-rebase-merges"
 msgstr ""
@@ -10953,6 +10989,9 @@
 msgid "git reflog [show] [<log-options>] [<ref>]"
 msgstr "git reflog [show] [ОПЦИЯ…] [УКАЗАТЕЛ]"
 
+msgid "git reflog list"
+msgstr "git reflog list"
+
 msgid ""
 "git reflog expire [--expire=<time>] [--expire-unreachable=<time>]\n"
 "                  [--rewrite] [--updateref] [--stale-fix]\n"
@@ -10978,6 +11017,10 @@
 msgid "invalid timestamp '%s' given to '--%s'"
 msgstr "неправилно времево клеймо „%s“ подадено към „--%s“"
 
+#, c-format
+msgid "%s does not accept arguments: '%s'"
+msgstr "„%s“ не приема аргументи: „%s“"
+
 msgid "do not actually prune any entries"
 msgstr "без окастряне на записи"
 
@@ -11109,7 +11152,7 @@
 "ползвайте „--mirror=fetch“ или „--mirror=push“"
 
 #, c-format
-msgid "unknown mirror argument: %s"
+msgid "unknown --mirror argument: %s"
 msgstr "неправилна стойност за „--mirror“: %s"
 
 msgid "fetch the remote branches"
@@ -11486,6 +11529,10 @@
 "командата „pack-objects“ не може да се стартира за препакетирането на "
 "гарантиращите обекти"
 
+msgid "failed to feed promisor objects to pack-objects"
+msgstr ""
+"гарантиращите обекти не може да се подадат на командата „git pack-objects“"
+
 msgid "repack: Expecting full hex object ID lines only from pack-objects."
 msgstr ""
 "repack: от „pack-objects“ се изискват редове само с пълни шестнайсетични "
@@ -11823,6 +11870,76 @@
 msgid "only one pattern can be given with -l"
 msgstr "опцията „-l“ приема точно един шаблон"
 
+msgid "need some commits to replay"
+msgstr "необходимо е да има подавания за прилагане отново"
+
+msgid "--onto and --advance are incompatible"
+msgstr "опциите „--onto“ и „--advance“ са несъвместими"
+
+msgid "all positive revisions given must be references"
+msgstr "всички зададени положителни версии трябва да са указатели"
+
+msgid "argument to --advance must be a reference"
+msgstr "аргументът към „--advance“ трябва да е указател"
+
+msgid ""
+"cannot advance target with multiple sources because ordering would be ill-"
+"defined"
+msgstr ""
+"цели с множество източници не може да се придвижат напред, защото подредбата "
+"не е добре дефинирана"
+
+msgid ""
+"cannot implicitly determine whether this is an --advance or --onto operation"
+msgstr ""
+"не може да се определи дали това действие е за „--advance“ или „--onto“"
+
+msgid ""
+"cannot advance target with multiple source branches because ordering would "
+"be ill-defined"
+msgstr ""
+"цели с множество клони-източници не може да се придвижат напред, защото "
+"подредбата не е добре дефинирана"
+
+msgid "cannot implicitly determine correct base for --onto"
+msgstr "правилната база за „--onto“ не може да се определи"
+
+msgid ""
+"(EXPERIMENTAL!) git replay ([--contained] --onto <newbase> | --advance "
+"<branch>) <revision-range>..."
+msgstr ""
+"(ЕКСПЕРИМЕНТАЛНО!) git replay ([--contained] --onto НОВА_БАЗА | --advance "
+"КЛОН) ДИАПАЗОН_ПОДАВАНИЯ…"
+
+msgid "make replay advance given branch"
+msgstr "прилагането наново придвижва дадения КЛОН напред"
+
+msgid "replay onto given commit"
+msgstr "прилагането наново върху даденото ПОДАВАНЕ"
+
+msgid "advance all branches contained in revision-range"
+msgstr "придвижване на всички КЛОНи в ДИАПАЗОНа_ПОДАВАНИЯ"
+
+msgid "option --onto or --advance is mandatory"
+msgstr "изисква се някоя от опциите „--onto“ или „--advance“"
+
+#, c-format
+msgid ""
+"some rev walking options will be overridden as '%s' bit in 'struct rev_info' "
+"will be forced"
+msgstr ""
+"някои опции за проследяване на указатели ще бъдат променени, защото битът "
+"„%s“ в структурата „struct rev_info“ има превес"
+
+msgid "error preparing revisions"
+msgstr "грешка при подготовката на версии"
+
+msgid "replaying down to root commit is not supported yet!"
+msgstr "не се поддържа прилагане наново и на началното подаване!"
+
+msgid "replaying merge commits is not supported yet!"
+msgstr "не се поддържа прилагане наново и на подавания със сливане!"
+
 msgid ""
 "git rerere [clear | forget <pathspec>... | diff | status | remaining | gc]"
 msgstr "git rerere [clear|forget ПЪТ…|diff|status|remaining|gc]"
@@ -12026,19 +12143,17 @@
 msgid "--prefix requires an argument"
 msgstr "опцията „--prefix“ изисква аргумент"
 
+msgid "no object format specified"
+msgstr "не е указан формат на обект"
+
+#, c-format
+msgid "unsupported object format: %s"
+msgstr "неподдържан формат на обект: „%s“"
+
 #, c-format
 msgid "unknown mode for --abbrev-ref: %s"
 msgstr "непознат режим за „--abbrev-ref“: „%s“"
 
-msgid "--exclude-hidden cannot be used together with --branches"
-msgstr "опциите „--exclude-hidden“ и „--branches“ са несъвместими"
-
-msgid "--exclude-hidden cannot be used together with --tags"
-msgstr "опциите „--exclude-hidden“ и „--tags“ са несъвместими"
-
-msgid "--exclude-hidden cannot be used together with --remotes"
-msgstr "опциите „--exclude-hidden“ и „--remotes“ са несъвместими"
-
 msgid "this operation must be run in a work tree"
 msgstr "тази команда трябва да се изпълни в работно дърво"
 
@@ -12116,8 +12231,8 @@
 msgid "allow commits with empty messages"
 msgstr "позволяване на празни съобщения при подаване"
 
-msgid "keep redundant, empty commits"
-msgstr "запазване на излишните, празни подавания"
+msgid "deprecated: use --empty=keep instead"
+msgstr "ОСТАРЯЛО: вместо това ползвайте „--empty=keep“"
 
 msgid "use the 'reference' format to refer to commits"
 msgstr "указване на подавания във формат за указател"
@@ -12242,7 +12357,7 @@
 msgstr "git shortlog [ОПЦИЯ…] [ДИАПАЗОН_НА_ВЕРСИИТЕ] [[--] [ПЪТ…]]"
 
 msgid "git log --pretty=short | git shortlog [<options>]"
-msgstr "git log --pretty=short|git shortlog [ОПЦИЯ…]"
+msgstr "git log --pretty=short | git shortlog [ОПЦИЯ…]"
 
 msgid "using multiple --group options with stdin is not supported"
 msgstr "повече от една опции „--group“ са несъвместими със стандартния вход"
@@ -12455,10 +12570,6 @@
 "извеждане на указателите приети от стандартния вход, които липсват в "
 "локалното хранилище"
 
-#, c-format
-msgid "only one of '%s', '%s' or '%s' can be given"
-msgstr "опциите „%s“, „%s“ и „%s“ са несъвместими"
-
 msgid ""
 "git sparse-checkout (init | list | set | add | reapply | disable | check-"
 "rules) [<options>]"
@@ -13479,25 +13590,25 @@
 "\n"
 "Write a message for tag:\n"
 "  %s\n"
-"Lines starting with '%c' will be ignored.\n"
+"Lines starting with '%s' will be ignored.\n"
 msgstr ""
 "\n"
 "Въведете съобщение за етикета.\n"
 "    %s\n"
-"Редовете, които започват с „%c“, ще бъдат пропуснати.\n"
+"Редовете, които започват с „%s“, ще бъдат пропуснати.\n"
 
 #, c-format
 msgid ""
 "\n"
 "Write a message for tag:\n"
 "  %s\n"
-"Lines starting with '%c' will be kept; you may remove them yourself if you "
+"Lines starting with '%s' will be kept; you may remove them yourself if you "
 "want to.\n"
 msgstr ""
 "\n"
 "Въведете съобщение за етикет.\n"
 "    %s\n"
-"Редовете, които започват с „%c“, също ще бъдат включени — може да ги "
+"Редовете, които започват с „%s“, също ще бъдат включени — може да ги "
 "изтриете вие.\n"
 
 msgid "unable to sign the tag"
@@ -13583,6 +13694,9 @@
 msgid "print only tags of the object"
 msgstr "извеждане само на етикетите на ОБЕКТА"
 
+msgid "could not start 'git column'"
+msgstr "неуспешно изпълнение на „git column“"
+
 #, c-format
 msgid "the '%s' option is only allowed in list mode"
 msgstr "опцията „%s“ изисква режим на списък"
@@ -13848,11 +13962,14 @@
 msgid "fsmonitor disabled"
 msgstr "следенето чрез файловата система е изключено"
 
-msgid "git update-ref [<options>] -d <refname> [<old-val>]"
-msgstr "git update-ref [ОПЦИЯ…] -d ИМЕ_НА_УКАЗАТЕЛ [СТАРА_СТОЙНОСТ]"
+msgid "git update-ref [<options>] -d <refname> [<old-oid>]"
+msgstr ""
+"git update-ref [ОПЦИЯ…] -d ИМЕ_НА_УКАЗАТЕЛ [СТАР_ИДЕНТИФИКАТОР_НА_ОБЕКТ]"
 
-msgid "git update-ref [<options>]    <refname> <new-val> [<old-val>]"
-msgstr "git update-ref [ОПЦИЯ…] ИМЕ_НА_УКАЗАТЕЛ НОВА_СТОЙНОСТ [СТАРА_СТОЙНОСТ]"
+msgid "git update-ref [<options>]    <refname> <new-oid> [<old-oid>]"
+msgstr ""
+"git update-ref [ОПЦИЯ…] ИМЕ_НА_УКАЗАТЕЛ НОВ_ИДЕНТИФИКАТОР_НА_ОБЕКТ "
+"[СТАР_ИДЕНТИФИКАТОР_НА_ОБЕКТ]"
 
 msgid "git update-ref [<options>] --stdin [-z]"
 msgstr "git update-ref [ОПЦИЯ…] --stdin [-z]"
@@ -13951,7 +14068,7 @@
 
 #, c-format
 msgid ""
-"If you meant to create a worktree containing a new orphan branch\n"
+"If you meant to create a worktree containing a new unborn branch\n"
 "(branch with no commits) for this repository, you can do so\n"
 "using the --orphan flag:\n"
 "\n"
@@ -13965,7 +14082,7 @@
 
 #, c-format
 msgid ""
-"If you meant to create a worktree containing a new orphan branch\n"
+"If you meant to create a worktree containing a new unborn branch\n"
 "(branch with no commits) for this repository, you can do so\n"
 "using the --orphan flag:\n"
 "\n"
@@ -14035,6 +14152,10 @@
 msgstr "инициализация"
 
 #, c-format
+msgid "could not find created worktree '%s'"
+msgstr "създаденото в „%s“ работно дърво липсва"
+
+#, c-format
 msgid "Preparing worktree (new branch '%s')"
 msgstr "Приготвяне на работното дърво (нов клон „%s“)"
 
@@ -14076,10 +14197,6 @@
 "доставете\n"
 "обектите от отдалеченото хранилище"
 
-#, c-format
-msgid "'%s' and '%s' cannot be used together"
-msgstr "опциите „%s“ и „%s“ са несъвместими"
-
 msgid "checkout <branch> even if already checked out in other worktree"
 msgstr "Изтегляне КЛОНа, дори и да е изтеглен в друго работно дърво"
 
@@ -14089,7 +14206,7 @@
 msgid "create or reset a branch"
 msgstr "създаване или зануляване на клони"
 
-msgid "create unborn/orphaned branch"
+msgid "create unborn branch"
 msgstr "създаване на неродѐн клон"
 
 msgid "populate the new working tree"
@@ -14112,11 +14229,8 @@
 msgstr "опциите „%s“, „%s“ и „%s“ са несъвместими"
 
 #, c-format
-msgid "options '%s', and '%s' cannot be used together"
-msgstr "опциите „%s“ и „%s“ са несъвместими"
-
-msgid "<commit-ish>"
-msgstr "ПОДАВАНЕ"
+msgid "option '%s' and commit-ish cannot be used together"
+msgstr "опциите „%s“ и указателите към подавания са несъвместими"
 
 msgid "added with --lock"
 msgstr "добавена с „--lock“"
@@ -14538,9 +14652,7 @@
 msgstr "Силно опростен сървър за хранилища на Git"
 
 msgid "Give an object a human readable name based on an available ref"
-msgstr ""
-"Задаване на име удобно за потребителите на обект въз основа на наличен "
-"указател"
+msgstr "Задаване на четимо от хора име на обект въз основа на наличен указател"
 
 msgid "Generate a zip archive of diagnostic information"
 msgstr "Създаване на архив във формат zip с диагностична информация"
@@ -14753,6 +14865,11 @@
 msgid "Create, list, delete refs to replace objects"
 msgstr "Създаване, извеждане, изтриване на указатели за замяна на обекти"
 
+msgid "EXPERIMENTAL: Replay commits on a new base, works with bare repos too"
+msgstr ""
+"ЕКСПЕРИМЕНТАЛНО: прилагане на подавания върху нова база, работи и с голи "
+"хранилища"
+
 msgid "Generates a summary of pending changes"
 msgstr "Обобщение на предстоящите промѐни"
 
@@ -14991,6 +15108,36 @@
 msgid "commit-graph file is too small"
 msgstr "файлът за гра̀фа с подаванията е твърде малък"
 
+msgid "commit-graph oid fanout chunk is wrong size"
+msgstr "откъсът за разпределянето в гра̀фа с подаванията е прекалено малък"
+
+msgid "commit-graph fanout values out of order"
+msgstr ""
+"стойностите за откъс за разпределяне в гра̀фа с подаванията не са подредени"
+
+msgid "commit-graph OID lookup chunk is the wrong size"
+msgstr "откъсът за търсенето в гра̀фа с подаванията е прекалено малък"
+
+msgid "commit-graph commit data chunk is wrong size"
+msgstr ""
+"откъсът за данните за подаванията в гра̀фа с подаванията е с неправилен размер"
+
+msgid "commit-graph generations chunk is wrong size"
+msgstr "откъсът за поколенията в гра̀фа с подаванията е с неправилен размер"
+
+msgid "commit-graph changed-path index chunk is too small"
+msgstr ""
+"откъсът за индекса с промѐни в пътищата в гра̀фа с подаванията е прекалено "
+"малък"
+
+#, c-format
+msgid ""
+"ignoring too-small changed-path chunk (%<PRIuMAX> < %<PRIuMAX>) in commit-"
+"graph file"
+msgstr ""
+"прескачане на прекалено малък откъс за индекса с промѐни (%<PRIuMAX> < "
+"%<PRIuMAX>) в пътищата в гра̀фа с подаванията"
+
 #, c-format
 msgid "commit-graph signature %X does not match signature %X"
 msgstr "отпечатъкът на гра̀фа с подаванията %X не съвпада с %X"
@@ -15007,6 +15154,19 @@
 msgid "commit-graph file is too small to hold %u chunks"
 msgstr "файлът с гра̀фа на подаванията е твърде малък, за да съдържа %u откъси"
 
+msgid "commit-graph required OID fanout chunk missing or corrupted"
+msgstr ""
+"откъсът за разпределянето необходимо на гра̀фа с подаванията липсва или е "
+"повреден"
+
+msgid "commit-graph required OID lookup chunk missing or corrupted"
+msgstr ""
+"откъсът за търсенето необходимо на гра̀фа с подаванията липсва или е повреден"
+
+msgid "commit-graph required commit data chunk missing or corrupted"
+msgstr ""
+"откъсът за данните необходими на гра̀фа с подаванията липсва или е повреден"
+
 msgid "commit-graph has no base graphs chunk"
 msgstr "базовият откъс липсва в гра̀фа с подаванията"
 
@@ -15020,6 +15180,9 @@
 msgid "commit count in base graph too high: %<PRIuMAX>"
 msgstr "броят подавания в основния граф е прекалено голям: %<PRIuMAX>"
 
+msgid "commit-graph chain file too small"
+msgstr "веригата на гра̀фа с подаванията е твърде малка"
+
 #, c-format
 msgid "invalid commit-graph chain: line '%s' not a hash"
 msgstr ""
@@ -15038,12 +15201,16 @@
 
 msgid "commit-graph requires overflow generation data but has none"
 msgstr ""
-"графът с подаванията изисква генериране на данни за отместването, но такива "
-"липсват"
+"графът с подаванията изисква данни за прелелите поколения, но такива липсват"
 
 msgid "commit-graph overflow generation data is too small"
 msgstr "прекалено малко данни за прелелите поколения в гра̀фа с подаванията"
 
+msgid "commit-graph extra-edges pointer out of bounds"
+msgstr ""
+"указателят за допълнителните ребра в гра̀фа с подаванията е извън позволения "
+"диапазон"
+
 msgid "Loading known commits in commit graph"
 msgstr "Зареждане на познатите подавания в гра̀фа с подаванията"
 
@@ -15201,6 +15368,10 @@
 msgstr "Проверка на подаванията в гра̀фа"
 
 #, c-format
+msgid "could not parse commit %s"
+msgstr "подаването „%s“ не може да бъде анализирано"
+
+#, c-format
 msgid "%s %s is not a commit!"
 msgstr "%s %s не е подаване!"
 
@@ -15652,8 +15823,13 @@
 msgid "bad zlib compression level %d"
 msgstr "неправилно ниво на компресиране: %d"
 
-msgid "core.commentChar should only be one ASCII character"
-msgstr "настройката „core.commentChar“ трябва да е само един знак от ASCII"
+#, c-format
+msgid "%s cannot contain newline"
+msgstr "%s не може да съдържа нови редове"
+
+#, c-format
+msgid "%s must have at least one character"
+msgstr "%s трябва да съдържа поне един знак"
 
 #, c-format
 msgid "ignoring unknown core.fsyncMethod value '%s'"
@@ -15678,9 +15854,9 @@
 msgid "must be one of nothing, matching, simple, upstream or current"
 msgstr ""
 "трябва да е една от следните стойности: „nothing“ (без изтласкване при липса "
-"на указател), „matching“ (всички клони със съвпадащи имена), "
-"„simple“ (клонът със същото име, от който се издърпва), „upstream“ (клонът, "
-"от който се издърпва) или „current“ (клонът със същото име)"
+"на указател), „matching“ (всички клони със съвпадащи имена), „simple“ "
+"(клонът със същото име, от който се издърпва), „upstream“ (клонът, от който "
+"се издърпва) или „current“ (клонът със същото име)"
 
 #, c-format
 msgid "unable to load config blob object '%s'"
@@ -15731,6 +15907,10 @@
 msgstr "новият конфигурационен файл „%s“ не може да бъде запазен"
 
 #, c-format
+msgid "no multi-line comment allowed: '%s'"
+msgstr "коментари на повече от един ред не са позволени: „%s“"
+
+#, c-format
 msgid "could not lock config file %s"
 msgstr "конфигурационният файл „%s“ не може да бъде заключен"
 
@@ -16218,8 +16398,8 @@
 "'dimmed-zebra', 'plain'"
 msgstr ""
 "настройката за цвят за преместване трябва да е една от: „no“ (без), "
-"„default“ (стандартно), „blocks“ (парчета), „zebra“ (райе), „dimmed-"
-"zebra“ (тъмно райе), „plain“ (обикновено)"
+"„default“ (стандартно), „blocks“ (парчета), „zebra“ (райе), „dimmed-zebra“ "
+"(тъмно райе), „plain“ (обикновено)"
 
 #, c-format
 msgid ""
@@ -16245,6 +16425,10 @@
 msgstr "Непозната стойност „%s“ за настройката „diff.submodule“"
 
 #, c-format
+msgid "unknown value for config '%s': %s"
+msgstr "непозната стойност за настройката „%s“: „%s“"
+
+#, c-format
 msgid ""
 "Found errors in 'diff.dirstat' config variable:\n"
 "%s"
@@ -16323,14 +16507,6 @@
 msgid "invalid mode '%s' in --color-moved-ws"
 msgstr "неправилен режим „%s“ за „ --color-moved-ws“"
 
-msgid ""
-"option diff-algorithm accepts \"myers\", \"minimal\", \"patience\" and "
-"\"histogram\""
-msgstr ""
-"опцията приема следните варианти за алгоритъм за разлики: „myers“ (по "
-"Майерс), „minimal“ (минимизиране на разликите), „patience“ (пасианс) и "
-"„histogram“ (хистограмен)"
-
 #, c-format
 msgid "invalid argument to %s"
 msgstr "неправилен аргумент към „%s“"
@@ -16374,8 +16550,8 @@
 msgid "output only the last line of --stat"
 msgstr "извеждане само на последния ред на „--stat“"
 
-msgid "<param1,param2>..."
-msgstr "ПАРАМЕТЪР_1, ПАРАМЕТЪР_2, …"
+msgid "<param1>,<param2>..."
+msgstr "ПАРАМЕТЪР_1,ПАРАМЕТЪР_2,…"
 
 msgid ""
 "output the distribution of relative amount of changes for each sub-directory"
@@ -16384,8 +16560,8 @@
 msgid "synonym for --dirstat=cumulative"
 msgstr "псевдоним на „--dirstat=cumulative“"
 
-msgid "synonym for --dirstat=files,param1,param2..."
-msgstr "псевдоним на „--dirstat=ФАЙЛ…,ПАРАМЕТЪР_1,ПАРАМЕТЪР_2,…“"
+msgid "synonym for --dirstat=files,<param1>,<param2>..."
+msgstr "псевдоним на „--dirstat=files,ПАРАМЕТЪР_1,ПАРАМЕТЪР_2,…“"
 
 msgid "warn if changes introduce conflict markers or whitespace errors"
 msgstr ""
@@ -16569,12 +16745,6 @@
 msgid "generate diff using the \"histogram diff\" algorithm"
 msgstr "разлика по хистограмния алгоритъм"
 
-msgid "<algorithm>"
-msgstr "АЛГОРИТЪМ"
-
-msgid "choose a diff algorithm"
-msgstr "избор на АЛГОРИТЪМа за разлики"
-
 msgid "<text>"
 msgstr "ТЕКСТ"
 
@@ -17588,6 +17758,14 @@
 msgstr "Файлът-ключалка „%s.lock“ не може да бъде създаден: %s"
 
 #, c-format
+msgid "could not write loose object index %s"
+msgstr "индексът с непакетирани обекти не може да се запише: %s"
+
+#, c-format
+msgid "failed to write loose object index %s\n"
+msgstr "грешка при записа на индекса с непакетирани обекти %s\n"
+
+#, c-format
 msgid "unexpected line: '%s'"
 msgstr "неочакван ред: „%s“"
 
@@ -17610,6 +17788,10 @@
 msgstr "Неуспешно сливане на подмодула „%s“ (няма подавания)"
 
 #, c-format
+msgid "Failed to merge submodule %s (repository corrupt)"
+msgstr "Неуспешно сливане на подмодула „%s“ (хранилището е с грешки)"
+
+#, c-format
 msgid "Failed to merge submodule %s (commits don't follow merge-base)"
 msgstr ""
 "Подмодулът „%s“ не може да бъде слят (базата за сливане не предшества "
@@ -18089,75 +18271,6 @@
 msgid "failed to read the cache"
 msgstr "кешът не може да бъде прочетен"
 
-msgid "multi-pack-index OID fanout is of the wrong size"
-msgstr ""
-"неправилен размер на откъса за разпределянето в индекса за множество пакети"
-
-msgid "multi-pack-index OID lookup chunk is the wrong size"
-msgstr "неправилен размер на откъса за търсенето в индекса за множество пакети"
-
-msgid "multi-pack-index object offset chunk is the wrong size"
-msgstr ""
-"неправилен размер на откъса за отместванията в индекса за множество пакети"
-
-#, c-format
-msgid "multi-pack-index file %s is too small"
-msgstr "файлът с индекса за множество пакети „%s“ е твърде малък"
-
-#, c-format
-msgid "multi-pack-index signature 0x%08x does not match signature 0x%08x"
-msgstr "отпечатъкът на индекса за множество пакети 0x%08x не съвпада с 0x%08x"
-
-#, c-format
-msgid "multi-pack-index version %d not recognized"
-msgstr "непозната версия на индекс за множество пакети — %d"
-
-#, c-format
-msgid "multi-pack-index hash version %u does not match version %u"
-msgstr ""
-"версията на контролната сума на индекса за множество пакети %u не съвпада с "
-"%u"
-
-msgid "multi-pack-index required pack-name chunk missing or corrupted"
-msgstr ""
-"откъсът за имена на пакети в индекса за множество пакети липсва или е "
-"повреден"
-
-msgid "multi-pack-index required OID fanout chunk missing or corrupted"
-msgstr ""
-"откъсът за разпределянето в индекса за множество пакети липсва или е повреден"
-
-msgid "multi-pack-index required OID lookup chunk missing or corrupted"
-msgstr "откъсът за търсене в индекс за множество пакети липсва или е повреден"
-
-msgid "multi-pack-index required object offsets chunk missing or corrupted"
-msgstr ""
-"откъсът за отмествания в индекс за множество пакети липсва или е повреден"
-
-msgid "multi-pack-index pack-name chunk is too short"
-msgstr ""
-"откъсът за име на пакет в индекс за множество пакети липсва или е повреден"
-
-#, c-format
-msgid "multi-pack-index pack names out of order: '%s' before '%s'"
-msgstr ""
-"неправилна подредба на имената в индекс за множество пакети: „%s“ се появи "
-"преди „%s“"
-
-#, c-format
-msgid "bad pack-int-id: %u (%u total packs)"
-msgstr ""
-"неправилен идентификатор на пакет (pack-int-id): %u (от общо %u пакети)"
-
-msgid "multi-pack-index stores a 64-bit offset, but off_t is too small"
-msgstr ""
-"индексът за множество пакети съдържа 64-битови отмествания, но размерът на "
-"„off_t“ е недостатъчен"
-
-msgid "multi-pack-index large offset out of bounds"
-msgstr ""
-"стойността на отместването в индекса за множество пакети е извън диапазона"
-
 #, c-format
 msgid "failed to add packfile '%s'"
 msgstr "пакетният файл „%s“ не може да бъде добавен"
@@ -18226,6 +18339,102 @@
 msgid "could not write multi-pack-index"
 msgstr "индексът за множество пакети не може да бъде запазен"
 
+msgid "Counting referenced objects"
+msgstr "Преброяване на свързаните обекти"
+
+msgid "Finding and deleting unreferenced packfiles"
+msgstr "Търсене и изтриване на несвързаните пакетни файлове"
+
+msgid "could not start pack-objects"
+msgstr "командата „pack-objects“ не може да бъде стартирана"
+
+msgid "could not finish pack-objects"
+msgstr "командата „pack-objects“ не може да бъде завършена"
+
+msgid "multi-pack-index OID fanout is of the wrong size"
+msgstr ""
+"неправилен размер на откъса за разпределянето в индекса за множество пакети"
+
+#, c-format
+msgid ""
+"oid fanout out of order: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]"
+msgstr ""
+"неправилна подредба на откъси (OID fanout): fanout[%d] = %<PRIx32> > "
+"%<PRIx32> = fanout[%d]"
+
+msgid "multi-pack-index OID lookup chunk is the wrong size"
+msgstr "неправилен размер на откъса за търсенето в индекса за множество пакети"
+
+msgid "multi-pack-index object offset chunk is the wrong size"
+msgstr ""
+"неправилен размер на откъса за отместванията в индекса за множество пакети"
+
+#, c-format
+msgid "multi-pack-index file %s is too small"
+msgstr "файлът с индекса за множество пакети „%s“ е твърде малък"
+
+#, c-format
+msgid "multi-pack-index signature 0x%08x does not match signature 0x%08x"
+msgstr "отпечатъкът на индекса за множество пакети 0x%08x не съвпада с 0x%08x"
+
+#, c-format
+msgid "multi-pack-index version %d not recognized"
+msgstr "непозната версия на индекс за множество пакети — %d"
+
+#, c-format
+msgid "multi-pack-index hash version %u does not match version %u"
+msgstr ""
+"версията на контролната сума на индекса за множество пакети %u не съвпада с "
+"%u"
+
+msgid "multi-pack-index required pack-name chunk missing or corrupted"
+msgstr ""
+"откъсът за имена на пакети в индекса за множество пакети липсва или е "
+"повреден"
+
+msgid "multi-pack-index required OID fanout chunk missing or corrupted"
+msgstr ""
+"откъсът за разпределянето в индекса за множество пакети липсва или е повреден"
+
+msgid "multi-pack-index required OID lookup chunk missing or corrupted"
+msgstr "откъсът за търсене в индекс за множество пакети липсва или е повреден"
+
+msgid "multi-pack-index required object offsets chunk missing or corrupted"
+msgstr ""
+"откъсът за отмествания в индекс за множество пакети липсва или е повреден"
+
+msgid "multi-pack-index pack-name chunk is too short"
+msgstr ""
+"откъсът за име на пакет в индекс за множество пакети липсва или е повреден"
+
+#, c-format
+msgid "multi-pack-index pack names out of order: '%s' before '%s'"
+msgstr ""
+"неправилна подредба на имената в индекс за множество пакети: „%s“ се появи "
+"преди „%s“"
+
+#, c-format
+msgid "bad pack-int-id: %u (%u total packs)"
+msgstr ""
+"неправилен идентификатор на пакет (pack-int-id): %u (от общо %u пакети)"
+
+msgid "MIDX does not contain the BTMP chunk"
+msgstr ""
+"липсва откъс за побитова маска във файла за индекса за множество пакети"
+
+#, c-format
+msgid "could not load bitmapped pack %<PRIu32>"
+msgstr "пакетът за битови маски %<PRIu32> не може да се отвори"
+
+msgid "multi-pack-index stores a 64-bit offset, but off_t is too small"
+msgstr ""
+"индексът за множество пакети съдържа 64-битови отмествания, но размерът на "
+"„off_t“ е недостатъчен"
+
+msgid "multi-pack-index large offset out of bounds"
+msgstr ""
+"стойността на отместването в индекса за множество пакети е извън диапазона"
+
 #, c-format
 msgid "failed to clear multi-pack-index at %s"
 msgstr "индексът за множество пакети не може да бъде изчистен при „%s“"
@@ -18241,13 +18450,6 @@
 msgid "Looking for referenced packfiles"
 msgstr "Търсене на указаните пакетни файлове"
 
-#, c-format
-msgid ""
-"oid fanout out of order: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]"
-msgstr ""
-"неправилна подредба на откъси (OID fanout): fanout[%d] = %<PRIx32> > "
-"%<PRIx32> = fanout[%d]"
-
 msgid "the midx contains no oid"
 msgstr "във файла с индекса за множество пакети няма идентификатори на обекти"
 
@@ -18279,18 +18481,6 @@
 msgid "incorrect object offset for oid[%d] = %s: %<PRIx64> != %<PRIx64>"
 msgstr "неправилно отместване на обект за oid[%d] = %s: %<PRIx64> != %<PRIx64>"
 
-msgid "Counting referenced objects"
-msgstr "Преброяване на свързаните обекти"
-
-msgid "Finding and deleting unreferenced packfiles"
-msgstr "Търсене и изтриване на несвързаните пакетни файлове"
-
-msgid "could not start pack-objects"
-msgstr "командата „pack-objects“ не може да бъде стартирана"
-
-msgid "could not finish pack-objects"
-msgstr "командата „pack-objects“ не може да бъде завършена"
-
 #, c-format
 msgid "unable to create lazy_dir thread: %s"
 msgstr "не може да се създаде нишка за директории (lazy_dir): %s"
@@ -18345,6 +18535,25 @@
 msgid "Bad %s value: '%s'"
 msgstr "Зададена е лоша стойност на променливата „%s“: „%s“"
 
+msgid "failed to decode tree entry"
+msgstr "записът в дърво не може да се декодира"
+
+#, c-format
+msgid "failed to map tree entry for %s"
+msgstr "не може да се открие съответствието на записа в дърво за „%s“"
+
+#, c-format
+msgid "bad %s in commit"
+msgstr "неправилен запис „%s“ в подаването"
+
+#, c-format
+msgid "unable to map %s %s in commit object"
+msgstr "не може да се открие съответствието на „%s %s“ в обекта-подаване"
+
+#, c-format
+msgid "Failed to convert object from %s to %s"
+msgstr "Неуспешно преобразуване на „%s“ към „%s“"
+
 #, c-format
 msgid "object directory %s does not exist; check .git/objects/info/alternates"
 msgstr ""
@@ -18451,6 +18660,10 @@
 msgstr "пакетираният обект „%s“ (в „%s“) е повреден"
 
 #, c-format
+msgid "missing mapping of %s to %s"
+msgstr "липсва съответствие на „%s“ към „%s“"
+
+#, c-format
 msgid "unable to write file %s"
 msgstr "файлът „%s“ не може да бъде записан"
 
@@ -18505,6 +18718,10 @@
 msgstr "обектът за „%s“ не може да се прочете"
 
 #, c-format
+msgid "cannot map object %s to %s"
+msgstr "липсва съответствие на обекта „%s“ към „%s“"
+
+#, c-format
 msgid "object fails fsck: %s"
 msgstr "„fsck“ откри грешка в обект: „%s“"
 
@@ -18792,6 +19009,11 @@
 msgid "could not open pack %s"
 msgstr "пакетът „%s“ не може да се отвори"
 
+msgid "could not determine MIDX preferred pack"
+msgstr ""
+"предпочитаният пакет за файла с индекса за множество пакети не може да се "
+"определи"
+
 #, c-format
 msgid "preferred pack (%s) is invalid"
 msgstr "предпочитаният пакет „%s“ е неправилен"
@@ -18819,6 +19041,11 @@
 "маска на подаване „%s“"
 
 #, c-format
+msgid "unable to load pack: '%s', disabling pack-reuse"
+msgstr ""
+"пакетът не може да се зареди: „%s“, преизползването на пакети се изключва"
+
+#, c-format
 msgid "object '%s' not found in type bitmaps"
 msgstr "обектът „%s“ липсва в битовата маска на видовете"
 
@@ -18917,6 +19144,9 @@
 msgstr ""
 "неправилен размер на откъс за обратен индекс в индекса за множество пакети"
 
+msgid "could not determine preferred pack"
+msgstr "предпочитаният пакет не може да се определи"
+
 msgid "cannot both write and verify reverse index"
 msgstr "обратният индекс не може едновременно да се записва и да се проверява"
 
@@ -18959,8 +19189,8 @@
 #, c-format
 msgid "option `%s' expects \"always\", \"auto\", or \"never\""
 msgstr ""
-"опцията „%s“ изисква някоя от стойностите: „always“ (винаги), "
-"„auto“ (автоматично) или „never“ (никога)"
+"опцията „%s“ изисква някоя от стойностите: „always“ (винаги), „auto“ "
+"(автоматично) или „never“ (никога)"
 
 #, c-format
 msgid "malformed object name '%s'"
@@ -18988,10 +19218,6 @@
 "„%s“ очаква неотрицателно цяло число, евентуално със суфикс „k“/„m“/„g“"
 
 #, c-format
-msgid "%s is incompatible with %s"
-msgstr "опциите „%s“ и „%s“ са несъвместими"
-
-#, c-format
 msgid "ambiguous option: %s (could be --%s%s or --%s%s)"
 msgstr "нееднозначна опция: „%s“ (може да е „--%s%s“ или „--%s%s“)"
 
@@ -19018,6 +19244,18 @@
 msgid "unknown non-ascii option in string: `%s'"
 msgstr "непозната стойност извън „ascii“ в низа: „%s“"
 
+#, c-format
+msgid "[=<%s>]"
+msgstr "[=%s]"
+
+#, c-format
+msgid "[<%s>]"
+msgstr "[%s]"
+
+#, c-format
+msgid " <%s>"
+msgstr " %s"
+
 msgid "..."
 msgstr "…"
 
@@ -19316,10 +19554,6 @@
 msgstr "„%s“ не може да се добави в индекса"
 
 #, c-format
-msgid "unable to stat '%s'"
-msgstr "„stat“ не може да се изпълни върху „%s“"
-
-#, c-format
 msgid "'%s' appears as both a file and as a directory"
 msgstr "„%s“ съществува и като файл, и като директория"
 
@@ -19864,7 +20098,7 @@
 
 #, c-format
 msgid "ignoring dangling symref %s"
-msgstr "игнориране на указател на обект извън клон „%s“"
+msgstr "игнориране на файл с указател на обект извън клон „%s“"
 
 #, c-format
 msgid "log for ref %s has gap after %s"
@@ -19905,10 +20139,6 @@
 msgstr "невъзможно е едновременно да се обработват „%s“ и „%s“"
 
 #, c-format
-msgid "could not remove reference %s"
-msgstr "Указателят „%s“ не може да бъде изтрит"
-
-#, c-format
 msgid "could not delete reference %s: %s"
 msgstr "Указателят „%s“ не може да бъде изтрит: %s"
 
@@ -19917,6 +20147,78 @@
 msgstr "Указателите не може да бъдат изтрити: %s"
 
 #, c-format
+msgid "refname is dangerous: %s"
+msgstr "опасно име на указател: %s"
+
+#, c-format
+msgid "trying to write ref '%s' with nonexistent object %s"
+msgstr "опит за запис на указател „%s“ към обект, който не съществува: %s"
+
+#, c-format
+msgid "trying to write non-commit object %s to branch '%s'"
+msgstr "опит за записване на обект, който не е подаване — %s, в клона „%s“"
+
+#, c-format
+msgid ""
+"multiple updates for 'HEAD' (including one via its referent '%s') are not "
+"allowed"
+msgstr ""
+"не са позволени повече от една промѐни (включително чрез сочещия го „%s“) на "
+"указателя „HEAD“"
+
+#, c-format
+msgid "cannot lock ref '%s': unable to resolve reference '%s'"
+msgstr ""
+"указателят „%s“ не може да се заключи: не може да се открие към какво сочи "
+"указателят „%s“"
+
+#, c-format
+msgid "cannot lock ref '%s': error reading reference"
+msgstr "указателят „%s“ не може да се заключи: грешка при четене на указателя"
+
+#, c-format
+msgid ""
+"multiple updates for '%s' (including one via symref '%s') are not allowed"
+msgstr ""
+"не са позволени повече от една промѐни на указателя „%s“ (включително през "
+"символния указател „%s“)"
+
+#, c-format
+msgid "cannot lock ref '%s': reference already exists"
+msgstr "указателят „%s“ не може да се заключи:cуказателят вече съществува"
+
+#, c-format
+msgid "cannot lock ref '%s': reference is missing but expected %s"
+msgstr ""
+"указателят „%s“ не може да се заключи: указателят липсва, а се очаква „%s“"
+
+#, c-format
+msgid "cannot lock ref '%s': is at %s but expected %s"
+msgstr ""
+"указателят „%s“ не може да се заключи: той сочи към „%s“, а се очаква да "
+"сочи към „%s“"
+
+#, c-format
+msgid "reftable: transaction prepare: %s"
+msgstr "таблица с указатели: подготовка на транзакция: %s"
+
+#, c-format
+msgid "reftable: transaction failure: %s"
+msgstr "таблица с указатели: неуспешна транзакция: %s"
+
+#, c-format
+msgid "unable to compact stack: %s"
+msgstr "стекът не може да се свие: %s"
+
+#, c-format
+msgid "refname %s not found"
+msgstr "името на указателя „%s“ не може да бъде открито"
+
+#, c-format
+msgid "refname %s is a symbolic ref, copying it is not supported"
+msgstr "името на указател „%s“ е символен указател, не може да се копира"
+
+#, c-format
 msgid "invalid refspec '%s'"
 msgstr "неправилен указател: „%s“"
 
@@ -19927,6 +20229,10 @@
 "„%s“"
 
 #, c-format
+msgid "unknown value for object-format: %s"
+msgstr "непозната стойност за „--object-format“: „%s“"
+
+#, c-format
 msgid "%sinfo/refs not valid: is this a git repository?"
 msgstr "„%sinfo/refs“ е неизползваемо, проверете дали е хранилище на git"
 
@@ -20382,7 +20688,18 @@
 "липсва"
 
 #, c-format
-msgid "could not get commit for ancestry-path argument %s"
+msgid "%s exists but is a symbolic ref"
+msgstr "„%s“ съществува и не е символна връзка"
+
+msgid ""
+"--merge requires one of the pseudorefs MERGE_HEAD, CHERRY_PICK_HEAD, "
+"REVERT_HEAD or REBASE_HEAD"
+msgstr ""
+"„--merge“ изисква някой от псевдоуказателите „MERGE_HEAD“, "
+"„CHERRY_PICK_HEAD“, „REVERT_HEAD“ или „REBASE_HEAD“"
+
+#, c-format
+msgid "could not get commit for --ancestry-path argument %s"
 msgstr "подаването „%s“ към опцията „--ancestry-path“ не може да бъде получено"
 
 msgid "--unpacked=<packfile> no longer supported"
@@ -20676,6 +20993,19 @@
 msgstr "неизвестно действие: %d"
 
 msgid ""
+"Resolve all conflicts manually, mark them as resolved with\n"
+"\"git add/rm <conflicted_files>\", then run \"git rebase --continue\".\n"
+"You can instead skip this commit: run \"git rebase --skip\".\n"
+"To abort and get back to the state before \"git rebase\", run \"git rebase --"
+"abort\"."
+msgstr ""
+"След коригирането на конфликтите отбележете решаването им чрез:\n"
+"„git add/rm ФАЙЛ_С_КОНФЛИКТ…“ и изпълнете „git rebase --continue“.\n"
+"Ако предпочитате да прескочите тази кръпка, изпълнете „git rebase --skip“.\n"
+"За да откажете пребазирането и да се върнете към първоначалното състояние,\n"
+"изпълнете „git rebase --abort“."
+
+msgid ""
 "after resolving the conflicts, mark the corrected paths\n"
 "with 'git add <paths>' or 'git rm <paths>'"
 msgstr ""
@@ -20926,10 +21256,6 @@
 msgstr "„%s“ не може да се обнови"
 
 #, c-format
-msgid "could not parse commit %s"
-msgstr "подаването „%s“ не може да бъде анализирано"
-
-#, c-format
 msgid "could not parse parent commit %s"
 msgstr "родителското подаване „%s“ не може да бъде анализирано"
 
@@ -21035,10 +21361,6 @@
 msgstr "неправилна команда „%.*s“"
 
 #, c-format
-msgid "%s does not accept arguments: '%s'"
-msgstr "„%s“ не приема аргументи: „%s“"
-
-#, c-format
 msgid "missing arguments for %s"
 msgstr "„%s“ изисква аргументи"
 
@@ -21333,6 +21655,9 @@
 msgid "Autostash exists; creating a new stash entry."
 msgstr "Вече има запис за автоматично скатано, затова се създава нов запис."
 
+msgid "autostash reference is a symref"
+msgstr "указателят за автоматично скатано e файл с указател"
+
 msgid "could not detach HEAD"
 msgstr "указателят „HEAD“ не може да се отдели"
 
@@ -21509,6 +21834,10 @@
 "не може да се зададе текуща работна директория при неправилни настройки"
 
 #, c-format
+msgid "'%s' already specified as '%s'"
+msgstr "„%s“ вече съществува като „%s“"
+
+#, c-format
 msgid "Expected git repo version <= %d, found %d"
 msgstr "Очаква се версия на хранилището на git <= %d, а не %d"
 
@@ -21657,6 +21986,10 @@
 msgstr "неправилно име на първоначалния клон: „%s“"
 
 #, c-format
+msgid "re-init: ignored --initial-branch=%s"
+msgstr "re-init: „--initial-branch=%s“ се пропуска"
+
+#, c-format
 msgid "unable to handle file type %d"
 msgstr "файлове от вид %d не се поддържат"
 
@@ -21666,18 +21999,19 @@
 
 msgid "attempt to reinitialize repository with different hash"
 msgstr ""
-"опит за повторно задаване на първото подаване в хранилището с различна "
-"контролна сума"
+"опит за зануляване на хранилището и инициализиране с различна контролна сума"
+
+msgid ""
+"attempt to reinitialize repository with different reference storage format"
+msgstr ""
+"опит за зануляване на хранилището и инициализиране с различен формат на "
+"съхраняване"
 
 #, c-format
 msgid "%s already exists"
 msgstr "Директорията „%s“ вече съществува"
 
 #, c-format
-msgid "re-init: ignored --initial-branch=%s"
-msgstr "re-init: „--initial-branch=%s“ се пропуска"
-
-#, c-format
 msgid "Reinitialized existing shared Git repository in %s%s\n"
 msgstr ""
 "Инициализиране наново на съществуващо, споделено хранилище на Git в „%s%s“\n"
@@ -21701,6 +22035,21 @@
 msgid "cannot use split index with a sparse index"
 msgstr "разделѐн индекс не може да се ползва частичен индекс"
 
+#. TRANSLATORS: The first %s is a command like "ls-tree".
+#, c-format
+msgid "bad %s format: element '%s' does not start with '('"
+msgstr "неправилен формат за „%s“: елементът „%s“ не започва с „(“"
+
+#. TRANSLATORS: The first %s is a command like "ls-tree".
+#, c-format
+msgid "bad %s format: element '%s' does not end in ')'"
+msgstr "неправилен формат за „%s“: елементът „%s“ не завършва с „)“"
+
+#. TRANSLATORS: %s is a command like "ls-tree".
+#, c-format
+msgid "bad %s format: %%%.*s"
+msgstr "неправилен формат за „%s“: %%%.*s"
+
 #. TRANSLATORS: IEC 80000-13:2008 gibibyte
 #, c-format
 msgid "%u.%2.2u GiB"
@@ -21948,12 +22297,6 @@
 "какъв брой записи в кеша на обектите-дървета да се отбележат като невалидни "
 "(стандартно е 0)"
 
-msgid "unhandled options"
-msgstr "неподдържани опции"
-
-msgid "error preparing revisions"
-msgstr "грешка при подготовката на версии"
-
 #, c-format
 msgid "commit %s is not marked reachable"
 msgstr "подаването „%s“ не е отбелязано като достижимо"
@@ -22034,29 +22377,6 @@
 msgid "empty trailer token in trailer '%.*s'"
 msgstr "празна завършваща лексема в епилога „%.*s“"
 
-#, c-format
-msgid "could not read input file '%s'"
-msgstr "входният файл „%s“ не може да бъде прочетен"
-
-#, c-format
-msgid "could not stat %s"
-msgstr "Не може да се получи информация чрез „stat“ за „%s“"
-
-#, c-format
-msgid "file %s is not a regular file"
-msgstr "„%s“ не е обикновен файл"
-
-#, c-format
-msgid "file %s is not writable by user"
-msgstr "„%s“: няма права̀ за записване на файла"
-
-msgid "could not open temporary file"
-msgstr "временният файл не може да се отвори"
-
-#, c-format
-msgid "could not rename temporary file to %s"
-msgstr "временният файл не може да се преименува на „%s“"
-
 msgid "full write to remote helper failed"
 msgstr "неуспешен пълен запис към насрещната помощна програма"
 
@@ -22110,9 +22430,6 @@
 msgid "invalid remote service path"
 msgstr "неправилен път на отдалечената услуга"
 
-msgid "operation not supported by protocol"
-msgstr "опцията не се поддържа от протокола"
-
 #, c-format
 msgid "can't connect to subservice %s"
 msgstr "неуспешно свързване към подуслугата „%s“"
@@ -22163,7 +22480,7 @@
 "изброяване на указателите"
 
 #, c-format
-msgid "helper %s does not support 'force'"
+msgid "helper %s does not support '--force'"
 msgstr "насрещната помощна програма „%s“ не поддържа опцията „--force“"
 
 msgid "couldn't run fast-export"
@@ -22248,10 +22565,6 @@
 msgstr "протокол версия 2 все още не се поддържа"
 
 #, c-format
-msgid "unknown value for config '%s': %s"
-msgstr "непозната стойност за настройката „%s“: „%s“"
-
-#, c-format
 msgid "transport '%s' not allowed"
 msgstr "преносът по „%s“ не е позволен"
 
@@ -22304,6 +22617,9 @@
 "спъсъкът с адреси на пратки обявени за налични от сървъра не може да се "
 "получи "
 
+msgid "operation not supported by protocol"
+msgstr "опцията не се поддържа от протокола"
+
 msgid "too-short tree object"
 msgstr "прекалено кратък обект-дърво"
 
@@ -22578,6 +22894,10 @@
 msgid "invalid '..' path segment"
 msgstr "неправилна част от пътя „..“"
 
+#, c-format
+msgid "error: unable to format message: %s\n"
+msgstr "ГРЕШКА: съобщението не може да се форматира: %s\n"
+
 msgid "usage: "
 msgstr "употреба: "
 
@@ -23147,6 +23467,10 @@
 msgid "cannot %s: Your index contains uncommitted changes."
 msgstr "не може да извършите „%s“, защото в индекса има неподадени промѐни."
 
+#, c-format
+msgid "unknown style '%s' given for '%s'"
+msgstr "непознат стил „%s“ за „%s“"
+
 msgid ""
 "Error: Your local changes to the following files would be overwritten by "
 "merge"
@@ -23398,8 +23722,8 @@
 #. at this point.
 msgid "What to do with this address? ([q]uit|[d]rop|[e]dit): "
 msgstr ""
-"Какво да се направи с този адрес? „q“ (спиране), „d“ (изтриване), "
-"„e“ (редактиране): "
+"Какво да се направи с този адрес? „q“ (спиране), „d“ (изтриване), „e“ "
+"(редактиране): "
 
 #, perl-format
 msgid "CA path \"%s\" does not exist"
diff --git a/po/ca.po b/po/ca.po
index d1a4e56..bcb4da8 100644
--- a/po/ca.po
+++ b/po/ca.po
@@ -1,7 +1,7 @@
 # Catalan translations for Git.
 # This file is distributed under the same license as the Git package.
 # Alex Henrie <alexhenrie24@gmail.com>, 2014-2016.
-# Jordi Mas i Hernàndez <jmas@softcatala.org>, 2016-2023
+# Jordi Mas i Hernàndez <jmas@softcatala.org>, 2016-2024
 #
 # Terminologia
 #
@@ -56,6 +56,7 @@
 #   Anglès           |  Català
 #   -----------------+---------------------------------
 #   blame            |  «blame»
+#   fanout           |  «fanout»
 #   HEAD             |  HEAD (f, la branca actual) - (no s'apostrofa)
 #   cherry pick      |  «cherry pick»
 #   promisor         |  «promisor»
@@ -70,14 +71,14 @@
 #
 # Criteris
 #   - Mantingueu en anglès les referències a seccions de la documentació, ja que no està traduïda.
-#   - Usem la convenció valenciana per a «per / per a», que inclou l'ús de «per a» davant d'infintiu
+#   - Usem la convenció valenciana per a «per / per a», que inclou l'ús de «per a» davant d'infinitiu
 #
 msgid ""
 msgstr ""
 "Project-Id-Version: Git\n"
 "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2023-11-13 18:55+0100\n"
-"PO-Revision-Date: 2023-11-13 19:00-0600\n"
+"POT-Creation-Date: 2024-02-16 07:14+0100\n"
+"PO-Revision-Date: 2024-02-16 07:16+0100\n"
 "Last-Translator: Jordi Mas i Hernàndez <jmas@softcatala.org>\n"
 "Language-Team: Catalan\n"
 "Language: ca\n"
@@ -592,6 +593,7 @@
 #. Consider translating (saying "no" discards!) as
 #. (saying "n" for "no" discards!) if the translation
 #. of the word "no" does not start with n.
+#.
 msgid ""
 "Your edited hunk does not apply. Edit again (saying \"no\" discards!) [y/n]? "
 msgstr ""
@@ -1503,6 +1505,10 @@
 msgstr "Opció inesperada --output"
 
 #, c-format
+msgid "extra command line parameter '%s'"
+msgstr "paràmetre extra de la línia d'ordres «%s»"
+
+#, c-format
 msgid "Unknown archive format '%s'"
 msgstr "Format d'arxiu desconegut «%s»"
 
@@ -1548,6 +1554,14 @@
 msgstr "--attr-source incorrecte o GIT_ATTR_SOURCE"
 
 #, c-format
+msgid "unable to stat '%s'"
+msgstr "no s'ha pogut fer «stat» a «%s»"
+
+#, c-format
+msgid "unable to read %s"
+msgstr "no s'ha pogut llegir %s"
+
+#, c-format
 msgid "Badly quoted content in file '%s': %s"
 msgstr "Comentari amb cometes errònies en el fitxer «%s»: %s"
 
@@ -1643,6 +1657,7 @@
 
 #. TRANSLATORS: the last %s will be replaced with "(roughly %d
 #. steps)" translation.
+#.
 #, c-format
 msgid "Bisecting: %d revision left to test after this %s\n"
 msgid_plural "Bisecting: %d revisions left to test after this %s\n"
@@ -1728,17 +1743,20 @@
 #. TRANSLATORS: This is a line listing a remote with duplicate
 #. refspecs in the advice message below. For RTL languages you'll
 #. probably want to swap the "%s" and leading "  " space around.
+#.
 #. #-#-#-#-#  object-name.c.po  #-#-#-#-#
 #. TRANSLATORS: This is line item of ambiguous object output
 #. from describe_ambiguous_object() above. For RTL languages
 #. you'll probably want to swap the "%s" and leading " " space
 #. around.
+#.
 #, c-format
 msgid "  %s\n"
 msgstr "  %s\n"
 
 #. TRANSLATORS: The second argument is a \n-delimited list of
 #. duplicate refspecs, composed above.
+#.
 #, c-format
 msgid ""
 "There are multiple remotes whose fetch refspecs map to the remote\n"
@@ -2143,6 +2161,7 @@
 #. TRANSLATORS: Make sure to include [y], [n], [e], [v] and [a]
 #. in your translation. The program will only accept English
 #. input at this point.
+#.
 #, c-format
 msgid "Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all: "
 msgstr ""
@@ -2480,6 +2499,7 @@
 #. TRANSLATORS: Make sure to include [Y] and [n] in your
 #. translation. The program will only accept English input
 #. at this point.
+#.
 msgid "Are you sure [Y/n]? "
 msgstr "N'esteu segur [Y/n]? "
 
@@ -2557,6 +2577,7 @@
 #. TRANSLATORS: Make sure to include [Y] and [n] in your
 #. translation. The program will only accept English input
 #. at this point.
+#.
 msgid "Do you want me to do it for you [Y/n]? "
 msgstr "Voleu que ho faci per vostè [Y/n]? "
 
@@ -2777,6 +2798,7 @@
 #. among various forms of relative timestamps, but
 #. your language may need more or fewer display
 #. columns.
+#.
 msgid "4 years, 11 months ago"
 msgstr "fa 4 anys i 11 mesos"
 
@@ -2838,12 +2860,12 @@
 msgstr "no s'ha pogut cercar l'objecte de comissió per a «%s»"
 
 #, c-format
-msgid ""
-"the branch '%s' is not fully merged.\n"
-"If you are sure you want to delete it, run 'git branch -D %s'"
-msgstr ""
-"la branca «%s» no està completament fusionada.\n"
-"Si esteu segur que voleu suprimir-la, executeu «git branch -D %s»"
+msgid "the branch '%s' is not fully merged"
+msgstr "la branca «%s» no està completament fusionada"
+
+#, c-format
+msgid "If you are sure you want to delete it, run 'git branch -D %s'"
+msgstr "Si esteu segur que voleu suprimir-la, executeu «git branch -D %s»"
 
 msgid "update of config-file failed"
 msgstr "ha fallat l'actualització del fitxer de configuració"
@@ -3884,8 +3906,8 @@
 msgid "new-branch"
 msgstr "branca-nova"
 
-msgid "new unparented branch"
-msgstr "branca òrfena nova"
+msgid "new unborn branch"
+msgstr "branca no nascuda nova"
 
 msgid "update ignored files (default)"
 msgstr "actualitza els fitxers ignorats (per defecte)"
@@ -4137,9 +4159,6 @@
 "clean.requireForce és per defecte cert i ni -i, -n ni -f s'han indicat; "
 "refusant netejar"
 
-msgid "-x and -X cannot be used together"
-msgstr "-x i -X no es poden usar junts"
-
 msgid "git clone [<options>] [--] <repo> [<dir>]"
 msgstr "git clone [<opcions>] [--] <repositori> [<directori>]"
 
@@ -4228,6 +4247,9 @@
 msgid "separate git dir from working tree"
 msgstr "separa el directori de git de l'arbre de treball"
 
+msgid "specify the reference format to use"
+msgstr "especifiqueu el format de referència a usar"
+
 msgid "key=value"
 msgstr "clau=valor"
 
@@ -4347,11 +4369,9 @@
 msgid "You must specify a repository to clone."
 msgstr "Heu d'especificar un repositori per a clonar."
 
-msgid ""
-"--bundle-uri is incompatible with --depth, --shallow-since, and --shallow-"
-"exclude"
-msgstr ""
-"--bundle-uri és incompatible amb --depth, --shallow-since i --shallow-exclude"
+#, c-format
+msgid "unknown ref storage format '%s'"
+msgstr "el format d'emmagatzematge de referència «%s» és desconegut"
 
 #, c-format
 msgid "repository '%s' does not exist"
@@ -4481,14 +4501,14 @@
 "--stdin-commits]\n"
 "                       [--changed-paths] [--[no-]max-new-filters <n>] [--"
 "[no-]progress]\n"
-"                       <split options>"
+"                       <split-options>"
 msgstr ""
 "git commit-graph write [--object-dir <dir>] [--append]\n"
 "                       [--split[=<strategy>]] [--reachable | --stdin-packs | "
 "--stdin-commits]\n"
 "                       [--changed-paths] [--[no-]max-new-filters <n>] [--"
 "[no-]progress]\n"
-"                       <split options>"
+"                       <split-options>"
 
 msgid "dir"
 msgstr "directori"
@@ -5007,6 +5027,7 @@
 
 #. TRANSLATORS: Leave "[(amend|reword):]" as-is,
 #. and only translate <commit>.
+#.
 msgid "[(amend|reword):]commit"
 msgstr "[(amend|reword):]commit"
 
@@ -5544,7 +5565,7 @@
 
 #, c-format
 msgid "option '%s' and commit-ishes cannot be used together"
-msgstr "les opcions «%s» i de comissió no es poden usar juntes"
+msgstr "opció «%s» i les de comissió no es poden usar juntes"
 
 msgid ""
 "git diagnose [(-o | --output-directory) <path>] [(-s | --suffix) <format>]\n"
@@ -6820,6 +6841,7 @@
 #. TRANSLATORS: %s is the configuration
 #. variable for tweaking threads, currently
 #. grep.threads
+#.
 #, c-format
 msgid "no threads support, ignoring %s"
 msgstr "no s'admeten fils, s'ignorarà %s"
@@ -6829,6 +6851,10 @@
 msgstr "no s'ha pogut llegir l'arbre (%s)"
 
 #, c-format
+msgid "unable to read tree %s"
+msgstr "no s'ha pogut llegir l'arbre %s"
+
+#, c-format
 msgid "unable to grep from object of type %s"
 msgstr "no es pot fer grep des d'un objecte de tipus %s"
 
@@ -7247,10 +7273,6 @@
 msgstr "S'HA TROBAT UNA COL·LISIÓ SHA1 AMB %s !"
 
 #, c-format
-msgid "unable to read %s"
-msgstr "no s'ha pogut llegir %s"
-
-#, c-format
 msgid "cannot read existing object info %s"
 msgstr "no es pot llegir la informació d'objecte existent %s"
 
@@ -7390,11 +7412,13 @@
 msgid ""
 "git init [-q | --quiet] [--bare] [--template=<template-directory>]\n"
 "         [--separate-git-dir <git-dir>] [--object-format=<format>]\n"
+"         [--ref-format=<format>]\n"
 "         [-b <branch-name> | --initial-branch=<branch-name>]\n"
 "         [--shared[=<permissions>]] [<directory>]"
 msgstr ""
 "git init [-q | --quiet] [--bare] [--template=<template-directory>]\n"
 "         [--separate-git-dir <git-dir>] [--object-format=<format>]\n"
+"         [--ref-format=<format>]\n"
 "         [-b <branch-name> | --initial-branch=<branch-name>]\n"
 "         [--shared[=<permissions>]] [<directory>]"
 
@@ -8110,6 +8134,12 @@
 "git merge-file [<opcions>] [-L <nom1> [-L <original> [-L <nom2>]]] <fitxer1> "
 "<fitxer-original> <fitxer2>"
 
+msgid ""
+"option diff-algorithm accepts \"myers\", \"minimal\", \"patience\" and "
+"\"histogram\""
+msgstr ""
+"l'opció diff-algorithm accepta «myers», «minimal», «patience» i «histogram»"
+
 msgid "send results to standard output"
 msgstr "envia els resultats a la sortida estàndard"
 
@@ -8131,6 +8161,12 @@
 msgid "for conflicts, use a union version"
 msgstr "en conflictes, usa una versió d'unió"
 
+msgid "<algorithm>"
+msgstr "<algorisme>"
+
+msgid "choose a diff algorithm"
+msgstr "trieu un algorisme per al diff"
+
 msgid "for conflicts, use this marker size"
 msgstr "en conflictes, usa aquesta mida de marcador"
 
@@ -8221,9 +8257,6 @@
 msgid "unknown strategy option: -X%s"
 msgstr "opció d'estratègia desconeguda: -X%s"
 
-msgid "--merge-base is incompatible with --stdin"
-msgstr "--merge-base és incompatible amb --stdin"
-
 #, c-format
 msgid "malformed input line: '%s'."
 msgstr "línia d'entrada mal formada: «%s»."
@@ -8856,6 +8889,7 @@
 
 #. TRANSLATORS: the first %s will be replaced by a git
 #. notes command: 'add', 'merge', 'remove', etc.
+#.
 #, c-format
 msgid "refusing to %s notes in %s (outside of refs/notes/)"
 msgstr "s'està refusant %s les notes en %s (fora de refs/notes/)"
@@ -9166,6 +9200,10 @@
 msgstr "inconsistència amb el comptador de diferències"
 
 #, c-format
+msgid "invalid pack.allowPackReuse value: '%s'"
+msgstr "valor pack.allowPackReuse value no vàlid: «%s»"
+
+#, c-format
 msgid ""
 "value of uploadpack.blobpackfileuri must be of the form '<object-hash> <pack-"
 "hash> <uri>' (got '%s')"
@@ -9430,10 +9468,10 @@
 #, c-format
 msgid ""
 "Total %<PRIu32> (delta %<PRIu32>), reused %<PRIu32> (delta %<PRIu32>), pack-"
-"reused %<PRIu32>"
+"reused %<PRIu32> (from %<PRIuMAX>)"
 msgstr ""
 "Total %<PRIu32> (%<PRIu32> diferències), reusats %<PRIu32> (%<PRIu32> "
-"diferències), paquets reusats %<PRIu32>"
+"diferències), paquets reusats %<PRIu32> (de %<PRIuMAX>)"
 
 msgid ""
 "'git pack-redundant' is nominated for removal.\n"
@@ -10398,13 +10436,6 @@
 msgstr "«switch» «c» espera un valor numèric"
 
 msgid ""
-"apply options are incompatible with rebase.autoSquash.  Consider adding --no-"
-"autosquash"
-msgstr ""
-"les opcions «apply» són incompatibles amb rebase.autoSquash. Considereu "
-"afegir-hi --no-autosquash"
-
-msgid ""
 "apply options are incompatible with rebase.rebaseMerges.  Consider adding --"
 "no-rebase-merges"
 msgstr ""
@@ -10922,6 +10953,7 @@
 #. TRANSLATORS: the colon ':' should align
 #. with the one in " Fetch URL: %s"
 #. translation.
+#.
 #, c-format
 msgid "  Push  URL: %s"
 msgstr "  URL de pujada: %s"
@@ -11414,6 +11446,77 @@
 msgid "only one pattern can be given with -l"
 msgstr "només es pot especificar un patró amb -l"
 
+msgid "need some commits to replay"
+msgstr "calen algunes comissions per tornar a reproduir"
+
+msgid "--onto and --advance are incompatible"
+msgstr "--onto i --advance són incompatibles"
+
+msgid "all positive revisions given must be references"
+msgstr "totes les revisions positives que s'han donat han de ser referències"
+
+msgid "argument to --advance must be a reference"
+msgstr "l'argument per a --advance ha de ser una referència"
+
+msgid ""
+"cannot advance target with multiple sources because ordering would be ill-"
+"defined"
+msgstr ""
+"no es pot avançar l'objectiu amb múltiples fonts perquè l'ordenació no "
+"estaria definida correctament"
+
+msgid ""
+"cannot implicitly determine whether this is an --advance or --onto operation"
+msgstr ""
+"no es pot determinar implícitament si aquesta és una operació --advance o --"
+"onto"
+
+msgid ""
+"cannot advance target with multiple source branches because ordering would "
+"be ill-defined"
+msgstr ""
+"no es pot avançar l'objectiu amb múltiples branques d'origen perquè "
+"l'ordenació no estaria definida correctament"
+
+msgid "cannot implicitly determine correct base for --onto"
+msgstr "no es pot determinar implícitament la base correcta per a --onto"
+
+msgid ""
+"(EXPERIMENTAL!) git replay ([--contained] --onto <newbase> | --advance "
+"<branch>) <revision-range>..."
+msgstr ""
+"(EXPERIMENTAL!) git replay ([--contained] --onto <newbase> | --advance "
+"<branch>) <revision-range>..."
+
+msgid "make replay advance given branch"
+msgstr "fes avançar la repetició de la branca donada"
+
+msgid "replay onto given commit"
+msgstr "torna a reproduir a la comissió donada"
+
+msgid "advance all branches contained in revision-range"
+msgstr "avança totes les branques contingudes a l'interval de revisions"
+
+msgid "option --onto or --advance is mandatory"
+msgstr "l'opció --onto o --advance és obligatòria"
+
+#, c-format
+msgid ""
+"some rev walking options will be overridden as '%s' bit in 'struct rev_info' "
+"will be forced"
+msgstr ""
+"algunes opcions de referència se sobreescriuran de forma forçada com a «%s» "
+"bits a «struct rev_info»"
+
+msgid "error preparing revisions"
+msgstr "s'ha produït un error en preparar les revisions"
+
+msgid "replaying down to root commit is not supported yet!"
+msgstr "encara no s'admet la reproducció cap avall en una comissió arrel"
+
+msgid "replaying merge commits is not supported yet!"
+msgstr "encara no s'admet la repetició de les comissió de fusió"
+
 msgid ""
 "git rerere [clear | forget <pathspec>... | diff | status | remaining | gc]"
 msgstr ""
@@ -11622,15 +11725,6 @@
 msgid "unknown mode for --abbrev-ref: %s"
 msgstr "mode desconegut per a --abbrev-ref: %s"
 
-msgid "--exclude-hidden cannot be used together with --branches"
-msgstr "--exclude-hidden no es pot utilitzar juntament amb --branches"
-
-msgid "--exclude-hidden cannot be used together with --tags"
-msgstr "--exclude-hidden no es pot utilitzar juntament amb --tags"
-
-msgid "--exclude-hidden cannot be used together with --remotes"
-msgstr "--exclude-hidden no es pot utilitzar juntament amb --remotes"
-
 msgid "this operation must be run in a work tree"
 msgstr "aquesta operació s'ha d'executar en un arbre de treball"
 
@@ -12040,10 +12134,6 @@
 msgid "show refs from stdin that aren't in local repository"
 msgstr "mostra les referències de stdin que no siguin en el repositori local"
 
-#, c-format
-msgid "only one of '%s', '%s' or '%s' can be given"
-msgstr "només es poden donar les opcions «%s», «%s», o «%s»"
-
 msgid ""
 "git sparse-checkout (init | list | set | add | reapply | disable | check-"
 "rules) [<options>]"
@@ -13519,28 +13609,28 @@
 
 #, c-format
 msgid ""
-"If you meant to create a worktree containing a new orphan branch\n"
+"If you meant to create a worktree containing a new unborn branch\n"
 "(branch with no commits) for this repository, you can do so\n"
 "using the --orphan flag:\n"
 "\n"
 "    git worktree add --orphan -b %s %s\n"
 msgstr ""
-"Si voleu crear un arbre de treball que contingui una branca orfe nova\n"
-"(branca sense comissions) per a aquest repositori, podeu fer-ho\n"
+"Si voleu crear un arbre de treball que contingui una branca no nascuda\n"
+"nova (branca sense comissions) per a aquest repositori, podeu fer-ho\n"
 "utilitzant l'argument --orphan:\n"
 "\n"
 "    git worktree add --orphan -b %s %s\n"
 
 #, c-format
 msgid ""
-"If you meant to create a worktree containing a new orphan branch\n"
+"If you meant to create a worktree containing a new unborn branch\n"
 "(branch with no commits) for this repository, you can do so\n"
 "using the --orphan flag:\n"
 "\n"
 "    git worktree add --orphan %s\n"
 msgstr ""
-"Si voleu crear un arbre de treball que contingui una branca orfe nova\n"
-"(branca sense comissions) per a aquest repositori, podeu fer-ho\n"
+"Si voleu crear un arbre de treball que contingui una branca no nascuda\n"
+"nova (branca sense comissions) per a aquest repositori, podeu fer-ho\n"
 "utilitzant l'argument --orphan:\n"
 "\n"
 "    git worktree add --orphan %s\n"
@@ -13603,6 +13693,10 @@
 msgstr "s'està inicialitzant"
 
 #, c-format
+msgid "could not find created worktree '%s'"
+msgstr "no s'ha pogut trobar l'arbre de treball creat «%s»"
+
+#, c-format
 msgid "Preparing worktree (new branch '%s')"
 msgstr "S'està preparant l'arbre de treball (branca nova «%s»)"
 
@@ -13641,10 +13735,6 @@
 "No hi ha referències locals o remotes malgrat hi existeix almenys un\n"
 "remot, aturada; useu «add -f» per a anul·lar o obtenir primer un remot"
 
-#, c-format
-msgid "'%s' and '%s' cannot be used together"
-msgstr "les opcions «%s» i «%s» no es poden usar juntes"
-
 msgid "checkout <branch> even if already checked out in other worktree"
 msgstr "agafa <branca> encara que sigui agafada en altre arbre de treball"
 
@@ -13654,8 +13744,8 @@
 msgid "create or reset a branch"
 msgstr "crea o restableix una branca"
 
-msgid "create unborn/orphaned branch"
-msgstr "crea una branca no nascuda/òrfena"
+msgid "create unborn branch"
+msgstr "crea una branca no nascuda"
 
 msgid "populate the new working tree"
 msgstr "emplena l'arbre de treball nou"
@@ -13679,11 +13769,8 @@
 msgstr "les opcions «%s», «%s», i «%s» no es poden usar juntes"
 
 #, c-format
-msgid "options '%s', and '%s' cannot be used together"
-msgstr "les opcions «%s» i «%s» no es poden usar juntes"
-
-msgid "<commit-ish>"
-msgstr "<commit-ish>"
+msgid "option '%s' and commit-ish cannot be used together"
+msgstr "opció «%s» i les de comissió no es poden usar juntes"
 
 msgid "added with --lock"
 msgstr "afegit amb --lock"
@@ -14313,6 +14400,11 @@
 msgid "Create, list, delete refs to replace objects"
 msgstr "Crea, llista i esborra referències per a substituir objectes"
 
+msgid "EXPERIMENTAL: Replay commits on a new base, works with bare repos too"
+msgstr ""
+"EXPERIMENTAL: torna a reproduir comissions sobre una nova base, també "
+"funciona amb repositoris nus"
+
 msgid "Generates a summary of pending changes"
 msgstr "Genera un resum dels canvis pendents"
 
@@ -14554,6 +14646,35 @@
 msgid "commit-graph file is too small"
 msgstr "el fitxer del graf de comissions és massa petit"
 
+msgid "commit-graph oid fanout chunk is wrong size"
+msgstr ""
+"el fragment de «fanout» de l'oid del graf de comissions és de mida incorrecta"
+
+msgid "commit-graph fanout values out of order"
+msgstr "valors de graf de comissions de «fanout» estan fora d'ordre"
+
+msgid "commit-graph OID lookup chunk is the wrong size"
+msgstr "el fragment de cerca OID és de mida incorrecta"
+
+msgid "commit-graph commit data chunk is wrong size"
+msgstr "el fragment de dades del graf de comissions és de mida incorrecta"
+
+msgid "commit-graph generations chunk is wrong size"
+msgstr ""
+"el fragment de les generacions del graf de comissions és de mida incorrecta"
+
+msgid "commit-graph changed-path index chunk is too small"
+msgstr ""
+"el fragment d'índex del canvi del camí del graf de comissions és massa petit"
+
+#, c-format
+msgid ""
+"ignoring too-small changed-path chunk (%<PRIuMAX> < %<PRIuMAX>) in commit-"
+"graph file"
+msgstr ""
+"s'ignorarà un fragment massa petit de camí canviat (%<PRIuMAX> < %<PRIuMAX>) "
+"al fitxer del graf de comissions"
+
 #, c-format
 msgid "commit-graph signature %X does not match signature %X"
 msgstr ""
@@ -14573,6 +14694,20 @@
 msgstr ""
 "el fitxer del graf de comissions és massa petit per a guardar %u fragments"
 
+msgid "commit-graph required OID fanout chunk missing or corrupted"
+msgstr ""
+"manca o està malmès el fragment del «fanout» OID requerit al graf de "
+"comissions"
+
+msgid "commit-graph required OID lookup chunk missing or corrupted"
+msgstr ""
+"manca o està malmès el fragment de cerca d'OID requerit al graf de comissions"
+
+msgid "commit-graph required commit data chunk missing or corrupted"
+msgstr ""
+"manca o està corromput el fragment de dades de publicació requerit al graf "
+"de comissions"
+
 msgid "commit-graph has no base graphs chunk"
 msgstr "el fragment del graf de comissions no té grafs de base"
 
@@ -14586,6 +14721,9 @@
 msgid "commit count in base graph too high: %<PRIuMAX>"
 msgstr "el nombre de comissions en el graf base és massa alt: %<PRIuMAX>"
 
+msgid "commit-graph chain file too small"
+msgstr "el fitxer de cadena del graf de comissions és massa petit"
+
 #, c-format
 msgid "invalid commit-graph chain: line '%s' not a hash"
 msgstr ""
@@ -14613,6 +14751,9 @@
 "les dades de generació de desbordament del graf de comissions són massa "
 "petites"
 
+msgid "commit-graph extra-edges pointer out of bounds"
+msgstr "punter de vores extra del graf de comissió està fora dels límits"
+
 msgid "Loading known commits in commit graph"
 msgstr "S'estan carregant comissions conegudes al graf de comissions"
 
@@ -15786,6 +15927,10 @@
 "Valor desconegut de la variable de configuració de «diff.submodule»: «%s»"
 
 #, c-format
+msgid "unknown value for config '%s': %s"
+msgstr "valor desconegut per al config «%s»': %s"
+
+#, c-format
 msgid ""
 "Found errors in 'diff.dirstat' config variable:\n"
 "%s"
@@ -15862,12 +16007,6 @@
 msgid "invalid mode '%s' in --color-moved-ws"
 msgstr "mode «%s» no vàlid en --color-moved-ws"
 
-msgid ""
-"option diff-algorithm accepts \"myers\", \"minimal\", \"patience\" and "
-"\"histogram\""
-msgstr ""
-"l'opció diff-algorithm accepta «myers», «minimal», «patience» i «histogram»"
-
 #, c-format
 msgid "invalid argument to %s"
 msgstr "argument no vàlid a %s"
@@ -15912,8 +16051,8 @@
 msgid "output only the last line of --stat"
 msgstr "mostra només l'última línia de --stat"
 
-msgid "<param1,param2>..."
-msgstr "<param1,param2>..."
+msgid "<param1>,<param2>..."
+msgstr "<param1>,<param2>..."
 
 msgid ""
 "output the distribution of relative amount of changes for each sub-directory"
@@ -15924,8 +16063,8 @@
 msgid "synonym for --dirstat=cumulative"
 msgstr "sinònim de --dirstat=cumulative"
 
-msgid "synonym for --dirstat=files,param1,param2..."
-msgstr "sinònim de --dirstat=files,param1,param2..."
+msgid "synonym for --dirstat=files,<param1>,<param2>..."
+msgstr "sinònim de --dirstat=files,<param1>,<param2>..."
 
 msgid "warn if changes introduce conflict markers or whitespace errors"
 msgstr ""
@@ -16108,12 +16247,6 @@
 msgid "generate diff using the \"histogram diff\" algorithm"
 msgstr "genera diff usant l'algorisme «histogram diff»"
 
-msgid "<algorithm>"
-msgstr "<algorisme>"
-
-msgid "choose a diff algorithm"
-msgstr "trieu un algorisme per al diff"
-
 msgid "<text>"
 msgstr "<text>"
 
@@ -16499,12 +16632,14 @@
 
 #. TRANSLATORS: The parameter will be 'ready', a protocol
 #. keyword.
+#.
 #, c-format
 msgid "expected packfile to be sent after '%s'"
 msgstr "s'esperava que el fitxer de paquet s'enviés després de «%s»"
 
 #. TRANSLATORS: The parameter will be 'ready', a protocol
 #. keyword.
+#.
 #, c-format
 msgid "expected no other sections to be sent after no '%s'"
 msgstr "no s'esperava que cap altra secció s'enviés després de «%s»"
@@ -17322,6 +17457,7 @@
 #. name, and the second argument is the abbreviated id of the
 #. commit that needs to be merged.  For example:
 #.  - go to submodule (mysubmodule), and either merge commit abc1234"
+#.
 #, c-format
 msgid ""
 " - go to submodule (%s), and either merge commit %s\n"
@@ -17356,6 +17492,7 @@
 
 #. TRANSLATORS: The %s arguments are: 1) tree hash of a merge
 #. base, and 2-3) the trees for the two trees we're merging.
+#.
 #, c-format
 msgid "collecting merge info failed for trees %s, %s, %s"
 msgstr ""
@@ -17616,6 +17753,12 @@
 msgid "multi-pack-index OID fanout is of the wrong size"
 msgstr "l'OID «fanout» de l'índex multipaquet és d'una mida incorrecta"
 
+#, c-format
+msgid ""
+"oid fanout out of order: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]"
+msgstr ""
+"oid «fanout» desordenat: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]"
+
 msgid "multi-pack-index OID lookup chunk is the wrong size"
 msgstr "El fragment de cerca OID índex multipaquet és de mida incorrecta"
 
@@ -17676,6 +17819,13 @@
 msgid "bad pack-int-id: %u (%u total packs)"
 msgstr "pack-int-id: %u incorrecte (%u paquets en total)"
 
+msgid "MIDX does not contain the BTMP chunk"
+msgstr "MIDX no conté el fragment BTMP"
+
+#, c-format
+msgid "could not load bitmapped pack %<PRIu32>"
+msgstr "no s'ha pogut carregar el paquet amb bits %<PRIu32>"
+
 msgid "multi-pack-index stores a 64-bit offset, but off_t is too small"
 msgstr ""
 "l'índex multipaquet emmagatzema un desplaçament de 64 bits, però off_t és "
@@ -17764,11 +17914,6 @@
 msgid "Looking for referenced packfiles"
 msgstr "S'estan cercant fitxers empaquetats referenciats"
 
-#, c-format
-msgid ""
-"oid fanout out of order: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]"
-msgstr "oid fanout desordenat: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]"
-
 msgid "the midx contains no oid"
 msgstr "el midx no conté cap oid"
 
@@ -17851,6 +17996,7 @@
 #. TRANSLATORS: The first %s is the name of
 #. the environment variable, the second %s is
 #. its value.
+#.
 #, c-format
 msgid "Bad %s value: '%s'"
 msgstr "Valor erroni de %s: «%s»"
@@ -18069,6 +18215,7 @@
 #. TRANSLATORS: This is a line of ambiguous object
 #. output shown when we cannot look up or parse the
 #. object in question. E.g. "deadbeef [bad object]".
+#.
 #, c-format
 msgid "%s [bad object]"
 msgstr "%s [objecte incorrecte]"
@@ -18077,6 +18224,7 @@
 #. object output. E.g.:
 #. *
 #.    "deadbeef commit 2021-01-01 - Some Commit Message"
+#.
 #, c-format
 msgid "%s commit %s - %s"
 msgstr "%s comissió %s - %s"
@@ -18091,6 +18239,7 @@
 #. *
 #. The third argument is the "tag" string
 #. from object.c.
+#.
 #, c-format
 msgid "%s tag %s - %s"
 msgstr "%s etiqueta %s - %s"
@@ -18100,18 +18249,21 @@
 #. the tag itself. E.g.:
 #. *
 #.    "deadbeef [bad tag, could not parse it]"
+#.
 #, c-format
 msgid "%s [bad tag, could not parse it]"
 msgstr "%s [etiqueta malmesa, no s'ha pogut analitzar]"
 
 #. TRANSLATORS: This is a line of ambiguous <type>
 #. object output. E.g. "deadbeef tree".
+#.
 #, c-format
 msgid "%s tree"
 msgstr "arbre %s"
 
 #. TRANSLATORS: This is a line of ambiguous <type>
 #. object output. E.g. "deadbeef blob".
+#.
 #, c-format
 msgid "%s blob"
 msgstr "blob %s"
@@ -18123,6 +18275,7 @@
 #. TRANSLATORS: The argument is the list of ambiguous
 #. objects composed in show_ambiguous_object(). See
 #. its "TRANSLATORS" comments for details.
+#.
 #, c-format
 msgid ""
 "The candidates are:\n"
@@ -18292,6 +18445,9 @@
 msgid "could not open pack %s"
 msgstr "no s'ha pogut obrir el paquet %s"
 
+msgid "could not determine MIDX preferred pack"
+msgstr "no s'ha pogut determinar el paquet preferit MIDX"
+
 #, c-format
 msgid "preferred pack (%s) is invalid"
 msgstr "el paquet preferit (%s) no és vàlid"
@@ -18318,6 +18474,12 @@
 "comissió «%s»"
 
 #, c-format
+msgid "unable to load pack: '%s', disabling pack-reuse"
+msgstr ""
+"no s'ha pogut carregar el paquet: «%s», s'està inhabilitant lareutilització "
+"de paquets"
+
+#, c-format
 msgid "object '%s' not found in type bitmaps"
 msgstr "no s'ha trobat l'objecte «%s» als tipus de mapes de bits"
 
@@ -18410,6 +18572,9 @@
 msgstr ""
 "el fragment de l'index invers de l'índex multipaquet és de mida incorrecta"
 
+msgid "could not determine preferred pack"
+msgstr "no s'ha pogut determinar el paquet preferit"
+
 msgid "cannot both write and verify reverse index"
 msgstr "no es pot escriure i verificar l'índex invers"
 
@@ -18475,10 +18640,6 @@
 msgstr "%s espera un valor enter no negatiu amb un sufix opcional k/m/g"
 
 #, c-format
-msgid "%s is incompatible with %s"
-msgstr "%s és incompatible amb %s"
-
-#, c-format
 msgid "ambiguous option: %s (could be --%s%s or --%s%s)"
 msgstr "opció ambigua: %s (pot ser --%s%s o --%s%s)"
 
@@ -18514,6 +18675,7 @@
 
 #. TRANSLATORS: the colon here should align with the
 #. one in "usage: %s" translation.
+#.
 #, c-format
 msgid "   or: %s"
 msgstr "   o: %s"
@@ -18536,6 +18698,7 @@
 #. function. The "%s" is a line in the (hopefully already
 #. translated) N_() usage string, which contained embedded
 #. newlines before we split it up.
+#.
 #, c-format
 msgid "%*s%s"
 msgstr "%*s%s"
@@ -18799,10 +18962,6 @@
 msgstr "no s'ha pogut afegir «%s» a l'índex"
 
 #, c-format
-msgid "unable to stat '%s'"
-msgstr "no s'ha pogut fer «stat» a «%s»"
-
-#, c-format
 msgid "'%s' appears as both a file and as a directory"
 msgstr "«%s» apareix com a fitxer i com a directori"
 
@@ -19384,10 +19543,6 @@
 msgstr "no es poden processar «%s» i «%s» a la vegada"
 
 #, c-format
-msgid "could not remove reference %s"
-msgstr "no s'ha pogut eliminar la referència %s"
-
-#, c-format
 msgid "could not delete reference %s: %s"
 msgstr "no s'ha pogut suprimir la referència %s: %s"
 
@@ -19570,6 +19725,7 @@
 #. TRANSLATORS: "matches '%s'%" is the <dst> part of "git push
 #. <remote> <src>:<dst>" push, and "being pushed ('%s')" is
 #. the <src>.
+#.
 #, c-format
 msgid ""
 "The destination you provided is not a full refname (i.e.,\n"
@@ -19610,7 +19766,7 @@
 "'%s:refs/tags/%s'?"
 msgstr ""
 "La part <src> de l'especificació de la referència és un objecte d'etiqueta.\n"
-"Voleu crear una etiqueta pujant-la a «%srefs/tags/%s»?"
+"Voleu crear una etiqueta pujant-la a «%s:refs/tags/%s»?"
 
 #, c-format
 msgid ""
@@ -19619,7 +19775,7 @@
 "'%s:refs/tags/%s'?"
 msgstr ""
 "La part <src> de l'especificació de la referència és un objecte d'arbre.\n"
-"Voleu crear una etiqueta pujant-la a «%srefs/tags/%s»?"
+"Voleu crear una etiqueta pujant-la a «%s:refs/tags/%s»?"
 
 #, c-format
 msgid ""
@@ -20203,6 +20359,7 @@
 
 #. TRANSLATORS: %s will be "revert", "cherry-pick" or
 #. "rebase".
+#.
 #, c-format
 msgid "%s: Unable to write new index file"
 msgstr "%s: No s'ha pogut escriure un fitxer d'índex nou"
@@ -20762,6 +20919,9 @@
 msgstr ""
 "El «stash» automàtic ja existeix; s'està creant una entrada «stash» nova."
 
+msgid "autostash reference is a symref"
+msgstr "la referència d'autostash és un symref"
+
 msgid "could not detach HEAD"
 msgstr "no s'ha pogut separar HEAD"
 
@@ -21005,7 +21165,8 @@
 "not a git repository (or any parent up to mount point %s)\n"
 "Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set)."
 msgstr ""
-"no és un repositori de git (ni cap pare fins al punt de muntatge %s)\n"
+"no és un repositori de git (ni existeix cap pare fins al punt de muntatge "
+"%s)\n"
 "S'atura a la frontera de sistema de fitxers (GIT_DISCOVERY_ACROSS_FILESYSTEM "
 "no està establert)."
 
@@ -21078,6 +21239,10 @@
 msgstr "nom de branca inicial no vàlid: «%s»"
 
 #, c-format
+msgid "re-init: ignored --initial-branch=%s"
+msgstr "reinicialització: s'ha ignorat --initial-branch=%s"
+
+#, c-format
 msgid "unable to handle file type %d"
 msgstr "no s'ha pogut gestionar el tipus de fitxer %d"
 
@@ -21088,15 +21253,17 @@
 msgid "attempt to reinitialize repository with different hash"
 msgstr "s'ha intentat reinicialitzar el repositori amb un resum diferent"
 
+msgid ""
+"attempt to reinitialize repository with different reference storage format"
+msgstr ""
+"s'ha intentat reactivar el repositori amb un format d'emmagatzematge de "
+"referència diferent"
+
 #, c-format
 msgid "%s already exists"
 msgstr "%s ja existeix"
 
 #, c-format
-msgid "re-init: ignored --initial-branch=%s"
-msgstr "reinicialització: s'ha ignorat --initial-branch=%s"
-
-#, c-format
 msgid "Reinitialized existing shared Git repository in %s%s\n"
 msgstr "S'ha reinicialitzat el repositori compartit existent del Git en %s%s\n"
 
@@ -21365,12 +21532,6 @@
 msgstr ""
 "nombre d'entrades a l'arbre de la memòria cau a invalidar (per defecte 0)"
 
-msgid "unhandled options"
-msgstr "opcions no gestionades"
-
-msgid "error preparing revisions"
-msgstr "s'ha produït un error en preparar les revisions"
-
 #, c-format
 msgid "commit %s is not marked reachable"
 msgstr "la comissió %s no està marcada com abastable"
@@ -21523,9 +21684,6 @@
 msgid "invalid remote service path"
 msgstr "el camí del servei remot no és vàlid"
 
-msgid "operation not supported by protocol"
-msgstr "opció no admesa pel protocol"
-
 #, c-format
 msgid "can't connect to subservice %s"
 msgstr "no es pot connectar al subservei %s"
@@ -21658,10 +21816,6 @@
 "encara no s'ha implementat la compatibilitat amb la versió v2 del protocol"
 
 #, c-format
-msgid "unknown value for config '%s': %s"
-msgstr "valor desconegut per al config «%s»': %s"
-
-#, c-format
 msgid "transport '%s' not allowed"
 msgstr "no es permet el transport «%s»"
 
@@ -21714,6 +21868,9 @@
 msgstr ""
 "no s'ha pogut recuperar la llista de paquets d'URI anunciats pel servidor"
 
+msgid "operation not supported by protocol"
+msgstr "opció no admesa pel protocol"
+
 msgid "too-short tree object"
 msgstr "objecte d'arbre massa curt"
 
@@ -22555,6 +22712,10 @@
 msgid "cannot %s: Your index contains uncommitted changes."
 msgstr "no es pot %s: El vostre índex conté canvis sense cometre."
 
+#, c-format
+msgid "unknown style '%s' given for '%s'"
+msgstr "estil desconegut «%s» donat per a «%s»"
+
 msgid ""
 "Error: Your local changes to the following files would be overwritten by "
 "merge"
@@ -22950,64 +23111,3 @@
 #, perl-format
 msgid "Do you really want to send %s? [y|N]: "
 msgstr "Esteu segur que voleu enviar %s? [y|N]: "
-
-#, c-format
-#~ msgid "options '%s=%s' and '%s=%s' cannot be used together"
-#~ msgstr "les opcions «%s=%s» i «%s=%s» no es poden usar juntes"
-
-#, c-format
-#~ msgid "%s : incompatible with something else"
-#~ msgstr "%s: és incompatible amb alguna altra cosa"
-
-#~ msgid "Could not write patch"
-#~ msgstr "No s'ha pogut escriure el pedaç"
-
-#, c-format
-#~ msgid "Could not stat '%s'"
-#~ msgstr "No s'ha pogut fer stat a «%s»"
-
-#, c-format
-#~ msgid "Cannot delete branch '%s' checked out at '%s'"
-#~ msgstr "No es pot suprimir la branca «%s» agafada a «%s»"
-
-#~ msgid "unable to write new_index file"
-#~ msgstr "no s'ha pogut escriure el fitxer new_index"
-
-#~ msgid "do not apply config rules"
-#~ msgstr "no apliquis les regles de configuració"
-
-#~ msgid "join whitespace-continued values"
-#~ msgstr "uneix els valors continus amb espais en blanc"
-
-#~ msgid "set parsing options"
-#~ msgstr "estableix les opcions d'anàlisi"
-
-#~ msgid "cannot move directory over file"
-#~ msgstr "no es pot moure un directori sobre un fitxer"
-
-#~ msgid "cannot use --filter without --stdout"
-#~ msgstr "no es pot utilitzar --filter sense --stdout"
-
-#~ msgid "cannot use --max-pack-size with --cruft"
-#~ msgstr "no es pot usar --max-pack-size amb --cruft"
-
-#~ msgid "--strategy requires --merge or --interactive"
-#~ msgstr "--strategy requereix --merge o --interactive"
-
-#, c-format
-#~ msgid ""
-#~ "commit-graph has generation number zero for commit %s, but non-zero "
-#~ "elsewhere"
-#~ msgstr ""
-#~ "el graf de comissions té nombre de generació zero per a la comissió %s, "
-#~ "però té no zero en altres llocs"
-
-#~ msgid "--merge-base only works with commits"
-#~ msgstr "--merge-base només funciona amb comissions"
-
-#~ msgid "scalar clone [<options>] [--] <repo> [<dir>]"
-#~ msgstr "scalar clone [<opcions>] [--] <repositori> [<dir>]"
-
-#, c-format
-#~ msgid "could not rename '%s' to '%s'"
-#~ msgstr "no s'ha pogut canviar el nom «%s» a «%s»"
diff --git a/po/de.po b/po/de.po
index 95a185a..2946566 100644
--- a/po/de.po
+++ b/po/de.po
@@ -8,8 +8,8 @@
 msgstr ""
 "Project-Id-Version: Git\n"
 "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2023-11-09 11:29+0100\n"
-"PO-Revision-Date: 2023-11-10 14:28+0100\n"
+"POT-Creation-Date: 2024-04-26 16:16+0200\n"
+"PO-Revision-Date: 2024-04-26 16:22+0200\n"
 "Last-Translator: Ralf Thielow <ralf.thielow@gmail.com>\n"
 "Language-Team: German\n"
 "Language: de\n"
@@ -512,12 +512,12 @@
 "---\n"
 "To remove '%c' lines, make them ' ' lines (context).\n"
 "To remove '%c' lines, delete them.\n"
-"Lines starting with %c will be removed.\n"
+"Lines starting with %s will be removed.\n"
 msgstr ""
 "---\n"
 "Um '%c' Zeilen zu entfernen, machen Sie aus diesen ' ' Zeilen (Kontext).\n"
 "Um '%c' Zeilen zu entfernen, löschen Sie diese.\n"
-"Zeilen, die mit %c beginnen, werden entfernt.\n"
+"Zeilen, die mit %s beginnen, werden entfernt.\n"
 
 msgid ""
 "If it does not apply cleanly, you will be given an opportunity to\n"
@@ -566,6 +566,7 @@
 "/ - search for a hunk matching the given regex\n"
 "s - split the current hunk into smaller hunks\n"
 "e - manually edit the current hunk\n"
+"p - print the current hunk\n"
 "? - print help\n"
 msgstr ""
 "j - diesen Patch-Block unbestimmt lassen, nächsten unbestimmten Patch-Block "
@@ -575,9 +576,10 @@
 "Block anzeigen\n"
 "K - diesen Patch-Block unbestimmt lassen, vorherigen Patch-Block anzeigen\n"
 "g - Patch-Block zum Hinspringen auswählen\n"
-"/ - nach Patch-Block suchen, der gegebenem regulärem Ausdruck entspricht\n"
+"/ - nach Patch-Block suchen, der regulärem Ausdruck entspricht\n"
 "s - aktuellen Patch-Block in kleinere Patch-Blöcke aufteilen\n"
 "e - aktuellen Patch-Block manuell editieren\n"
+"p - aktuellen Patch-Block anzeigen\n"
 "? - Hilfe anzeigen\n"
 
 msgid "No previous hunk"
@@ -640,8 +642,8 @@
 "Deaktivieren Sie diese Nachricht mit \"git config advice.%s false\""
 
 #, c-format
-msgid "%shint: %.*s%s\n"
-msgstr "%sHinweis: %.*s%s\n"
+msgid "%shint:%s%.*s%s\n"
+msgstr "%sHinweis:%s%.*s%s\n"
 
 msgid "Cherry-picking is not possible because you have unmerged files."
 msgstr ""
@@ -1160,10 +1162,6 @@
 msgstr[1] "Wende Patch %%s mit %d Zurückweisungen an..."
 
 #, c-format
-msgid "truncating .rej filename to %.*s.rej"
-msgstr "Verkürze Name von .rej Datei zu %.*s.rej"
-
-#, c-format
 msgid "cannot open %s"
 msgstr "kann '%s' nicht öffnen"
 
@@ -1474,6 +1472,10 @@
 msgstr "Unerwartete Option --output"
 
 #, c-format
+msgid "extra command line parameter '%s'"
+msgstr "zusätzlicher Befehlszeilenparameter '%s'"
+
+#, c-format
 msgid "Unknown archive format '%s'"
 msgstr "Unbekanntes Archivformat '%s'"
 
@@ -1519,6 +1521,14 @@
 msgstr "ungültiges --attr-source oder GIT_ATTR_SOURCE"
 
 #, c-format
+msgid "unable to stat '%s'"
+msgstr "konnte '%s' nicht lesen"
+
+#, c-format
+msgid "unable to read %s"
+msgstr "kann %s nicht lesen"
+
+#, c-format
 msgid "Badly quoted content in file '%s': %s"
 msgstr "Ungültiger Inhalt bzgl. Anführungszeichen in Datei '%s': %s"
 
@@ -1588,6 +1598,10 @@
 msgstr "konnte Datei '%s' nicht erstellen"
 
 #, c-format
+msgid "unable to start 'show' for object '%s'"
+msgstr "konnte 'show' für Objekt '%s' nicht starten"
+
+#, c-format
 msgid "could not read file '%s'"
 msgstr "Konnte Datei '%s' nicht lesen"
 
@@ -1698,12 +1712,10 @@
 msgid "not tracking: ambiguous information for ref '%s'"
 msgstr "kein Tracking: mehrdeutige Informationen für Referenz '%s'"
 
-#. #-#-#-#-#  branch.c.po  #-#-#-#-#
 #. TRANSLATORS: This is a line listing a remote with duplicate
 #. refspecs in the advice message below. For RTL languages you'll
 #. probably want to swap the "%s" and leading "  " space around.
 #.
-#. #-#-#-#-#  object-name.c.po  #-#-#-#-#
 #. TRANSLATORS: This is line item of ambiguous object output
 #. from describe_ambiguous_object() above. For RTL languages
 #. you'll probably want to swap the "%s" and leading " " space
@@ -1741,6 +1753,9 @@
 msgid "'%s' is not a valid branch name"
 msgstr "'%s' ist kein gültiger Branchname"
 
+msgid "See `man git check-ref-format`"
+msgstr "Siehe `man git check-ref-format`"
+
 #, c-format
 msgid "a branch named '%s' already exists"
 msgstr "Branch '%s' existiert bereits"
@@ -1947,14 +1962,8 @@
 msgid "adding embedded git repository: %s"
 msgstr "Füge eingebettetes Repository hinzu: %s"
 
-msgid ""
-"Use -f if you really want to add them.\n"
-"Turn this message off by running\n"
-"\"git config advice.addIgnoredFile false\""
-msgstr ""
-"Nutzen Sie die Option -f, wenn sie wirklich hinzugefügt werden sollen.\n"
-"Um diese Meldung abzuschalten, führen Sie folgenden Befehl aus:\n"
-"\"git config advice.addIgnoredFile false\""
+msgid "Use -f if you really want to add them."
+msgstr "Verwenden Sie -f, wenn Sie diese wirklich hinzufügen möchten."
 
 msgid "adding files failed"
 msgstr "Hinzufügen von Dateien fehlgeschlagen"
@@ -1972,14 +1981,8 @@
 msgid "Nothing specified, nothing added.\n"
 msgstr "Nichts spezifiziert, nichts hinzugefügt.\n"
 
-msgid ""
-"Maybe you wanted to say 'git add .'?\n"
-"Turn this message off by running\n"
-"\"git config advice.addEmptyPathspec false\""
-msgstr ""
-"Eventuell meinten Sie 'git add .'?\n"
-"Um diese Meldung abzuschalten, führen Sie folgenden Befehl aus:\n"
-"\"git config advice.addEmptyPathspec false\""
+msgid "Maybe you wanted to say 'git add .'?"
+msgstr "Meinten Sie vielleicht 'git add .'?"
 
 msgid "index file corrupt"
 msgstr "Index-Datei beschädigt"
@@ -2056,21 +2059,22 @@
 msgstr "Fehler beim Aufteilen der Patches."
 
 #, c-format
-msgid "When you have resolved this problem, run \"%s --continue\"."
+msgid "When you have resolved this problem, run \"%s --continue\".\n"
 msgstr ""
-"Wenn Sie das Problem aufgelöst haben, führen Sie \"%s --continue\" aus."
+"Wenn Sie dieses Problem behoben haben, führen Sie \"%s --continue\" aus.\n"
 
 #, c-format
-msgid "If you prefer to skip this patch, run \"%s --skip\" instead."
+msgid "If you prefer to skip this patch, run \"%s --skip\" instead.\n"
 msgstr ""
 "Falls Sie diesen Patch auslassen möchten, führen Sie stattdessen \"%s --"
-"skip\" aus."
+"skip\" aus.\n"
 
 #, c-format
-msgid "To record the empty patch as an empty commit, run \"%s --allow-empty\"."
+msgid ""
+"To record the empty patch as an empty commit, run \"%s --allow-empty\".\n"
 msgstr ""
-"Um den leeren Patch als einen leeren Commit zu speichern, führen Sie \"%s --"
-"allow-empty\" aus."
+"Um den leeren Patch als leeren Commit aufzuzeichnen, führen Sie \"%s --allow-"
+"empty\" aus.\n"
 
 #, c-format
 msgid "To restore the original branch and stop patching, run \"%s --abort\"."
@@ -2830,13 +2834,14 @@
 msgstr "konnte Commit-Objekt für '%s' nicht nachschlagen"
 
 #, c-format
-msgid ""
-"the branch '%s' is not fully merged.\n"
-"If you are sure you want to delete it, run 'git branch -D %s'"
+msgid "the branch '%s' is not fully merged"
+msgstr "der Branch '%s' ist nicht vollständig zusammengeführt"
+
+#, c-format
+msgid "If you are sure you want to delete it, run 'git branch -D %s'"
 msgstr ""
-"Der Branch '%s' ist nicht vollständig zusammengeführt.\n"
-"Wenn Sie sicher sind diesen Branch zu entfernen, führen Sie 'git branch -D "
-"%s' aus."
+"Wenn Sie sicher sind, dass Sie den Branch löschen wollen, führen Sie 'git "
+"branch -D %s' aus."
 
 msgid "update of config-file failed"
 msgstr "Aktualisierung der Konfigurationsdatei fehlgeschlagen."
@@ -2939,11 +2944,11 @@
 msgid ""
 "Please edit the description for the branch\n"
 "  %s\n"
-"Lines starting with '%c' will be stripped.\n"
+"Lines starting with '%s' will be stripped.\n"
 msgstr ""
 "Bitte ändern Sie die Beschreibung für den Branch\n"
 "  %s\n"
-"Zeilen, die mit '%c' beginnen, werden entfernt.\n"
+"Zeilen, die mit '%s' beginnen, werden entfernt.\n"
 
 msgid "Generic options"
 msgstr "Allgemeine Optionen"
@@ -3152,10 +3157,12 @@
 msgstr "nicht in einem Git-Repository ausgeführt - keine Hooks zum Anzeigen\n"
 
 msgid ""
-"git bugreport [(-o | --output-directory) <path>] [(-s | --suffix) <format>]\n"
+"git bugreport [(-o | --output-directory) <path>]\n"
+"              [(-s | --suffix) <format> | --no-suffix]\n"
 "              [--diagnose[=<mode>]]"
 msgstr ""
-"git bugreport [(-o | --output-directory) <Pfad>] [(-s | --suffix) <Format>]\n"
+"git bugreport [(-o | --output-directory) <Pfad>]\n"
+"              [(-s | --suffix) <Format> | --no-suffix]\n"
 "              [--diagnose[=<Modus>]]"
 
 msgid ""
@@ -3649,6 +3656,10 @@
 msgid "path '%s' is unmerged"
 msgstr "Pfad '%s' ist nicht zusammengeführt"
 
+#, c-format
+msgid "unable to read tree (%s)"
+msgstr "konnte \"Tree\"-Objekt (%s) nicht lesen"
+
 msgid "you need to resolve your current index first"
 msgstr "Sie müssen zuerst die Konflikte in Ihrem aktuellen Index auflösen."
 
@@ -3887,6 +3898,10 @@
 msgid "missing branch or commit argument"
 msgstr "Branch- oder Commit-Argument fehlt"
 
+#, c-format
+msgid "unknown conflict style '%s'"
+msgstr "unbekannter Konfliktstil '%s'"
+
 msgid "perform a 3-way merge with the new branch"
 msgstr "einen 3-Wege-Merge mit dem neuen Branch ausführen"
 
@@ -3905,8 +3920,8 @@
 msgid "new-branch"
 msgstr "neuer Branch"
 
-msgid "new unparented branch"
-msgstr "neuer Branch ohne Eltern-Commit"
+msgid "new unborn branch"
+msgstr "neuer ungeborener Branch"
 
 msgid "update ignored files (default)"
 msgstr "ignorierte Dateien aktualisieren (Standard)"
@@ -4146,22 +4161,10 @@
 msgid "remove only ignored files"
 msgstr "nur ignorierte Dateien löschen"
 
-msgid ""
-"clean.requireForce set to true and neither -i, -n, nor -f given; refusing to "
-"clean"
+msgid "clean.requireForce is true and -f not given: refusing to clean"
 msgstr ""
-"clean.requireForce auf \"true\" gesetzt und weder -i, -n noch -f gegeben; "
-"\"clean\" verweigert"
-
-msgid ""
-"clean.requireForce defaults to true and neither -i, -n, nor -f given; "
-"refusing to clean"
-msgstr ""
-"clean.requireForce standardmäßig auf \"true\" gesetzt und weder -i, -n noch -"
-"f gegeben; \"clean\" verweigert"
-
-msgid "-x and -X cannot be used together"
-msgstr "-x und -X können nicht gemeinsam verwendet werden"
+"clean.requireForce ist 'true' und -f ist nicht angegeben: clean wird "
+"verweigert"
 
 msgid "git clone [<options>] [--] <repo> [<dir>]"
 msgstr "git clone [<Optionen>] [--] <Repository> [<Verzeichnis>]"
@@ -4175,8 +4178,8 @@
 msgid "create a bare repository"
 msgstr "ein Bare-Repository erstellen"
 
-msgid "create a mirror repository (implies bare)"
-msgstr "ein Spiegelarchiv erstellen (impliziert bare)"
+msgid "create a mirror repository (implies --bare)"
+msgstr "ein Spiegel-Repository erstellen (impliziert --bare)"
 
 msgid "to clone from a local repository"
 msgstr "von einem lokalen Repository klonen"
@@ -4256,6 +4259,9 @@
 msgid "separate git dir from working tree"
 msgstr "Git-Verzeichnis vom Arbeitsverzeichnis separieren"
 
+msgid "specify the reference format to use"
+msgstr "das zu verwendende Referenzformat angeben"
+
 msgid "key=value"
 msgstr "Schlüssel=Wert"
 
@@ -4379,12 +4385,9 @@
 msgid "You must specify a repository to clone."
 msgstr "Sie müssen ein Repository zum Klonen angeben."
 
-msgid ""
-"--bundle-uri is incompatible with --depth, --shallow-since, and --shallow-"
-"exclude"
-msgstr ""
-"--bundle-uri ist inkompatibel mit --depth, --shallow-since und --shallow-"
-"exclude"
+#, c-format
+msgid "unknown ref storage format '%s'"
+msgstr "unbekanntes Speicherformat für Referenzen '%s'"
 
 #, c-format
 msgid "repository '%s' does not exist"
@@ -4511,6 +4514,10 @@
 msgid "padding space between columns"
 msgstr "Abstand zwischen Spalten auffüllen"
 
+#, c-format
+msgid "%s must be non-negative"
+msgstr "%s muss nicht-negativ sein"
+
 msgid "--command must be the first argument"
 msgstr "--command muss an erster Stelle stehen"
 
@@ -4526,7 +4533,7 @@
 "--stdin-commits]\n"
 "                       [--changed-paths] [--[no-]max-new-filters <n>] [--"
 "[no-]progress]\n"
-"                       <split options>"
+"                       <split-options>"
 msgstr ""
 "git commit-graph write [--object-dir <Verzeichnis>] [--append]\n"
 "                       [--split[=<Strategie>]] [--reachable | --stdin-packs "
@@ -4829,38 +4836,38 @@
 #, c-format
 msgid ""
 "Please enter the commit message for your changes. Lines starting\n"
-"with '%c' will be ignored.\n"
+"with '%s' will be ignored.\n"
 msgstr ""
 "Bitte geben Sie eine Commit-Beschreibung für Ihre Änderungen ein. Zeilen,\n"
-"die mit '%c' beginnen, werden ignoriert.\n"
+"die mit '%s' beginnen, werden ignoriert.\n"
 
 #, 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"
+"with '%s' will be ignored, and an empty message aborts the commit.\n"
 msgstr ""
 "Bitte geben Sie eine Commit-Beschreibung für Ihre Änderungen ein. Zeilen,\n"
-"die mit '%c' beginnen, werden ignoriert, und eine leere Beschreibung\n"
+"die mit '%s' beginnen, werden ignoriert, und eine leere Beschreibung\n"
 "bricht den Commit ab.\n"
 
 #, 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"
+"with '%s' will be kept; you may remove them yourself if you want to.\n"
 msgstr ""
 "Bitte geben Sie eine Commit-Beschreibung für Ihre Änderungen ein. Zeilen,\n"
-"die mit '%c' beginnen, werden beibehalten; wenn Sie möchten, können Sie\n"
+"die mit '%s' beginnen, werden beibehalten; wenn Sie möchten, können Sie\n"
 "diese entfernen.\n"
 
 #, 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"
+"with '%s' will be kept; you may remove them yourself if you want to.\n"
 "An empty message aborts the commit.\n"
 msgstr ""
 "Bitte geben Sie eine Commit-Beschreibung für Ihre Änderungen ein. Zeilen, "
 "die\n"
-"mit '%c' beginnen, werden beibehalten; wenn Sie möchten, können Sie diese "
+"mit '%s' beginnen, werden beibehalten; wenn Sie möchten, können Sie diese "
 "entfernen.\n"
 "Eine leere Beschreibung bricht den Commit ab.\n"
 
@@ -5311,6 +5318,10 @@
 msgid "with --get, use default value when missing entry"
 msgstr "mit --get, benutze den Standardwert, wenn der Eintrag fehlt"
 
+msgid "human-readable comment string (# will be prepended as needed)"
+msgstr ""
+"menschenlesbare Kommentarzeichenfolge (# wird bei Bedarf vorangestellt)"
+
 #, c-format
 msgid "wrong number of arguments, should be %d"
 msgstr "Falsche Anzahl von Argumenten - sollte %d sein."
@@ -5405,6 +5416,10 @@
 msgid "--default is only applicable to --get"
 msgstr "--default ist nur anwendbar auf --get"
 
+msgid "--comment is only applicable to add/set/replace operations"
+msgstr ""
+"--comment darf nur für die Operationen add/set/replace verwendet werden"
+
 msgid "--fixed-value only applies with 'value-pattern'"
 msgstr "--fixed-value wird nur zusammen mit 'Wert-Muster' angewendet"
 
@@ -6276,6 +6291,9 @@
 msgid "read reference patterns from stdin"
 msgstr "Referenzmuster von Standard-Eingabe lesen"
 
+msgid "also include HEAD ref and pseudorefs"
+msgstr "auch die Referenz HEAD und Pseudoreferenzen einschließen"
+
 msgid "unknown arguments supplied with --stdin"
 msgstr "unbekannte Argumente mit --stdin geliefert"
 
@@ -6892,7 +6910,6 @@
 msgid "invalid number of threads specified (%d) for %s"
 msgstr "ungültige Anzahl von Threads (%d) für %s angegeben"
 
-#. #-#-#-#-#  grep.c.po  #-#-#-#-#
 #. TRANSLATORS: %s is the configuration
 #. variable for tweaking threads, currently
 #. grep.threads
@@ -6902,7 +6919,7 @@
 msgstr "keine Unterstützung von Threads, '%s' wird ignoriert"
 
 #, c-format
-msgid "unable to read tree (%s)"
+msgid "unable to read tree %s"
 msgstr "konnte \"Tree\"-Objekt (%s) nicht lesen"
 
 #, c-format
@@ -7327,10 +7344,6 @@
 msgstr "SHA1 KOLLISION MIT %s GEFUNDEN !"
 
 #, c-format
-msgid "unable to read %s"
-msgstr "kann %s nicht lesen"
-
-#, c-format
 msgid "cannot read existing object info %s"
 msgstr "Kann existierende Informationen zu Objekt %s nicht lesen."
 
@@ -7470,11 +7483,13 @@
 msgid ""
 "git init [-q | --quiet] [--bare] [--template=<template-directory>]\n"
 "         [--separate-git-dir <git-dir>] [--object-format=<format>]\n"
+"         [--ref-format=<format>]\n"
 "         [-b <branch-name> | --initial-branch=<branch-name>]\n"
 "         [--shared[=<permissions>]] [<directory>]"
 msgstr ""
 "git init [-q | --quiet] [--bare] [--template=<Vorlagenverzeichnis>]\n"
 "         [--separate-git-dir <Git-Verzeichnis>] [--object-format=<Format>]\n"
+"         [--ref-format=<Format>]\n"
 "         [-b <Branchname> | --initial-branch=<Branchname>]\n"
 "         [--shared[=<Berechtigungen>]] [<Verzeichnis>]"
 
@@ -7518,7 +7533,7 @@
 
 msgid ""
 "git interpret-trailers [--in-place] [--trim-empty]\n"
-"                       [(--trailer (<key>|<keyAlias>)[(=|:)<value>])...]\n"
+"                       [(--trailer (<key>|<key-alias>)[(=|:)<value>])...]\n"
 "                       [--parse] [<file>...]"
 msgstr ""
 "git interpret-trailers [--in-place] [--trim-empty]\n"
@@ -7526,6 +7541,32 @@
 "[(=|:)<Wert>])...]\n"
 "                       [--parse] [<Datei>...]"
 
+#, c-format
+msgid "could not stat %s"
+msgstr "Konnte '%s' nicht lesen"
+
+#, c-format
+msgid "file %s is not a regular file"
+msgstr "Datei '%s' ist keine reguläre Datei"
+
+#, c-format
+msgid "file %s is not writable by user"
+msgstr "Datei %s ist vom Benutzer nicht beschreibbar."
+
+msgid "could not open temporary file"
+msgstr "konnte temporäre Datei '%s' nicht öffnen"
+
+#, c-format
+msgid "could not read input file '%s'"
+msgstr "Konnte Eingabe-Datei '%s' nicht lesen"
+
+msgid "could not read from stdin"
+msgstr "konnte nicht von der Standard-Eingabe lesen"
+
+#, c-format
+msgid "could not rename temporary file to %s"
+msgstr "konnte temporäre Datei nicht zu %s umbenennen"
+
 msgid "edit files in place"
 msgstr "vorhandene Dateien direkt bearbeiten"
 
@@ -7920,18 +7961,6 @@
 msgid "could not get object info about '%s'"
 msgstr "konnte Objekt-Informationen über '%s' nicht bestimmen"
 
-#, c-format
-msgid "bad ls-files format: element '%s' does not start with '('"
-msgstr "ungültiges ls-files-Format: Element '%s' fängt nicht mit '(' an"
-
-#, c-format
-msgid "bad ls-files format: element '%s' does not end in ')'"
-msgstr "ungültiges ls-files-Format: Element '%s' endet nicht auf ')'"
-
-#, c-format
-msgid "bad ls-files format: %%%.*s"
-msgstr "ungültiges ls-files-Format: %%%.*s"
-
 msgid "git ls-files [<options>] [<file>...]"
 msgstr "git ls-files [<Optionen>] [<Datei>...]"
 
@@ -8069,18 +8098,6 @@
 msgid "git ls-tree [<options>] <tree-ish> [<path>...]"
 msgstr "git ls-tree [<Optionen>] <Commit-Referenz> [<Pfad>...]"
 
-#, c-format
-msgid "bad ls-tree format: element '%s' does not start with '('"
-msgstr "ungültiges ls-tree-Format: Element '%s' fängt nicht mit '(' an"
-
-#, c-format
-msgid "bad ls-tree format: element '%s' does not end in ')'"
-msgstr "ungültiges ls-tree-Format: Element '%s' endet nicht mit ')'"
-
-#, c-format
-msgid "bad ls-tree format: %%%.*s"
-msgstr "ungültiges ls-tree-Format: %%%.*s"
-
 msgid "only show trees"
 msgstr "nur Verzeichnisse anzeigen"
 
@@ -8195,6 +8212,13 @@
 "git merge-file [<Optionen>] [-L <Name1> [-L <orig> [-L <Name2>]]] <Datei1> "
 "<orig-Datei> <Datei2>"
 
+msgid ""
+"option diff-algorithm accepts \"myers\", \"minimal\", \"patience\" and "
+"\"histogram\""
+msgstr ""
+"Option diff-algorithm akzeptiert: \"myers\", \"minimal\", \"patience\" and "
+"\"histogram\""
+
 msgid "send results to standard output"
 msgstr "Ergebnisse zur Standard-Ausgabe senden"
 
@@ -8216,6 +8240,12 @@
 msgid "for conflicts, use a union version"
 msgstr "bei Konflikten eine gemeinsame Variante verwenden"
 
+msgid "<algorithm>"
+msgstr "<Algorithmus>"
+
+msgid "choose a diff algorithm"
+msgstr "einen Algorithmus für Änderungen wählen"
+
 msgid "for conflicts, use this marker size"
 msgstr "bei Konflikten diese Kennzeichnungslänge verwenden"
 
@@ -8257,6 +8287,10 @@
 msgid "Merging %s with %s\n"
 msgstr "Führe %s mit %s zusammen\n"
 
+#, c-format
+msgid "could not parse as tree '%s'"
+msgstr "'%s' konnte nicht als Tree geparst werden"
+
 msgid "not something we can merge"
 msgstr "nichts was wir zusammenführen können"
 
@@ -8307,9 +8341,6 @@
 msgid "unknown strategy option: -X%s"
 msgstr "unbekannte Strategie-Option: -X%s"
 
-msgid "--merge-base is incompatible with --stdin"
-msgstr "--merge-base ist inkompatibel mit --stdin"
-
 #, c-format
 msgid "malformed input line: '%s'."
 msgstr "Fehlerhafte Eingabezeile: '%s'."
@@ -8468,10 +8499,10 @@
 
 #, c-format
 msgid ""
-"Lines starting with '%c' will be ignored, and an empty message aborts\n"
+"Lines starting with '%s' will be ignored, and an empty message aborts\n"
 "the commit.\n"
 msgstr ""
-"Zeilen, die mit '%c' beginnen, werden ignoriert,\n"
+"Zeilen, die mit '%s' beginnen, werden ignoriert,\n"
 "und eine leere Beschreibung bricht den Commit ab.\n"
 
 msgid "Empty commit message."
@@ -8636,9 +8667,6 @@
 msgid "object '%s' tagged as '%s', but is a '%s' type"
 msgstr "Objekt '%s' als '%s' getaggt, aber ist ein '%s' Typ"
 
-msgid "could not read from stdin"
-msgstr "konnte nicht von der Standard-Eingabe lesen"
-
 msgid "tag on stdin did not pass our strict fsck check"
 msgstr ""
 "Tag von der Standardeingabe für unsere strenge Überprüfung bei fsck ungültig"
@@ -8905,10 +8933,6 @@
 msgid "Write/edit the notes for the following object:"
 msgstr "Schreiben/Bearbeiten der Notizen für das folgende Objekt:"
 
-#, c-format
-msgid "unable to start 'show' for object '%s'"
-msgstr "konnte 'show' für Objekt '%s' nicht starten"
-
 msgid "could not read 'show' output"
 msgstr "Konnte Ausgabe von 'show' nicht lesen."
 
@@ -9265,6 +9289,10 @@
 msgstr "Inkonsistenz mit der Anzahl von Deltas"
 
 #, c-format
+msgid "invalid pack.allowPackReuse value: '%s'"
+msgstr "ungültiger Wert für pack.allowPackReuse: '%s'"
+
+#, c-format
 msgid ""
 "value of uploadpack.blobpackfileuri must be of the form '<object-hash> <pack-"
 "hash> <uri>' (got '%s')"
@@ -9533,10 +9561,10 @@
 #, c-format
 msgid ""
 "Total %<PRIu32> (delta %<PRIu32>), reused %<PRIu32> (delta %<PRIu32>), pack-"
-"reused %<PRIu32>"
+"reused %<PRIu32> (from %<PRIuMAX>)"
 msgstr ""
 "Gesamt %<PRIu32> (Delta %<PRIu32>), Wiederverwendet %<PRIu32> (Delta "
-"%<PRIu32>), Pack wiederverwendet %<PRIu32>"
+"%<PRIu32>), Paket wiederverwendet %<PRIu32> (von %<PRIuMAX>)"
 
 msgid ""
 "'git pack-redundant' is nominated for removal.\n"
@@ -9556,10 +9584,11 @@
 msgstr "Ausführung ohne --i-still-use-this verweigert"
 
 msgid ""
-"git pack-refs [--all] [--no-prune] [--include <pattern>] [--exclude "
+"git pack-refs [--all] [--no-prune] [--auto] [--include <pattern>] [--exclude "
 "<pattern>]"
 msgstr ""
-"git pack-refs [--all] [--no-prune] [--include <Muster>] [--exclude <Muster>]"
+"git pack-refs [--all] [--no-prune] [--auto] [--include <Muster>] [--exclude "
+"<Muster>]"
 
 msgid "pack everything"
 msgstr "alles packen"
@@ -9567,6 +9596,9 @@
 msgid "prune loose refs (default)"
 msgstr "lose Referenzen entfernen (Standard)"
 
+msgid "auto-pack refs as needed"
+msgstr "auto-pack-Referenzen nach Bedarf"
+
 msgid "references to include"
 msgstr "einzubeziehende Referenzen"
 
@@ -9803,7 +9835,7 @@
 msgstr "git push [<Optionen>] [<Repository> [<Refspec>...]]"
 
 msgid "tag shorthand without <tag>"
-msgstr "Kurzschrift für Tag ohne <Tag>"
+msgstr "Kurzschrift für das Tag ohne <Tag>"
 
 msgid "--delete only accepts plain target ref names"
 msgstr "--delete akzeptiert nur reine Referenznamen als Ziel"
@@ -10258,21 +10290,6 @@
 msgid "could not remove '%s'"
 msgstr "Konnte '%s' nicht löschen"
 
-msgid ""
-"Resolve all conflicts manually, mark them as resolved with\n"
-"\"git add/rm <conflicted_files>\", then run \"git rebase --continue\".\n"
-"You can instead skip this commit: run \"git rebase --skip\".\n"
-"To abort and get back to the state before \"git rebase\", run \"git rebase --"
-"abort\"."
-msgstr ""
-"Lösen Sie alle Konflikte manuell auf, markieren Sie diese mit\n"
-"\"git add/rm <konfliktbehaftete_Dateien>\" und führen Sie dann\n"
-"\"git rebase --continue\" aus.\n"
-"Sie können auch stattdessen diesen Commit auslassen, indem\n"
-"Sie \"git rebase --skip\" ausführen.\n"
-"Um abzubrechen und zurück zum Zustand vor \"git rebase\" zu gelangen,\n"
-"führen Sie \"git rebase --abort\" aus."
-
 #, c-format
 msgid ""
 "\n"
@@ -10305,13 +10322,16 @@
 "Optionen für \"am\" und Optionen für \"merge\" können nicht gemeinsam "
 "verwendet werden"
 
+msgid "--empty=ask is deprecated; use '--empty=stop' instead."
+msgstr "--empty=ask ist veraltet; verwenden Sie stattdessen '--empty=stop'."
+
 #, c-format
 msgid ""
 "unrecognized empty type '%s'; valid values are \"drop\", \"keep\", and "
-"\"ask\"."
+"\"stop\"."
 msgstr ""
 "nicht erkannter leerer Typ '%s'; gültige Werte sind \"drop\", \"keep\", und "
-"\"ask\"."
+"\"stop\"."
 
 msgid ""
 "--rebase-merges with an empty string argument is deprecated and will stop "
@@ -10499,8 +10519,8 @@
 "'preserve' gesetzt, was nicht länger unterstützt wird; nutzen Sie\n"
 "stattdessen 'merges'"
 
-msgid "No rebase in progress?"
-msgstr "Kein Rebase im Gange?"
+msgid "no rebase in progress"
+msgstr "kein Rebase im Gange"
 
 msgid "The --edit-todo action can only be used during interactive rebase."
 msgstr ""
@@ -10548,13 +10568,6 @@
 msgstr "Schalter `C' erwartet einen numerischen Wert."
 
 msgid ""
-"apply options are incompatible with rebase.autoSquash.  Consider adding --no-"
-"autosquash"
-msgstr ""
-"apply-Optionen sind mit rebase.autoSquash nicht kompatibel. Erwägen Sie das "
-"Hinzufügen von --no-autosquash"
-
-msgid ""
 "apply options are incompatible with rebase.rebaseMerges.  Consider adding --"
 "no-rebase-merges"
 msgstr ""
@@ -10706,6 +10719,9 @@
 msgid "git reflog [show] [<log-options>] [<ref>]"
 msgstr "git reflog [show] [<log-Optionen>] [<Referenz>]"
 
+msgid "git reflog list"
+msgstr "git reflog list"
+
 msgid ""
 "git reflog expire [--expire=<time>] [--expire-unreachable=<time>]\n"
 "                  [--rewrite] [--updateref] [--stale-fix]\n"
@@ -10732,6 +10748,10 @@
 msgid "invalid timestamp '%s' given to '--%s'"
 msgstr "ungültiger Zeitstempel '%s' für '--%s'"
 
+#, c-format
+msgid "%s does not accept arguments: '%s'"
+msgstr "%s akzeptiert keine Argumente: '%s'"
+
 msgid "do not actually prune any entries"
 msgstr "Einträge nicht wirklich löschen"
 
@@ -10861,8 +10881,8 @@
 "\t benutzen Sie stattdessen --mirror=fetch oder --mirror=push"
 
 #, c-format
-msgid "unknown mirror argument: %s"
-msgstr "unbekanntes Argument für Option mirror: %s"
+msgid "unknown --mirror argument: %s"
+msgstr "unbekanntes --mirror Argument: %s"
 
 msgid "fetch the remote branches"
 msgstr "die Remote-Branches anfordern"
@@ -11238,6 +11258,9 @@
 "Konnte 'pack-objects' für das Neupacken von Objekten aus partiell geklonten\n"
 "Remote-Repositories nicht starten."
 
+msgid "failed to feed promisor objects to pack-objects"
+msgstr "promisor-Objekte konnten nicht an pack-objects übergeben werden"
+
 msgid "repack: Expecting full hex object ID lines only from pack-objects."
 msgstr ""
 "repack: Erwarte Zeilen mit vollständiger Hex-Objekt-ID nur von pack-objects."
@@ -11567,6 +11590,77 @@
 msgid "only one pattern can be given with -l"
 msgstr "Mit -l kann nur ein Muster angegeben werden"
 
+msgid "need some commits to replay"
+msgstr "zum erneuten Abspielen werden Commits benötigt"
+
+msgid "--onto and --advance are incompatible"
+msgstr "--onto und --advance sind inkompatibel"
+
+msgid "all positive revisions given must be references"
+msgstr "alle angegebenen positiven Commits müssen Referenzen sein"
+
+msgid "argument to --advance must be a reference"
+msgstr "Argument für --advance muss eine Referenz sein"
+
+msgid ""
+"cannot advance target with multiple sources because ordering would be ill-"
+"defined"
+msgstr ""
+"kann Ziel nicht mit mehreren Quellen erweitern, da die Reihenfolge unklar "
+"wäre"
+
+msgid ""
+"cannot implicitly determine whether this is an --advance or --onto operation"
+msgstr ""
+"kann nicht implizit bestimmen, ob es sich um eine --advance oder --onto "
+"Operation handelt"
+
+msgid ""
+"cannot advance target with multiple source branches because ordering would "
+"be ill-defined"
+msgstr ""
+"kann Ziel nicht mit mehreren Quell-Branches erweitern, da die Reihenfolge "
+"unklar wäre"
+
+msgid "cannot implicitly determine correct base for --onto"
+msgstr "kann nicht implizit die richtige Basis für --onto bestimmen"
+
+msgid ""
+"(EXPERIMENTAL!) git replay ([--contained] --onto <newbase> | --advance "
+"<branch>) <revision-range>..."
+msgstr ""
+"(EXPERIMENTELL!) git replay ([--contained] --onto <neue-Basis> | --advance "
+"<Branch>) <Commitbereich>..."
+
+msgid "make replay advance given branch"
+msgstr "angegebenen Branch durch neues Abspielen erweitern"
+
+msgid "replay onto given commit"
+msgstr "auf angegebenen Commit neu abspielen"
+
+msgid "advance all branches contained in revision-range"
+msgstr "alle Branches erweitern, die in Commitbereich liegen"
+
+msgid "option --onto or --advance is mandatory"
+msgstr "Option --onto oder --advance erforderlich"
+
+#, c-format
+msgid ""
+"some rev walking options will be overridden as '%s' bit in 'struct rev_info' "
+"will be forced"
+msgstr ""
+"einige Optionen für das Abgehen von Commits werden außer Kraft gesetzt, da "
+"das '%s' Bit in 'struct rev_info' erzwungen wird"
+
+msgid "error preparing revisions"
+msgstr "Fehler beim Vorbereiten der Commits"
+
+msgid "replaying down to root commit is not supported yet!"
+msgstr "erneutes Abspielen bis zum Root-Commit wird noch nicht unterstützt!"
+
+msgid "replaying merge commits is not supported yet!"
+msgstr "erneutes Abspielen von Merge-Commits wird noch nicht unterstützt!"
+
 msgid ""
 "git rerere [clear | forget <pathspec>... | diff | status | remaining | gc]"
 msgstr ""
@@ -11774,19 +11868,17 @@
 msgid "--prefix requires an argument"
 msgstr "--prefix benötigt ein Argument"
 
+msgid "no object format specified"
+msgstr "kein Objektformat angegeben"
+
+#, c-format
+msgid "unsupported object format: %s"
+msgstr "nicht unterstütztes Objekt-Format: %s"
+
 #, c-format
 msgid "unknown mode for --abbrev-ref: %s"
 msgstr "unbekannter Modus für --abbrev-ref: %s"
 
-msgid "--exclude-hidden cannot be used together with --branches"
-msgstr "--exclude-hidden kann nicht zusammen mit --branches verwendet werden"
-
-msgid "--exclude-hidden cannot be used together with --tags"
-msgstr "--exclude-hidden kann nicht zusammen mit --tags verwendet werden"
-
-msgid "--exclude-hidden cannot be used together with --remotes"
-msgstr "--exclude-hidden kann nicht zusammen mit --remotes verwendet werden"
-
 msgid "this operation must be run in a work tree"
 msgstr "Diese Operation muss in einem Arbeitsverzeichnis ausgeführt werden."
 
@@ -11865,8 +11957,8 @@
 msgid "allow commits with empty messages"
 msgstr "Commits mit leerer Beschreibung erlauben"
 
-msgid "keep redundant, empty commits"
-msgstr "redundante, leere Commits behalten"
+msgid "deprecated: use --empty=keep instead"
+msgstr "veraltet: benutzen Sie stattdessen --empty=keep"
 
 msgid "use the 'reference' format to refer to commits"
 msgstr "das 'reference' Format nutzen, um auf Commits zu verweisen"
@@ -12202,10 +12294,6 @@
 "Referenzen von der Standard-Eingabe anzeigen, die sich nicht im lokalen "
 "Repository befinden"
 
-#, c-format
-msgid "only one of '%s', '%s' or '%s' can be given"
-msgstr "es kann nur eines von '%s', '%s' oder '%s' angegeben werden"
-
 msgid ""
 "git sparse-checkout (init | list | set | add | reapply | disable | check-"
 "rules) [<options>]"
@@ -13244,26 +13332,26 @@
 "\n"
 "Write a message for tag:\n"
 "  %s\n"
-"Lines starting with '%c' will be ignored.\n"
+"Lines starting with '%s' will be ignored.\n"
 msgstr ""
 "\n"
-"Geben Sie eine Beschreibung für Tag\n"
+"Geben Sie eine Beschreibung für das Tag:\n"
 "  %s\n"
-"ein. Zeilen, die mit '%c' beginnen, werden ignoriert.\n"
+"ein. Zeilen, die mit '%s' beginnen, werden ignoriert.\n"
 
 #, c-format
 msgid ""
 "\n"
 "Write a message for tag:\n"
 "  %s\n"
-"Lines starting with '%c' will be kept; you may remove them yourself if you "
+"Lines starting with '%s' will be kept; you may remove them yourself if you "
 "want to.\n"
 msgstr ""
 "\n"
-"Geben Sie eine Beschreibung für Tag\n"
+"Geben Sie eine Beschreibung für das Tag\n"
 "  %s\n"
-"ein. Zeilen, die mit '%c' beginnen, werden behalten; Sie dürfen diese\n"
-"selbst entfernen wenn Sie möchten.\n"
+"ein. Zeilen, die mit '%s' beginnen, werden behalten; Sie dürfen diese\n"
+"selbst entfernen, wenn Sie möchten.\n"
 
 msgid "unable to sign the tag"
 msgstr "konnte Tag nicht signieren"
@@ -13348,6 +13436,9 @@
 msgid "print only tags of the object"
 msgstr "nur Tags von dem Objekt ausgeben"
 
+msgid "could not start 'git column'"
+msgstr "konnte 'git column' nicht starten"
+
 #, c-format
 msgid "the '%s' option is only allowed in list mode"
 msgstr "die Option '%s' ist nur im Listenmodus erlaubt"
@@ -13611,12 +13702,11 @@
 msgid "fsmonitor disabled"
 msgstr "Dateisystem-Monitor deaktiviert"
 
-msgid "git update-ref [<options>] -d <refname> [<old-val>]"
-msgstr "git update-ref [<Optionen>] -d <Referenzname> [<alter-Wert>]"
+msgid "git update-ref [<options>] -d <refname> [<old-oid>]"
+msgstr "git update-ref [<Optionen>] -d <Referenzname> [<alte-oid>]"
 
-msgid "git update-ref [<options>]    <refname> <new-val> [<old-val>]"
-msgstr ""
-"git update-ref [<Optionen>]    <Referenzname> <neuer-Wert> [<alter-Wert>]"
+msgid "git update-ref [<options>]    <refname> <new-oid> [<old-oid>]"
+msgstr "git update-ref [<Optionen>]    <Referenzname> <neue-oid> [<alte-oid>]"
 
 msgid "git update-ref [<options>] --stdin [-z]"
 msgstr "git update-ref [<Optionen>] --stdin [-z]"
@@ -13717,33 +13807,29 @@
 
 #, c-format
 msgid ""
-"If you meant to create a worktree containing a new orphan branch\n"
+"If you meant to create a worktree containing a new unborn branch\n"
 "(branch with no commits) for this repository, you can do so\n"
 "using the --orphan flag:\n"
 "\n"
 "    git worktree add --orphan -b %s %s\n"
 msgstr ""
-"Wenn Sie ein Arbeitsverzeichnis erstellen möchten, um einen neuen verwaisten "
-"Branch\n"
-"(Branch ohne Commits) für dieses Repository zu erstellen, können Sie dies "
-"mit\n"
-"der Option --orphan tun:\n"
+"Wenn Sie ein Arbeitsverzeichnis erstellen möchten, welches einen neuen\n"
+"ungeborenen Branch (Branch ohne Commits) für dieses Repository erzeugt,\n"
+"können Sie dies mit der Option --orphan tun:\n"
 "\n"
 "    git worktree add --orphan -b %s %s\n"
 
 #, c-format
 msgid ""
-"If you meant to create a worktree containing a new orphan branch\n"
+"If you meant to create a worktree containing a new unborn branch\n"
 "(branch with no commits) for this repository, you can do so\n"
 "using the --orphan flag:\n"
 "\n"
 "    git worktree add --orphan %s\n"
 msgstr ""
-"Wenn Sie ein Arbeitsverzeichnis erstellen möchten, um einen neuen verwaisten "
-"Branch\n"
-"(Branch ohne Commits) für dieses Repository zu erstellen, können Sie dies "
-"mit\n"
-"der Option --orphan tun:\n"
+"Wenn Sie ein Arbeitsverzeichnis erstellen möchten, welches einen neuen\n"
+"ungeborenen Branch (Branch ohne Commits) für dieses Repository erzeugt,\n"
+"können Sie dies mit der Option --orphan tun:\n"
 "\n"
 "    git worktree add --orphan %s\n"
 
@@ -13806,6 +13892,10 @@
 msgstr "initialisiere"
 
 #, c-format
+msgid "could not find created worktree '%s'"
+msgstr "konnte erstelltes Arbeitsverzeichnis '%s' nicht finden"
+
+#, c-format
 msgid "Preparing worktree (new branch '%s')"
 msgstr "Bereite Arbeitsverzeichnis vor (neuer Branch '%s')"
 
@@ -13845,10 +13935,6 @@
 "Referenz zu überschreiben\n"
 "oder rufen Sie diese zuerst ab"
 
-#, c-format
-msgid "'%s' and '%s' cannot be used together"
-msgstr "'%s' und '%s' können nicht zusammen verwendet werden"
-
 msgid "checkout <branch> even if already checked out in other worktree"
 msgstr ""
 "<Branch> auschecken, auch wenn dieser bereits in einem anderen "
@@ -13860,8 +13946,8 @@
 msgid "create or reset a branch"
 msgstr "Branch erstellen oder umsetzen"
 
-msgid "create unborn/orphaned branch"
-msgstr "ungeborenen/verwaisten Branch erstellen"
+msgid "create unborn branch"
+msgstr "ungeborenen Branch erzeugen"
 
 msgid "populate the new working tree"
 msgstr "das neue Arbeitsverzeichnis auschecken"
@@ -13886,11 +13972,8 @@
 "die Optionen '%s', '%s' und '%s' können nicht gemeinsam verwendet werden"
 
 #, c-format
-msgid "options '%s', and '%s' cannot be used together"
-msgstr "die Optionen '%s' und '%s' können nicht gemeinsam verwendet werden"
-
-msgid "<commit-ish>"
-msgstr "<Commit-Angabe>"
+msgid "option '%s' and commit-ish cannot be used together"
+msgstr "Option '%s' und commit-ish können nicht gemeinsam verwendet werden"
 
 msgid "added with --lock"
 msgstr "mit --lock hinzugefügt"
@@ -14541,6 +14624,11 @@
 msgid "Create, list, delete refs to replace objects"
 msgstr "Referenzen für ersetzende Objekte erstellen, auflisten, löschen"
 
+msgid "EXPERIMENTAL: Replay commits on a new base, works with bare repos too"
+msgstr ""
+"EXPERIMENTELL: Commits auf neuer Basis abspielen, funktioniert auch mit Bare-"
+"Repositories"
+
 msgid "Generates a summary of pending changes"
 msgstr "eine Übersicht über ausstehende Änderungen generieren"
 
@@ -14785,6 +14873,32 @@
 msgid "commit-graph file is too small"
 msgstr "Commit-Graph-Datei ist zu klein"
 
+msgid "commit-graph oid fanout chunk is wrong size"
+msgstr "Commit-Graph OID fanout Chunk hat die falsche Größe"
+
+msgid "commit-graph fanout values out of order"
+msgstr "Commit-Graph fanout-Werte sind nicht in Ordnung"
+
+msgid "commit-graph OID lookup chunk is the wrong size"
+msgstr "Commit-Graph OID Lookup Chunk hat die falsche Größe"
+
+msgid "commit-graph commit data chunk is wrong size"
+msgstr "Commit-Graph Commit Daten Chunk hat die falsche Größe"
+
+msgid "commit-graph generations chunk is wrong size"
+msgstr "Commit-Graph Generations Chunk hat die falsche Größe"
+
+msgid "commit-graph changed-path index chunk is too small"
+msgstr "Commit-Graph changed-path Index Chunk ist zu klein"
+
+#, c-format
+msgid ""
+"ignoring too-small changed-path chunk (%<PRIuMAX> < %<PRIuMAX>) in commit-"
+"graph file"
+msgstr ""
+"ignoriere zu kleinen Chunk für geänderte Pfade (%<PRIuMAX> < %<PRIuMAX>) in "
+"Commit-Graph-Datei"
+
 #, c-format
 msgid "commit-graph signature %X does not match signature %X"
 msgstr "Commit-Graph-Signatur %X stimmt nicht mit Signatur %X überein"
@@ -14801,6 +14915,16 @@
 msgid "commit-graph file is too small to hold %u chunks"
 msgstr "Commit-Graph-Datei ist zu klein, um %u Chunks zu enthalten"
 
+msgid "commit-graph required OID fanout chunk missing or corrupted"
+msgstr "Commit-Graph benötigter OID fanout Chunk fehlt oder ist beschädigt"
+
+msgid "commit-graph required OID lookup chunk missing or corrupted"
+msgstr "Commit-Graph benötigter OID lookup Chunk fehlt oder ist beschädigt"
+
+msgid "commit-graph required commit data chunk missing or corrupted"
+msgstr ""
+"Commit-Graph erforderlicher Commit-Daten Chunk fehlt oder ist beschädigt"
+
 msgid "commit-graph has no base graphs chunk"
 msgstr "Commit-Graph hat keinen Basis-Graph-Chunk"
 
@@ -14814,6 +14938,9 @@
 msgid "commit count in base graph too high: %<PRIuMAX>"
 msgstr "Anzahl der Commits im Basisgraph zu hoch: %<PRIuMAX>"
 
+msgid "commit-graph chain file too small"
+msgstr "Commit-Graph Chain-Datei zu klein"
+
 #, c-format
 msgid "invalid commit-graph chain: line '%s' not a hash"
 msgstr "Ungültige Commit-Graph Verkettung: Zeile '%s' ist kein Hash"
@@ -14834,6 +14961,9 @@
 msgid "commit-graph overflow generation data is too small"
 msgstr "Commit-Graph Überlaufgenerierungsdaten sind zu klein"
 
+msgid "commit-graph extra-edges pointer out of bounds"
+msgstr "commit-graph extra-edges Zeiger außerhalb der Grenzen"
+
 msgid "Loading known commits in commit graph"
 msgstr "Lade bekannte Commits in Commit-Graph"
 
@@ -14985,6 +15115,10 @@
 msgstr "Commit in Commit-Graph überprüfen"
 
 #, c-format
+msgid "could not parse commit %s"
+msgstr "Konnte Commit %s nicht parsen."
+
+#, c-format
 msgid "%s %s is not a commit!"
 msgstr "%s %s ist kein Commit!"
 
@@ -15423,8 +15557,13 @@
 msgid "bad zlib compression level %d"
 msgstr "ungültiger zlib Komprimierungsgrad %d"
 
-msgid "core.commentChar should only be one ASCII character"
-msgstr "core.commentChar sollte nur ein ASCII-Zeichen sein"
+#, c-format
+msgid "%s cannot contain newline"
+msgstr "%s kann keinen Zeilenumbruch enthalten"
+
+#, c-format
+msgid "%s must have at least one character"
+msgstr "%s muss mindestens ein Zeichen enthalten"
 
 #, c-format
 msgid "ignoring unknown core.fsyncMethod value '%s'"
@@ -15502,6 +15641,10 @@
 msgstr "Konnte neue Konfigurationsdatei '%s' nicht schreiben."
 
 #, c-format
+msgid "no multi-line comment allowed: '%s'"
+msgstr "kein mehrzeiliger Kommentar erlaubt: '%s'"
+
+#, c-format
 msgid "could not lock config file %s"
 msgstr "Konnte Konfigurationsdatei '%s' nicht sperren."
 
@@ -16001,6 +16144,10 @@
 msgstr "Unbekannter Wert in Konfigurationsvariable 'diff.submodule': '%s'"
 
 #, c-format
+msgid "unknown value for config '%s': %s"
+msgstr "Unbekannter Wert für Konfiguration '%s': %s"
+
+#, c-format
 msgid ""
 "Found errors in 'diff.dirstat' config variable:\n"
 "%s"
@@ -16082,13 +16229,6 @@
 msgid "invalid mode '%s' in --color-moved-ws"
 msgstr "ungültiger Modus '%s' in --color-moved-ws"
 
-msgid ""
-"option diff-algorithm accepts \"myers\", \"minimal\", \"patience\" and "
-"\"histogram\""
-msgstr ""
-"Option diff-algorithm akzeptiert: \"myers\", \"minimal\", \"patience\" and "
-"\"histogram\""
-
 #, c-format
 msgid "invalid argument to %s"
 msgstr "ungültiges Argument für %s"
@@ -16132,8 +16272,8 @@
 msgid "output only the last line of --stat"
 msgstr "nur die letzte Zeile von --stat ausgeben"
 
-msgid "<param1,param2>..."
-msgstr "<Parameter1,Parameter2>..."
+msgid "<param1>,<param2>..."
+msgstr "<Parameter1>,<Parameter2>..."
 
 msgid ""
 "output the distribution of relative amount of changes for each sub-directory"
@@ -16144,8 +16284,8 @@
 msgid "synonym for --dirstat=cumulative"
 msgstr "Synonym für --dirstat=cumulative"
 
-msgid "synonym for --dirstat=files,param1,param2..."
-msgstr "Synonym für --dirstat=files,Parameter1,Parameter2..."
+msgid "synonym for --dirstat=files,<param1>,<param2>..."
+msgstr "Synonym für --dirstat=files,<Parameter1>,<Parameter2>..."
 
 msgid "warn if changes introduce conflict markers or whitespace errors"
 msgstr ""
@@ -16328,12 +16468,6 @@
 msgid "generate diff using the \"histogram diff\" algorithm"
 msgstr "Änderungen durch Nutzung des Algorithmus \"Histogram Diff\" erzeugen"
 
-msgid "<algorithm>"
-msgstr "<Algorithmus>"
-
-msgid "choose a diff algorithm"
-msgstr "einen Algorithmus für Änderungen wählen"
-
 msgid "<text>"
 msgstr "<Text>"
 
@@ -17337,6 +17471,14 @@
 msgstr "Konnte '%s.lock' nicht erstellen: %s"
 
 #, c-format
+msgid "could not write loose object index %s"
+msgstr "konnte den losen Objektindex %s nicht schreiben"
+
+#, c-format
+msgid "failed to write loose object index %s\n"
+msgstr "Fehler beim Schreiben des losen Objektindexes %s\n"
+
+#, c-format
 msgid "unexpected line: '%s'"
 msgstr "unerwartete Zeile: '%s'"
 
@@ -17347,6 +17489,10 @@
 msgstr "angeführtes CRLF entdeckt"
 
 #, c-format
+msgid "unable to format message: %s"
+msgstr "Meldung kann nicht formatiert werden: %s"
+
+#, c-format
 msgid "Failed to merge submodule %s (not checked out)"
 msgstr "Fehler beim Merge von Submodul %s (nicht ausgecheckt)."
 
@@ -17359,6 +17505,11 @@
 msgstr "Fehler beim Merge von Submodul %s (Commits nicht vorhanden)."
 
 #, c-format
+msgid "Failed to merge submodule %s (repository corrupt)"
+msgstr ""
+"Submodul %s konnte nicht zusammengeführt werden (Repository beschädigt)"
+
+#, c-format
 msgid "Failed to merge submodule %s (commits don't follow merge-base)"
 msgstr "Fehler beim Merge von Submodul %s (Commits folgen keiner Merge-Basis)"
 
@@ -17547,7 +17698,7 @@
 #. conflict in a submodule. The first argument is the submodule
 #. name, and the second argument is the abbreviated id of the
 #. commit that needs to be merged.  For example:
-#.  - go to submodule (mysubmodule), and either merge commit abc1234"
+#. - go to submodule (mysubmodule), and either merge commit abc1234"
 #.
 #, c-format
 msgid ""
@@ -17845,66 +17996,6 @@
 msgid "failed to read the cache"
 msgstr "Lesen des Zwischenspeichers fehlgeschlagen"
 
-msgid "multi-pack-index OID fanout is of the wrong size"
-msgstr "Multi-Pack-Index OID fanout hat die falsche Größe"
-
-msgid "multi-pack-index OID lookup chunk is the wrong size"
-msgstr "multi-pack-index OID-Lookup-Chunk hat die falsche Größe"
-
-msgid "multi-pack-index object offset chunk is the wrong size"
-msgstr "multi-pack-index Object-Offset-Chunk hat die falsche Größe"
-
-#, c-format
-msgid "multi-pack-index file %s is too small"
-msgstr "Multi-Pack-Index-Datei %s ist zu klein."
-
-#, c-format
-msgid "multi-pack-index signature 0x%08x does not match signature 0x%08x"
-msgstr ""
-"Multi-Pack-Index-Signatur 0x%08x stimmt nicht mit Signatur 0x%08x überein."
-
-#, c-format
-msgid "multi-pack-index version %d not recognized"
-msgstr "Multi-Pack-Index-Version %d nicht erkannt."
-
-#, c-format
-msgid "multi-pack-index hash version %u does not match version %u"
-msgstr "Multi-Pack-Index Hash-Version %u stimmt nicht mit Version %u überein"
-
-msgid "multi-pack-index required pack-name chunk missing or corrupted"
-msgstr ""
-"multi-pack-index erforderlicher Pack-Name Chunk fehlt oder ist beschädigt"
-
-msgid "multi-pack-index required OID fanout chunk missing or corrupted"
-msgstr ""
-"multi-pack-index erforderlicher OID-Fanout-Chunk fehlt oder ist beschädigt"
-
-msgid "multi-pack-index required OID lookup chunk missing or corrupted"
-msgstr ""
-"multi-pack-index erforderlicher OID Lookup Chunk fehlt oder ist beschädigt"
-
-msgid "multi-pack-index required object offsets chunk missing or corrupted"
-msgstr ""
-"multi-pack-index benötigte Objekt Offsets Chunk fehlt oder ist beschädigt"
-
-msgid "multi-pack-index pack-name chunk is too short"
-msgstr "multi-pack-index Pack-Name Chunk ist zu klein"
-
-#, c-format
-msgid "multi-pack-index pack names out of order: '%s' before '%s'"
-msgstr "Falsche Reihenfolge bei Multi-Pack-Index Pack-Namen: '%s' vor '%s'"
-
-#, c-format
-msgid "bad pack-int-id: %u (%u total packs)"
-msgstr "Ungültige pack-int-id: %u (%u Pakete insgesamt)"
-
-msgid "multi-pack-index stores a 64-bit offset, but off_t is too small"
-msgstr ""
-"Multi-Pack-Index speichert einen 64-Bit Offset, aber off_t ist zu klein"
-
-msgid "multi-pack-index large offset out of bounds"
-msgstr "multi-pack-index großer Offset außerhalb der Grenzen"
-
 #, c-format
 msgid "failed to add packfile '%s'"
 msgstr "Fehler beim Hinzufügen von Packdatei '%s'"
@@ -17970,6 +18061,92 @@
 msgid "could not write multi-pack-index"
 msgstr "Multi-Pack-Index konnte nicht geschrieben werden"
 
+msgid "Counting referenced objects"
+msgstr "Referenzierte Objekte zählen"
+
+msgid "Finding and deleting unreferenced packfiles"
+msgstr "Suchen und Löschen von unreferenzierten Pack-Dateien"
+
+msgid "could not start pack-objects"
+msgstr "Konnte 'pack-objects' nicht ausführen"
+
+msgid "could not finish pack-objects"
+msgstr "Konnte 'pack-objects' nicht beenden"
+
+msgid "multi-pack-index OID fanout is of the wrong size"
+msgstr "Multi-Pack-Index OID fanout hat die falsche Größe"
+
+#, c-format
+msgid ""
+"oid fanout out of order: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]"
+msgstr ""
+"Ungültige oid fanout Reihenfolge: fanout[%d] = %<PRIx32> > %<PRIx32> = "
+"fanout[%d]"
+
+msgid "multi-pack-index OID lookup chunk is the wrong size"
+msgstr "multi-pack-index OID-Lookup-Chunk hat die falsche Größe"
+
+msgid "multi-pack-index object offset chunk is the wrong size"
+msgstr "multi-pack-index Object-Offset-Chunk hat die falsche Größe"
+
+#, c-format
+msgid "multi-pack-index file %s is too small"
+msgstr "Multi-Pack-Index-Datei %s ist zu klein."
+
+#, c-format
+msgid "multi-pack-index signature 0x%08x does not match signature 0x%08x"
+msgstr ""
+"Multi-Pack-Index-Signatur 0x%08x stimmt nicht mit Signatur 0x%08x überein."
+
+#, c-format
+msgid "multi-pack-index version %d not recognized"
+msgstr "Multi-Pack-Index-Version %d nicht erkannt."
+
+#, c-format
+msgid "multi-pack-index hash version %u does not match version %u"
+msgstr "Multi-Pack-Index Hash-Version %u stimmt nicht mit Version %u überein"
+
+msgid "multi-pack-index required pack-name chunk missing or corrupted"
+msgstr ""
+"multi-pack-index erforderlicher Pack-Name Chunk fehlt oder ist beschädigt"
+
+msgid "multi-pack-index required OID fanout chunk missing or corrupted"
+msgstr ""
+"multi-pack-index erforderlicher OID-Fanout-Chunk fehlt oder ist beschädigt"
+
+msgid "multi-pack-index required OID lookup chunk missing or corrupted"
+msgstr ""
+"multi-pack-index erforderlicher OID Lookup Chunk fehlt oder ist beschädigt"
+
+msgid "multi-pack-index required object offsets chunk missing or corrupted"
+msgstr ""
+"multi-pack-index benötigte Objekt Offsets Chunk fehlt oder ist beschädigt"
+
+msgid "multi-pack-index pack-name chunk is too short"
+msgstr "multi-pack-index Pack-Name Chunk ist zu klein"
+
+#, c-format
+msgid "multi-pack-index pack names out of order: '%s' before '%s'"
+msgstr "Falsche Reihenfolge bei Multi-Pack-Index Pack-Namen: '%s' vor '%s'"
+
+#, c-format
+msgid "bad pack-int-id: %u (%u total packs)"
+msgstr "Ungültige pack-int-id: %u (%u Pakete insgesamt)"
+
+msgid "MIDX does not contain the BTMP chunk"
+msgstr "MIDX enthält keinen BTMP-Chunk"
+
+#, c-format
+msgid "could not load bitmapped pack %<PRIu32>"
+msgstr "konnte Bitmap-Paket nicht laden %<PRIu32>"
+
+msgid "multi-pack-index stores a 64-bit offset, but off_t is too small"
+msgstr ""
+"Multi-Pack-Index speichert einen 64-Bit Offset, aber off_t ist zu klein"
+
+msgid "multi-pack-index large offset out of bounds"
+msgstr "multi-pack-index großer Offset außerhalb der Grenzen"
+
 #, c-format
 msgid "failed to clear multi-pack-index at %s"
 msgstr "Fehler beim Löschen des Multi-Pack-Index bei %s"
@@ -17983,13 +18160,6 @@
 msgid "Looking for referenced packfiles"
 msgstr "Suche nach referenzierten Pack-Dateien"
 
-#, c-format
-msgid ""
-"oid fanout out of order: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]"
-msgstr ""
-"Ungültige oid fanout Reihenfolge: fanout[%d] = %<PRIx32> > %<PRIx32> = "
-"fanout[%d]"
-
 msgid "the midx contains no oid"
 msgstr "das midx enthält keine oid"
 
@@ -18018,18 +18188,6 @@
 msgid "incorrect object offset for oid[%d] = %s: %<PRIx64> != %<PRIx64>"
 msgstr "Falscher Objekt-Offset für oid[%d] = %s: %<PRIx64> != %<PRIx64>"
 
-msgid "Counting referenced objects"
-msgstr "Referenzierte Objekte zählen"
-
-msgid "Finding and deleting unreferenced packfiles"
-msgstr "Suchen und Löschen von unreferenzierten Pack-Dateien"
-
-msgid "could not start pack-objects"
-msgstr "Konnte 'pack-objects' nicht ausführen"
-
-msgid "could not finish pack-objects"
-msgstr "Konnte 'pack-objects' nicht beenden"
-
 #, c-format
 msgid "unable to create lazy_dir thread: %s"
 msgstr "Kann lazy_dir Thread nicht erzeugen: %s"
@@ -18081,6 +18239,25 @@
 msgid "Bad %s value: '%s'"
 msgstr "Ungültiger %s Wert: '%s'"
 
+msgid "failed to decode tree entry"
+msgstr "Tree-Eintrag konnte nicht dekodiert werden"
+
+#, c-format
+msgid "failed to map tree entry for %s"
+msgstr "der Tree-Eintrag für %s konnte nicht zugeordnet werden"
+
+#, c-format
+msgid "bad %s in commit"
+msgstr "ungültiges %s in Commit"
+
+#, c-format
+msgid "unable to map %s %s in commit object"
+msgstr "kann %s %s in Commit-Objekt nicht zuordnen"
+
+#, c-format
+msgid "Failed to convert object from %s to %s"
+msgstr "Objekt konnte nicht von %s nach %s konvertiert werden"
+
 #, c-format
 msgid "object directory %s does not exist; check .git/objects/info/alternates"
 msgstr ""
@@ -18188,6 +18365,10 @@
 msgstr "Gepacktes Objekt %s (gespeichert in %s) ist beschädigt."
 
 #, c-format
+msgid "missing mapping of %s to %s"
+msgstr "fehlende Abbildung von %s auf %s"
+
+#, c-format
 msgid "unable to write file %s"
 msgstr "Konnte Datei %s nicht schreiben."
 
@@ -18243,6 +18424,10 @@
 msgstr "Kann Objekt für %s nicht lesen."
 
 #, c-format
+msgid "cannot map object %s to %s"
+msgstr "kann Objekt %s nicht auf %s abbilden"
+
+#, c-format
 msgid "object fails fsck: %s"
 msgstr "fsck schlägt bei Objekt fehl: %s"
 
@@ -18304,7 +18489,7 @@
 #. TRANSLATORS: This is a line of ambiguous commit
 #. object output. E.g.:
 #. *
-#.    "deadbeef commit 2021-01-01 - Some Commit Message"
+#. "deadbeef commit 2021-01-01 - Some Commit Message"
 #.
 #, c-format
 msgid "%s commit %s - %s"
@@ -18313,7 +18498,7 @@
 #. TRANSLATORS: This is a line of ambiguous
 #. tag object output. E.g.:
 #. *
-#.    "deadbeef tag 2022-01-01 - Some Tag Message"
+#. "deadbeef tag 2022-01-01 - Some Tag Message"
 #. *
 #. The second argument is the YYYY-MM-DD found
 #. in the tag.
@@ -18329,7 +18514,7 @@
 #. tag object output where we couldn't parse
 #. the tag itself. E.g.:
 #. *
-#.    "deadbeef [bad tag, could not parse it]"
+#. "deadbeef [bad tag, could not parse it]"
 #.
 #, c-format
 msgid "%s [bad tag, could not parse it]"
@@ -18525,6 +18710,9 @@
 msgid "could not open pack %s"
 msgstr "konnte Paket '%s' nicht öffnen"
 
+msgid "could not determine MIDX preferred pack"
+msgstr "konnte das von MIDX bevorzugte Paket nicht ermitteln"
+
 #, c-format
 msgid "preferred pack (%s) is invalid"
 msgstr "bevorzugtes Paket (%s) ist ungültig"
@@ -18548,6 +18736,17 @@
 "fehlerhafte ewah-Bitmap: abgeschnittener Header für Bitmap des Commits \"%s\""
 
 #, c-format
+msgid "unable to load pack: '%s', disabling pack-reuse"
+msgstr ""
+"Paket kann nicht geladen werden: '%s', Deaktivierung der Paket-"
+"Wiederverwendung"
+
+msgid "unable to compute preferred pack, disabling pack-reuse"
+msgstr ""
+"kann bevorzugtes Paket nicht berechnen, Wiederverwendung von Paketen wird "
+"deaktiviert"
+
+#, c-format
 msgid "object '%s' not found in type bitmaps"
 msgstr "Objekt '%s' nicht im Typ Bitmaps gefunden"
 
@@ -18638,6 +18837,9 @@
 msgid "multi-pack-index reverse-index chunk is the wrong size"
 msgstr "multi-pack-index Reverse-Index Chunk hat die falsche Größe"
 
+msgid "could not determine preferred pack"
+msgstr "konnte das bevorzugte Paket nicht bestimmen"
+
 msgid "cannot both write and verify reverse index"
 msgstr ""
 "Reverse-Index kann nicht gleichzeitig geschrieben und verifiziert werden"
@@ -18704,10 +18906,6 @@
 "Suffix"
 
 #, c-format
-msgid "%s is incompatible with %s"
-msgstr "%s ist inkompatibel mit %s."
-
-#, c-format
 msgid "ambiguous option: %s (could be --%s%s or --%s%s)"
 msgstr "Mehrdeutige Option: %s (kann --%s%s oder --%s%s sein)"
 
@@ -19031,10 +19229,6 @@
 msgstr "Konnte '%s' nicht dem Index hinzufügen."
 
 #, c-format
-msgid "unable to stat '%s'"
-msgstr "konnte '%s' nicht lesen"
-
-#, c-format
 msgid "'%s' appears as both a file and as a directory"
 msgstr "'%s' scheint eine Datei und ein Verzeichnis zu sein"
 
@@ -19613,10 +19807,6 @@
 msgstr "kann '%s' und '%s' nicht zur selben Zeit verarbeiten"
 
 #, c-format
-msgid "could not remove reference %s"
-msgstr "konnte Referenz %s nicht löschen"
-
-#, c-format
 msgid "could not delete reference %s: %s"
 msgstr "konnte Referenz %s nicht entfernen: %s"
 
@@ -19625,6 +19815,76 @@
 msgstr "konnte Referenzen nicht entfernen: %s"
 
 #, c-format
+msgid "refname is dangerous: %s"
+msgstr "Referenzname ist gefährlich: %s"
+
+#, c-format
+msgid "trying to write ref '%s' with nonexistent object %s"
+msgstr "Versuch, Referenz '%s' mit nicht existierendem Objekt %s zu schreiben"
+
+#, c-format
+msgid "trying to write non-commit object %s to branch '%s'"
+msgstr "Versuch, Nicht-Commit-Objekt %s in Branch '%s' zu schreiben"
+
+#, c-format
+msgid ""
+"multiple updates for 'HEAD' (including one via its referent '%s') are not "
+"allowed"
+msgstr ""
+"mehrere Aktualisierungen für 'HEAD' (einschließlich einer über seinen "
+"Referenten '%s') sind nicht erlaubt"
+
+#, c-format
+msgid "cannot lock ref '%s': unable to resolve reference '%s'"
+msgstr ""
+"kann Referenz '%s' nicht sperren: Referenz '%s' kann nicht aufgelöst werden"
+
+#, c-format
+msgid "cannot lock ref '%s': error reading reference"
+msgstr "kann Referenz '%s' nicht sperren: Fehler beim Lesen der Referenz"
+
+#, c-format
+msgid ""
+"multiple updates for '%s' (including one via symref '%s') are not allowed"
+msgstr ""
+"mehrere Aktualisierungen für '%s' (einschließlich einer über die symbolische "
+"Referenz '%s') sind nicht erlaubt"
+
+#, c-format
+msgid "cannot lock ref '%s': reference already exists"
+msgstr "kann Referenz '%s' nicht sperren: Referenz existiert bereits"
+
+#, c-format
+msgid "cannot lock ref '%s': reference is missing but expected %s"
+msgstr "kann Referenz '%s' nicht sperren: Referenz fehlt, aber bei %s erwartet"
+
+#, c-format
+msgid "cannot lock ref '%s': is at %s but expected %s"
+msgstr "kann Referenz '%s' nicht sperren: ist bei %s, aber bei %s erwartet"
+
+#, c-format
+msgid "reftable: transaction prepare: %s"
+msgstr "reftable: Transaktion vorbereiten: %s"
+
+#, c-format
+msgid "reftable: transaction failure: %s"
+msgstr "reftable: Transaktionsfehler: %s"
+
+#, c-format
+msgid "unable to compact stack: %s"
+msgstr "kann Stapel nicht verkleinern: %s"
+
+#, c-format
+msgid "refname %s not found"
+msgstr "Referenzname %s nicht gefunden"
+
+#, c-format
+msgid "refname %s is a symbolic ref, copying it is not supported"
+msgstr ""
+"Referenzname %s ist eine symbolische Referenz, Kopieren wird nicht "
+"unterstützt"
+
+#, c-format
 msgid "invalid refspec '%s'"
 msgstr "ungültige Refspec '%s'"
 
@@ -19633,6 +19893,10 @@
 msgstr "Ungültiges Quoting beim \"push-option\"-Wert: '%s'"
 
 #, c-format
+msgid "unknown value for object-format: %s"
+msgstr "unbekannter Wert für Objektformat: %s"
+
+#, c-format
 msgid "%sinfo/refs not valid: is this a git repository?"
 msgstr "%sinfo/refs nicht gültig: Ist das ein Git-Repository?"
 
@@ -19810,16 +20074,13 @@
 "\n"
 "Neither worked, so we gave up. You must fully qualify the ref."
 msgstr ""
-"Das angegebene Ziel ist kein vollständiger Referenzname (startet mit \"refs/"
-"\").\n"
-"Wir versuchten zu erraten, was Sie meinten, mit:\n"
+"Das angegebene Ziel ist kein vollständiger Referenzname (startet mit\n"
+"\"refs/\"). Wir versuchten zu erraten, was Sie meinten, mit:\n"
 "\n"
 "- Suche einer Referenz, die mit '%s' übereinstimmt, auf der Remote-Seite\n"
-"- Prüfung, ob die versendete <Quelle> ('%s') eine Referenz in \"refs/{heads,"
-"tags}\"\n"
-"  ist, in dessen Falle wir einen entsprechenden refs/{heads,tags} Präfix "
-"auf\n"
-"  der Remote-Seite hinzufügen würden.\n"
+"- Prüfung, ob die versendete <Quelle> ('%s') eine Referenz in\n"
+"  \"refs/{heads,tags}/\" ist, in dessen Falle wir einen entsprechenden\n"
+"  refs/{heads,tags}/ Präfix auf der Remote-Seite hinzufügen würden.\n"
 "\n"
 "Keines hat funktioniert, sodass wir aufgegeben haben. Sie müssen die\n"
 "Referenz mit vollqualifizierten Namen angeben."
@@ -20089,8 +20350,19 @@
 msgstr "resolve-undo zeichnet `%s` auf, das fehlt"
 
 #, c-format
-msgid "could not get commit for ancestry-path argument %s"
-msgstr "konnte kein Commit für das Argument ancestry-path %s erhalten"
+msgid "%s exists but is a symbolic ref"
+msgstr "%s existiert, ist aber eine symbolische Referenz"
+
+msgid ""
+"--merge requires one of the pseudorefs MERGE_HEAD, CHERRY_PICK_HEAD, "
+"REVERT_HEAD or REBASE_HEAD"
+msgstr ""
+"--merge erfordert einen der Pseudoreferenzen MERGE_HEAD, CHERRY_PICK_HEAD, "
+"REVERT_HEAD oder REBASE_HEAD"
+
+#, c-format
+msgid "could not get commit for --ancestry-path argument %s"
+msgstr "konnte keinen Commit für das Argument --ancestry-path erhalten %s"
 
 msgid "--unpacked=<packfile> no longer supported"
 msgstr "--unpacked=<Pack-Datei> wird nicht länger unterstützt"
@@ -20378,6 +20650,21 @@
 msgstr "Unbekannte Aktion: %d"
 
 msgid ""
+"Resolve all conflicts manually, mark them as resolved with\n"
+"\"git add/rm <conflicted_files>\", then run \"git rebase --continue\".\n"
+"You can instead skip this commit: run \"git rebase --skip\".\n"
+"To abort and get back to the state before \"git rebase\", run \"git rebase --"
+"abort\"."
+msgstr ""
+"Lösen Sie alle Konflikte manuell auf, markieren Sie diese mit\n"
+"\"git add/rm <konfliktbehaftete_Dateien>\" und führen Sie dann\n"
+"\"git rebase --continue\" aus.\n"
+"Sie können auch stattdessen diesen Commit auslassen, indem\n"
+"Sie \"git rebase --skip\" ausführen.\n"
+"Um abzubrechen und zurück zum Zustand vor \"git rebase\" zu gelangen,\n"
+"führen Sie \"git rebase --abort\" aus."
+
+msgid ""
 "after resolving the conflicts, mark the corrected paths\n"
 "with 'git add <paths>' or 'git rm <paths>'"
 msgstr ""
@@ -20605,10 +20892,6 @@
 msgstr "Konnte %s nicht aktualisieren."
 
 #, c-format
-msgid "could not parse commit %s"
-msgstr "Konnte Commit %s nicht parsen."
-
-#, c-format
 msgid "could not parse parent commit %s"
 msgstr "Konnte Eltern-Commit %s nicht parsen."
 
@@ -20714,10 +20997,6 @@
 msgstr "ungültiger Befehl '%.*s'"
 
 #, c-format
-msgid "%s does not accept arguments: '%s'"
-msgstr "%s akzeptiert keine Argumente: '%s'"
-
-#, c-format
 msgid "missing arguments for %s"
 msgstr "Fehlende Argumente für %s."
 
@@ -21004,6 +21283,9 @@
 msgid "Autostash exists; creating a new stash entry."
 msgstr "Automatischer Stash existiert; ein neuer Stash-Eintrag wird erstellt."
 
+msgid "autostash reference is a symref"
+msgstr "Referenz für autostash ist eine symbolische Referenz"
+
 msgid "could not detach HEAD"
 msgstr "konnte HEAD nicht loslösen"
 
@@ -21180,6 +21462,10 @@
 "Konnte Arbeitsverzeichnis mit ungültiger Konfiguration nicht einrichten."
 
 #, c-format
+msgid "'%s' already specified as '%s'"
+msgstr "'%s' bereits als '%s' angegeben"
+
+#, c-format
 msgid "Expected git repo version <= %d, found %d"
 msgstr "Erwartete Git-Repository-Version <= %d, %d gefunden"
 
@@ -21324,6 +21610,10 @@
 msgstr "ungültiger initialer Branchname: '%s'"
 
 #, c-format
+msgid "re-init: ignored --initial-branch=%s"
+msgstr "Neu-Initialisierung: --initial-branch=%s ignoriert"
+
+#, c-format
 msgid "unable to handle file type %d"
 msgstr "kann nicht mit Dateityp %d umgehen"
 
@@ -21334,15 +21624,17 @@
 msgid "attempt to reinitialize repository with different hash"
 msgstr "Versuch, das Repository mit einem anderen Hash zu reinitialisieren"
 
+msgid ""
+"attempt to reinitialize repository with different reference storage format"
+msgstr ""
+"Versuch, das Repository mit einem anderen Referenzspeicherformat neu zu "
+"initialisieren"
+
 #, c-format
 msgid "%s already exists"
 msgstr "%s existiert bereits"
 
 #, c-format
-msgid "re-init: ignored --initial-branch=%s"
-msgstr "Neu-Initialisierung: --initial-branch=%s ignoriert"
-
-#, c-format
 msgid "Reinitialized existing shared Git repository in %s%s\n"
 msgstr "Bestehendes verteiltes Git-Repository in %s%s neuinitialisiert\n"
 
@@ -21365,6 +21657,21 @@
 msgid "cannot use split index with a sparse index"
 msgstr "kann aufgeteilten Index nicht mit einem Sparse-Index benutzen"
 
+#. TRANSLATORS: The first %s is a command like "ls-tree".
+#, c-format
+msgid "bad %s format: element '%s' does not start with '('"
+msgstr "ungültiges %s-Format: Element '%s' beginnt nicht mit '('"
+
+#. TRANSLATORS: The first %s is a command like "ls-tree".
+#, c-format
+msgid "bad %s format: element '%s' does not end in ')'"
+msgstr "ungültiges %s-Format: Element '%s' endet nicht auf ')'"
+
+#. TRANSLATORS: %s is a command like "ls-tree".
+#, c-format
+msgid "bad %s format: %%%.*s"
+msgstr "ungültiges %s-Format: %%%.*s"
+
 #. TRANSLATORS: IEC 80000-13:2008 gibibyte
 #, c-format
 msgid "%u.%2.2u GiB"
@@ -21611,12 +21918,6 @@
 "Anzahl der Einträge im Cache-Verzeichnis, die ungültig gemacht werden sollen "
 "(Standardwert 0)"
 
-msgid "unhandled options"
-msgstr "unbehandelte Optionen"
-
-msgid "error preparing revisions"
-msgstr "Fehler beim Vorbereiten der Commits"
-
 #, c-format
 msgid "commit %s is not marked reachable"
 msgstr "Commit %s ist nicht als erreichbar gekennzeichnet."
@@ -21697,29 +21998,6 @@
 msgid "empty trailer token in trailer '%.*s'"
 msgstr "leerer Anhang-Token in Anhang '%.*s'"
 
-#, c-format
-msgid "could not read input file '%s'"
-msgstr "Konnte Eingabe-Datei '%s' nicht lesen"
-
-#, c-format
-msgid "could not stat %s"
-msgstr "Konnte '%s' nicht lesen"
-
-#, c-format
-msgid "file %s is not a regular file"
-msgstr "Datei '%s' ist keine reguläre Datei"
-
-#, c-format
-msgid "file %s is not writable by user"
-msgstr "Datei %s ist vom Benutzer nicht beschreibbar."
-
-msgid "could not open temporary file"
-msgstr "konnte temporäre Datei '%s' nicht öffnen"
-
-#, c-format
-msgid "could not rename temporary file to %s"
-msgstr "konnte temporäre Datei nicht zu %s umbenennen"
-
 msgid "full write to remote helper failed"
 msgstr "Vollständiges Schreiben zu Remote-Helper fehlgeschlagen."
 
@@ -21772,9 +22050,6 @@
 msgid "invalid remote service path"
 msgstr "ungültiger Remote-Service Pfad."
 
-msgid "operation not supported by protocol"
-msgstr "die Operation wird von dem Protokoll nicht unterstützt"
-
 #, c-format
 msgid "can't connect to subservice %s"
 msgstr "kann keine Verbindung zu Subservice %s herstellen"
@@ -21821,8 +22096,8 @@
 msgstr "Remote-Helper unterstützt kein Push; Refspec benötigt"
 
 #, c-format
-msgid "helper %s does not support 'force'"
-msgstr "Remote-Helper %s unterstützt kein 'force'."
+msgid "helper %s does not support '--force'"
+msgstr "Helper %s unterstützt '--force' nicht"
 
 msgid "couldn't run fast-export"
 msgstr "Konnte \"fast-export\" nicht ausführen."
@@ -21905,10 +22180,6 @@
 msgstr "Unterstützung für Protokoll v2 noch nicht implementiert."
 
 #, c-format
-msgid "unknown value for config '%s': %s"
-msgstr "Unbekannter Wert für Konfiguration '%s': %s"
-
-#, c-format
 msgid "transport '%s' not allowed"
 msgstr "Übertragungsart '%s' nicht erlaubt."
 
@@ -21961,6 +22232,9 @@
 msgid "could not retrieve server-advertised bundle-uri list"
 msgstr "konnte die vom Server angekündigte bundle-uri-Liste nicht abrufen"
 
+msgid "operation not supported by protocol"
+msgstr "die Operation wird von dem Protokoll nicht unterstützt"
+
 msgid "too-short tree object"
 msgstr "zu kurzes Tree-Objekt"
 
@@ -22256,6 +22530,10 @@
 msgid "invalid '..' path segment"
 msgstr "ungültiges '..' Pfadsegment"
 
+#, c-format
+msgid "error: unable to format message: %s\n"
+msgstr "Fehler: Meldung kann nicht formatiert werden: %s\n"
+
 msgid "usage: "
 msgstr "Verwendung: "
 
@@ -22849,6 +23127,10 @@
 msgstr ""
 "%s nicht möglich: Die Staging-Area enthält nicht committete Änderungen."
 
+#, c-format
+msgid "unknown style '%s' given for '%s'"
+msgstr "unbekannter Stil '%s' für '%s' angegeben"
+
 msgid ""
 "Error: Your local changes to the following files would be overwritten by "
 "merge"
diff --git a/po/fr.po b/po/fr.po
index ee2e610..837a695 100644
--- a/po/fr.po
+++ b/po/fr.po
@@ -80,8 +80,8 @@
 msgstr ""
 "Project-Id-Version: git\n"
 "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2023-11-08 04:57+0000\n"
-"PO-Revision-Date: 2023-11-11 10:00+0100\n"
+"POT-Creation-Date: 2024-04-16 22:57+0000\n"
+"PO-Revision-Date: 2024-04-20 17:11+0800\n"
 "Last-Translator: Cédric Malard <c.malard-git@valdun.net>\n"
 "Language-Team: Jean-Noël Avila <jn.avila@free.fr>\n"
 "Language: fr\n"
@@ -576,12 +576,12 @@
 "---\n"
 "To remove '%c' lines, make them ' ' lines (context).\n"
 "To remove '%c' lines, delete them.\n"
-"Lines starting with %c will be removed.\n"
+"Lines starting with %s will be removed.\n"
 msgstr ""
 "---\n"
 "Pour éliminer les lignes '%c', rendez-les ' ' (contexte).\n"
 "Pour éliminer les lignes '%c', effacez-les.\n"
-"Les lignes commençant par %c seront éliminées.\n"
+"Les lignes commençant par %s seront éliminées.\n"
 
 msgid ""
 "If it does not apply cleanly, you will be given an opportunity to\n"
@@ -628,6 +628,7 @@
 "/ - search for a hunk matching the given regex\n"
 "s - split the current hunk into smaller hunks\n"
 "e - manually edit the current hunk\n"
+"p - print the current hunk\n"
 "? - print help\n"
 msgstr ""
 "j - laisser cette section non décidée et aller à la suivante non-décidée\n"
@@ -638,6 +639,7 @@
 "/ - rechercher une section correspondant à une regex donnée\n"
 "s - découper la section en sections plus petites\n"
 "e - éditer manuellement la section actuelle\n"
+"p - afficher la section actuelle\n"
 "? - afficher l'aide\n"
 
 msgid "No previous hunk"
@@ -700,8 +702,8 @@
 "Désactivez ce message avec \"git config advice.%s false\""
 
 #, c-format
-msgid "%shint: %.*s%s\n"
-msgstr "%sastuce: %.*s%s\n"
+msgid "%shint:%s%.*s%s\n"
+msgstr "%sastuce :%s%.*s%s\n"
 
 msgid "Cherry-picking is not possible because you have unmerged files."
 msgstr "Impossible de picorer car vous avez des fichiers non fusionnés."
@@ -1526,6 +1528,10 @@
 msgstr "Option --output inattendue"
 
 #, c-format
+msgid "extra command line parameter '%s'"
+msgstr "paramètre de commande supplémentaire '%s'"
+
+#, c-format
 msgid "Unknown archive format '%s'"
 msgstr "Format d'archive inconnu '%s'"
 
@@ -1571,6 +1577,14 @@
 msgstr "mauvais --attr-source ou GIT_ATTR_SOURCE"
 
 #, c-format
+msgid "unable to stat '%s'"
+msgstr "fstat de '%s' impossible"
+
+#, c-format
+msgid "unable to read %s"
+msgstr "impossible de lire %s"
+
+#, c-format
 msgid "Badly quoted content in file '%s': %s"
 msgstr "Contenu mal cité dans le fichier '%s' : %s"
 
@@ -1789,6 +1803,9 @@
 msgid "'%s' is not a valid branch name"
 msgstr "'%s' n'est pas un nom de branche valide"
 
+msgid "See `man git check-ref-format`"
+msgstr "Voir `man git check-ref-format`"
+
 #, c-format
 msgid "a branch named '%s' already exists"
 msgstr "Une branche nommée '%s' existe déjà"
@@ -1988,14 +2005,8 @@
 msgid "adding embedded git repository: %s"
 msgstr "dépôt git embarqué ajouté : %s"
 
-msgid ""
-"Use -f if you really want to add them.\n"
-"Turn this message off by running\n"
-"\"git config advice.addIgnoredFile false\""
-msgstr ""
-"Utilisez -f si vous voulez vraiment les ajouter.\n"
-"Éliminez ce message en lançant\n"
-"\"git config advice.addIgnoredFile false\""
+msgid "Use -f if you really want to add them."
+msgstr "Utilisez -f si vous voulez vraiment les ajouter"
 
 msgid "adding files failed"
 msgstr "échec de l'ajout de fichiers"
@@ -2014,14 +2025,8 @@
 msgid "Nothing specified, nothing added.\n"
 msgstr "Rien de spécifié, rien n'a été ajouté.\n"
 
-msgid ""
-"Maybe you wanted to say 'git add .'?\n"
-"Turn this message off by running\n"
-"\"git config advice.addEmptyPathspec false\""
-msgstr ""
-"Peut-être avez-vous voulu dire 'git add .' ?\n"
-"Éliminez ce message en lançant\n"
-"\"git config advice.addEmptyPathspec false\""
+msgid "Maybe you wanted to say 'git add .'?"
+msgstr "Vous vouliez sûrement utiliser 'git add .' ?"
 
 msgid "index file corrupt"
 msgstr "fichier d'index corrompu"
@@ -2098,18 +2103,19 @@
 msgstr "Échec de découpage des patchs."
 
 #, c-format
-msgid "When you have resolved this problem, run \"%s --continue\"."
-msgstr "Quand vous avez résolu ce problème, lancez \"%s --continue\"."
+msgid "When you have resolved this problem, run \"%s --continue\".\n"
+msgstr "Quand vous avez résolu ce problème, lancez \"%s --continue\".\n"
 
 #, c-format
-msgid "If you prefer to skip this patch, run \"%s --skip\" instead."
-msgstr "Si vous préférez plutôt sauter ce patch, lancez \"%s --skip\"."
+msgid "If you prefer to skip this patch, run \"%s --skip\" instead.\n"
+msgstr "Si vous préférez plutôt sauter cette rustine, lancez \"%s --skip\".\n"
 
 #, c-format
-msgid "To record the empty patch as an empty commit, run \"%s --allow-empty\"."
+msgid ""
+"To record the empty patch as an empty commit, run \"%s --allow-empty\".\n"
 msgstr ""
 "Pour enregistrer la rustine vide comme un commit vide, lancez \"%s --allow-"
-"empty\"."
+"empty\".\n"
 
 #, c-format
 msgid "To restore the original branch and stop patching, run \"%s --abort\"."
@@ -2874,12 +2880,12 @@
 msgstr "impossible de rechercher l'objet commit pour '%s'"
 
 #, c-format
-msgid ""
-"the branch '%s' is not fully merged.\n"
-"If you are sure you want to delete it, run 'git branch -D %s'"
-msgstr ""
-"la branche '%s' n'est pas totalement fusionnée.\n"
-"Si vous souhaitez réellement la supprimer, lancez 'git branch -D %s'"
+msgid "the branch '%s' is not fully merged"
+msgstr "la branche '%s' n'est pas complètement fusionnée"
+
+#, c-format
+msgid "If you are sure you want to delete it, run 'git branch -D %s'"
+msgstr "Si vous souhaitez réellement la supprimer, lancez 'git branch -D %s'"
 
 msgid "update of config-file failed"
 msgstr "échec de la mise à jour du fichier de configuration"
@@ -2983,11 +2989,11 @@
 msgid ""
 "Please edit the description for the branch\n"
 "  %s\n"
-"Lines starting with '%c' will be stripped.\n"
+"Lines starting with '%s' will be stripped.\n"
 msgstr ""
 "Veuillez éditer la description de la branche\n"
 "  %s\n"
-"Les lignes commençant par '%c' seront ignorées.\n"
+"Les lignes commençant par '%s' seront ignorées.\n"
 
 msgid "Generic options"
 msgstr "Options génériques"
@@ -3190,11 +3196,12 @@
 msgstr "lancé hors d'un dépôt git - aucun crochet à montrer\n"
 
 msgid ""
-"git bugreport [(-o | --output-directory) <path>] [(-s | --suffix) <format>]\n"
+"git bugreport [(-o | --output-directory) <path>]\n"
+"              [(-s | --suffix) <format> | --no-suffix]\n"
 "              [--diagnose[=<mode>]]"
 msgstr ""
-"git bugreport [(-o | --output-directory) <chemin>] [(-s | --suffix) "
-"<format>]\n"
+"git bugreport [(-o | --output-directory) <chemin>]\n"
+"              [(-s | --suffix) <format> | --no-suffix]\n"
 "              [--diagnose[=<mode>]]"
 
 msgid ""
@@ -3686,6 +3693,10 @@
 msgid "path '%s' is unmerged"
 msgstr "le chemin '%s' n'est pas fusionné"
 
+#, c-format
+msgid "unable to read tree (%s)"
+msgstr "impossible de lire l'arbre (%s)"
+
 msgid "you need to resolve your current index first"
 msgstr "vous devez d'abord résoudre votre index courant"
 
@@ -3919,6 +3930,10 @@
 msgid "missing branch or commit argument"
 msgstr "argument de branche ou de commit manquant"
 
+#, c-format
+msgid "unknown conflict style '%s'"
+msgstr "style de conflit inconnu '%s'"
+
 msgid "perform a 3-way merge with the new branch"
 msgstr "effectuer une fusion à 3 points avec la nouvelle branche"
 
@@ -3937,8 +3952,8 @@
 msgid "new-branch"
 msgstr "nouvelle branche"
 
-msgid "new unparented branch"
-msgstr "nouvelle branche sans parent"
+msgid "new unborn branch"
+msgstr "nouvelle branche non née"
 
 msgid "update ignored files (default)"
 msgstr "mettre à jour les fichiers ignorés (par défaut)"
@@ -4178,22 +4193,9 @@
 msgid "remove only ignored files"
 msgstr "supprimer seulement les fichiers ignorés"
 
-msgid ""
-"clean.requireForce set to true and neither -i, -n, nor -f given; refusing to "
-"clean"
+msgid "clean.requireForce is true and -f not given: refusing to clean"
 msgstr ""
-"clean.requireForce positionné à true et ni -i, -n ou -f fourni ; refus de "
-"nettoyer"
-
-msgid ""
-"clean.requireForce defaults to true and neither -i, -n, nor -f given; "
-"refusing to clean"
-msgstr ""
-"clean.requireForce à true par défaut et ni -i, -n ou -f fourni ; refus de "
-"nettoyer"
-
-msgid "-x and -X cannot be used together"
-msgstr "-x et -X ne peuvent pas être utilisés ensemble"
+"clean.requireForce positionné est true et -f non fourni ; refus de nettoyer"
 
 msgid "git clone [<options>] [--] <repo> [<dir>]"
 msgstr "git clone [<options>] [--] <dépôt> [<répertoire>]"
@@ -4207,8 +4209,8 @@
 msgid "create a bare repository"
 msgstr "créer un dépôt nu"
 
-msgid "create a mirror repository (implies bare)"
-msgstr "créer un dépôt miroir (implique dépôt nu)"
+msgid "create a mirror repository (implies --bare)"
+msgstr "créer un dépôt miroir (implique --bare)"
 
 msgid "to clone from a local repository"
 msgstr "pour cloner depuis un dépôt local"
@@ -4285,6 +4287,9 @@
 msgid "separate git dir from working tree"
 msgstr "séparer le répertoire git de la copie de travail"
 
+msgid "specify the reference format to use"
+msgstr "spécifier le format de réference à utiliser"
+
 msgid "key=value"
 msgstr "clé=valeur"
 
@@ -4407,12 +4412,9 @@
 msgid "You must specify a repository to clone."
 msgstr "Vous devez spécifier un dépôt à cloner."
 
-msgid ""
-"--bundle-uri is incompatible with --depth, --shallow-since, and --shallow-"
-"exclude"
-msgstr ""
-"--bundle-uri est incompatible avec --depth, --shallow-since, et --shallow-"
-"exclude"
+#, c-format
+msgid "unknown ref storage format '%s'"
+msgstr "Format de stockage de réf inconnu '%s'"
 
 #, c-format
 msgid "repository '%s' does not exist"
@@ -4532,6 +4534,10 @@
 msgid "padding space between columns"
 msgstr "remplissage d'espace entre les colonnes"
 
+#, c-format
+msgid "%s must be non-negative"
+msgstr "%s doit être non négatif"
+
 msgid "--command must be the first argument"
 msgstr "--command doit être le premier argument"
 
@@ -4546,14 +4552,14 @@
 "--stdin-commits]\n"
 "                       [--changed-paths] [--[no-]max-new-filters <n>] [--"
 "[no-]progress]\n"
-"                       <split options>"
+"                       <split-options>"
 msgstr ""
 "git commit-graph write [--object-dir <rép>] [--append]\n"
 "                       [--split[=<stratégie>]] [--reachable | --stdin-packs "
 "| --stdin-commits]\n"
 "                       [--changed-paths] [--[no-]max-new-filters <n>] [--"
 "[no-]progress]\n"
-"                       <options de division>"
+"                       <options-de-division>"
 
 msgid "dir"
 msgstr "répertoire"
@@ -4845,38 +4851,38 @@
 #, c-format
 msgid ""
 "Please enter the commit message for your changes. Lines starting\n"
-"with '%c' will be ignored.\n"
+"with '%s' will be ignored.\n"
 msgstr ""
 "Veuillez saisir le message de validation pour vos modifications. Les lignes\n"
-"commençant par '%c' seront ignorées.\n"
+"commençant par '%s' seront ignorées.\n"
 
 #, 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"
+"with '%s' will be ignored, and an empty message aborts the commit.\n"
 msgstr ""
 "Veuillez saisir le message de validation pour vos modifications. Les lignes\n"
-"commençant par '%c' seront ignorées, et un message vide abandonne la "
+"commençant par '%s' seront ignorées, et un message vide abandonne la "
 "validation.\n"
 
 #, 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"
+"with '%s' will be kept; you may remove them yourself if you want to.\n"
 msgstr ""
 "Veuillez saisir le message de validation pour vos modifications. Les lignes "
 "commençant\n"
-"par '%c' seront conservées ; vous pouvez les supprimer vous-même si vous le "
+"par '%s' seront conservées ; vous pouvez les supprimer vous-même si vous le "
 "souhaitez.\n"
 
 #, 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"
+"with '%s' will be kept; you may remove them yourself if you want to.\n"
 "An empty message aborts the commit.\n"
 msgstr ""
 "Veuillez saisir le message de validation pour vos modifications. Les lignes\n"
-"commençant par '%c' seront conservées ; vous pouvez les supprimer vous-même\n"
+"commençant par '%s' seront conservées ; vous pouvez les supprimer vous-même\n"
 "si vous le souhaitez. Un message vide abandonne la validation.\n"
 
 msgid ""
@@ -5328,6 +5334,11 @@
 msgid "with --get, use default value when missing entry"
 msgstr "avec --get, utiliser le valeur par défaut quand l'entrée n'existe pas"
 
+msgid "human-readable comment string (# will be prepended as needed)"
+msgstr ""
+"chaîne des commentaires lisibles par l'utilisateur (# sera ajouté en préfixe "
+"selon les besoins)"
+
 #, c-format
 msgid "wrong number of arguments, should be %d"
 msgstr "mauvais nombre d'arguments, devrait être %d"
@@ -5422,6 +5433,9 @@
 msgid "--default is only applicable to --get"
 msgstr "--default n'est applicable qu'avec --get"
 
+msgid "--comment is only applicable to add/set/replace operations"
+msgstr "--comment n'est applicable qu'avec les opérations add/set/replace"
+
 msgid "--fixed-value only applies with 'value-pattern'"
 msgstr "--fixed-value ne s'applique qu'à 'motif-de-valeur'"
 
@@ -6278,6 +6292,9 @@
 msgid "read reference patterns from stdin"
 msgstr "lire les motifs de références depuis l'entrée standard"
 
+msgid "also include HEAD ref and pseudorefs"
+msgstr "inclure aussi la référence HEAD et les pseudo-réfs"
+
 msgid "unknown arguments supplied with --stdin"
 msgstr "arguments inconnus fournis avec l'option --stdin"
 
@@ -6903,8 +6920,8 @@
 msgstr "pas de support des fils, ignore %s"
 
 #, c-format
-msgid "unable to read tree (%s)"
-msgstr "impossible de lire l'arbre (%s)"
+msgid "unable to read tree %s"
+msgstr "impossible de lire l'arbre %s"
 
 #, c-format
 msgid "unable to grep from object of type %s"
@@ -7325,10 +7342,6 @@
 msgstr "COLLISION SHA1 TROUVÉE AVEC %s !"
 
 #, c-format
-msgid "unable to read %s"
-msgstr "impossible de lire %s"
-
-#, c-format
 msgid "cannot read existing object info %s"
 msgstr "impossible de lire l'information existante de l'objet %s"
 
@@ -7469,12 +7482,14 @@
 msgid ""
 "git init [-q | --quiet] [--bare] [--template=<template-directory>]\n"
 "         [--separate-git-dir <git-dir>] [--object-format=<format>]\n"
+"         [--ref-format=<format>]\n"
 "         [-b <branch-name> | --initial-branch=<branch-name>]\n"
 "         [--shared[=<permissions>]] [<directory>]"
 msgstr ""
-"git init [-q | --quiet] [--bare] [--template=<répertoire-modèle>]\n"
-"         [--separate-git-dir <rép-git>] [--object-format=<format>]\\n\"\n"
-"         [-b <nom-de-branche> | --initial-branch=<nom-de-branche>]\\n\"\n"
+"git init [-q | --quiet] [--bare] [--template=<répertoire-de-modèles>]\n"
+"         [--separate-git-dir <rép-git>] [--object-format=<format>]\n"
+"         [--ref-format=<format>]\n"
+"         [-b <nom-de-branch> | --initial-branch=<nom-de-branche>]\n"
 "         [--shared[=<permissions>]] [<répertoire>]"
 
 msgid "permissions"
@@ -7517,7 +7532,7 @@
 
 msgid ""
 "git interpret-trailers [--in-place] [--trim-empty]\n"
-"                       [(--trailer (<key>|<keyAlias>)[(=|:)<value>])...]\n"
+"                       [(--trailer (<key>|<key-alias>)[(=|:)<value>])...]\n"
 "                       [--parse] [<file>...]"
 msgstr ""
 "git interpret-trailers [--in-place] [--trim-empty]\n"
@@ -7525,6 +7540,32 @@
 "[(=|:)<valeur>])...]\n"
 "                       [--parse] [<fichier>...]"
 
+#, c-format
+msgid "could not stat %s"
+msgstr "stat impossible de %s"
+
+#, c-format
+msgid "file %s is not a regular file"
+msgstr "%s n'est pas un fichier régulier"
+
+#, c-format
+msgid "file %s is not writable by user"
+msgstr "le fichier %s n'est pas inscriptible par l'utilisateur"
+
+msgid "could not open temporary file"
+msgstr "impossible de créer un fichier temporaire"
+
+#, c-format
+msgid "could not read input file '%s'"
+msgstr "impossible de lire le fichier d'entrée '%s'"
+
+msgid "could not read from stdin"
+msgstr "impossible de lire depuis l'entrée standard"
+
+#, c-format
+msgid "could not rename temporary file to %s"
+msgstr "impossible de renommer un fichier temporaire en %s"
+
 msgid "edit files in place"
 msgstr "éditer les fichiers sur place"
 
@@ -7930,18 +7971,6 @@
 msgid "could not get object info about '%s'"
 msgstr "impossible d'obtenir l'information d'objet pour '%s'"
 
-#, c-format
-msgid "bad ls-files format: element '%s' does not start with '('"
-msgstr "mauvais format ls-files : l'élément '%s' ne commence pas par '('"
-
-#, c-format
-msgid "bad ls-files format: element '%s' does not end in ')'"
-msgstr "mauvais format ls-files : l'élément '%s' ne se termine pas par ')'"
-
-#, c-format
-msgid "bad ls-files format: %%%.*s"
-msgstr "mauvais format ls-files : %%%.*s"
-
 msgid "git ls-files [<options>] [<file>...]"
 msgstr "git ls-files [<options>] [<fichier>...]"
 
@@ -8077,18 +8106,6 @@
 msgid "git ls-tree [<options>] <tree-ish> [<path>...]"
 msgstr "git ls-tree [<options>] <arbre ou apparenté> [<chemin>...]"
 
-#, c-format
-msgid "bad ls-tree format: element '%s' does not start with '('"
-msgstr "mauvais format ls-tree : l'élément '%s' ne commence pas par '('"
-
-#, c-format
-msgid "bad ls-tree format: element '%s' does not end in ')'"
-msgstr "mauvais format ls-tree : l'élément '%s' ne se termine pas ')'"
-
-#, c-format
-msgid "bad ls-tree format: %%%.*s"
-msgstr "mauvais format ls-tree : %%%.*s"
-
 msgid "only show trees"
 msgstr "afficher seulement les arbres"
 
@@ -8204,6 +8221,13 @@
 "git merge-file [<options>] [-L <nom1> [-L <orig> [-L <nom2>]]] <fichier1> "
 "<fichier-orig> <fichier2>"
 
+msgid ""
+"option diff-algorithm accepts \"myers\", \"minimal\", \"patience\" and "
+"\"histogram\""
+msgstr ""
+"l'option diff-algorithm accept \"myers\", \"minimal\", \"patience\" et "
+"\"histogram\""
+
 msgid "send results to standard output"
 msgstr "envoyer les résultats sur la sortie standard"
 
@@ -8225,6 +8249,12 @@
 msgid "for conflicts, use a union version"
 msgstr "pour les conflits, utiliser l'ensemble des versions"
 
+msgid "<algorithm>"
+msgstr "<algorithme>"
+
+msgid "choose a diff algorithm"
+msgstr "choisir un algorithme de différence"
+
 msgid "for conflicts, use this marker size"
 msgstr "pour les conflits, utiliser cette taille de marqueur"
 
@@ -8266,6 +8296,10 @@
 msgid "Merging %s with %s\n"
 msgstr "Fusion de %s avec %s\n"
 
+#, c-format
+msgid "could not parse as tree '%s'"
+msgstr "impossible d'analyser '%s' comme un arbre"
+
 msgid "not something we can merge"
 msgstr "pas possible de fusionner ceci"
 
@@ -8315,9 +8349,6 @@
 msgid "unknown strategy option: -X%s"
 msgstr "option de stratégie inconnue : -X%s"
 
-msgid "--merge-base is incompatible with --stdin"
-msgstr "--merge-base est incompatible avec --stdin"
-
 #, c-format
 msgid "malformed input line: '%s'."
 msgstr "ligne en entrée malformée : '%s'."
@@ -8476,10 +8507,10 @@
 
 #, c-format
 msgid ""
-"Lines starting with '%c' will be ignored, and an empty message aborts\n"
+"Lines starting with '%s' will be ignored, and an empty message aborts\n"
 "the commit.\n"
 msgstr ""
-"Les lignes commençant par '%c' seront ignorées, et un message vide\n"
+"Les lignes commençant par '%s' seront ignorées, et un message vide\n"
 "abandonne la validation.\n"
 
 msgid "Empty commit message."
@@ -8641,9 +8672,6 @@
 msgid "object '%s' tagged as '%s', but is a '%s' type"
 msgstr "l'objet '%s' étiqueté comme '%s', mais est de type '%s'"
 
-msgid "could not read from stdin"
-msgstr "impossible de lire depuis l'entrée standard"
-
 msgid "tag on stdin did not pass our strict fsck check"
 msgstr "l'étiquette sur stdin n'a pas passé le test strict fsck"
 
@@ -9265,6 +9293,10 @@
 msgstr "inconsistance dans le compte de delta"
 
 #, c-format
+msgid "invalid pack.allowPackReuse value: '%s'"
+msgstr "valeur invalide de pack.allowPackReuse : '%s'"
+
+#, c-format
 msgid ""
 "value of uploadpack.blobpackfileuri must be of the form '<object-hash> <pack-"
 "hash> <uri>' (got '%s')"
@@ -9527,10 +9559,10 @@
 #, c-format
 msgid ""
 "Total %<PRIu32> (delta %<PRIu32>), reused %<PRIu32> (delta %<PRIu32>), pack-"
-"reused %<PRIu32>"
+"reused %<PRIu32> (from %<PRIuMAX>)"
 msgstr ""
 "Total %<PRIu32> (delta %<PRIu32>), réutilisés %<PRIu32> (delta %<PRIu32>), "
-"réutilisés du pack %<PRIu32>"
+"réutilisés du paquet %<PRIu32> (depuis %<PRIuMAX>)"
 
 msgid ""
 "'git pack-redundant' is nominated for removal.\n"
@@ -9549,10 +9581,11 @@
 msgstr "refus de lancer sans --i-still-use-this"
 
 msgid ""
-"git pack-refs [--all] [--no-prune] [--include <pattern>] [--exclude "
+"git pack-refs [--all] [--no-prune] [--auto] [--include <pattern>] [--exclude "
 "<pattern>]"
 msgstr ""
-"git pack-refs [--all] [--no-prune] [--include <motif>] [--exclude <motif>]"
+"git pack-refs [--all] [--no-prune] [--auto] [--include <motif>] [--exclude "
+"<motif>]"
 
 msgid "pack everything"
 msgstr "empaqueter tout"
@@ -9560,6 +9593,9 @@
 msgid "prune loose refs (default)"
 msgstr "élaguer les références perdues (défaut)"
 
+msgid "auto-pack refs as needed"
+msgstr "auto-empaqueter les réfs au besoin"
+
 msgid "references to include"
 msgstr "références à inclure"
 
@@ -10239,19 +10275,6 @@
 msgid "could not remove '%s'"
 msgstr "impossible de supprimer '%s'"
 
-msgid ""
-"Resolve all conflicts manually, mark them as resolved with\n"
-"\"git add/rm <conflicted_files>\", then run \"git rebase --continue\".\n"
-"You can instead skip this commit: run \"git rebase --skip\".\n"
-"To abort and get back to the state before \"git rebase\", run \"git rebase --"
-"abort\"."
-msgstr ""
-"Résolvez tous les conflits manuellement, marquez-les comme résolus avec\n"
-"\"git add/rm <fichier en conflit>\", puis lancez \"git rebase --continue\".\n"
-"Si vous préférez sauter ce commit, lancez \"git rebase --skip\". Pour "
-"arrêter\n"
-"et revenir à l'état antérieur à la commande, lancez \"git rebase --abort\"."
-
 #, c-format
 msgid ""
 "\n"
@@ -10282,13 +10305,16 @@
 msgstr ""
 "Les options d'apply et celles de merge ne peuvent pas être utilisées ensemble"
 
+msgid "--empty=ask is deprecated; use '--empty=stop' instead."
+msgstr "--empty=ask est obsolète ; utilisez '--empty=stop' à la place."
+
 #, c-format
 msgid ""
 "unrecognized empty type '%s'; valid values are \"drop\", \"keep\", and "
-"\"ask\"."
+"\"stop\"."
 msgstr ""
 "type vide non connu '%s' ; les valeurs valides sont \"drop\" (abandonner), "
-"\"keep\" (garder) et \"ask\" (demander)."
+"\"keep\" (garder) et \"stop\" (arrêter)."
 
 msgid ""
 "--rebase-merges with an empty string argument is deprecated and will stop "
@@ -10470,8 +10496,8 @@
 "Note : votre configuration `pull.rebase` peut aussi être 'preserve',\n"
 "qui n'est plus géré ; utilisez 'merges' à la place"
 
-msgid "No rebase in progress?"
-msgstr "Pas de rebasage en cours ?"
+msgid "no rebase in progress"
+msgstr "Pas de rebasage en cours"
 
 msgid "The --edit-todo action can only be used during interactive rebase."
 msgstr ""
@@ -10520,13 +10546,6 @@
 msgstr "l'option `C' attend un valeur numérique"
 
 msgid ""
-"apply options are incompatible with rebase.autoSquash.  Consider adding --no-"
-"autosquash"
-msgstr ""
-"les options d'application sont incompatibles avec rebase.autoSquash. "
-"Considérez l'ajout de --no-autosquash"
-
-msgid ""
 "apply options are incompatible with rebase.rebaseMerges.  Consider adding --"
 "no-rebase-merges"
 msgstr ""
@@ -10675,6 +10694,9 @@
 msgid "git reflog [show] [<log-options>] [<ref>]"
 msgstr "git reflog [show] [<options-de-journal>] [<réf>]"
 
+msgid "git reflog list"
+msgstr "git reflog list"
+
 msgid ""
 "git reflog expire [--expire=<time>] [--expire-unreachable=<time>]\n"
 "                  [--rewrite] [--updateref] [--stale-fix]\n"
@@ -10700,6 +10722,10 @@
 msgid "invalid timestamp '%s' given to '--%s'"
 msgstr "horodatage invalide '%s' fourni à '--%s'"
 
+#, c-format
+msgid "%s does not accept arguments: '%s'"
+msgstr "%s n'accepte pas d'argument : '%s'"
+
 msgid "do not actually prune any entries"
 msgstr "ne pas réellement élaguer des entrées"
 
@@ -10830,8 +10856,8 @@
 "\t d'utiliser --mirror=fetch ou --mirror=push à la place"
 
 #, c-format
-msgid "unknown mirror argument: %s"
-msgstr "argument miroir inconnu : %s"
+msgid "unknown --mirror argument: %s"
+msgstr "argument de --mirror inconnu : %s"
 
 msgid "fetch the remote branches"
 msgstr "rapatrier les branches distantes"
@@ -11206,6 +11232,9 @@
 msgstr ""
 "ne pas démarrer pack-objects pour ré-empaqueter les objects de prometteur"
 
+msgid "failed to feed promisor objects to pack-objects"
+msgstr "Échéc de la fourniture les objets du prometteur à pack-objects"
+
 msgid "repack: Expecting full hex object ID lines only from pack-objects."
 msgstr ""
 "repack : attente de lignes d'Id d'objets en hexa complet seulement depuis "
@@ -11535,6 +11564,77 @@
 msgid "only one pattern can be given with -l"
 msgstr "-l n'accepte qu'un motifs"
 
+msgid "need some commits to replay"
+msgstr "commits requis pour pouvoir rejouer"
+
+msgid "--onto and --advance are incompatible"
+msgstr "--onto et --advance sont incompatibles"
+
+msgid "all positive revisions given must be references"
+msgstr "toutes les révisions positives fournies doivent être des références"
+
+msgid "argument to --advance must be a reference"
+msgstr "l'argument de --advance doit être une référence"
+
+msgid ""
+"cannot advance target with multiple sources because ordering would be ill-"
+"defined"
+msgstr ""
+"impossible d'avancer la cible avec des sources multiples parce l'ordre ne "
+"serait pas total"
+
+msgid ""
+"cannot implicitly determine whether this is an --advance or --onto operation"
+msgstr ""
+"impossible de déterminer implicitement s'il y a une opération --advance ou --"
+"onto"
+
+msgid ""
+"cannot advance target with multiple source branches because ordering would "
+"be ill-defined"
+msgstr ""
+"impossible d'avancer la cible sur des branches sources multiples parce que "
+"l'ordre ne serait pas total"
+
+msgid "cannot implicitly determine correct base for --onto"
+msgstr "impossible de déterminer implicitement une base correcte pour --onto"
+
+msgid ""
+"(EXPERIMENTAL!) git replay ([--contained] --onto <newbase> | --advance "
+"<branch>) <revision-range>..."
+msgstr ""
+"(EXPERIMENTAL!) git replay ([--contained] --onto <nouvelle-base> | --advance "
+"<branche>) <plage-de-révision>..."
+
+msgid "make replay advance given branch"
+msgstr "faire rejouer en avançant la branche indiquée"
+
+msgid "replay onto given commit"
+msgstr "rejouer par-dessus le commit indiqué"
+
+msgid "advance all branches contained in revision-range"
+msgstr "avancer toutes les branches contenues dans la plage-de-révisions"
+
+msgid "option --onto or --advance is mandatory"
+msgstr "une option --onto ou --advance est obligatoire"
+
+#, c-format
+msgid ""
+"some rev walking options will be overridden as '%s' bit in 'struct rev_info' "
+"will be forced"
+msgstr ""
+"certaines options de parcours de révs seront surchargées car le bit '%s' "
+"dans 'struct rev_info' sera forcé"
+
+msgid "error preparing revisions"
+msgstr "erreur lors de la préparation des révisions"
+
+msgid "replaying down to root commit is not supported yet!"
+msgstr "rejouer jusqu'au commit racine n'est pas encore géré !"
+
+msgid "replaying merge commits is not supported yet!"
+msgstr "rejouer des commits de fusion n'est pas encore géré !"
+
 msgid ""
 "git rerere [clear | forget <pathspec>... | diff | status | remaining | gc]"
 msgstr ""
@@ -11742,19 +11842,17 @@
 msgid "--prefix requires an argument"
 msgstr "--prefix exige un argument"
 
+msgid "no object format specified"
+msgstr "aucun format d'objet spécifié"
+
+#, c-format
+msgid "unsupported object format: %s"
+msgstr "format d'objet non géré : %s"
+
 #, c-format
 msgid "unknown mode for --abbrev-ref: %s"
 msgstr "mode inconnu pour --abbrev-ref : %s"
 
-msgid "--exclude-hidden cannot be used together with --branches"
-msgstr "--exclude-hidden ne peut être utilisé avec --branches"
-
-msgid "--exclude-hidden cannot be used together with --tags"
-msgstr "--exclude-hidden ne peut pas être utilisé avec --tags"
-
-msgid "--exclude-hidden cannot be used together with --remotes"
-msgstr "--exclude-hidden ne peut pas être utilisé avec --remotes"
-
 msgid "this operation must be run in a work tree"
 msgstr "cette opération doit être effectuée dans un arbre de travail"
 
@@ -11832,8 +11930,8 @@
 msgid "allow commits with empty messages"
 msgstr "autoriser les validations avec des messages vides"
 
-msgid "keep redundant, empty commits"
-msgstr "garder les validations redondantes, vides"
+msgid "deprecated: use --empty=keep instead"
+msgstr "obsolète : utilisez --empty=keep à la place"
 
 msgid "use the 'reference' format to refer to commits"
 msgstr "utiliser le format 'reference' pour se référer aux commits"
@@ -12171,10 +12269,6 @@
 "afficher les références de l'entrée standard qui ne sont pas dans le dépôt "
 "local"
 
-#, c-format
-msgid "only one of '%s', '%s' or '%s' can be given"
-msgstr "les options '%s', '%s' et '%s' sont mutuellement exclusives"
-
 msgid ""
 "git sparse-checkout (init | list | set | add | reapply | disable | check-"
 "rules) [<options>]"
@@ -13207,25 +13301,25 @@
 "\n"
 "Write a message for tag:\n"
 "  %s\n"
-"Lines starting with '%c' will be ignored.\n"
+"Lines starting with '%s' will be ignored.\n"
 msgstr ""
 "\n"
 "Écrivez un message pour l'étiquette :\n"
 "  %s\n"
-"Les lignes commençant par '%c' seront ignorées.\n"
+"Les lignes commençant par '%s' seront ignorées.\n"
 
 #, c-format
 msgid ""
 "\n"
 "Write a message for tag:\n"
 "  %s\n"
-"Lines starting with '%c' will be kept; you may remove them yourself if you "
+"Lines starting with '%s' will be kept; you may remove them yourself if you "
 "want to.\n"
 msgstr ""
 "\n"
 "Écrivez un message pour l'étiquette :\n"
 "  %s\n"
-"Les lignes commençant par '%c' seront gardées ; vous pouvez les retirer vous-"
+"Les lignes commençant par '%s' seront gardées ; vous pouvez les retirer vous-"
 "même si vous le souhaitez.\n"
 
 msgid "unable to sign the tag"
@@ -13312,6 +13406,9 @@
 msgid "print only tags of the object"
 msgstr "afficher seulement les étiquettes de l'objet"
 
+msgid "could not start 'git column'"
+msgstr "impossible de démarrer 'git column'"
+
 #, c-format
 msgid "the '%s' option is only allowed in list mode"
 msgstr "l'option '%s' est autorisée seulement en mode de liste"
@@ -13567,13 +13664,12 @@
 msgid "fsmonitor disabled"
 msgstr "fsmonitor désactivé"
 
-msgid "git update-ref [<options>] -d <refname> [<old-val>]"
-msgstr "git update-ref [<options>] -d <nom-référence> [<ancienne-valeur>]"
+msgid "git update-ref [<options>] -d <refname> [<old-oid>]"
+msgstr "git update-ref [<options>] -d <nom-référence> [<ancien-oid>]"
 
-msgid "git update-ref [<options>]    <refname> <new-val> [<old-val>]"
+msgid "git update-ref [<options>]    <refname> <new-oid> [<old-oid>]"
 msgstr ""
-"git update-ref [<options>]    <nom-référence> <nouvelle-valeur> [<ancienne-"
-"valeur>]"
+"git update-ref [<options>]    <nom-référence> <nouvel-oid> [<ancien-oid>]"
 
 msgid "git update-ref [<options>] --stdin [-z]"
 msgstr "git update-ref [<options>] --stdin [-z]"
@@ -13673,28 +13769,28 @@
 
 #, c-format
 msgid ""
-"If you meant to create a worktree containing a new orphan branch\n"
+"If you meant to create a worktree containing a new unborn branch\n"
 "(branch with no commits) for this repository, you can do so\n"
 "using the --orphan flag:\n"
 "\n"
 "    git worktree add --orphan -b %s %s\n"
 msgstr ""
 "Si vous vouliez créer un arbre-de-travail contenant une nouvelle branche\n"
-"orpheline (une branche sans commit) pour ce dépôt, vous pouvez le faire\n"
+"non-née (une branche sans commit) pour ce dépôt, vous pouvez le faire\n"
 "en utilisant le drapeau --orphan :\n"
 "\n"
 "    git worktree add --orphan -b %s %s\n"
 
 #, c-format
 msgid ""
-"If you meant to create a worktree containing a new orphan branch\n"
+"If you meant to create a worktree containing a new unborn branch\n"
 "(branch with no commits) for this repository, you can do so\n"
 "using the --orphan flag:\n"
 "\n"
 "    git worktree add --orphan %s\n"
 msgstr ""
 "Si vous vouliez créer un arbre-de-travail contenant une nouvelle branche\n"
-"orpheline (une branche sans commit) pour ce dépôt, vous pouvez le faire\n"
+"non-née (une branche sans commit) pour ce dépôt, vous pouvez le faire\n"
 "en utilisant le drapeau --orphan :\n"
 "\n"
 "    git worktree add --orphan %s\n"
@@ -13757,6 +13853,10 @@
 msgstr "initialisation"
 
 #, c-format
+msgid "could not find created worktree '%s'"
+msgstr "impossible de trouver l'arbre-de-travail créé '%s'"
+
+#, c-format
 msgid "Preparing worktree (new branch '%s')"
 msgstr "Préparation de l'arbre de travail (nouvelle branche '%s')"
 
@@ -13797,10 +13897,6 @@
 "on arrête ; utilisez 'add -f' pour passe outre ou récupérer le distant en "
 "premier"
 
-#, c-format
-msgid "'%s' and '%s' cannot be used together"
-msgstr "'%s' et '%s' ne peuvent pas être utilisées ensemble"
-
 msgid "checkout <branch> even if already checked out in other worktree"
 msgstr ""
 "extraire la <branche> même si elle est déjà extraite dans une autre copie de "
@@ -13812,8 +13908,8 @@
 msgid "create or reset a branch"
 msgstr "créer ou réinitialiser une branche"
 
-msgid "create unborn/orphaned branch"
-msgstr "créer une branche non née/orpheline"
+msgid "create unborn branch"
+msgstr "créer une branche non née"
 
 msgid "populate the new working tree"
 msgstr "remplissage de la nouvelle copie de travail"
@@ -13835,11 +13931,9 @@
 msgstr "les options '%s', '%s' et '%s' ne peuvent pas être utilisées ensemble"
 
 #, c-format
-msgid "options '%s', and '%s' cannot be used together"
-msgstr "les options '%s' et '%s' ne peuvent pas être utilisées ensemble"
-
-msgid "<commit-ish>"
-msgstr "<commit-esque>"
+msgid "option '%s' and commit-ish cannot be used together"
+msgstr ""
+"l'option '%s' et des commit-esques ne peuvent pas être utilisés ensemble"
 
 msgid "added with --lock"
 msgstr "ajouté avec --lock"
@@ -14480,6 +14574,11 @@
 msgid "Create, list, delete refs to replace objects"
 msgstr "Créer, lister, supprimer des référence pour remplacer des objets"
 
+msgid "EXPERIMENTAL: Replay commits on a new base, works with bare repos too"
+msgstr ""
+"EXPÉRIMENTAL ; rejoue des commits sur une nouvelle base, fonctionne aussi "
+"avec les dépôts nus"
+
 msgid "Generates a summary of pending changes"
 msgstr "Générer une résumé des modifications en attentes"
 
@@ -14722,6 +14821,35 @@
 msgid "commit-graph file is too small"
 msgstr "le graphe de commit est trop petit"
 
+msgid "commit-graph oid fanout chunk is wrong size"
+msgstr ""
+"le tronçon de distribution d'oid du graphe de commit n'a pas la bonne taille"
+
+msgid "commit-graph fanout values out of order"
+msgstr "les valeurs de distribution du graphe de commit sont désordonnées"
+
+msgid "commit-graph OID lookup chunk is the wrong size"
+msgstr ""
+"le tronçon de recherche de l'OID du graphe de commits n'a pas la bonne taille"
+
+msgid "commit-graph commit data chunk is wrong size"
+msgstr "le tronçon de données du graphe de commit n'a pas la bonne taille"
+
+msgid "commit-graph generations chunk is wrong size"
+msgstr "le tronçon des générations du graphe de commit n'a pas la bonne taille"
+
+msgid "commit-graph changed-path index chunk is too small"
+msgstr ""
+"le tronçon d'index des chemins modifiés du graphe de commit est trop petit"
+
+#, c-format
+msgid ""
+"ignoring too-small changed-path chunk (%<PRIuMAX> < %<PRIuMAX>) in commit-"
+"graph file"
+msgstr ""
+"tronçon de chemin modifié dans le fichier de graphe de commits trop petit "
+"((%<PRIuMAX> < %<PRIuMAX>)) ignoré"
+
 #, c-format
 msgid "commit-graph signature %X does not match signature %X"
 msgstr ""
@@ -14741,6 +14869,21 @@
 msgid "commit-graph file is too small to hold %u chunks"
 msgstr "le graphe de commit est trop petit pour contenir %u tronçons"
 
+msgid "commit-graph required OID fanout chunk missing or corrupted"
+msgstr ""
+"le tronçon de distribution des OID requis du graphe de commits est manquant "
+"ou corrompu"
+
+msgid "commit-graph required OID lookup chunk missing or corrupted"
+msgstr ""
+"le tronçon de recherche OID requis par le graphe de commits est manquant ou "
+"corrompu"
+
+msgid "commit-graph required commit data chunk missing or corrupted"
+msgstr ""
+"le tronçon d'étalement OID requis par le graphe de commits est manquant ou "
+"corrompu"
+
 msgid "commit-graph has no base graphs chunk"
 msgstr "le graphe de commit n'a pas de tronçon de graphes de base"
 
@@ -14754,6 +14897,9 @@
 msgid "commit count in base graph too high: %<PRIuMAX>"
 msgstr "nombre de commits dans le graphe de base trop haut : %<PRIuMAX>"
 
+msgid "commit-graph chain file too small"
+msgstr "la chaine du graphe de commit est trop petite"
+
 #, c-format
 msgid "invalid commit-graph chain: line '%s' not a hash"
 msgstr ""
@@ -14781,6 +14927,9 @@
 "les données de génération de débordement du graphe de commits sont trop "
 "petites"
 
+msgid "commit-graph extra-edges pointer out of bounds"
+msgstr "pointeur hors-gamme d'arêtes supplémentaires du graphe de commits"
+
 msgid "Loading known commits in commit graph"
 msgstr "Lecture des commits connus dans un graphe de commit"
 
@@ -14941,6 +15090,10 @@
 msgstr "Verification des commits dans le graphe de commits"
 
 #, c-format
+msgid "could not parse commit %s"
+msgstr "impossible d'analyser le commit %s"
+
+#, c-format
 msgid "%s %s is not a commit!"
 msgstr "%s %s n'est pas un commit !"
 
@@ -15379,8 +15532,13 @@
 msgid "bad zlib compression level %d"
 msgstr "niveau de compression zlib incorrect %d"
 
-msgid "core.commentChar should only be one ASCII character"
-msgstr "core.commentChar ne devrait être qu'un unique caractère ASCII"
+#, c-format
+msgid "%s cannot contain newline"
+msgstr "%s ne peut pas contenir de retour à la ligne"
+
+#, c-format
+msgid "%s must have at least one character"
+msgstr "%s doit contenir au moins un caractère"
 
 #, c-format
 msgid "ignoring unknown core.fsyncMethod value '%s'"
@@ -15455,6 +15613,10 @@
 msgstr "impossible d'écrire le fichier de configuration %s"
 
 #, c-format
+msgid "no multi-line comment allowed: '%s'"
+msgstr "aucun commentaire multi-ligne permis : '%s'"
+
+#, c-format
 msgid "could not lock config file %s"
 msgstr "impossible de verrouiller le fichier de configuration %s"
 
@@ -15961,6 +16123,10 @@
 "Valeur inconnue pour la variable de configuration 'diff.submodule' : '%s'"
 
 #, c-format
+msgid "unknown value for config '%s': %s"
+msgstr "valeur inconnue pour la config '%s' : %s"
+
+#, c-format
 msgid ""
 "Found errors in 'diff.dirstat' config variable:\n"
 "%s"
@@ -16042,13 +16208,6 @@
 msgid "invalid mode '%s' in --color-moved-ws"
 msgstr "mode invalide '%s' dans --color-moved-ws"
 
-msgid ""
-"option diff-algorithm accepts \"myers\", \"minimal\", \"patience\" and "
-"\"histogram\""
-msgstr ""
-"l'option diff-algorithm accept \"myers\", \"minimal\", \"patience\" et "
-"\"histogram\""
-
 #, c-format
 msgid "invalid argument to %s"
 msgstr "argument invalide pour %s"
@@ -16092,8 +16251,8 @@
 msgid "output only the last line of --stat"
 msgstr "afficher seulement la dernière ligne de --stat"
 
-msgid "<param1,param2>..."
-msgstr "<param1,param2>..."
+msgid "<param1>,<param2>..."
+msgstr "<param1>,<param2>..."
 
 msgid ""
 "output the distribution of relative amount of changes for each sub-directory"
@@ -16104,8 +16263,8 @@
 msgid "synonym for --dirstat=cumulative"
 msgstr "synonyme pour --dirstat=cumulative"
 
-msgid "synonym for --dirstat=files,param1,param2..."
-msgstr "synonyme pour --dirstat=files,param1,param2..."
+msgid "synonym for --dirstat=files,<param1>,<param2>..."
+msgstr "synonyme pour --dirstat=files,<param1>,<param2>..."
 
 msgid "warn if changes introduce conflict markers or whitespace errors"
 msgstr ""
@@ -16293,12 +16452,6 @@
 msgstr ""
 "générer un diff en utilisant l'algorithme de différence \"histogramme\""
 
-msgid "<algorithm>"
-msgstr "<algorithme>"
-
-msgid "choose a diff algorithm"
-msgstr "choisir un algorithme de différence"
-
 msgid "<text>"
 msgstr "<texte>"
 
@@ -17310,6 +17463,14 @@
 msgstr "Impossible de créer '%s.lock' : %s"
 
 #, c-format
+msgid "could not write loose object index %s"
+msgstr "impossible d'écrire l'objet esseulé %s"
+
+#, c-format
+msgid "failed to write loose object index %s\n"
+msgstr "Échec de l'écriture de l'index d'objet esseulé %s\n"
+
+#, c-format
 msgid "unexpected line: '%s'"
 msgstr "ligne inattendue : '%s'"
 
@@ -17332,6 +17493,10 @@
 msgstr "Échec de fusion du sous-module %s (commits non présents)"
 
 #, c-format
+msgid "Failed to merge submodule %s (repository corrupt)"
+msgstr "Échec de la fusion du sous-module %s (dépôt corrompu)"
+
+#, c-format
 msgid "Failed to merge submodule %s (commits don't follow merge-base)"
 msgstr ""
 "Échec de la fusion du sous-module %s (les commits ne descendent pas de la "
@@ -17805,76 +17970,6 @@
 msgid "failed to read the cache"
 msgstr "impossible de lire le cache"
 
-msgid "multi-pack-index OID fanout is of the wrong size"
-msgstr "l'étalement de l'OID d'index multi-paquet n'a pas la bonne taille"
-
-msgid "multi-pack-index OID lookup chunk is the wrong size"
-msgstr ""
-"le tronçon de recherche de l'OID d'index multi-paquet n'a pas la bonne taille"
-
-msgid "multi-pack-index object offset chunk is the wrong size"
-msgstr ""
-"le tronçon de décalage de l'OID d'index multi-paquet n'a pas la bonne taille"
-
-#, c-format
-msgid "multi-pack-index file %s is too small"
-msgstr "le fichier d'index multi-paquet %s est trop petit"
-
-#, c-format
-msgid "multi-pack-index signature 0x%08x does not match signature 0x%08x"
-msgstr ""
-"la signature de l'index multi-paquet 0x%08x ne correspond pas à la signature "
-"0x%08x"
-
-#, c-format
-msgid "multi-pack-index version %d not recognized"
-msgstr "la version d'index multi-paquet %d n'est pas reconnue"
-
-#, c-format
-msgid "multi-pack-index hash version %u does not match version %u"
-msgstr ""
-"la version d'empreinte d'index multi-paquet %u ne correspond pas à la "
-"version %u"
-
-msgid "multi-pack-index required pack-name chunk missing or corrupted"
-msgstr ""
-"le tronçon de nom de paquet requis par l'index multi-paquet est manquant ou "
-"corrompu"
-
-msgid "multi-pack-index required OID fanout chunk missing or corrupted"
-msgstr ""
-"le tronçon d'étalement OID requis de l'index multi-paquet est manquant ou "
-"corrompu"
-
-msgid "multi-pack-index required OID lookup chunk missing or corrupted"
-msgstr ""
-"le tronçon de recherche OID requis de l'index multi-paquet est manquant ou "
-"corrompu"
-
-msgid "multi-pack-index required object offsets chunk missing or corrupted"
-msgstr ""
-"le tronçon de décalage d'objet requis de l'index multi-paquet est manquant "
-"ou corrompu"
-
-msgid "multi-pack-index pack-name chunk is too short"
-msgstr "le tronçon de nom de paquet de l'index multi-paquet est trop petit"
-
-#, c-format
-msgid "multi-pack-index pack names out of order: '%s' before '%s'"
-msgstr ""
-"index multi-paquet les noms de paquets sont en désordre : '%s' avant '%s'"
-
-#, c-format
-msgid "bad pack-int-id: %u (%u total packs)"
-msgstr "mauvais pack-int-id : %u (%u paquets au total)"
-
-msgid "multi-pack-index stores a 64-bit offset, but off_t is too small"
-msgstr ""
-"l'index multi-paquet stocke un décalage en 64-bit, mais off_t est trop petit"
-
-msgid "multi-pack-index large offset out of bounds"
-msgstr "le grand décalage de l'index-multi-paquet est hors limite"
-
 #, c-format
 msgid "failed to add packfile '%s'"
 msgstr "échec de l'ajout du fichier paquet '%s'"
@@ -17940,6 +18035,102 @@
 msgid "could not write multi-pack-index"
 msgstr "échec de l'écriture de l'index de multi-paquet"
 
+msgid "Counting referenced objects"
+msgstr "Comptage des objets référencés"
+
+msgid "Finding and deleting unreferenced packfiles"
+msgstr "Recherche et effacement des fichiers paquets non-référencés"
+
+msgid "could not start pack-objects"
+msgstr "impossible de démarrer le groupement d'objets"
+
+msgid "could not finish pack-objects"
+msgstr "impossible de finir le groupement d'objets"
+
+msgid "multi-pack-index OID fanout is of the wrong size"
+msgstr "l'étalement de l'OID d'index multi-paquet n'a pas la bonne taille"
+
+#, c-format
+msgid ""
+"oid fanout out of order: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]"
+msgstr ""
+"étalement oid en désordre : étalement[%d] = %<PRIx32> > %<PRIx32> = "
+"étalement[%d]"
+
+msgid "multi-pack-index OID lookup chunk is the wrong size"
+msgstr ""
+"le tronçon de recherche de l'OID d'index multi-paquet n'a pas la bonne taille"
+
+msgid "multi-pack-index object offset chunk is the wrong size"
+msgstr ""
+"le tronçon de décalage de l'OID d'index multi-paquet n'a pas la bonne taille"
+
+#, c-format
+msgid "multi-pack-index file %s is too small"
+msgstr "le fichier d'index multi-paquet %s est trop petit"
+
+#, c-format
+msgid "multi-pack-index signature 0x%08x does not match signature 0x%08x"
+msgstr ""
+"la signature de l'index multi-paquet 0x%08x ne correspond pas à la signature "
+"0x%08x"
+
+#, c-format
+msgid "multi-pack-index version %d not recognized"
+msgstr "la version d'index multi-paquet %d n'est pas reconnue"
+
+#, c-format
+msgid "multi-pack-index hash version %u does not match version %u"
+msgstr ""
+"la version d'empreinte d'index multi-paquet %u ne correspond pas à la "
+"version %u"
+
+msgid "multi-pack-index required pack-name chunk missing or corrupted"
+msgstr ""
+"le tronçon de nom de paquet requis par l'index multi-paquet est manquant ou "
+"corrompu"
+
+msgid "multi-pack-index required OID fanout chunk missing or corrupted"
+msgstr ""
+"le tronçon d'étalement OID requis de l'index multi-paquet est manquant ou "
+"corrompu"
+
+msgid "multi-pack-index required OID lookup chunk missing or corrupted"
+msgstr ""
+"le tronçon de recherche OID requis de l'index multi-paquet est manquant ou "
+"corrompu"
+
+msgid "multi-pack-index required object offsets chunk missing or corrupted"
+msgstr ""
+"le tronçon de décalage d'objet requis de l'index multi-paquet est manquant "
+"ou corrompu"
+
+msgid "multi-pack-index pack-name chunk is too short"
+msgstr "le tronçon de nom de paquet de l'index multi-paquet est trop petit"
+
+#, c-format
+msgid "multi-pack-index pack names out of order: '%s' before '%s'"
+msgstr ""
+"index multi-paquet les noms de paquets sont en désordre : '%s' avant '%s'"
+
+#, c-format
+msgid "bad pack-int-id: %u (%u total packs)"
+msgstr "mauvais pack-int-id : %u (%u paquets au total)"
+
+msgid "MIDX does not contain the BTMP chunk"
+msgstr "le MIDX ne contient pas de tronçon BTMP"
+
+#, c-format
+msgid "could not load bitmapped pack %<PRIu32>"
+msgstr "impossible d'ouvrir le paquet bitmappé %<PRIu32>"
+
+msgid "multi-pack-index stores a 64-bit offset, but off_t is too small"
+msgstr ""
+"l'index multi-paquet stocke un décalage en 64-bit, mais off_t est trop petit"
+
+msgid "multi-pack-index large offset out of bounds"
+msgstr "le grand décalage de l'index-multi-paquet est hors limite"
+
 #, c-format
 msgid "failed to clear multi-pack-index at %s"
 msgstr "échec du nettoyage de l'index de multi-paquet à %s"
@@ -17953,13 +18144,6 @@
 msgid "Looking for referenced packfiles"
 msgstr "Recherche de fichiers paquets référencés"
 
-#, c-format
-msgid ""
-"oid fanout out of order: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]"
-msgstr ""
-"étalement oid en désordre : étalement[%d] = %<PRIx32> > %<PRIx32> = "
-"étalement[%d]"
-
 msgid "the midx contains no oid"
 msgstr "le midx ne contient aucun oid"
 
@@ -17988,18 +18172,6 @@
 msgid "incorrect object offset for oid[%d] = %s: %<PRIx64> != %<PRIx64>"
 msgstr "décalage d'objet incorrect pour oid[%d] = %s : %<PRIx64> != %<PRIx64>"
 
-msgid "Counting referenced objects"
-msgstr "Comptage des objets référencés"
-
-msgid "Finding and deleting unreferenced packfiles"
-msgstr "Recherche et effacement des fichiers paquets non-référencés"
-
-msgid "could not start pack-objects"
-msgstr "impossible de démarrer le groupement d'objets"
-
-msgid "could not finish pack-objects"
-msgstr "impossible de finir le groupement d'objets"
-
 #, c-format
 msgid "unable to create lazy_dir thread: %s"
 msgstr "impossible de créer le fil lazy_dir : %s"
@@ -18045,6 +18217,25 @@
 msgid "Bad %s value: '%s'"
 msgstr "Mauvaise valeur de %s : '%s'"
 
+msgid "failed to decode tree entry"
+msgstr "échec de décodage de l'entrée d'abre"
+
+#, c-format
+msgid "failed to map tree entry for %s"
+msgstr "échec de mise en correspondance de l'entrée d'arbre avec %s"
+
+#, c-format
+msgid "bad %s in commit"
+msgstr "%s mauvais dans le commit"
+
+#, c-format
+msgid "unable to map %s %s in commit object"
+msgstr "impossible de faire correspondre %s %s dans l'objet de commit"
+
+#, c-format
+msgid "Failed to convert object from %s to %s"
+msgstr "Échec de conversion de l'objet de %s vers %s"
+
 #, c-format
 msgid "object directory %s does not exist; check .git/objects/info/alternates"
 msgstr ""
@@ -18149,6 +18340,10 @@
 msgstr "l'objet empaqueté %s (stocké dans %s) est corrompu"
 
 #, c-format
+msgid "missing mapping of %s to %s"
+msgstr "correspondance manquante entre %s et %s"
+
+#, c-format
 msgid "unable to write file %s"
 msgstr "impossible d'écrire le fichier %s"
 
@@ -18203,6 +18398,10 @@
 msgstr "impossible de lire l'objet pour %s"
 
 #, c-format
+msgid "cannot map object %s to %s"
+msgstr "impossible de faire correspondre l'objet %s avec %s"
+
+#, c-format
 msgid "object fails fsck: %s"
 msgstr "l'objet est en échec de fsck : %s"
 
@@ -18486,6 +18685,9 @@
 msgid "could not open pack %s"
 msgstr "impossible d'ouvrir le paquet '%s'"
 
+msgid "could not determine MIDX preferred pack"
+msgstr "impossible de déterminer le paquet préféré de MIDX"
+
 #, c-format
 msgid "preferred pack (%s) is invalid"
 msgstr "le paquet préféré (%s) est invalide"
@@ -18508,6 +18710,10 @@
 msgstr "bitmap ewah corrompue : entête tronqué pour la bitmap du commit '%s'"
 
 #, c-format
+msgid "unable to load pack: '%s', disabling pack-reuse"
+msgstr "impossible de charger le paquet : '%s', pack-reuse désactivé"
+
+#, c-format
 msgid "object '%s' not found in type bitmaps"
 msgstr "objet '%s' non trouvé dans les bitmaps de type"
 
@@ -18599,6 +18805,9 @@
 msgstr ""
 "le tronçon d'index inversé de l'index multi-paquet n'a pas la bonne taille"
 
+msgid "could not determine preferred pack"
+msgstr "impossible de déterminer le paquet préféré"
+
 msgid "cannot both write and verify reverse index"
 msgstr "impossible de lire et vérifier à la fois l'index inverse"
 
@@ -18663,10 +18872,6 @@
 msgstr "%s attend une valeur entière non négative avec une suffixe k/m/g"
 
 #, c-format
-msgid "%s is incompatible with %s"
-msgstr "%s est incompatible avec %s"
-
-#, c-format
 msgid "ambiguous option: %s (could be --%s%s or --%s%s)"
 msgstr "option ambigüe : %s (devrait être --%s%s ou --%s%s)"
 
@@ -18995,10 +19200,6 @@
 msgstr "impossible d'ajouter '%s' à l'index"
 
 #, c-format
-msgid "unable to stat '%s'"
-msgstr "fstat de '%s' impossible"
-
-#, c-format
 msgid "'%s' appears as both a file and as a directory"
 msgstr "'%s' existe à la fois comme un fichier et un répertoire"
 
@@ -19575,10 +19776,6 @@
 msgstr "impossible de traiter '%s' et '%s' en même temps"
 
 #, c-format
-msgid "could not remove reference %s"
-msgstr "impossible de supprimer la référence %s"
-
-#, c-format
 msgid "could not delete reference %s: %s"
 msgstr "impossible de supprimer la référence %s : %s"
 
@@ -19587,6 +19784,79 @@
 msgstr "impossible de supprimer les références : %s"
 
 #, c-format
+msgid "refname is dangerous: %s"
+msgstr "le nom de réference est dangereux : %s"
+
+#, c-format
+msgid "trying to write ref '%s' with nonexistent object %s"
+msgstr "essai d'écriture de la réf '%s' avec l'objet inexistant %s"
+
+#, c-format
+msgid "trying to write non-commit object %s to branch '%s'"
+msgstr "essai d'écriture de l'objet non commit %s dans la branche '%s'"
+
+#, c-format
+msgid ""
+"multiple updates for 'HEAD' (including one via its referent '%s') are not "
+"allowed"
+msgstr ""
+"mises à jour multiples pour la réf 'HEAD' (l'une d'elle étant via son "
+"référence '%s') non permises"
+
+#, c-format
+msgid "cannot lock ref '%s': unable to resolve reference '%s'"
+msgstr ""
+"impossible de verrouiller la référence '%s' : impossible de résoudre la "
+"référence '%s'"
+
+#, c-format
+msgid "cannot lock ref '%s': error reading reference"
+msgstr ""
+"impossible de verrouiller la référence '%s' : erreur de lecture de la "
+"référence"
+
+#, c-format
+msgid ""
+"multiple updates for '%s' (including one via symref '%s') are not allowed"
+msgstr ""
+"mises à jour multiples pour '%s' (dont un via la symref '%s') non permises"
+
+#, c-format
+msgid "cannot lock ref '%s': reference already exists"
+msgstr "impossible de verrouiller la référence '%s' : la référence existe déjà"
+
+#, c-format
+msgid "cannot lock ref '%s': reference is missing but expected %s"
+msgstr ""
+"impossible de verrouiller la réf '%s' : la référence manque mais %s était "
+"attendu"
+
+#, c-format
+msgid "cannot lock ref '%s': is at %s but expected %s"
+msgstr "impossible de verrouiller '%s' : pointe sur %s mais %s était attendu"
+
+#, c-format
+msgid "reftable: transaction prepare: %s"
+msgstr "reftable : préparation de transaction : %s"
+
+#, c-format
+msgid "reftable: transaction failure: %s"
+msgstr "reftable : échec de transaction : %s"
+
+#, c-format
+msgid "unable to compact stack: %s"
+msgstr "impossible de compacter la pile : %s"
+
+#, c-format
+msgid "refname %s not found"
+msgstr "nom de réf '%s' non trouvé"
+
+#, c-format
+msgid "refname %s is a symbolic ref, copying it is not supported"
+msgstr ""
+"le nom de réf %s est une réf symbolique, la copie n'est pas prise en charge"
+
+#, c-format
 msgid "invalid refspec '%s'"
 msgstr "spécificateur de réference invalide : '%s'"
 
@@ -19595,6 +19865,10 @@
 msgstr "citation invalide dans la valeur push-option : '%s'"
 
 #, c-format
+msgid "unknown value for object-format: %s"
+msgstr "valeur inconnue pour object-format : %s"
+
+#, c-format
 msgid "%sinfo/refs not valid: is this a git repository?"
 msgstr "%sinfo/refs n'est pas valide : est-ce bien un dépôt git ?"
 
@@ -19773,7 +20047,7 @@
 "Neither worked, so we gave up. You must fully qualify the ref."
 msgstr ""
 "La destination que vous avez fournie n'est pas un nom de référence complète\n"
-"(c'est-à-dire commençant par \"ref/\"). Essai d'approximation par :\n"
+"(c'est-à-dire commençant par \"refs/\"). Essai d'approximation par :\n"
 "\n"
 "- Recherche d'une référence qui correspond à '%s' sur le serveur distant.\n"
 "- Vérification si la <source> en cours de poussée ('%s')\n"
@@ -20050,9 +20324,19 @@
 msgstr "resolve-undo enregistre `%s` qui manque"
 
 #, c-format
-msgid "could not get commit for ancestry-path argument %s"
+msgid "%s exists but is a symbolic ref"
+msgstr "%s existe mais c'est une référence symbolique"
+
+msgid ""
+"--merge requires one of the pseudorefs MERGE_HEAD, CHERRY_PICK_HEAD, "
+"REVERT_HEAD or REBASE_HEAD"
 msgstr ""
-"impossible de récupérer le commit pour l'argument de chemin d'ascendance %s"
+"--merge nécessite une pseudo-réf MERGE_HEAD, CHERRY_PICK_HEAD, REVERT_HEAD "
+"ou REBASE_HEAD"
+
+#, c-format
+msgid "could not get commit for --ancestry-path argument %s"
+msgstr "impossible de récupérer le commit pour l'argument --ancestry-path %s"
 
 msgid "--unpacked=<packfile> no longer supported"
 msgstr "--unpacked=<fichier-paquet> n'est plus géré"
@@ -20342,6 +20626,19 @@
 msgstr "action inconnue : %d"
 
 msgid ""
+"Resolve all conflicts manually, mark them as resolved with\n"
+"\"git add/rm <conflicted_files>\", then run \"git rebase --continue\".\n"
+"You can instead skip this commit: run \"git rebase --skip\".\n"
+"To abort and get back to the state before \"git rebase\", run \"git rebase --"
+"abort\"."
+msgstr ""
+"Résolvez tous les conflits manuellement, marquez-les comme résolus avec\n"
+"\"git add/rm <fichier en conflit>\", puis lancez \"git rebase --continue\".\n"
+"Si vous préférez sauter ce commit, lancez \"git rebase --skip\". Pour "
+"arrêter\n"
+"et revenir à l'état antérieur à la commande, lancez \"git rebase --abort\"."
+
+msgid ""
 "after resolving the conflicts, mark the corrected paths\n"
 "with 'git add <paths>' or 'git rm <paths>'"
 msgstr ""
@@ -20565,10 +20862,6 @@
 msgstr "impossible de mettre à jour %s"
 
 #, c-format
-msgid "could not parse commit %s"
-msgstr "impossible d'analyser le commit %s"
-
-#, c-format
 msgid "could not parse parent commit %s"
 msgstr "impossible d'analyser le commit parent %s"
 
@@ -20674,10 +20967,6 @@
 msgstr "commande '%.*s' invalide"
 
 #, c-format
-msgid "%s does not accept arguments: '%s'"
-msgstr "%s n'accepte pas d'argument : '%s'"
-
-#, c-format
 msgid "missing arguments for %s"
 msgstr "argument manquant pour %s"
 
@@ -20961,6 +21250,9 @@
 msgstr ""
 "Un remisage automatique existe ; création d'une nouvelle entrée de remisage."
 
+msgid "autostash reference is a symref"
+msgstr "la référence d'auto-remisage est une symref"
+
 msgid "could not detach HEAD"
 msgstr "impossible de détacher HEAD"
 
@@ -21133,6 +21425,10 @@
 "configuration invalide"
 
 #, c-format
+msgid "'%s' already specified as '%s'"
+msgstr "'%s' déjà spécifié comme '%s'"
+
+#, c-format
 msgid "Expected git repo version <= %d, found %d"
 msgstr "Version attendue du dépôt git <= %d, %d trouvée"
 
@@ -21280,6 +21576,10 @@
 msgstr "nom de branche initiale invalide : '%s'"
 
 #, c-format
+msgid "re-init: ignored --initial-branch=%s"
+msgstr "re-initialisation : --initial-branch=%s ignoré"
+
+#, c-format
 msgid "unable to handle file type %d"
 msgstr "impossible de traiter le fichier de type %d"
 
@@ -21290,15 +21590,17 @@
 msgid "attempt to reinitialize repository with different hash"
 msgstr "essai de réinitialisation du dépôt avec une empreinte différente"
 
+msgid ""
+"attempt to reinitialize repository with different reference storage format"
+msgstr ""
+"essai de réinitialisation du dépôt avec un format de stockage de références "
+"différent"
+
 #, c-format
 msgid "%s already exists"
 msgstr "%s existe déjà"
 
 #, c-format
-msgid "re-init: ignored --initial-branch=%s"
-msgstr "re-initialisation : --initial-branch=%s ignoré"
-
-#, c-format
 msgid "Reinitialized existing shared Git repository in %s%s\n"
 msgstr "Dépôt Git existant partagé réinitialisé dans %s%s\n"
 
@@ -21321,6 +21623,21 @@
 msgid "cannot use split index with a sparse index"
 msgstr "impossible d'utiliser l'index scindé avec un index clairsemé"
 
+#. TRANSLATORS: The first %s is a command like "ls-tree".
+#, c-format
+msgid "bad %s format: element '%s' does not start with '('"
+msgstr "mauvais format %s : l'élément '%s' ne commence pas par '('"
+
+#. TRANSLATORS: The first %s is a command like "ls-tree".
+#, c-format
+msgid "bad %s format: element '%s' does not end in ')'"
+msgstr "mauvais format '%s' : l'élément '%s' ne se termine pas ')'"
+
+#. TRANSLATORS: %s is a command like "ls-tree".
+#, c-format
+msgid "bad %s format: %%%.*s"
+msgstr "mauvais format %s : %%%.*s"
+
 #. TRANSLATORS: IEC 80000-13:2008 gibibyte
 #, c-format
 msgid "%u.%2.2u GiB"
@@ -21567,12 +21884,6 @@
 msgid "number of entries in the cache tree to invalidate (default 0)"
 msgstr "nombre d'entrées dans l'arbre de cache à invalider (par défaut, 0)"
 
-msgid "unhandled options"
-msgstr "options non gérées"
-
-msgid "error preparing revisions"
-msgstr "erreur lors de la préparation des révisions"
-
 #, c-format
 msgid "commit %s is not marked reachable"
 msgstr "le commit %s n'est pas marqué joignable"
@@ -21657,29 +21968,6 @@
 msgid "empty trailer token in trailer '%.*s'"
 msgstr "symbole vide dans la ligne de fin '%.*s'"
 
-#, c-format
-msgid "could not read input file '%s'"
-msgstr "impossible de lire le fichier d'entrée '%s'"
-
-#, c-format
-msgid "could not stat %s"
-msgstr "stat impossible de %s"
-
-#, c-format
-msgid "file %s is not a regular file"
-msgstr "%s n'est pas un fichier régulier"
-
-#, c-format
-msgid "file %s is not writable by user"
-msgstr "le fichier %s n'est pas inscriptible par l'utilisateur"
-
-msgid "could not open temporary file"
-msgstr "impossible de créer un fichier temporaire"
-
-#, c-format
-msgid "could not rename temporary file to %s"
-msgstr "impossible de renommer un fichier temporaire en %s"
-
 msgid "full write to remote helper failed"
 msgstr "échec de l'écriture totale sur l'assistant distant"
 
@@ -21732,9 +22020,6 @@
 msgid "invalid remote service path"
 msgstr "chemin de service distant invalide"
 
-msgid "operation not supported by protocol"
-msgstr "option non supportée par le protocole"
-
 #, c-format
 msgid "can't connect to subservice %s"
 msgstr "impossible de se connecter au sous-service %s"
@@ -21783,8 +22068,8 @@
 "nécessaire"
 
 #, c-format
-msgid "helper %s does not support 'force'"
-msgstr "l'assistant %s ne gère pas 'force'"
+msgid "helper %s does not support '--force'"
+msgstr "l'assistant %s ne gère pas '--force'"
 
 msgid "couldn't run fast-export"
 msgstr "impossible de lancer fast-export"
@@ -21867,10 +22152,6 @@
 msgstr "le support du protocole v2 n'est pas encore implanté"
 
 #, c-format
-msgid "unknown value for config '%s': %s"
-msgstr "valeur inconnue pour la config '%s' : %s"
-
-#, c-format
 msgid "transport '%s' not allowed"
 msgstr "transport '%s' non permis"
 
@@ -21924,6 +22205,9 @@
 msgstr ""
 "impossible de récupérer la liste de bundle-uris annoncée par le serveur"
 
+msgid "operation not supported by protocol"
+msgstr "option non supportée par le protocole"
+
 msgid "too-short tree object"
 msgstr "objet arbre trop court"
 
@@ -22208,6 +22492,10 @@
 msgid "invalid '..' path segment"
 msgstr "segment de chemin '..' invalide"
 
+#, c-format
+msgid "error: unable to format message: %s\n"
+msgstr "erreur : impossible de formater le message : %s\n"
+
 msgid "usage: "
 msgstr "usage : "
 
@@ -22773,6 +23061,10 @@
 msgid "cannot %s: Your index contains uncommitted changes."
 msgstr "%s impossible : votre index contient des modifications non validées."
 
+#, c-format
+msgid "unknown style '%s' given for '%s'"
+msgstr "style inconnu '%s' pour '%s'"
+
 msgid ""
 "Error: Your local changes to the following files would be overwritten by "
 "merge"
@@ -23174,6 +23466,100 @@
 msgid "Do you really want to send %s? [y|N]: "
 msgstr "Souhaitez-vous réellement envoyer %s ?[y|N] : "
 
+#~ msgid ""
+#~ "Use -f if you really want to add them.\n"
+#~ "Turn this message off by running\n"
+#~ "\"git config advice.addIgnoredFile false\""
+#~ msgstr ""
+#~ "Utilisez -f si vous voulez vraiment les ajouter.\n"
+#~ "Éliminez ce message en lançant\n"
+#~ "\"git config advice.addIgnoredFile false\""
+
+#~ msgid ""
+#~ "Maybe you wanted to say 'git add .'?\n"
+#~ "Turn this message off by running\n"
+#~ "\"git config advice.addEmptyPathspec false\""
+#~ msgstr ""
+#~ "Peut-être avez-vous voulu dire 'git add .' ?\n"
+#~ "Éliminez ce message en lançant\n"
+#~ "\"git config advice.addEmptyPathspec false\""
+
+#~ msgid ""
+#~ "clean.requireForce defaults to true and neither -i, -n, nor -f given; "
+#~ "refusing to clean"
+#~ msgstr ""
+#~ "clean.requireForce à true par défaut et ni -i, -n ou -f fourni ; refus de "
+#~ "nettoyer"
+
+#, c-format
+#~ msgid "bad ls-files format: element '%s' does not start with '('"
+#~ msgstr "mauvais format ls-files : l'élément '%s' ne commence pas par '('"
+
+#, c-format
+#~ msgid "bad ls-files format: element '%s' does not end in ')'"
+#~ msgstr "mauvais format ls-files : l'élément '%s' ne se termine pas par ')'"
+
+#, c-format
+#~ msgid "bad ls-files format: %%%.*s"
+#~ msgstr "mauvais format ls-files : %%%.*s"
+
+#~ msgid "keep redundant, empty commits"
+#~ msgstr "garder les validations redondantes, vides"
+
+#~ msgid "core.commentChar should only be one ASCII character"
+#~ msgstr "core.commentChar ne devrait être qu'un unique caractère ASCII"
+
+#~ msgid "-x and -X cannot be used together"
+#~ msgstr "-x et -X ne peuvent pas être utilisés ensemble"
+
+#~ msgid ""
+#~ "--bundle-uri is incompatible with --depth, --shallow-since, and --shallow-"
+#~ "exclude"
+#~ msgstr ""
+#~ "--bundle-uri est incompatible avec --depth, --shallow-since, et --shallow-"
+#~ "exclude"
+
+#~ msgid "--merge-base is incompatible with --stdin"
+#~ msgstr "--merge-base est incompatible avec --stdin"
+
+#~ msgid ""
+#~ "apply options are incompatible with rebase.autoSquash.  Consider adding --"
+#~ "no-autosquash"
+#~ msgstr ""
+#~ "les options d'application sont incompatibles avec rebase.autoSquash. "
+#~ "Considérez l'ajout de --no-autosquash"
+
+#~ msgid "--exclude-hidden cannot be used together with --branches"
+#~ msgstr "--exclude-hidden ne peut être utilisé avec --branches"
+
+#~ msgid "--exclude-hidden cannot be used together with --tags"
+#~ msgstr "--exclude-hidden ne peut pas être utilisé avec --tags"
+
+#~ msgid "--exclude-hidden cannot be used together with --remotes"
+#~ msgstr "--exclude-hidden ne peut pas être utilisé avec --remotes"
+
+#, c-format
+#~ msgid "only one of '%s', '%s' or '%s' can be given"
+#~ msgstr "les options '%s', '%s' et '%s' sont mutuellement exclusives"
+
+#, c-format
+#~ msgid "'%s' and '%s' cannot be used together"
+#~ msgstr "'%s' et '%s' ne peuvent pas être utilisées ensemble"
+
+#, c-format
+#~ msgid "options '%s', and '%s' cannot be used together"
+#~ msgstr "les options '%s' et '%s' ne peuvent pas être utilisées ensemble"
+
+#~ msgid "<commit-ish>"
+#~ msgstr "<commit-esque>"
+
+#, c-format
+#~ msgid "%s is incompatible with %s"
+#~ msgstr "%s est incompatible avec %s"
+
+#~ msgid "unhandled options"
+#~ msgstr "options non gérées"
+
 #, c-format
 #~ msgid "options '%s=%s' and '%s=%s' cannot be used together"
 #~ msgstr ""
diff --git a/po/id.po b/po/id.po
index 9698367..2dc4b79 100644
--- a/po/id.po
+++ b/po/id.po
@@ -7,8 +7,8 @@
 msgstr ""
 "Project-Id-Version: Git\n"
 "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2023-11-12 20:04+0700\n"
-"PO-Revision-Date: 2023-11-12 20:30+0700\n"
+"POT-Creation-Date: 2024-04-25 18:57+0000\n"
+"PO-Revision-Date: 2024-04-26 15:33+0700\n"
 "Last-Translator: Bagas Sanjaya <bagasdotme@gmail.com>\n"
 "Language-Team: Indonesian\n"
 "Language: id\n"
@@ -591,12 +591,12 @@
 "---\n"
 "To remove '%c' lines, make them ' ' lines (context).\n"
 "To remove '%c' lines, delete them.\n"
-"Lines starting with %c will be removed.\n"
+"Lines starting with %s will be removed.\n"
 msgstr ""
 "---\n"
 "Untuk menghapus baris '%c', buatlah menjadi baris ' ' (konteks).\n"
 "Untuk menghapus baris '%c', hapuslahnya.\n"
-"Baris yang diawali dengan %c akan dihapus.\n"
+"Baris yang diawali dengan %s akan dihapus.\n"
 
 #: add-patch.c
 msgid ""
@@ -651,17 +651,19 @@
 "/ - search for a hunk matching the given regex\n"
 "s - split the current hunk into smaller hunks\n"
 "e - manually edit the current hunk\n"
+"p - print the current hunk\n"
 "? - print help\n"
 msgstr ""
-"j - biarkan bingkah ini ragu, lihat bingkah ragu berikutnya\n"
-"J - biarkan bingkah ini ragu, lihat bingkah berikutnya\n"
-"k - biarkan bingkah ini ragu, lihat bingkah ragu sebelumnya\n"
-"K - biarkan bingkah ini ragu, lihat bingkah sebelumnya\n"
+"j - biarkan bingkah ini, lihat bingkah berikutnya yang belum diputuskan\n"
+"J - biarkan bingkah ini, lihat bingkah berikutnya\n"
+"k - biarkan bingkah ini, lihat bingkah sebelumnya yang belum diputuskan\n"
+"K - biarkan bingkah ini, lihat bingkah sebelumnya\n"
 "g - pilih satu bingkah untuk dikunjungi\n"
 "/ - cari satu bingkah yang cocok dengan regex yang diberikan\n"
 "s - belah bingkah saat ini ke dalam bingkah yang lebih kecil\n"
 "e - sunting bingkah saat ini secara manual\n"
-"? - cetak bantuan\n"
+"p - lihat bingkah saat ini\n"
+"? - lihat bantuan\n"
 
 #: add-patch.c
 msgid "No previous hunk"
@@ -740,8 +742,8 @@
 
 #: advice.c
 #, c-format
-msgid "%shint: %.*s%s\n"
-msgstr "%shint: %.*s%s\n"
+msgid "%shint:%s%.*s%s\n"
+msgstr "%spetunjuk:%s%.*s%s\n"
 
 #: advice.c
 msgid "Cherry-picking is not possible because you have unmerged files."
@@ -909,7 +911,7 @@
 msgstr "tanda kutip tak ditutup"
 
 #: alias.c builtin/cat-file.c builtin/notes.c builtin/prune-packed.c
-#: builtin/receive-pack.c builtin/tag.c
+#: builtin/receive-pack.c builtin/tag.c t/helper/test-pkt-line.c
 msgid "too many arguments"
 msgstr "terlalu banyak argumen"
 
@@ -924,12 +926,13 @@
 msgstr "opsi abai spasi putih tidak dikenal '%s'"
 
 #: apply.c archive.c builtin/add.c builtin/branch.c builtin/checkout-index.c
-#: builtin/checkout.c builtin/clone.c builtin/commit.c builtin/describe.c
-#: builtin/diff-tree.c builtin/difftool.c builtin/fast-export.c builtin/fetch.c
-#: builtin/help.c builtin/index-pack.c builtin/init-db.c builtin/log.c
-#: builtin/ls-files.c builtin/merge-base.c builtin/merge.c
-#: builtin/pack-objects.c builtin/push.c builtin/rebase.c builtin/repack.c
-#: builtin/reset.c builtin/rev-list.c builtin/show-branch.c builtin/stash.c
+#: builtin/checkout.c builtin/clean.c builtin/clone.c builtin/commit.c
+#: builtin/describe.c builtin/diff-tree.c builtin/difftool.c
+#: builtin/fast-export.c builtin/fetch.c builtin/help.c builtin/index-pack.c
+#: builtin/init-db.c builtin/log.c builtin/ls-files.c builtin/merge-base.c
+#: builtin/merge-tree.c builtin/merge.c builtin/pack-objects.c builtin/rebase.c
+#: builtin/repack.c builtin/replay.c builtin/reset.c builtin/rev-list.c
+#: builtin/rev-parse.c builtin/show-branch.c builtin/stash.c
 #: builtin/submodule--helper.c builtin/tag.c builtin/worktree.c parse-options.c
 #: range-diff.c revision.c
 #, c-format
@@ -1358,11 +1361,6 @@
 
 #: apply.c
 #, c-format
-msgid "truncating .rej filename to %.*s.rej"
-msgstr "memotong nama berkas .rej ke %.*s.rej"
-
-#: apply.c
-#, c-format
 msgid "cannot open %s"
 msgstr "tidak dapat membuka %s"
 
@@ -1754,6 +1752,11 @@
 
 #: archive.c
 #, c-format
+msgid "extra command line parameter '%s'"
+msgstr "parameter konfigurasi tambahan: '%s'"
+
+#: archive.c
+#, c-format
 msgid "Unknown archive format '%s'"
 msgstr "Format arsip tidak dikenal '%s'"
 
@@ -1808,6 +1811,17 @@
 msgid "bad --attr-source or GIT_ATTR_SOURCE"
 msgstr "--attr-source atau GIT_ATTR_SOURCE jelek"
 
+#: attr.c read-cache.c
+#, c-format
+msgid "unable to stat '%s'"
+msgstr "tidak dapat men-stat '%s'"
+
+#: bisect.c builtin/cat-file.c builtin/index-pack.c builtin/notes.c
+#: builtin/pack-objects.c combine-diff.c rerere.c
+#, c-format
+msgid "unable to read %s"
+msgstr "tidak dapat membaca %s"
+
 #: bisect.c
 #, c-format
 msgid "Badly quoted content in file '%s': %s"
@@ -1887,6 +1901,11 @@
 msgid "could not create file '%s'"
 msgstr "tidak dapat membuat berkas '%s'"
 
+#: bisect.c builtin/notes.c
+#, c-format
+msgid "unable to start 'show' for object '%s'"
+msgstr "tidak dapat memulai 'show' untuk objek '%s'"
+
 #: bisect.c builtin/merge.c
 #, c-format
 msgid "could not read file '%s'"
@@ -1937,8 +1956,8 @@
 "--reverse dan --first-parent bersama-sama butuh komit terbaru yang disebutkan"
 
 #: blame.c builtin/commit.c builtin/log.c builtin/merge.c
-#: builtin/pack-objects.c builtin/shortlog.c midx.c pack-bitmap.c remote.c
-#: sequencer.c submodule.c
+#: builtin/pack-objects.c builtin/shortlog.c midx-write.c pack-bitmap.c
+#: remote.c sequencer.c submodule.c
 msgid "revision walk setup failed"
 msgstr "persiapan jalan revisi gagal"
 
@@ -2063,6 +2082,10 @@
 msgid "'%s' is not a valid branch name"
 msgstr "'%s' bukan nama cabang valid"
 
+#: branch.c builtin/branch.c
+msgid "See `man git check-ref-format`"
+msgstr "Lihat `man git check-ref-format`"
+
 #: branch.c
 #, c-format
 msgid "a branch named '%s' already exists"
@@ -2302,14 +2325,8 @@
 msgstr "menambahkan repositori git tertanam: %s"
 
 #: builtin/add.c
-msgid ""
-"Use -f if you really want to add them.\n"
-"Turn this message off by running\n"
-"\"git config advice.addIgnoredFile false\""
-msgstr ""
-"Gunakan -f jika Anda benar-benar ingin menambahkannya.\n"
-"Matikan pesan ini dengan menjalankan\n"
-"\"git config advice.addIgnoredFile false\""
+msgid "Use -f if you really want to add them."
+msgstr "Gunakan -f jika Anda benar-benar ingin menambahkannya."
 
 #: builtin/add.c
 msgid "adding files failed"
@@ -2332,14 +2349,8 @@
 msgstr "Tidak ada yang disebutkan, tidak ada yang ditambahkan.\n"
 
 #: builtin/add.c
-msgid ""
-"Maybe you wanted to say 'git add .'?\n"
-"Turn this message off by running\n"
-"\"git config advice.addEmptyPathspec false\""
-msgstr ""
-"Mungkin Anda ingin bilang 'git add .'?\n"
-"Matikan pesan ini dengan menjalankan\n"
-"\"git config advice.addEmptyPathspec false\""
+msgid "Maybe you wanted to say 'git add .'?"
+msgstr "Mungkin Anda ingin bilang 'git add .'?"
 
 #: builtin/add.c builtin/check-ignore.c builtin/checkout.c builtin/clean.c
 #: builtin/commit.c builtin/diff-tree.c builtin/grep.c builtin/mv.c
@@ -2359,8 +2370,8 @@
 msgstr "tindakan jelek '%s' untuk '%s'"
 
 #: builtin/am.c builtin/blame.c builtin/fetch.c builtin/pack-objects.c
-#: builtin/pull.c diff-merges.c gpg-interface.c ls-refs.c parallel-checkout.c
-#: sequencer.c setup.c
+#: builtin/pull.c builtin/revert.c config.c diff-merges.c gpg-interface.c
+#: ls-refs.c parallel-checkout.c sequencer.c setup.c
 #, c-format
 msgid "invalid value for '%s': '%s'"
 msgstr "nilai tidak valid untuk '%s': '%s'"
@@ -2444,29 +2455,30 @@
 
 #: builtin/am.c
 #, c-format
-msgid "When you have resolved this problem, run \"%s --continue\"."
-msgstr "Saat Anda sudah menyelesaikan masalah ini, jalankan \"%s --continue\"."
-
-#: builtin/am.c
-#, c-format
-msgid "If you prefer to skip this patch, run \"%s --skip\" instead."
+msgid "When you have resolved this problem, run \"%s --continue\".\n"
 msgstr ""
-"Jika Anda lebih suka melewati tambalan ini, jalankan \"%s --skip\" sebagai "
-"gantinya."
+"Saat Anda sudah menyelesaikan masalah ini, jalankan \"%s --continue\".\n"
 
 #: builtin/am.c
 #, c-format
-msgid "To record the empty patch as an empty commit, run \"%s --allow-empty\"."
+msgid "If you prefer to skip this patch, run \"%s --skip\" instead.\n"
+msgstr ""
+"Jika Anda lebih suka melewati tambalan ini, jalankan \"%s --skip\" saja.\n"
+
+#: builtin/am.c
+#, c-format
+msgid ""
+"To record the empty patch as an empty commit, run \"%s --allow-empty\".\n"
 msgstr ""
 "Untuk merekam tambalan kosong sebagai komit kosong, jalankan \"%s --allow-"
-"empty\"."
+"empty\".\n"
 
 #: builtin/am.c
 #, c-format
 msgid "To restore the original branch and stop patching, run \"%s --abort\"."
 msgstr ""
 "Untuk mengembalikan cabang yang asli dan berhenti menambal, jalankan \"%s --"
-"abort\""
+"abort\"."
 
 #: builtin/am.c
 msgid "Patch sent with format=flowed; space at the end of lines might be lost."
@@ -2523,8 +2535,7 @@
 msgid "applying to an empty history"
 msgstr "menerapkan ke sebuah riwayat kosong"
 
-#: builtin/am.c builtin/commit.c builtin/merge.c sequencer.c
-#: t/helper/test-fast-rebase.c
+#: builtin/am.c builtin/commit.c builtin/merge.c builtin/replay.c sequencer.c
 msgid "failed to write commit object"
 msgstr "gagal menulis objek komit"
 
@@ -2710,8 +2721,9 @@
 msgstr "n"
 
 #: builtin/am.c builtin/branch.c builtin/bugreport.c builtin/cat-file.c
-#: builtin/diagnose.c builtin/for-each-ref.c builtin/ls-files.c
-#: builtin/ls-tree.c builtin/replace.c builtin/tag.c builtin/verify-tag.c
+#: builtin/clone.c builtin/diagnose.c builtin/for-each-ref.c builtin/init-db.c
+#: builtin/ls-files.c builtin/ls-tree.c builtin/replace.c builtin/tag.c
+#: builtin/verify-tag.c
 msgid "format"
 msgstr "format"
 
@@ -3406,12 +3418,13 @@
 
 #: builtin/branch.c
 #, c-format
-msgid ""
-"the branch '%s' is not fully merged.\n"
-"If you are sure you want to delete it, run 'git branch -D %s'"
-msgstr ""
-"cabang '%s' belum sepenuhnya tergabung.\n"
-"kalau Anda yakin ingin menghapusnya, jalankan 'git branch -D %s'"
+msgid "the branch '%s' is not fully merged"
+msgstr "cabang '%s' belum sepenuhnya digabungkan"
+
+#: builtin/branch.c
+#, c-format
+msgid "If you are sure you want to delete it, run 'git branch -D %s'"
+msgstr "Jika anda yakin untuk menghapusnya, lakukan 'git branch -D %s'"
 
 #: builtin/branch.c
 msgid "update of config-file failed"
@@ -3535,11 +3548,11 @@
 msgid ""
 "Please edit the description for the branch\n"
 "  %s\n"
-"Lines starting with '%c' will be stripped.\n"
+"Lines starting with '%s' will be stripped.\n"
 msgstr ""
 "Mohon sunting deskripsi untuk cabang\n"
 "  %s\n"
-"Baris yang diawali dengan '%c' akan dicopot.\n"
+"Baris yang diawali dengan '%s' akan dicopot.\n"
 
 #: builtin/branch.c
 msgid "Generic options"
@@ -3802,11 +3815,12 @@
 
 #: builtin/bugreport.c
 msgid ""
-"git bugreport [(-o | --output-directory) <path>] [(-s | --suffix) <format>]\n"
+"git bugreport [(-o | --output-directory) <path>]\n"
+"              [(-s | --suffix) <format> | --no-suffix]\n"
 "              [--diagnose[=<mode>]]"
 msgstr ""
-"git bugreport [(-o | --output-directory) <berkas>] [(-s |-- suffix) "
-"<format>]\n"
+"git bugreport [(-o | --output-directory) <jalur>]\n"
+"              [(-s | --suffix) <format> | --no-suffix]\n"
 "              [--diagnose[=<mode>]]"
 
 #: builtin/bugreport.c
@@ -4420,6 +4434,12 @@
 msgid "path '%s' is unmerged"
 msgstr "jalur '%s' tak tergabung"
 
+#: builtin/checkout.c builtin/grep.c builtin/merge-tree.c builtin/reset.c
+#: merge-ort.c reset.c sequencer.c tree-walk.c
+#, c-format
+msgid "unable to read tree (%s)"
+msgstr "tidak dapat membaca pohon (%s)"
+
 #: builtin/checkout.c
 msgid "you need to resolve your current index first"
 msgstr "Anda perlu selesaikan dulu indeks Anda saat ini"
@@ -4443,7 +4463,7 @@
 msgid "HEAD is now at"
 msgstr "HEAD sekarang berada di"
 
-#: builtin/checkout.c builtin/clone.c t/helper/test-fast-rebase.c
+#: builtin/checkout.c builtin/clone.c
 msgid "unable to update HEAD"
 msgstr "tidak dapat memperbarui HEAD"
 
@@ -4690,6 +4710,11 @@
 msgstr "kehilangan argumen cabang atau komit"
 
 #: builtin/checkout.c
+#, c-format
+msgid "unknown conflict style '%s'"
+msgstr "gaya konflik '%s' tidak dikenal"
+
+#: builtin/checkout.c
 msgid "perform a 3-way merge with the new branch"
 msgstr "lakukan penggabungan 3 arah dengan cabang baru"
 
@@ -4714,8 +4739,8 @@
 msgstr "cabang baru"
 
 #: builtin/checkout.c
-msgid "new unparented branch"
-msgstr "cabang baru tanpa induk"
+msgid "new unborn branch"
+msgstr "cabang yatim baru"
 
 #: builtin/checkout.c builtin/merge.c
 msgid "update ignored files (default)"
@@ -4783,7 +4808,7 @@
 msgid "you must specify path(s) to restore"
 msgstr "Anda harus sebutkan jalur untuk dipulihkan"
 
-#: builtin/checkout.c builtin/clone.c builtin/remote.c
+#: builtin/checkout.c builtin/clone.c builtin/remote.c builtin/replay.c
 #: builtin/submodule--helper.c builtin/worktree.c
 msgid "branch"
 msgstr "cabang"
@@ -5012,24 +5037,8 @@
 msgstr "hanya hapus berkas terabaikan"
 
 #: builtin/clean.c
-msgid ""
-"clean.requireForce set to true and neither -i, -n, nor -f given; refusing to "
-"clean"
-msgstr ""
-"clean.requireForce disetel ke true dan baik -i, -n, atau -f tidak diberikan; "
-"menolak membersihkan"
-
-#: builtin/clean.c
-msgid ""
-"clean.requireForce defaults to true and neither -i, -n, nor -f given; "
-"refusing to clean"
-msgstr ""
-"clean.requireForce asal ke true dan baik -i, -n, atau -f tidak diberikan; "
-"menolak membersihkan"
-
-#: builtin/clean.c
-msgid "-x and -X cannot be used together"
-msgstr "-x dan -X tidak dapat digunakan bersamaan"
+msgid "clean.requireForce is true and -f not given: refusing to clean"
+msgstr "clean.requireForce 'true' dan -f tidak diberikan: menolak membersihkan"
 
 #: builtin/clone.c
 msgid "git clone [<options>] [--] <repo> [<dir>]"
@@ -5048,8 +5057,8 @@
 msgstr "buat repositori bare"
 
 #: builtin/clone.c
-msgid "create a mirror repository (implies bare)"
-msgstr "buat repositori cermin (implikasikan bare)"
+msgid "create a mirror repository (implies --bare)"
+msgstr "buat repositori cermin (mengimplikasikan --bare)"
 
 #: builtin/clone.c
 msgid "to clone from a local repository"
@@ -5122,6 +5131,7 @@
 msgstr "buat klon dangkal sejak waktu yang disebutkan"
 
 #: builtin/clone.c builtin/fetch.c builtin/pull.c builtin/rebase.c
+#: builtin/replay.c
 msgid "revision"
 msgstr "revisi"
 
@@ -5149,6 +5159,10 @@
 msgid "separate git dir from working tree"
 msgstr "pisahkan direktori git dari pohon kerja"
 
+#: builtin/clone.c builtin/init-db.c
+msgid "specify the reference format to use"
+msgstr "sebutkan format referensi untuk digunakan"
+
 #: builtin/clone.c
 msgid "key=value"
 msgstr "kunci=nilai"
@@ -5299,13 +5313,10 @@
 msgid "You must specify a repository to clone."
 msgstr "Anda harus sebutkan repositori untuk diklon."
 
-#: builtin/clone.c
-msgid ""
-"--bundle-uri is incompatible with --depth, --shallow-since, and --shallow-"
-"exclude"
-msgstr ""
-"--bundle-uri tidak kompatibel dengan --depth, --shallow-since, dan --shallow-"
-"exclude"
+#: builtin/clone.c builtin/init-db.c setup.c
+#, c-format
+msgid "unknown ref storage format '%s'"
+msgstr "format penyimpanan referensi tidak dikenal '%s'"
 
 #: builtin/clone.c
 #, c-format
@@ -5454,6 +5465,11 @@
 msgstr "bantalan spasi di antara kolom"
 
 #: builtin/column.c
+#, c-format
+msgid "%s must be non-negative"
+msgstr "%s harus non-negatif"
+
+#: builtin/column.c
 msgid "--command must be the first argument"
 msgstr "--command harus menjadi argumen pertama"
 
@@ -5471,13 +5487,13 @@
 "--stdin-commits]\n"
 "                       [--changed-paths] [--[no-]max-new-filters <n>] [--"
 "[no-]progress]\n"
-"                       <split options>"
+"                       <split-options>"
 msgstr ""
 "git commit-graph write [--object-dir <direktori>] [--append]\n"
 "                       [--split[=<strategi>]] [--reachable | --stdin-packs | "
 "--stdin-commits]\n"
-"                       [--changed-paths] [--[no-]max-new-filters <n>] [--[-"
-"no-]progress]\n"
+"                       [--changed-paths] [--[no-]max-new-filters <n>] [--"
+"[no-]progress]\n"
 "                       <opsi pemisahan>"
 
 #: builtin/commit-graph.c builtin/fetch.c builtin/log.c builtin/repack.c
@@ -5794,7 +5810,7 @@
 "tidak dapat memilih karakter komentar yang tidak terpakai\n"
 "dalam pesan komit saat ini"
 
-#: builtin/commit.c builtin/merge-tree.c
+#: builtin/commit.c
 #, c-format
 msgid "could not lookup commit '%s'"
 msgstr "tidak dapat mencari komit '%s'"
@@ -5839,38 +5855,38 @@
 #, c-format
 msgid ""
 "Please enter the commit message for your changes. Lines starting\n"
-"with '%c' will be ignored.\n"
+"with '%s' will be ignored.\n"
 msgstr ""
 "Mohon masukkan pesan komit untuk perubahan Anda. Baris yang diawali\n"
-"dengan '%c' akan diabaikan.\n"
+"dengan '%s' akan diabaikan.\n"
 
 #: builtin/commit.c
 #, 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"
+"with '%s' will be ignored, and an empty message aborts the commit.\n"
 msgstr ""
 "Mohon masukkan pesan komit untuk perubahan Anda. Baris yang diawali\n"
-"dengan '%c' akan diabaikan, dan pesan kosong batalkan komit.\n"
+"dengan '%s' akan diabaikan, dan pesan kosong batalkan komit.\n"
 
 #: builtin/commit.c
 #, 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"
+"with '%s' will be kept; you may remove them yourself if you want to.\n"
 msgstr ""
 "Mohon masukkan pesan komit untuk perubahan Anda. Baris yang diawali\n"
-"dengan '%c' akan tetap; Anda dapat menghapusnya jika Anda mau.\n"
+"dengan '%s' akan tetap; Anda dapat menghapusnya jika Anda mau.\n"
 
 #: builtin/commit.c
 #, 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"
+"with '%s' will be kept; you may remove them yourself if you want to.\n"
 "An empty message aborts the commit.\n"
 msgstr ""
 "Mohon masukkan pesan komit untuk perubahan Anda. Baris yang diawali\n"
-"dengan '%c' akan tetap; Anda dapat menghapusnya jika Anda mau.\n"
+"dengan '%s' akan tetap; Anda dapat menghapusnya jika Anda mau.\n"
 "Pesan kosong batalkan komit.\n"
 
 #: builtin/commit.c
@@ -6102,7 +6118,7 @@
 msgid "override date for commit"
 msgstr "timpa tanggal komit"
 
-#: builtin/commit.c builtin/merge-tree.c parse-options.h ref-filter.h
+#: builtin/commit.c parse-options.h ref-filter.h
 msgid "commit"
 msgstr "komit"
 
@@ -6433,6 +6449,11 @@
 msgstr "dengan --get, gunakan nilai asali ketika kehilangan entri"
 
 #: builtin/config.c
+msgid "human-readable comment string (# will be prepended as needed)"
+msgstr ""
+"untai komentar yang dapat dibaca manusia (# akan ditambahkan bila diperlukan"
+
+#: builtin/config.c
 #, c-format
 msgid "wrong number of arguments, should be %d"
 msgstr "jumlah argumen salah, seharusnya %d"
@@ -6548,6 +6569,12 @@
 msgstr "--default hanya dapat diterapkan pada --get"
 
 #: builtin/config.c
+msgid "--comment is only applicable to add/set/replace operations"
+msgstr ""
+"--comment hanya dapat diterapkan pada operasi penambahan/penyetelan/"
+"penggantian"
+
+#: builtin/config.c
 msgid "--fixed-value only applies with 'value-pattern'"
 msgstr "--fixed-value hanya diterapkan dengan 'pola nilai'"
 
@@ -7615,6 +7642,10 @@
 msgstr "baca pola referensi dari masukan standar"
 
 #: builtin/for-each-ref.c
+msgid "also include HEAD ref and pseudorefs"
+msgstr "juga termasuk referensi HEAD dan referensi semu"
+
+#: builtin/for-each-ref.c
 msgid "unknown arguments supplied with --stdin"
 msgstr "argumen tidak dikenal diberikan dengan --stdin"
 
@@ -8397,8 +8428,8 @@
 
 #: builtin/grep.c
 #, c-format
-msgid "unable to read tree (%s)"
-msgstr "tidak dapat membaca pohon (%s)"
+msgid "unable to read tree %s"
+msgstr "tidak dapat membaca pohon %s"
 
 #: builtin/grep.c
 #, c-format
@@ -8929,11 +8960,6 @@
 msgid "SHA1 COLLISION FOUND WITH %s !"
 msgstr "TUMBUKAN SHA1 DITEMUKAN DENGAN %s !"
 
-#: builtin/index-pack.c builtin/pack-objects.c
-#, c-format
-msgid "unable to read %s"
-msgstr "tidak dapat membaca %s"
-
 #: builtin/index-pack.c
 #, c-format
 msgid "cannot read existing object info %s"
@@ -9111,11 +9137,13 @@
 msgid ""
 "git init [-q | --quiet] [--bare] [--template=<template-directory>]\n"
 "         [--separate-git-dir <git-dir>] [--object-format=<format>]\n"
+"         [--ref-format=<format>]\n"
 "         [-b <branch-name> | --initial-branch=<branch-name>]\n"
 "         [--shared[=<permissions>]] [<directory>]"
 msgstr ""
 "git init [-q | --quiet] [--bare] [--template=<direktori templat>]\n"
 "         [--separate-git-dir <direktori git>] [--object-format=<format>]\n"
+"\t  [--ref-format=<format>]\n"
 "         [-b <nama cabang> | --initial-branch=<nama cabang>]\n"
 "         [--shared[=<perizinan>]] [<direktori>]"
 
@@ -9171,7 +9199,7 @@
 #: builtin/interpret-trailers.c
 msgid ""
 "git interpret-trailers [--in-place] [--trim-empty]\n"
-"                       [(--trailer (<key>|<keyAlias>)[(=|:)<value>])...]\n"
+"                       [(--trailer (<key>|<key-alias>)[(=|:)<value>])...]\n"
 "                       [--parse] [<file>...]"
 msgstr ""
 "git interpret-trailers [--in-place] [--trim-empty]\n"
@@ -9179,6 +9207,39 @@
 "[(=|:)<nilai>])...]\n"
 "                       [--parse] [<berkas>...]"
 
+#: builtin/interpret-trailers.c wrapper.c
+#, c-format
+msgid "could not stat %s"
+msgstr "tidak dapat membaca %s"
+
+#: builtin/interpret-trailers.c
+#, c-format
+msgid "file %s is not a regular file"
+msgstr "berkas %s bukan sebuah berkas reguler"
+
+#: builtin/interpret-trailers.c
+#, c-format
+msgid "file %s is not writable by user"
+msgstr "berkas %s tidak dapat ditulis oleh pengguna"
+
+#: builtin/interpret-trailers.c
+msgid "could not open temporary file"
+msgstr "tidak dapat membuka berkas sementara"
+
+#: builtin/interpret-trailers.c
+#, c-format
+msgid "could not read input file '%s'"
+msgstr "tidak dapat membaca berkas masukan '%s'"
+
+#: builtin/interpret-trailers.c builtin/mktag.c imap-send.c
+msgid "could not read from stdin"
+msgstr "tidak dapat membaca dari masukan standar"
+
+#: builtin/interpret-trailers.c
+#, c-format
+msgid "could not rename temporary file to %s"
+msgstr "tidak dapat menamai ulang berkas sementara ke %s"
+
 #: builtin/interpret-trailers.c
 msgid "edit files in place"
 msgstr "sunting berkas di tempat"
@@ -9280,7 +9341,7 @@
 "lacak evolusi rentang baris <awal>,<akhir> atau fungsi :<nama fungsi> dalam "
 "<berkas>"
 
-#: builtin/log.c builtin/shortlog.c bundle.c
+#: builtin/log.c builtin/replay.c builtin/shortlog.c bundle.c
 #, c-format
 msgid "unrecognized argument: %s"
 msgstr "argumen tidak dikenal: %s"
@@ -9687,21 +9748,6 @@
 msgstr "tidak dapat mendapatkan info objek tentang '%s'"
 
 #: builtin/ls-files.c
-#, c-format
-msgid "bad ls-files format: element '%s' does not start with '('"
-msgstr "format ls-files jelek: elemen '%s' tidak dimulai dengan '('"
-
-#: builtin/ls-files.c
-#, c-format
-msgid "bad ls-files format: element '%s' does not end in ')'"
-msgstr "format ls-files jelek: elemen '%s' tidak diakhiri dengan ')'"
-
-#: builtin/ls-files.c
-#, c-format
-msgid "bad ls-files format: %%%.*s"
-msgstr "format ls-files jelek: %%%.*s"
-
-#: builtin/ls-files.c
 msgid "git ls-files [<options>] [<file>...]"
 msgstr "git ls-files [<opsi>] [<berkas>...]"
 
@@ -9794,7 +9840,7 @@
 msgstr ""
 "jika <berkas> apapun tidak berada di indeks, perlakukan sebagai kesalahan"
 
-#: builtin/ls-files.c
+#: builtin/ls-files.c builtin/merge-tree.c
 msgid "tree-ish"
 msgstr "mirip-pohon"
 
@@ -9874,21 +9920,6 @@
 msgstr "git ls-tree [<opsi>] <mirip-pohon> [<jalur>...]"
 
 #: builtin/ls-tree.c
-#, c-format
-msgid "bad ls-tree format: element '%s' does not start with '('"
-msgstr "format ls-tree jelek: elemen '%s' tidak dimulai dengan '('"
-
-#: builtin/ls-tree.c
-#, c-format
-msgid "bad ls-tree format: element '%s' does not end in ')'"
-msgstr "format ls-tree jelek: elemen '%s' tidak diakhiri dengan ')'"
-
-#: builtin/ls-tree.c
-#, c-format
-msgid "bad ls-tree format: %%%.*s"
-msgstr "format ls-tree jelek: %%%.*s"
-
-#: builtin/ls-tree.c
 msgid "only show trees"
 msgstr "hanya perlihatkan pohon"
 
@@ -10036,6 +10067,14 @@
 "git merge-file [<opsi>] [-L <nama 1> [-L <asli> [-L <nama 2>]]] <berkas 1> "
 "<berkas asli> <berkas 2>"
 
+#: builtin/merge-file.c diff.c
+msgid ""
+"option diff-algorithm accepts \"myers\", \"minimal\", \"patience\" and "
+"\"histogram\""
+msgstr ""
+"opsi diff-algorithm terima \"myers\", \"minimal\", \"patience\" dan "
+"\"histogram\""
+
 #: builtin/merge-file.c
 msgid "send results to standard output"
 msgstr "kirim hasil ke keluaran standar"
@@ -10064,6 +10103,14 @@
 msgid "for conflicts, use a union version"
 msgstr "untuk konflik, gunakan versi bersatu"
 
+#: builtin/merge-file.c diff.c
+msgid "<algorithm>"
+msgstr "<algoritma>"
+
+#: builtin/merge-file.c diff.c
+msgid "choose a diff algorithm"
+msgstr "pilih algoritma diff"
+
 #: builtin/merge-file.c
 msgid "for conflicts, use this marker size"
 msgstr "untuk konflik, gunakan ukuran penanda ini"
@@ -10116,6 +10163,11 @@
 msgid "Merging %s with %s\n"
 msgstr "Menggabungkan %s dengan %s\n"
 
+#: builtin/merge-tree.c
+#, c-format
+msgid "could not parse as tree '%s'"
+msgstr "tidak dapat mengurai '%s' sebagai pohon"
+
 #: builtin/merge-tree.c builtin/merge.c
 msgid "not something we can merge"
 msgstr "bukan sesuatu yang kami bisa gabungkan"
@@ -10181,10 +10233,6 @@
 msgid "unknown strategy option: -X%s"
 msgstr "opsi strategi tidak dikenal: -X%s"
 
-#: builtin/merge-tree.c
-msgid "--merge-base is incompatible with --stdin"
-msgstr "--merge-base tidak kompatibel dengan --stdin"
-
 #: builtin/merge-tree.c builtin/notes.c
 #, c-format
 msgid "malformed input line: '%s'."
@@ -10342,7 +10390,7 @@
 msgid "Bad branch.%s.mergeoptions string: %s"
 msgstr "Untai branch.%s.mergeoptions jelek: %s"
 
-#: builtin/merge.c builtin/stash.c merge-recursive.c
+#: builtin/merge.c merge-recursive.c
 msgid "Unable to write index."
 msgstr "Tidak dapat menulis indeks."
 
@@ -10350,7 +10398,7 @@
 msgid "Not handling anything other than two heads merge."
 msgstr "Tak tangani apapun selain penggabungan dua kepala."
 
-#: builtin/merge.c t/helper/test-fast-rebase.c
+#: builtin/merge.c
 #, c-format
 msgid "unable to write %s"
 msgstr "tidak dapat menulis %s"
@@ -10384,10 +10432,10 @@
 #: builtin/merge.c
 #, c-format
 msgid ""
-"Lines starting with '%c' will be ignored, and an empty message aborts\n"
+"Lines starting with '%s' will be ignored, and an empty message aborts\n"
 "the commit.\n"
 msgstr ""
-"Baris yang diawali dengan '%c' akan diabaikan, dan pesan kosong batalkan\n"
+"Baris yang diawali dengan '%s' akan diabaikan, dan pesan kosong batalkan\n"
 "komit.\n"
 
 #: builtin/merge.c
@@ -10585,10 +10633,6 @@
 msgid "object '%s' tagged as '%s', but is a '%s' type"
 msgstr "objek '%s' ditag sebagai '%s', tetapi bertipe '%s'"
 
-#: builtin/mktag.c imap-send.c trailer.c
-msgid "could not read from stdin"
-msgstr "tidak dapat membaca dari masukan standar"
-
 #: builtin/mktag.c
 msgid "tag on stdin did not pass our strict fsck check"
 msgstr "tag pada masukan standar tidak lolos pemeriksaan fsck ketat kami"
@@ -10926,11 +10970,6 @@
 msgstr "Tulis/sunting catatan untuk objek berikut:"
 
 #: builtin/notes.c
-#, c-format
-msgid "unable to start 'show' for object '%s'"
-msgstr "tidak dapat memulai 'show' untuk objek '%s'"
-
-#: builtin/notes.c
 msgid "could not read 'show' output"
 msgstr "tidak dapat membaca keluaran 'show'"
 
@@ -11365,6 +11404,11 @@
 
 #: builtin/pack-objects.c
 #, c-format
+msgid "invalid pack.allowPackReuse value: '%s'"
+msgstr "nilai pack.allowPackReuse tidak valid: '%s'"
+
+#: builtin/pack-objects.c
+#, c-format
 msgid ""
 "value of uploadpack.blobpackfileuri must be of the form '<object-hash> <pack-"
 "hash> <uri>' (got '%s')"
@@ -11694,10 +11738,10 @@
 #, c-format
 msgid ""
 "Total %<PRIu32> (delta %<PRIu32>), reused %<PRIu32> (delta %<PRIu32>), pack-"
-"reused %<PRIu32>"
+"reused %<PRIu32> (from %<PRIuMAX>)"
 msgstr ""
 "Total %<PRIu32> (delta %<PRIu32>), digunakan ulang %<PRIu32> (delta "
-"%<PRIu32>), pak yang digunakan ulang %<PRIu32>"
+"%<PRIu32>), pak yang digunakan ulang %<PRIu32> (dari %<PRIuMAX>)"
 
 #: builtin/pack-redundant.c
 msgid ""
@@ -11719,10 +11763,11 @@
 
 #: builtin/pack-refs.c
 msgid ""
-"git pack-refs [--all] [--no-prune] [--include <pattern>] [--exclude "
+"git pack-refs [--all] [--no-prune] [--auto] [--include <pattern>] [--exclude "
 "<pattern>]"
 msgstr ""
-"git pack-refs [--all] [--no-prune] [--include <pola>] [--exclude <pola>]"
+"git pack-refs [--all] [--no-prune] [--auto] [--include <pola>][--exclude "
+"<pola>]"
 
 #: builtin/pack-refs.c
 msgid "pack everything"
@@ -11733,6 +11778,10 @@
 msgstr "pangkas referensi longgar (asali)"
 
 #: builtin/pack-refs.c
+msgid "auto-pack refs as needed"
+msgstr "otomatis pak referensi jika dibutuhkan"
+
+#: builtin/pack-refs.c
 msgid "references to include"
 msgstr "referensi untuk ditambahkan"
 
@@ -12530,21 +12579,6 @@
 msgstr "tidak dapat menghapus '%s'"
 
 #: builtin/rebase.c
-msgid ""
-"Resolve all conflicts manually, mark them as resolved with\n"
-"\"git add/rm <conflicted_files>\", then run \"git rebase --continue\".\n"
-"You can instead skip this commit: run \"git rebase --skip\".\n"
-"To abort and get back to the state before \"git rebase\", run \"git rebase --"
-"abort\"."
-msgstr ""
-"Selesaikan semua konflik secara manual, tandai sebagai terselesaikan\n"
-"dengan \"git add/rm <berkas terkonflik>\", lalu jalankan\n"
-"\"git rebase --continue\".\n"
-"Anda juga bisa melewatkan komit ini: jalankan \"git rebase --skip\".\n"
-"Untuk membatalkan dan kembali ke kondisi sebelum \"git rebase\",jalankan "
-"\"git rebase --abort\"."
-
-#: builtin/rebase.c
 #, c-format
 msgid ""
 "\n"
@@ -12578,13 +12612,17 @@
 msgstr "opsi apply dan opsi merge tidak dapat digunakan bersamaan"
 
 #: builtin/rebase.c
+msgid "--empty=ask is deprecated; use '--empty=stop' instead."
+msgstr "--empty=ask usang; gunakan '--empty=stop' sebagai gantinya."
+
+#: builtin/rebase.c
 #, c-format
 msgid ""
 "unrecognized empty type '%s'; valid values are \"drop\", \"keep\", and "
-"\"ask\"."
+"\"stop\"."
 msgstr ""
 "tipe kosong tak dikenali '%s'; nilai yang valid adalah \"drop\", \"keep\", "
-"dan \"ask\"."
+"dan \"stop\"."
 
 #: builtin/rebase.c
 msgid ""
@@ -12726,7 +12764,7 @@
 msgid "(REMOVED) was: try to recreate merges instead of ignoring them"
 msgstr "(USANG) yaitu:  coba buat ulang penggabungan daripada abaikannya"
 
-#: builtin/rebase.c
+#: builtin/rebase.c builtin/revert.c
 msgid "how to handle commits that become empty"
 msgstr "bagaimana cara menangani komit yang menjadi kosong"
 
@@ -12808,15 +12846,15 @@
 "yang tidak lagi didukung; gunakan 'merges' sebagai gantinya"
 
 #: builtin/rebase.c
-msgid "No rebase in progress?"
-msgstr "Tidak ada pendasaran ulang yang sedang berjalan?"
+msgid "no rebase in progress"
+msgstr "tidak ada pendasaran ulang yang sedang berjalan"
 
 #: builtin/rebase.c
 msgid "The --edit-todo action can only be used during interactive rebase."
 msgstr ""
 "Aksi --edit-todo hanya dapat digunakan selama pendasaran ulang interaktif."
 
-#: builtin/rebase.c t/helper/test-fast-rebase.c
+#: builtin/rebase.c
 msgid "Cannot read HEAD"
 msgstr "Tidak dapat membaca HEAD"
 
@@ -12864,14 +12902,6 @@
 
 #: builtin/rebase.c
 msgid ""
-"apply options are incompatible with rebase.autoSquash.  Consider adding --no-"
-"autosquash"
-msgstr ""
-"opsi penerapan tidak kompatibel dengan rebase.autoSquash. "
-"Pertimbangkanmenambahkan --no-autosquash"
-
-#: builtin/rebase.c
-msgid ""
 "apply options are incompatible with rebase.rebaseMerges.  Consider adding --"
 "no-rebase-merges"
 msgstr ""
@@ -13046,6 +13076,10 @@
 msgstr "git remote [show] [<opsi log>] [<referensi>]"
 
 #: builtin/reflog.c
+msgid "git reflog list"
+msgstr "git reflog list"
+
+#: builtin/reflog.c
 msgid ""
 "git reflog expire [--expire=<time>] [--expire-unreachable=<time>]\n"
 "                  [--rewrite] [--updateref] [--stale-fix]\n"
@@ -13074,6 +13108,11 @@
 msgid "invalid timestamp '%s' given to '--%s'"
 msgstr "stempel waktu tidak valid '%s' diberikan ke '--%s'"
 
+#: builtin/reflog.c sequencer.c
+#, c-format
+msgid "%s does not accept arguments: '%s'"
+msgstr "%s tidak menerima argumen: '%s'"
+
 #: builtin/reflog.c
 msgid "do not actually prune any entries"
 msgstr "jangan benar-benar pangkas entri apapun"
@@ -13236,8 +13275,8 @@
 
 #: builtin/remote.c
 #, c-format
-msgid "unknown mirror argument: %s"
-msgstr "argumen mirror tidak dikenal: %s"
+msgid "unknown --mirror argument: %s"
+msgstr "argumen --mirror tidak dikenal: %s"
 
 #: builtin/remote.c
 msgid "fetch the remote branches"
@@ -13368,10 +13407,10 @@
 "Note: Some branches outside the refs/remotes/ hierarchy were not removed;\n"
 "to delete them, use:"
 msgstr[0] ""
-"Catatan: Sebuah cabang diluar hierarki refs/remotes tidak dihapus;\n"
+"Catatan: Sebuah cabang diluar hierarki refs/remotes/ tidak dihapus;\n"
 "untuk menghapusnya, gunakan:"
 msgstr[1] ""
-"Catatan: Beberapa cabang diluar hierarki refs/remotes tidak dihapus;\n"
+"Catatan: Beberapa cabang diluar hierarki refs/remotes/ tidak dihapus;\n"
 "untuk menghapusnya, gunakan:"
 
 #: builtin/remote.c
@@ -13694,6 +13733,10 @@
 msgstr "tidak dapat memulai pack-objects untuk mengepak ulang objek pejanji"
 
 #: builtin/repack.c
+msgid "failed to feed promisor objects to pack-objects"
+msgstr "gagal mengumpan objek penjanji ke pack-objects"
+
+#: builtin/repack.c
 msgid "repack: Expecting full hex object ID lines only from pack-objects."
 msgstr "repack: Mengharapkan baris ID objek hex penuh hanya dari pack-objects."
 
@@ -14108,6 +14151,94 @@
 msgid "only one pattern can be given with -l"
 msgstr "hanya satu pola yang dapat diberikan dengan -l"
 
+#: builtin/replay.c
+msgid "need some commits to replay"
+msgstr "butuh beberapa komit untuk dimainkan ulang"
+
+#: builtin/replay.c
+msgid "--onto and --advance are incompatible"
+msgstr "--onto dan --advance tidak kompatibel"
+
+#: builtin/replay.c
+msgid "all positive revisions given must be references"
+msgstr "semua revisi positif yang diberikan haruslah referensi"
+
+#: builtin/replay.c
+msgid "argument to --advance must be a reference"
+msgstr "argumen pada --advance harus sebuah referensi"
+
+#: builtin/replay.c
+msgid ""
+"cannot advance target with multiple sources because ordering would be ill-"
+"defined"
+msgstr ""
+"tidak dapat memajukan target dengan banyak sumber karena pengurutannya akan "
+"menjadi tidak jelas"
+
+#: builtin/replay.c
+msgid ""
+"cannot implicitly determine whether this is an --advance or --onto operation"
+msgstr ""
+"tidak dapat menentukan secara tidak langsung apakah ini operasi --advance "
+"atau --onto"
+
+#: builtin/replay.c
+msgid ""
+"cannot advance target with multiple source branches because ordering would "
+"be ill-defined"
+msgstr ""
+"tidak dapat memajukan target dengan banyak cabang sumber karena "
+"pengurutannya akan menjadi tidak jelas"
+
+#: builtin/replay.c
+msgid "cannot implicitly determine correct base for --onto"
+msgstr "tidak dapat menentukan secara tidak langsung dasar untuk --onto"
+
+#: builtin/replay.c
+msgid ""
+"(EXPERIMENTAL!) git replay ([--contained] --onto <newbase> | --advance "
+"<branch>) <revision-range>..."
+msgstr ""
+"(EKSPERIMENTAL!) git replay ([--contained] --onto <dasar baru> | --advance "
+"<cabang>) <rentang revisi>..."
+
+#: builtin/replay.c
+msgid "make replay advance given branch"
+msgstr "buat pemainan ulang memajukan caban yang diberikan"
+
+#: builtin/replay.c
+msgid "replay onto given commit"
+msgstr "mainkan ulang pada komit yang diberikan"
+
+#: builtin/replay.c
+msgid "advance all branches contained in revision-range"
+msgstr "majukan semua cabang yang berada pada rentang komit"
+
+#: builtin/replay.c
+msgid "option --onto or --advance is mandatory"
+msgstr "opsi --onto atau --advance diwajibkan"
+
+#: builtin/replay.c
+#, c-format
+msgid ""
+"some rev walking options will be overridden as '%s' bit in 'struct rev_info' "
+"will be forced"
+msgstr ""
+"beberapa opsi jalan revisi akan ditimpa oleh karena bit '%s' di 'struct "
+"rev_info' akan dipaksakan"
+
+#: builtin/replay.c
+msgid "error preparing revisions"
+msgstr "kesalahan menyiapkan revisi"
+
+#: builtin/replay.c
+msgid "replaying down to root commit is not supported yet!"
+msgstr "memainkan ulang ke komit akar belum didukung!"
+
+#: builtin/replay.c
+msgid "replaying merge commits is not supported yet!"
+msgstr "memainkan ulang komit penggabungan belum didukung!"
+
 #: builtin/rerere.c
 msgid ""
 "git rerere [clear | forget <pathspec>... | diff | status | remaining | gc]"
@@ -14366,22 +14497,19 @@
 msgstr "--prefix butuh sebuah argumen"
 
 #: builtin/rev-parse.c
+msgid "no object format specified"
+msgstr "tidak ada format objek yang disebutkan"
+
+#: builtin/rev-parse.c
+#, c-format
+msgid "unsupported object format: %s"
+msgstr "format objek tidak didukung: '%s'"
+
+#: builtin/rev-parse.c
 #, c-format
 msgid "unknown mode for --abbrev-ref: %s"
 msgstr "mode untuk --abbrev-ref tidak dikenal: %s"
 
-#: builtin/rev-parse.c revision.c
-msgid "--exclude-hidden cannot be used together with --branches"
-msgstr "--exclude-hidden tidak dapat digunakan bersamaan dengan --branches"
-
-#: builtin/rev-parse.c revision.c
-msgid "--exclude-hidden cannot be used together with --tags"
-msgstr "--exclude-hidden tidak dapat digunakan bersamaan dengan --tags"
-
-#: builtin/rev-parse.c revision.c
-msgid "--exclude-hidden cannot be used together with --remotes"
-msgstr "--exclude-hidden tidak dapat digunakan dengan --remotes"
-
 #: builtin/rev-parse.c setup.c
 msgid "this operation must be run in a work tree"
 msgstr "operasi ini harus dijalankan di dalam pohon kerja"
@@ -14482,8 +14610,8 @@
 msgstr "perbolehkan komit dengan pesan kosong"
 
 #: builtin/revert.c
-msgid "keep redundant, empty commits"
-msgstr "simpan komit kosong mubazir"
+msgid "deprecated: use --empty=keep instead"
+msgstr "usang: gunakan --empty=keep sebagai gantinya"
 
 #: builtin/revert.c
 msgid "use the 'reference' format to refer to commits"
@@ -14894,11 +15022,6 @@
 "perlihatkan referensi dari masukan standar yang tidak ada dalam repositori "
 "lokal"
 
-#: builtin/show-ref.c
-#, c-format
-msgid "only one of '%s', '%s' or '%s' can be given"
-msgstr "hanya salah satu dari '%s', '%s', dan '%s' dapat diberikan"
-
 #: builtin/sparse-checkout.c
 msgid ""
 "git sparse-checkout (init | list | set | add | reapply | disable | check-"
@@ -14949,7 +15072,7 @@
 msgid "toggle the use of a sparse index"
 msgstr "gunakan indeks tipis"
 
-#: builtin/sparse-checkout.c commit-graph.c midx.c sequencer.c
+#: builtin/sparse-checkout.c commit-graph.c midx-write.c sequencer.c
 #, c-format
 msgid "unable to create leading directories of %s"
 msgstr "tidak dapat membuat direktori utama dari %s"
@@ -16148,12 +16271,12 @@
 "\n"
 "Write a message for tag:\n"
 "  %s\n"
-"Lines starting with '%c' will be ignored.\n"
+"Lines starting with '%s' will be ignored.\n"
 msgstr ""
 "\n"
 "Tulis pesan untuk tag:\n"
 "  %s\n"
-"Baris yang diawali dengan '%c' akan diabaikan.\n"
+"Baris yang diawali dengan '%s' akan diabaikan.\n"
 
 #: builtin/tag.c
 #, c-format
@@ -16161,13 +16284,13 @@
 "\n"
 "Write a message for tag:\n"
 "  %s\n"
-"Lines starting with '%c' will be kept; you may remove them yourself if you "
+"Lines starting with '%s' will be kept; you may remove them yourself if you "
 "want to.\n"
 msgstr ""
 "\n"
 "Tulis pesan untuk tag:\n"
 "  %s\n"
-"Baris yang diawali dengan '%c' akan disimpan; Anda dapat menghapusnya bila "
+"Baris yang diawali dengan '%s' akan disimpan; Anda dapat menghapusnya bila "
 "Anda mau.\n"
 
 #: builtin/tag.c
@@ -16278,6 +16401,10 @@
 msgstr "hanya cetak tag dari objek"
 
 #: builtin/tag.c
+msgid "could not start 'git column'"
+msgstr "tidak dapat memulai 'git column'"
+
+#: builtin/tag.c
 #, c-format
 msgid "the '%s' option is only allowed in list mode"
 msgstr "opsi '%s' hanya diperbolehkan dalam mode daftar"
@@ -16589,13 +16716,12 @@
 msgstr "fsmonitor dinonaktifkan"
 
 #: builtin/update-ref.c
-msgid "git update-ref [<options>] -d <refname> [<old-val>]"
-msgstr "git update-ref [<opsi>] -d <nama referensi> [<nilai lama>]"
+msgid "git update-ref [<options>] -d <refname> [<old-oid>]"
+msgstr "git update-ref [<opsi>] -d <nama referensi> [<oid lama>]"
 
 #: builtin/update-ref.c
-msgid "git update-ref [<options>]    <refname> <new-val> [<old-val>]"
-msgstr ""
-"git update-ref [<opsi>]    <nama referensi> <nilai baru> [<nilai lama>]"
+msgid "git update-ref [<options>]    <refname> <new-oid> [<old-oid>]"
+msgstr "git update-ref [<options>]    <nama referensi> <oid baru> [<oid lama>]"
 
 #: builtin/update-ref.c
 msgid "git update-ref [<options>] --stdin [-z]"
@@ -16720,7 +16846,7 @@
 #: builtin/worktree.c
 #, c-format
 msgid ""
-"If you meant to create a worktree containing a new orphan branch\n"
+"If you meant to create a worktree containing a new unborn branch\n"
 "(branch with no commits) for this repository, you can do so\n"
 "using the --orphan flag:\n"
 "\n"
@@ -16734,7 +16860,7 @@
 #: builtin/worktree.c
 #, c-format
 msgid ""
-"If you meant to create a worktree containing a new orphan branch\n"
+"If you meant to create a worktree containing a new unborn branch\n"
 "(branch with no commits) for this repository, you can do so\n"
 "using the --orphan flag:\n"
 "\n"
@@ -16814,6 +16940,11 @@
 
 #: builtin/worktree.c
 #, c-format
+msgid "could not find created worktree '%s'"
+msgstr "tidak dapat menemukan pohon kerja yang dibuat '%s'"
+
+#: builtin/worktree.c
+#, c-format
 msgid "Preparing worktree (new branch '%s')"
 msgstr "Menyiapkan pohon kerja (cabang baru '%s')"
 
@@ -16859,11 +16990,6 @@
 "terlebih dahulu"
 
 #: builtin/worktree.c
-#, c-format
-msgid "'%s' and '%s' cannot be used together"
-msgstr "'%s' dan '%s' tidak dapat digunakan bersamaan"
-
-#: builtin/worktree.c
 msgid "checkout <branch> even if already checked out in other worktree"
 msgstr ""
 "checkout <cabang> bahkan jika sudah di-checkout pada pohon kerja lainnya"
@@ -16877,7 +17003,7 @@
 msgstr "buat atau setel ulang sebuah cabang"
 
 #: builtin/worktree.c
-msgid "create unborn/orphaned branch"
+msgid "create unborn branch"
 msgstr "buat cabang belum lahir/yatim"
 
 #: builtin/worktree.c
@@ -16907,12 +17033,8 @@
 
 #: builtin/worktree.c
 #, c-format
-msgid "options '%s', and '%s' cannot be used together"
-msgstr "Opsi '%s', dan '%s' tidak dapat digunakan bersamaan"
-
-#: builtin/worktree.c
-msgid "<commit-ish>"
-msgstr "<mirip-komit>"
+msgid "option '%s' and commit-ish cannot be used together"
+msgstr "opsi '%s' dan mirip-komit tidak dapat digunakan bersamaan"
 
 #: builtin/worktree.c
 msgid "added with --lock"
@@ -17715,6 +17837,12 @@
 msgstr "Buat, daftar, hapus referensi untuk mengganti objek"
 
 #: command-list.h
+msgid "EXPERIMENTAL: Replay commits on a new base, works with bare repos too"
+msgstr ""
+"EKSPERIMENTAL: Mainkan ulang komit pada dasar baru, dan juga bekerja pada "
+"repositori bare"
+
+#: command-list.h
 msgid "Generates a summary of pending changes"
 msgstr "Buat ringkasan perubahan tertunda"
 
@@ -18032,6 +18160,39 @@
 msgstr "berkas grafik komit terlalu kecil"
 
 #: commit-graph.c
+msgid "commit-graph oid fanout chunk is wrong size"
+msgstr "bingkah oid grafik komit kipas keluar salah ukuran"
+
+#: commit-graph.c
+msgid "commit-graph fanout values out of order"
+msgstr "nilai kipas keluar grafik komit tidak berurutan"
+
+#: commit-graph.c
+msgid "commit-graph OID lookup chunk is the wrong size"
+msgstr "bingkah OID pencarian grafik komit salah ukuran"
+
+#: commit-graph.c
+msgid "commit-graph commit data chunk is wrong size"
+msgstr "bingkah data grafik komit salah ukuran"
+
+#: commit-graph.c
+msgid "commit-graph generations chunk is wrong size"
+msgstr "bingkah generasi grafik komit salah ukuran"
+
+#: commit-graph.c
+msgid "commit-graph changed-path index chunk is too small"
+msgstr "bingkah indeks grafik komit jalur berubah terlalu kecil"
+
+#: commit-graph.c
+#, c-format
+msgid ""
+"ignoring too-small changed-path chunk (%<PRIuMAX> < %<PRIuMAX>) in commit-"
+"graph file"
+msgstr ""
+"mengabaikan bingkah jalur berubah yang terlalu kecil (%<PRIuMAX> < "
+"%<PRIuMAX>) di dalam berkas grafik komit"
+
+#: commit-graph.c
 #, c-format
 msgid "commit-graph signature %X does not match signature %X"
 msgstr "tanda tangan grafik komit %X tidak cocok dengan tanda tangan %X"
@@ -18052,6 +18213,19 @@
 msgstr "berkas grafik komit terlalu kecil untuk menyimpan %u bingkah"
 
 #: commit-graph.c
+msgid "commit-graph required OID fanout chunk missing or corrupted"
+msgstr ""
+"bingkah grafik komit OID kipas keluar yang diperlukan hilang atau rusak"
+
+#: commit-graph.c
+msgid "commit-graph required OID lookup chunk missing or corrupted"
+msgstr "bingkah grafik komit OID pencarian yang diperlukan hilang atau rusak"
+
+#: commit-graph.c
+msgid "commit-graph required commit data chunk missing or corrupted"
+msgstr "bingkah grafik komit data komit yang diperlukan hilang atau rusak"
+
+#: commit-graph.c
 msgid "commit-graph has no base graphs chunk"
 msgstr "grafik komit tidak punya bingkah grafik dasar"
 
@@ -18069,6 +18243,10 @@
 msgstr "jumlah komit pada grafik dasar terlalu tinggi: %<PRIuMAX>"
 
 #: commit-graph.c
+msgid "commit-graph chain file too small"
+msgstr "berkas rantai grafik komit terlalu kecil"
+
+#: commit-graph.c
 #, c-format
 msgid "invalid commit-graph chain: line '%s' not a hash"
 msgstr "rantai grafik komit tidak cocok: baris '%s' bukan sebuah hash"
@@ -18095,6 +18273,10 @@
 msgstr "data generasi luapan grafik komit terlalu kecil"
 
 #: commit-graph.c
+msgid "commit-graph extra-edges pointer out of bounds"
+msgstr "penunjuk tepi tambahan grafik komit di luar batas"
+
+#: commit-graph.c
 msgid "Loading known commits in commit graph"
 msgstr "Memuat komit yang dikenal di grafik komit"
 
@@ -18274,6 +18456,11 @@
 msgid "Verifying commits in commit graph"
 msgstr "Memverifikasi komit di dalam grafik komit"
 
+#: commit-reach.c sequencer.c
+#, c-format
+msgid "could not parse commit %s"
+msgstr "tidak dapat menguraikan komit %s"
+
 #: commit.c
 #, c-format
 msgid "%s %s is not a commit!"
@@ -18807,8 +18994,14 @@
 msgstr "level kompresi zlib jelek %d"
 
 #: config.c
-msgid "core.commentChar should only be one ASCII character"
-msgstr "core.commentChar seharusnya hanya satu karakter ASCII"
+#, c-format
+msgid "%s cannot contain newline"
+msgstr "%s tidak dapat berisi baris baru"
+
+#: config.c
+#, c-format
+msgid "%s must have at least one character"
+msgstr "%s harus ada sedikitnya satu karakter"
 
 #: config.c
 #, c-format
@@ -18898,6 +19091,11 @@
 
 #: config.c
 #, c-format
+msgid "no multi-line comment allowed: '%s'"
+msgstr "komentar multi baris tidak diperbolehkan: '%s'"
+
+#: config.c
+#, c-format
 msgid "could not lock config file %s"
 msgstr "tidak dapat mengunci berkas konfigurasi %s"
 
@@ -19505,6 +19703,11 @@
 msgid "Unknown value for 'diff.submodule' config variable: '%s'"
 msgstr "Nilai tidak dikenal untuk variabel konfigurasi 'diff.submodule': '%s'"
 
+#: diff.c transport.c
+#, c-format
+msgid "unknown value for config '%s': %s"
+msgstr "nilai tidak dikenal untuk konfigurasi '%s': %s"
+
 #: diff.c
 #, c-format
 msgid ""
@@ -19602,14 +19805,6 @@
 msgstr "mode tidak valid '%s' dalam --color-moved-ws"
 
 #: diff.c
-msgid ""
-"option diff-algorithm accepts \"myers\", \"minimal\", \"patience\" and "
-"\"histogram\""
-msgstr ""
-"opsi diff-algorithm terima \"myers\", \"minimal\", \"patience\" dan "
-"\"histogram\""
-
-#: diff.c
 #, c-format
 msgid "invalid argument to %s"
 msgstr "argumen tidak valid ke %s"
@@ -19666,8 +19861,8 @@
 msgstr "keluarkan hanya baris terakhir --stat"
 
 #: diff.c
-msgid "<param1,param2>..."
-msgstr "<parameter 1,parameter 2>..."
+msgid "<param1>,<param2>..."
+msgstr "<parameter 1>,<parameter 2>..."
 
 #: diff.c
 msgid ""
@@ -19680,8 +19875,8 @@
 msgstr "sinonim untuk --dirstat=cumulative"
 
 #: diff.c
-msgid "synonym for --dirstat=files,param1,param2..."
-msgstr "sinonim untuk --dirstat=files,param1,param2..."
+msgid "synonym for --dirstat=files,<param1>,<param2>..."
+msgstr "sinonim untuk --dirstat=files,<parameter 1>,<parameter 2>..."
 
 #: diff.c
 msgid "warn if changes introduce conflict markers or whitespace errors"
@@ -19914,14 +20109,6 @@
 msgstr "buat diff menggunakan algoritma \"diff histogram\""
 
 #: diff.c
-msgid "<algorithm>"
-msgstr "<algoritma>"
-
-#: diff.c
-msgid "choose a diff algorithm"
-msgstr "pilih algoritma diff"
-
-#: diff.c
 msgid "<text>"
 msgstr "<teks>"
 
@@ -21137,6 +21324,16 @@
 msgid "Unable to create '%s.lock': %s"
 msgstr "Tidak dapat membuat '%s.lock': %s"
 
+#: loose.c
+#, c-format
+msgid "could not write loose object index %s"
+msgstr "tidak dapat menulis indeks objek longgar %s"
+
+#: loose.c
+#, c-format
+msgid "failed to write loose object index %s\n"
+msgstr "gagal menulis indeks objek longgar %s\n"
+
 #: ls-refs.c
 #, c-format
 msgid "unexpected line: '%s'"
@@ -21150,6 +21347,11 @@
 msgid "quoted CRLF detected"
 msgstr "CRLF terkutip terdeteksi"
 
+#: mem-pool.c strbuf.c wrapper.c
+#, c-format
+msgid "unable to format message: %s"
+msgstr "tidak dapat memformat pesan: %s"
+
 #: merge-ort.c merge-recursive.c
 #, c-format
 msgid "Failed to merge submodule %s (not checked out)"
@@ -21167,6 +21369,11 @@
 
 #: merge-ort.c merge-recursive.c
 #, c-format
+msgid "Failed to merge submodule %s (repository corrupt)"
+msgstr "Gagal menggabungkan submodul %s (repositori rusak)"
+
+#: merge-ort.c merge-recursive.c
+#, c-format
 msgid "Failed to merge submodule %s (commits don't follow merge-base)"
 msgstr ""
 "Gagal menggabungkan submodul %s (komit tidak mengikuti dasar penggabungan)"
@@ -21725,11 +21932,117 @@
 msgid "failed to read the cache"
 msgstr "gagal membaca tembolok"
 
+#: midx-write.c
+#, c-format
+msgid "failed to add packfile '%s'"
+msgstr "gagal menambah berkas pak '%s'"
+
+#: midx-write.c
+#, c-format
+msgid "failed to open pack-index '%s'"
+msgstr "gagal membuka indeks pak '%s'"
+
+#: midx-write.c
+#, c-format
+msgid "failed to locate object %d in packfile"
+msgstr "gagal melokasi objek %d di dalam berkas pak"
+
+#: midx-write.c
+msgid "cannot store reverse index file"
+msgstr "tidak dapat menyimpan berkas indeks balik"
+
+#: midx-write.c
+#, c-format
+msgid "could not parse line: %s"
+msgstr "tidak dapat menguraikan baris: %s"
+
+#: midx-write.c
+#, c-format
+msgid "malformed line: %s"
+msgstr "baris jelek '%s'."
+
+#: midx-write.c
+msgid "ignoring existing multi-pack-index; checksum mismatch"
+msgstr "abaikan indeks multipak yang sudah ada; checksum tidak cocok"
+
+#: midx-write.c
+msgid "could not load pack"
+msgstr "tidak dapat memuat pak"
+
+#: midx-write.c
+#, c-format
+msgid "could not open index for %s"
+msgstr "tidak dapat membuka indeks untuk %s"
+
+#: midx-write.c
+msgid "Adding packfiles to multi-pack-index"
+msgstr "Menambahkan berkas pak ke indeks multipak"
+
+#: midx-write.c
+#, c-format
+msgid "unknown preferred pack: '%s'"
+msgstr "pak yang disukai tidak dikenal: '%s'"
+
+#: midx-write.c
+#, c-format
+msgid "cannot select preferred pack %s with no objects"
+msgstr "tidak dapat memilih pak yang disukai %s tanpa objek"
+
+#: midx-write.c
+#, c-format
+msgid "did not see pack-file %s to drop"
+msgstr "tidak melihat berkas pak %s untuk dijeblokkan"
+
+#: midx-write.c
+#, c-format
+msgid "preferred pack '%s' is expired"
+msgstr "pak yang disukai '%s' kadaluarsa"
+
+#: midx-write.c
+msgid "no pack files to index."
+msgstr "tidak ada berkas pak untuk diindeks."
+
+#: midx-write.c
+msgid "refusing to write multi-pack .bitmap without any objects"
+msgstr "menolak menulis .bitmap multipak tanpa objek apapun"
+
+#: midx-write.c
+msgid "could not write multi-pack bitmap"
+msgstr "tidak dapat menulis bitmap multipak"
+
+#: midx-write.c
+msgid "could not write multi-pack-index"
+msgstr "gagal menulis indeks multipak"
+
+#: midx-write.c
+msgid "Counting referenced objects"
+msgstr "Menghitung objek tereferensi"
+
+#: midx-write.c
+msgid "Finding and deleting unreferenced packfiles"
+msgstr "Mencari dan menghapus berkas pak tak tereferensi"
+
+#: midx-write.c
+msgid "could not start pack-objects"
+msgstr "tidak dapat memulai pack-objects"
+
+#: midx-write.c
+msgid "could not finish pack-objects"
+msgstr "tidak dapat menyelesaikan pack-objects"
+
 #: midx.c
 msgid "multi-pack-index OID fanout is of the wrong size"
 msgstr "OID kipas-keluar indeks multipak salah ukuran"
 
 #: midx.c
+#, c-format
+msgid ""
+"oid fanout out of order: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]"
+msgstr ""
+"kipas-keluar oid tidak berurutan: fanout[%d] =%<PRIx32> > %<PRIx32> = "
+"fanout[%d]"
+
+#: midx.c
 msgid "multi-pack-index OID lookup chunk is the wrong size"
 msgstr "bingkah pencarian OID kipas-keluar indeks multipak salah ukuran"
 
@@ -21791,6 +22104,15 @@
 msgstr "pack-int-id jelek: %u (total pak %u)"
 
 #: midx.c
+msgid "MIDX does not contain the BTMP chunk"
+msgstr "MIDX tidak berisi bingkah BTMP"
+
+#: midx.c
+#, c-format
+msgid "could not load bitmapped pack %<PRIu32>"
+msgstr "tidak dapat membuka pak terbitmap %<PRIu32>"
+
+#: midx.c
 msgid "multi-pack-index stores a 64-bit offset, but off_t is too small"
 msgstr "indeks multipak simpan offset 64-bit, tapi off_t terlalu kecil"
 
@@ -21800,88 +22122,6 @@
 
 #: midx.c
 #, c-format
-msgid "failed to add packfile '%s'"
-msgstr "gagal menambah berkas pak '%s'"
-
-#: midx.c
-#, c-format
-msgid "failed to open pack-index '%s'"
-msgstr "gagal membuka indeks pak '%s'"
-
-#: midx.c
-#, c-format
-msgid "failed to locate object %d in packfile"
-msgstr "gagal melokasi objek %d di dalam berkas pak"
-
-#: midx.c
-msgid "cannot store reverse index file"
-msgstr "tidak dapat menyimpan berkas indeks balik"
-
-#: midx.c
-#, c-format
-msgid "could not parse line: %s"
-msgstr "tidak dapat menguraikan baris: %s"
-
-#: midx.c
-#, c-format
-msgid "malformed line: %s"
-msgstr "baris jelek '%s'."
-
-#: midx.c
-msgid "ignoring existing multi-pack-index; checksum mismatch"
-msgstr "abaikan indeks multipak yang sudah ada; checksum tidak cocok"
-
-#: midx.c
-msgid "could not load pack"
-msgstr "tidak dapat memuat pak"
-
-#: midx.c
-#, c-format
-msgid "could not open index for %s"
-msgstr "tidak dapat membuka indeks untuk %s"
-
-#: midx.c
-msgid "Adding packfiles to multi-pack-index"
-msgstr "Menambahkan berkas pak ke indeks multipak"
-
-#: midx.c
-#, c-format
-msgid "unknown preferred pack: '%s'"
-msgstr "pak yang disukai tidak dikenal: '%s'"
-
-#: midx.c
-#, c-format
-msgid "cannot select preferred pack %s with no objects"
-msgstr "tidak dapat memilih pak yang disukai %s tanpa objek"
-
-#: midx.c
-#, c-format
-msgid "did not see pack-file %s to drop"
-msgstr "tidak melihat berkas pak %s untuk dijeblokkan"
-
-#: midx.c
-#, c-format
-msgid "preferred pack '%s' is expired"
-msgstr "pak yang disukai '%s' kadaluarsa"
-
-#: midx.c
-msgid "no pack files to index."
-msgstr "tidak ada berkas pak untuk diindeks."
-
-#: midx.c
-msgid "refusing to write multi-pack .bitmap without any objects"
-msgstr "menolak menulis .bitmap multipak tanpa objek apapun"
-
-#: midx.c
-msgid "could not write multi-pack bitmap"
-msgstr "tidak dapat menulis bitmap multipak"
-
-#: midx.c
-msgid "could not write multi-pack-index"
-msgstr "gagal menulis indeks multipak"
-
-#: midx.c
-#, c-format
 msgid "failed to clear multi-pack-index at %s"
 msgstr "gagal membersihkan indeks multipak pada %s"
 
@@ -21898,14 +22138,6 @@
 msgstr "Mencari berkas pak yang direferensikan"
 
 #: midx.c
-#, c-format
-msgid ""
-"oid fanout out of order: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]"
-msgstr ""
-"kipas-keluar oid tidak berurutan: fanout[%d] =%<PRIx32> > %<PRIx32> = "
-"fanout[%d]"
-
-#: midx.c
 msgid "the midx contains no oid"
 msgstr "midx tidak berisi oid"
 
@@ -21941,22 +22173,6 @@
 msgid "incorrect object offset for oid[%d] = %s: %<PRIx64> != %<PRIx64>"
 msgstr "offset objek salah untuk oid[%d] = %s: %<PRIx64> != %<PRIx64>"
 
-#: midx.c
-msgid "Counting referenced objects"
-msgstr "Menghitung objek tereferensi"
-
-#: midx.c
-msgid "Finding and deleting unreferenced packfiles"
-msgstr "Mencari dan menghapus berkas pak tak tereferensi"
-
-#: midx.c
-msgid "could not start pack-objects"
-msgstr "tidak dapat memulai pack-objects"
-
-#: midx.c
-msgid "could not finish pack-objects"
-msgstr "tidak dapat menyelesaikan pack-objects"
-
 #: name-hash.c
 #, c-format
 msgid "unable to create lazy_dir thread: %s"
@@ -22012,6 +22228,30 @@
 msgid "Bad %s value: '%s'"
 msgstr "Nilai %s jelek: '%s'"
 
+#: object-file-convert.c
+msgid "failed to decode tree entry"
+msgstr "gagal mendekode entri pohon"
+
+#: object-file-convert.c
+#, c-format
+msgid "failed to map tree entry for %s"
+msgstr "gagal memetakan entri pohon untuk %s"
+
+#: object-file-convert.c
+#, c-format
+msgid "bad %s in commit"
+msgstr "%s di dalam komit"
+
+#: object-file-convert.c
+#, c-format
+msgid "unable to map %s %s in commit object"
+msgstr "tidak dapat memetakan %s %s pada objek komit"
+
+#: object-file-convert.c
+#, c-format
+msgid "Failed to convert object from %s to %s"
+msgstr "Gagal mengkonversi objek dari %s ke %s"
+
 #: object-file.c
 #, c-format
 msgid "object directory %s does not exist; check .git/objects/info/alternates"
@@ -22141,6 +22381,11 @@
 
 #: object-file.c
 #, c-format
+msgid "missing mapping of %s to %s"
+msgstr "pemetaan %s ke %s hilang"
+
+#: object-file.c
+#, c-format
 msgid "unable to write file %s"
 msgstr "tidak dapat menulis berkas %s"
 
@@ -22210,6 +22455,11 @@
 
 #: object-file.c
 #, c-format
+msgid "cannot map object %s to %s"
+msgstr "tidak dapat memetakan objek %s ke %s"
+
+#: object-file.c
+#, c-format
 msgid "object fails fsck: %s"
 msgstr "fsck objek gagal: %s"
 
@@ -22542,6 +22792,10 @@
 msgid "could not open pack %s"
 msgstr "tidak dapat membuka '%s'"
 
+#: pack-bitmap.c t/helper/test-read-midx.c
+msgid "could not determine MIDX preferred pack"
+msgstr "tidak dapat menentukan pak MIDX terpilih"
+
 #: pack-bitmap.c
 #, c-format
 msgid "preferred pack (%s) is invalid"
@@ -22567,6 +22821,16 @@
 
 #: pack-bitmap.c
 #, c-format
+msgid "unable to load pack: '%s', disabling pack-reuse"
+msgstr "tidak dapat memuat pak: '%s', mematikan penggunaan ulang pak"
+
+#: pack-bitmap.c
+msgid "unable to compute preferred pack, disabling pack-reuse"
+msgstr ""
+"tidak dapat menghitung pak yang disukai, mematikan penggunaan ulang pak"
+
+#: pack-bitmap.c
+#, c-format
 msgid "object '%s' not found in type bitmaps"
 msgstr "objek '%s' tidak ditemukan di bitmap tipe"
 
@@ -22680,6 +22944,10 @@
 msgid "multi-pack-index reverse-index chunk is the wrong size"
 msgstr "bingkah indeks balik multipak salah ukuran"
 
+#: pack-revindex.c
+msgid "could not determine preferred pack"
+msgstr "tidak dapat menentukan pak terpilih"
+
 #: pack-write.c
 msgid "cannot both write and verify reverse index"
 msgstr "tidak dapat kedua-duanya menulis dan memverifikasi indeks balik"
@@ -22762,11 +23030,6 @@
 
 #: parse-options.c
 #, c-format
-msgid "%s is incompatible with %s"
-msgstr "%s tidak kompatibel dengan %s"
-
-#: parse-options.c
-#, c-format
 msgid "ambiguous option: %s (could be --%s%s or --%s%s)"
 msgstr "opsi ambigu: %s (bisa jadi --%s%s atau --%s%s)"
 
@@ -23166,11 +23429,6 @@
 
 #: read-cache.c
 #, c-format
-msgid "unable to stat '%s'"
-msgstr "tidak dapat men-stat '%s'"
-
-#: read-cache.c
-#, c-format
 msgid "'%s' appears as both a file and as a directory"
 msgstr "'%s' muncul baik sebagai sebuah berkas dan sebagai sebuah direktori"
 
@@ -23855,21 +24113,99 @@
 msgid "cannot process '%s' and '%s' at the same time"
 msgstr "tidak dapat memproses '%s' dan '%s' pada waktu yang bersamaan"
 
-#: refs/files-backend.c
-#, c-format
-msgid "could not remove reference %s"
-msgstr "tidak dapat menghapus referensi %s"
-
-#: refs/files-backend.c refs/packed-backend.c
+#: refs.c
 #, c-format
 msgid "could not delete reference %s: %s"
 msgstr "tidak dapat menghapus referensi %s: %s"
 
-#: refs/files-backend.c refs/packed-backend.c
+#: refs.c
 #, c-format
 msgid "could not delete references: %s"
 msgstr "tidak dapat menghapus referensi: %s"
 
+#: refs/reftable-backend.c
+#, c-format
+msgid "refname is dangerous: %s"
+msgstr "nama referensi berbahaya: %s"
+
+#: refs/reftable-backend.c
+#, c-format
+msgid "trying to write ref '%s' with nonexistent object %s"
+msgstr "mencoba menulis referensi '%s' dengan objek %s yang tak ada"
+
+#: refs/reftable-backend.c
+#, c-format
+msgid "trying to write non-commit object %s to branch '%s'"
+msgstr "mencoba menulis objek non-komit %s pada cabang '%s'"
+
+#: refs/reftable-backend.c
+#, c-format
+msgid ""
+"multiple updates for 'HEAD' (including one via its referent '%s') are not "
+"allowed"
+msgstr ""
+"beberapa pembaruan 'HEAD' (termasuk yang lewat perujuknya '%s' tidak "
+"diperbolehkan"
+
+#: refs/reftable-backend.c
+#, c-format
+msgid "cannot lock ref '%s': unable to resolve reference '%s'"
+msgstr "tidak dapat mengunci '%s': tidak dapat menguraikan referensi '%s'"
+
+#: refs/reftable-backend.c
+#, c-format
+msgid "cannot lock ref '%s': error reading reference"
+msgstr "tidak dapat mengunci referensi '%s': kesalahan membaca referensi"
+
+#: refs/reftable-backend.c
+#, c-format
+msgid ""
+"multiple updates for '%s' (including one via symref '%s') are not allowed"
+msgstr ""
+"beberapa pembaruan '%s' (termasuk yang lewat referensi simboliknya "
+"'%s')tidak diperbolehkan"
+
+#: refs/reftable-backend.c
+#, c-format
+msgid "cannot lock ref '%s': reference already exists"
+msgstr "tidak dapat mengunci referensi '%s': referensi sudah ada"
+
+#: refs/reftable-backend.c
+#, c-format
+msgid "cannot lock ref '%s': reference is missing but expected %s"
+msgstr ""
+"tidak dapat mengunci referensi '%s' referensi %s hilang tapi diharapkan"
+
+#: refs/reftable-backend.c
+#, c-format
+msgid "cannot lock ref '%s': is at %s but expected %s"
+msgstr "tidak dapat mengunci referensi '%s': pada %s tetapi diharapkan %s"
+
+#: refs/reftable-backend.c
+#, c-format
+msgid "reftable: transaction prepare: %s"
+msgstr "reftable: menyiapkan transaksi: %s"
+
+#: refs/reftable-backend.c
+#, c-format
+msgid "reftable: transaction failure: %s"
+msgstr "reftable: transaksi gagal: %s"
+
+#: refs/reftable-backend.c
+#, c-format
+msgid "unable to compact stack: %s"
+msgstr "tidak dapat memampatkan tumpukan: %s"
+
+#: refs/reftable-backend.c
+#, c-format
+msgid "refname %s not found"
+msgstr "nama referensi %s tidak ditemukan"
+
+#: refs/reftable-backend.c
+#, c-format
+msgid "refname %s is a symbolic ref, copying it is not supported"
+msgstr "nama referensi %s simbolik, menyalinnya tidak didukung"
+
 #: refspec.c
 #, c-format
 msgid "invalid refspec '%s'"
@@ -23882,6 +24218,11 @@
 
 #: remote-curl.c
 #, c-format
+msgid "unknown value for object-format: %s"
+msgstr "nilai object-format tidak dikenal: %s"
+
+#: remote-curl.c
+#, c-format
 msgid "%sinfo/refs not valid: is this a git repository?"
 msgstr "%sinfo/refs tidak valid: apakah ini sebuah repositori git?"
 
@@ -24100,9 +24441,9 @@
 msgstr ""
 "Tujuan yang Anda berikan bukan nama referensi penuh (seperti \n"
 "dimulai dengan \"refs/\"). Kami mencoba menebak maksud Anda dengan:\n"
-"- Cari referensi yang cocok dengan '%s' pada sisi remote.\n"
-"- Perika apakah <src> yang sedang didorong ('%s') adalah \n"
-"  referensi pada \"refs/{heads,tags}\". Bila demikian kami \n"
+"- mencari referensi yang cocok dengan '%s' pada sisi remote.\n"
+"- memeriksa apakah <src> yang sedang didorong ('%s') adalah \n"
+"  referensi pada \"refs/{heads,tags}/\". Bila demikian kami \n"
 "  menambahkan awalan refs/{heads,tags}/ yang bersesuaian pada sisi \n"
 "  remote.\n"
 "\n"
@@ -24429,8 +24770,21 @@
 
 #: revision.c
 #, c-format
-msgid "could not get commit for ancestry-path argument %s"
-msgstr "tidak dapat mendapatkan komit untuk argumen jalur leluhur '%s'"
+msgid "%s exists but is a symbolic ref"
+msgstr "%s ada dan tapi referensi simbolik"
+
+#: revision.c
+msgid ""
+"--merge requires one of the pseudorefs MERGE_HEAD, CHERRY_PICK_HEAD, "
+"REVERT_HEAD or REBASE_HEAD"
+msgstr ""
+"--merge butuh salah satu dari referensi semu MERGE_HEAD, CHERRY_PICK_HEAD, "
+"REVERT_HEAD atau REBASE_HEAD"
+
+#: revision.c
+#, c-format
+msgid "could not get commit for --ancestry-path argument %s"
+msgstr "tidak dapat mendapatkan komit untuk argumen --ancestry-path %s"
 
 #: revision.c
 msgid "--unpacked=<packfile> no longer supported"
@@ -24794,6 +25148,21 @@
 
 #: sequencer.c
 msgid ""
+"Resolve all conflicts manually, mark them as resolved with\n"
+"\"git add/rm <conflicted_files>\", then run \"git rebase --continue\".\n"
+"You can instead skip this commit: run \"git rebase --skip\".\n"
+"To abort and get back to the state before \"git rebase\", run \"git rebase --"
+"abort\"."
+msgstr ""
+"Selesaikan semua konflik secara manual, tandai sebagai terselesaikan\n"
+"dengan \"git add/rm <berkas terkonflik>\", lalu jalankan\n"
+"\"git rebase --continue\".\n"
+"Anda juga bisa melewatkan komit ini: jalankan \"git rebase --skip\".\n"
+"Untuk membatalkan dan kembali ke kondisi sebelum \"git rebase\",jalankan "
+"\"git rebase --abort\"."
+
+#: sequencer.c
+msgid ""
 "after resolving the conflicts, mark the corrected paths\n"
 "with 'git add <paths>' or 'git rm <paths>'"
 msgstr ""
@@ -25042,18 +25411,13 @@
 msgid "corrupt author: missing date information"
 msgstr "pengarang rusak: informasi tanggal hilang"
 
-#: sequencer.c t/helper/test-fast-rebase.c
+#: sequencer.c
 #, c-format
 msgid "could not update %s"
 msgstr "tidak dapat memperbarui %s"
 
 #: sequencer.c
 #, c-format
-msgid "could not parse commit %s"
-msgstr "tidak dapat menguraikan komit %s"
-
-#: sequencer.c
-#, c-format
 msgid "could not parse parent commit %s"
 msgstr "tidak dapat menguraikan komit induk %s"
 
@@ -25186,11 +25550,6 @@
 
 #: sequencer.c
 #, c-format
-msgid "%s does not accept arguments: '%s'"
-msgstr "%s tidak menerima argumen: '%s'"
-
-#: sequencer.c
-#, c-format
 msgid "missing arguments for %s"
 msgstr "argumen hilang untuk %s"
 
@@ -25537,6 +25896,10 @@
 msgstr "Stase otomatis sudah ada; membuat entri stase baru."
 
 #: sequencer.c
+msgid "autostash reference is a symref"
+msgstr "referensi autostase itu referensi simbolik"
+
+#: sequencer.c
 msgid "could not detach HEAD"
 msgstr "tidak dapat melepas HEAD"
 
@@ -25742,6 +26105,11 @@
 
 #: setup.c
 #, c-format
+msgid "'%s' already specified as '%s'"
+msgstr "'%s' sudah diberikan yaitu '%s'"
+
+#: setup.c
+#, c-format
 msgid "Expected git repo version <= %d, found %d"
 msgstr "Versi repositori git diharapkan <= %d, dapat %d"
 
@@ -25918,6 +26286,11 @@
 
 #: setup.c
 #, c-format
+msgid "re-init: ignored --initial-branch=%s"
+msgstr "re-init: --initial-branch=%s diabaikan"
+
+#: setup.c
+#, c-format
 msgid "unable to handle file type %d"
 msgstr "tidak dapat menangani tipe berkas %d"
 
@@ -25931,14 +26304,16 @@
 msgstr "mencoba menginisialisasi ulang repositori dengan hash yang berbeda"
 
 #: setup.c
-#, c-format
-msgid "%s already exists"
-msgstr "%s sudah ada"
+msgid ""
+"attempt to reinitialize repository with different reference storage format"
+msgstr ""
+"mencoba menginisialisasi ulang repositori dengan format penyimpanan "
+"referensi yang berbeda"
 
 #: setup.c
 #, c-format
-msgid "re-init: ignored --initial-branch=%s"
-msgstr "re-init: --initial-branch=%s diabaikan"
+msgid "%s already exists"
+msgstr "%s sudah ada"
 
 #: setup.c
 #, c-format
@@ -25969,6 +26344,24 @@
 msgid "cannot use split index with a sparse index"
 msgstr "tidak dapat menggunakan indeks terpisah dengan indeks tipis"
 
+#. TRANSLATORS: The first %s is a command like "ls-tree".
+#: strbuf.c
+#, c-format
+msgid "bad %s format: element '%s' does not start with '('"
+msgstr "format %s jelek: elemen '%s' tidak dimulai dengan '('"
+
+#. TRANSLATORS: The first %s is a command like "ls-tree".
+#: strbuf.c
+#, c-format
+msgid "bad %s format: element '%s' does not end in ')'"
+msgstr "format %s jelek: elemen '%s' tidak diakhiri dengan ')'"
+
+#. TRANSLATORS: %s is a command like "ls-tree".
+#: strbuf.c
+#, c-format
+msgid "bad %s format: %%%.*s"
+msgstr "format %s jelek: %%%.*s"
+
 #. TRANSLATORS: IEC 80000-13:2008 gibibyte
 #: strbuf.c
 #, c-format
@@ -26264,14 +26657,6 @@
 msgid "number of entries in the cache tree to invalidate (default 0)"
 msgstr "jumlah entri di dalam pohon tembolok untuk dinirvalidasi (asali 0)"
 
-#: t/helper/test-fast-rebase.c
-msgid "unhandled options"
-msgstr "opsi tak tertangani"
-
-#: t/helper/test-fast-rebase.c
-msgid "error preparing revisions"
-msgstr "kesalahan menyiapkan revisi"
-
 #: t/helper/test-reach.c
 #, c-format
 msgid "commit %s is not marked reachable"
@@ -26378,35 +26763,6 @@
 msgid "empty trailer token in trailer '%.*s'"
 msgstr "token trailer kosong dalam trailer '%.*s'"
 
-#: trailer.c
-#, c-format
-msgid "could not read input file '%s'"
-msgstr "tidak dapat membaca berkas masukan '%s'"
-
-#: trailer.c wrapper.c
-#, c-format
-msgid "could not stat %s"
-msgstr "tidak dapat membaca %s"
-
-#: trailer.c
-#, c-format
-msgid "file %s is not a regular file"
-msgstr "berkas %s bukan sebuah berkas reguler"
-
-#: trailer.c
-#, c-format
-msgid "file %s is not writable by user"
-msgstr "berkas %s tidak dapat ditulis oleh pengguna"
-
-#: trailer.c
-msgid "could not open temporary file"
-msgstr "tidak dapat membuka berkas sementara"
-
-#: trailer.c
-#, c-format
-msgid "could not rename temporary file to %s"
-msgstr "tidak dapat menamai ulang berkas sementara ke %s"
-
 #: transport-helper.c
 msgid "full write to remote helper failed"
 msgstr "gagal menulis penuh ke pembantu remote"
@@ -26469,10 +26825,6 @@
 msgid "invalid remote service path"
 msgstr "jalur layanan remote tidak valid"
 
-#: transport-helper.c transport.c
-msgid "operation not supported by protocol"
-msgstr "operasi tidak didukung oleh protokol"
-
 #: transport-helper.c
 #, c-format
 msgid "can't connect to subservice %s"
@@ -26532,8 +26884,8 @@
 
 #: transport-helper.c
 #, c-format
-msgid "helper %s does not support 'force'"
-msgstr "pembantu %s tidak mendukung 'force'"
+msgid "helper %s does not support '--force'"
+msgstr "pembantu %s tidak mendukung '--force'"
 
 #: transport-helper.c
 msgid "couldn't run fast-export"
@@ -26638,11 +26990,6 @@
 
 #: transport.c
 #, c-format
-msgid "unknown value for config '%s': %s"
-msgstr "nilai tidak dikenal untuk konfigurasi '%s': %s"
-
-#: transport.c
-#, c-format
 msgid "transport '%s' not allowed"
 msgstr "transportasi '%s' tidak diperbolehkan"
 
@@ -26701,6 +27048,10 @@
 msgid "could not retrieve server-advertised bundle-uri list"
 msgstr "tidak dapat menerima daftar bundle-uri teriklankan server"
 
+#: transport.c
+msgid "operation not supported by protocol"
+msgstr "operasi tidak didukung oleh protokol"
+
 #: tree-walk.c
 msgid "too-short tree object"
 msgstr "objek pohon terlalu pendek"
@@ -27017,6 +27368,11 @@
 msgstr "segmen jalur '..' tidak valid"
 
 #: usage.c
+#, c-format
+msgid "error: unable to format message: %s\n"
+msgstr "kesalahan: tidak dapat memformat pesan: %s\n"
+
+#: usage.c
 msgid "usage: "
 msgstr "penggunaan: "
 
@@ -27722,6 +28078,11 @@
 msgid "cannot %s: Your index contains uncommitted changes."
 msgstr "tidak dapat %s: indeks Anda berisi perubahan yang belum dikomit."
 
+#: xdiff-interface.c
+#, c-format
+msgid "unknown style '%s' given for '%s'"
+msgstr "nilai gaya tidak dikenal '%s' diberikan untuk '%s'"
+
 #: git-merge-octopus.sh git-merge-resolve.sh
 msgid ""
 "Error: Your local changes to the following files would be overwritten by "
diff --git a/po/sv.po b/po/sv.po
index cd2a86a..ad1aad9 100644
--- a/po/sv.po
+++ b/po/sv.po
@@ -1,14 +1,14 @@
 # Swedish translations for Git.
-# Copyright (C) 2010-2023 Peter Krefting <peter@softwolves.pp.se>
+# Copyright (C) 2010-2024 Peter Krefting <peter@softwolves.pp.se>
 # This file is distributed under the same license as the Git package.
-# Peter Krefting <peter@softwolves.pp.se>, 2010-2023.
+# Peter Krefting <peter@softwolves.pp.se>, 2010-2024.
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: git 2.43.0\n"
+"Project-Id-Version: git 2.45.0\n"
 "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2023-11-09 14:12+0100\n"
-"PO-Revision-Date: 2023-11-09 14:28+0100\n"
+"POT-Creation-Date: 2024-04-27 15:19+0100\n"
+"PO-Revision-Date: 2024-04-27 15:20+0100\n"
 "Last-Translator: Peter Krefting <peter@softwolves.pp.se>\n"
 "Language-Team: Svenska <tp-sv@listor.tp-sv.se>\n"
 "Language: sv\n"
@@ -490,12 +490,12 @@
 "---\n"
 "To remove '%c' lines, make them ' ' lines (context).\n"
 "To remove '%c' lines, delete them.\n"
-"Lines starting with %c will be removed.\n"
+"Lines starting with %s will be removed.\n"
 msgstr ""
 "---\n"
 "Ta bort ”%c” rader genom att göra dem ” ”-rader (sammanhang).\n"
 "Ta bort ”%c” rader genom att radera dem.\n"
-"Rader som börjar med %c kommer att tas bort.\n"
+"Rader som börjar med %s kommer att tas bort.\n"
 
 msgid ""
 "If it does not apply cleanly, you will be given an opportunity to\n"
@@ -542,6 +542,7 @@
 "/ - search for a hunk matching the given regex\n"
 "s - split the current hunk into smaller hunks\n"
 "e - manually edit the current hunk\n"
+"p - print the current hunk\n"
 "? - print help\n"
 msgstr ""
 "j - lämna stycket obestämt, se nästa obestämda stycke\n"
@@ -552,6 +553,7 @@
 "/ - sök efter stycke som motsvarar angivet reguljärt uttryck\n"
 "s - dela aktuellt stycke i mindre styckens\n"
 "e - redigera aktuellt stycke manuellt\n"
+"p - visa aktuellt stycke\n"
 "? - visa hjälp\n"
 
 msgid "No previous hunk"
@@ -614,8 +616,8 @@
 "Slå av meddelandet med ”git config advice.%s false”"
 
 #, c-format
-msgid "%shint: %.*s%s\n"
-msgstr "%stips: %.*s%s\n"
+msgid "%shint:%s%.*s%s\n"
+msgstr "%stips:%s%.*s%s\n"
 
 msgid "Cherry-picking is not possible because you have unmerged files."
 msgstr ""
@@ -889,11 +891,11 @@
 
 #, c-format
 msgid "unable to read symlink %s"
-msgstr "kunde inte läsa symboliska länken %s"
+msgstr "kan inte läsa symboliska länken %s"
 
 #, c-format
 msgid "unable to open or read %s"
-msgstr "kunde inte öppna eller läsa %s"
+msgstr "kan inte öppna eller läsa %s"
 
 #, c-format
 msgid "invalid start of line: '%c'"
@@ -1116,10 +1118,6 @@
 msgstr[1] "Tillämpade patchen %%s med %d refuserade..."
 
 #, c-format
-msgid "truncating .rej filename to %.*s.rej"
-msgstr "trunkerar .rej-filnamnet till %.*s.rej"
-
-#, c-format
 msgid "cannot open %s"
 msgstr "kan inte öppna %s"
 
@@ -1168,7 +1166,7 @@
 msgstr[1] "%d rader applicerade efter att ha rättat fel i blanksteg."
 
 msgid "Unable to write new index file"
-msgstr "Kunde inte skriva ny indexfil"
+msgstr "Kan inte skriva ny indexfil"
 
 msgid "don't apply changes matching the given path"
 msgstr "tillämpa inte ändringar som motsvarar given sökväg"
@@ -1276,7 +1274,7 @@
 
 #, c-format
 msgid "unable to start '%s' filter"
-msgstr "kunde inte starta filtret ”%s”"
+msgstr "kane inte starta filtret ”%s”"
 
 msgid "unable to redirect descriptor"
 msgstr "kan inte omdirigera handtag"
@@ -1418,6 +1416,10 @@
 msgstr "Oväntad flagga --output"
 
 #, c-format
+msgid "extra command line parameter '%s'"
+msgstr "falsk konfigureringsparameter: ”%s”"
+
+#, c-format
 msgid "Unknown archive format '%s'"
 msgstr "Okänt arkivformat ”%s”"
 
@@ -1430,7 +1432,7 @@
 msgstr "%-*s är inte ett giltigt namn på attribut"
 
 msgid "unable to add additional attribute"
-msgstr "Kunde inte lägga till ytterligare attribut"
+msgstr "kan inte lägga till ytterligare attribut"
 
 #, c-format
 msgid "ignoring overly long attributes line %d"
@@ -1463,6 +1465,14 @@
 msgstr "felaktig --attr-source eller GIT_ATTR_SOURCE"
 
 #, c-format
+msgid "unable to stat '%s'"
+msgstr "kan inte ta status på ”%s”"
+
+#, c-format
+msgid "unable to read %s"
+msgstr "kan inte läsa %s"
+
+#, c-format
 msgid "Badly quoted content in file '%s': %s"
 msgstr "Felaktigt citerat innehåll i filen ”%s”: %s"
 
@@ -1532,6 +1542,10 @@
 msgstr "kunde inte skapa filen ”%s”"
 
 #, c-format
+msgid "unable to start 'show' for object '%s'"
+msgstr "kan inte starta ”show” för objektet ”%s”"
+
+#, c-format
 msgid "could not read file '%s'"
 msgstr "kunde inte läsa filen ”%s”"
 
@@ -1681,6 +1695,9 @@
 msgid "'%s' is not a valid branch name"
 msgstr "”%s” är inte ett giltigt grennamn"
 
+msgid "See `man git check-ref-format`"
+msgstr "Se ”man git check-ref-format”"
+
 #, c-format
 msgid "a branch named '%s' already exists"
 msgstr "det finns redan en gren som heter ”%s”"
@@ -1873,14 +1890,8 @@
 msgid "adding embedded git repository: %s"
 msgstr "lägger till inbäddat git-arkiv: %s"
 
-msgid ""
-"Use -f if you really want to add them.\n"
-"Turn this message off by running\n"
-"\"git config advice.addIgnoredFile false\""
-msgstr ""
-"Använd -f om du verkligen vill lägga till dem.\n"
-"Slå av detta meddelande med\n"
-"”git config advice.addIgnoredFile false”"
+msgid "Use -f if you really want to add them."
+msgstr "Använd -f om du verkligen vill lägga till dem."
 
 msgid "adding files failed"
 msgstr "misslyckades lägga till filer"
@@ -1897,20 +1908,14 @@
 msgid "Nothing specified, nothing added.\n"
 msgstr "Inget angivet, inget tillagt.\n"
 
-msgid ""
-"Maybe you wanted to say 'git add .'?\n"
-"Turn this message off by running\n"
-"\"git config advice.addEmptyPathspec false\""
-msgstr ""
-"Tänkte du kanske säga ”git add .”?\n"
-"Slå av detta meddelande genom att köra\n"
-"”git config advice.addEmptyPathspec false”"
+msgid "Maybe you wanted to say 'git add .'?"
+msgstr "Tänkte du kanske säga ”git add .”?"
 
 msgid "index file corrupt"
 msgstr "indexfilen trasig"
 
 msgid "unable to write new index file"
-msgstr "kunde inte skriva ny indexfil"
+msgstr "kan inte skriva ny indexfil"
 
 #, c-format
 msgid "bad action '%s' for '%s'"
@@ -1981,18 +1986,19 @@
 msgstr "Misslyckades dela patchar."
 
 #, c-format
-msgid "When you have resolved this problem, run \"%s --continue\"."
-msgstr "När du har löst problemet, kör ”%s --continue”."
+msgid "When you have resolved this problem, run \"%s --continue\".\n"
+msgstr "När du har löst problemet, kör ”%s --continue”.\n"
 
 #, c-format
-msgid "If you prefer to skip this patch, run \"%s --skip\" instead."
-msgstr "Om du hellre vill hoppa över patchen, kör ”%s --skip” i stället."
+msgid "If you prefer to skip this patch, run \"%s --skip\" instead.\n"
+msgstr "Om du hellre vill hoppa över patchen, kör ”%s --skip” i stället.\n"
 
 #, c-format
-msgid "To record the empty patch as an empty commit, run \"%s --allow-empty\"."
+msgid ""
+"To record the empty patch as an empty commit, run \"%s --allow-empty\".\n"
 msgstr ""
 "För att registrera den tomma patchen som en tom incheckning, kör ”%s --allow-"
-"empty”."
+"empty”.\n"
 
 #, c-format
 msgid "To restore the original branch and stop patching, run \"%s --abort\"."
@@ -2013,7 +2019,7 @@
 
 #, c-format
 msgid "unable to parse commit %s"
-msgstr "kunde inte tolka incheckningen %s"
+msgstr "kan inte tolka incheckningen %s"
 
 msgid "Repository lacks necessary blobs to fall back on 3-way merge."
 msgstr ""
@@ -2044,7 +2050,7 @@
 msgstr "tillämpar på en tom historik"
 
 msgid "failed to write commit object"
-msgstr "kunde inte skriva incheckningsobjekt"
+msgstr "misslyckades skriva incheckningsobjekt"
 
 #, c-format
 msgid "cannot resume: %s does not exist."
@@ -2345,7 +2351,7 @@
 msgid ""
 "could not check out original HEAD '%s'. Try 'git bisect reset <commit>'."
 msgstr ""
-"Kunde inte checka ut original-HEAD ”%s”. Försök ”git bisect reset "
+"kan inte checka ut original-HEAD ”%s”. Försök ”git bisect reset "
 "<incheckning>”."
 
 #, c-format
@@ -2582,7 +2588,7 @@
 msgstr "visa inte objektnamn för gränsincheckningar (Standard: av)"
 
 msgid "do not treat root commits as boundaries (Default: off)"
-msgstr "vehandla inte rotincheckningar som gränser (Standard: av)"
+msgstr "behandla inte rotincheckningar som gränser (Standard: av)"
 
 msgid "show work cost statistics"
 msgstr "visa statistik över arbetskostnad"
@@ -2734,12 +2740,12 @@
 msgstr "kunde inte slå upp incheckningsobjekt för ”%s”"
 
 #, c-format
-msgid ""
-"the branch '%s' is not fully merged.\n"
-"If you are sure you want to delete it, run 'git branch -D %s'"
-msgstr ""
-"grenen ”%s” har inte slagits samman i sin helhet.\n"
-"Om du är säker på att du vill ta bort den, kör ”git branch -D %s”"
+msgid "the branch '%s' is not fully merged"
+msgstr "grenen ”%s” har inte slagits samman i sin helhet"
+
+#, c-format
+msgid "If you are sure you want to delete it, run 'git branch -D %s'"
+msgstr "Om du är säker på att du vill ta bort den, kör ”git branch -D %s”"
 
 msgid "update of config-file failed"
 msgstr "misslyckades uppdatera konfigurationsfil"
@@ -2837,11 +2843,11 @@
 msgid ""
 "Please edit the description for the branch\n"
 "  %s\n"
-"Lines starting with '%c' will be stripped.\n"
+"Lines starting with '%s' will be stripped.\n"
 msgstr ""
 "Redigera beskrivningen för grenen\n"
 "  %s\n"
-"Rader som inleds med ”%c” ignoreras.\n"
+"Rader som inleds med ”%s” ignoreras.\n"
 
 msgid "Generic options"
 msgstr "Allmänna flaggor"
@@ -3040,11 +3046,13 @@
 msgstr "körs inte från ett git-arkiv - inga krokar att visa\n"
 
 msgid ""
-"git bugreport [(-o | --output-directory) <path>] [(-s | --suffix) <format>]\n"
+"git bugreport [(-o | --output-directory) <path>]\n"
+"              [(-s | --suffix) <format> | --no-suffix]\n"
 "              [--diagnose[=<mode>]]"
 msgstr ""
-"git bugreport [(-o | --output-directory) <fil>] [(-s | --suffix) <format>]\n"
-"              [--diagnose[=<läge>]"
+"git bugreport [(-o | --output-directory) <sökväg>]\n"
+"              [(-s | --suffix) <format> | --no-suffix]\n"
+"              [--diagnose[=<läge>]]"
 
 msgid ""
 "Thank you for filling out a Git bug report!\n"
@@ -3105,7 +3113,7 @@
 
 #, c-format
 msgid "unable to create diagnostics archive %s"
-msgstr "kunde inte skapa diagnostikarkiven %s"
+msgstr "kan inte skapa diagnostikarkiven %s"
 
 msgid "System Info"
 msgstr "Systeminfo"
@@ -3115,7 +3123,7 @@
 
 #, c-format
 msgid "unable to write to %s"
-msgstr "kunde inte skriva till %s"
+msgstr "kan inte skriva till %s"
 
 #, c-format
 msgid "Created new report at '%s'.\n"
@@ -3395,7 +3403,7 @@
 
 #, c-format
 msgid "unable to parse contact: %s"
-msgstr "kunde inte tolka kontakt: %s"
+msgstr "kan inte tolka kontakt: %s"
 
 msgid "no contacts specified"
 msgstr "inga kontakter angavs"
@@ -3476,7 +3484,7 @@
 
 #, c-format
 msgid "Unable to add merge result for '%s'"
-msgstr "Kunde inte lägga till sammanslagningsresultat för ”%s”"
+msgstr "Kan inte lägga till sammanslagningsresultat för ”%s”"
 
 #, c-format
 msgid "Recreated %d merge conflict"
@@ -3524,6 +3532,10 @@
 msgid "path '%s' is unmerged"
 msgstr "sökvägen ”%s” har inte slagits ihop"
 
+#, c-format
+msgid "unable to read tree (%s)"
+msgstr "kan inte läsa träd (%s)"
+
 msgid "you need to resolve your current index first"
 msgstr "du måste lösa ditt befintliga index först"
 
@@ -3754,6 +3766,10 @@
 msgid "missing branch or commit argument"
 msgstr "saknar gren- eller incheckingsargument"
 
+#, c-format
+msgid "unknown conflict style '%s'"
+msgstr "okänd konflikttyp ”%s”"
+
 msgid "perform a 3-way merge with the new branch"
 msgstr "utför en 3-vägssammanslagning för den nya grenen"
 
@@ -3772,8 +3788,8 @@
 msgid "new-branch"
 msgstr "ny-gren"
 
-msgid "new unparented branch"
-msgstr "ny gren utan förälder"
+msgid "new unborn branch"
+msgstr "ny ofödd gren"
 
 msgid "update ignored files (default)"
 msgstr "uppdatera ignorerade filer (standard)"
@@ -4009,22 +4025,8 @@
 msgid "remove only ignored files"
 msgstr "ta endast bort ignorerade filer"
 
-msgid ""
-"clean.requireForce set to true and neither -i, -n, nor -f given; refusing to "
-"clean"
-msgstr ""
-"clean.requireForce satt till true, men varken -i, -n eller -f angavs; vägrar "
-"städa"
-
-msgid ""
-"clean.requireForce defaults to true and neither -i, -n, nor -f given; "
-"refusing to clean"
-msgstr ""
-"clean.requireForce har standardvärdet true och varken -i, -n eller -f "
-"angavs; vägrar städa"
-
-msgid "-x and -X cannot be used together"
-msgstr "-x och -X kan inte användas samtidigt"
+msgid "clean.requireForce is true and -f not given: refusing to clean"
+msgstr "clean.requireForce är true och -f angavs inte: vägrar städa"
 
 msgid "git clone [<options>] [--] <repo> [<dir>]"
 msgstr "git clone [<flaggor>] [--] <arkiv> [<kat>]"
@@ -4038,8 +4040,8 @@
 msgid "create a bare repository"
 msgstr "skapa ett naket (”bare”) arkiv"
 
-msgid "create a mirror repository (implies bare)"
-msgstr "skapa ett spegelarkiv (implicerar ”bare”)"
+msgid "create a mirror repository (implies --bare)"
+msgstr "skapa ett spegelarkiv (implicerar --bare)"
 
 msgid "to clone from a local repository"
 msgstr "för att klona från ett lokalt arkiv"
@@ -4113,6 +4115,9 @@
 msgid "separate git dir from working tree"
 msgstr "separera gitkatalogen från arbetskatalogen"
 
+msgid "specify the reference format to use"
+msgstr "använd referensformatet som ska användas"
+
 msgid "key=value"
 msgstr "nyckel=värde"
 
@@ -4211,10 +4216,10 @@
 msgstr "HEAD hos fjärren pekar på en obefintlig referens, kan inte checka ut"
 
 msgid "unable to checkout working tree"
-msgstr "kunde inte checka ut arbetskatalogen"
+msgstr "kan inte checka ut arbetskatalogen"
 
 msgid "unable to write parameters to config file"
-msgstr "kunde inte skriva parametrar till konfigurationsfilen"
+msgstr "kan inte skriva parametrar till konfigurationsfilen"
 
 msgid "cannot repack to clean up"
 msgstr "kan inte packa om för att städa upp"
@@ -4228,12 +4233,9 @@
 msgid "You must specify a repository to clone."
 msgstr "Du måste ange ett arkiv att klona."
 
-msgid ""
-"--bundle-uri is incompatible with --depth, --shallow-since, and --shallow-"
-"exclude"
-msgstr ""
-"--bundle-uri är inkompatibelt med --depth, --shallow-since och --shallow-"
-"exclude"
+#, c-format
+msgid "unknown ref storage format '%s'"
+msgstr "okänt format för lagring av referenser ”%s”"
 
 #, c-format
 msgid "repository '%s' does not exist"
@@ -4347,6 +4349,10 @@
 msgid "padding space between columns"
 msgstr "spaltfyllnad mellan spalter"
 
+#, c-format
+msgid "%s must be non-negative"
+msgstr "%s måste vara icke-negativt"
+
 msgid "--command must be the first argument"
 msgstr "--command måste vara första argument"
 
@@ -4361,7 +4367,7 @@
 "--stdin-commits]\n"
 "                       [--changed-paths] [--[no-]max-new-filters <n>] [--"
 "[no-]progress]\n"
-"                       <split options>"
+"                       <split-options>"
 msgstr ""
 "git commit-graph write [--object-dir <kat>] [--append]\n"
 "                       [--split[=<strategi>]] [--reachable | --stdin-packs | "
@@ -4575,7 +4581,7 @@
 msgstr "Du måste ange sökvägar tillsammans med --include/--only."
 
 msgid "unable to create temporary index"
-msgstr "kunde inte skapa temporär indexfil"
+msgstr "kan inte skapa temporär indexfil"
 
 msgid "interactive add failed"
 msgstr "interaktiv tilläggning misslyckades"
@@ -4599,7 +4605,7 @@
 msgstr "kan inte läsa indexet"
 
 msgid "unable to write temporary index file"
-msgstr "kunde inte skriva temporär indexfil"
+msgstr "kan inte skriva temporär indexfil"
 
 #, c-format
 msgid "commit '%s' lacks author header"
@@ -4620,7 +4626,7 @@
 "unable to select a comment character that is not used\n"
 "in the current commit message"
 msgstr ""
-"kunde inte välja ett kommentarstecken som inte använts\n"
+"kan inte välja ett kommentarstecken som inte använts\n"
 "i det befintliga incheckningsmeddelandet"
 
 #, c-format
@@ -4658,35 +4664,35 @@
 #, c-format
 msgid ""
 "Please enter the commit message for your changes. Lines starting\n"
-"with '%c' will be ignored.\n"
+"with '%s' will be ignored.\n"
 msgstr ""
 "Ange incheckningsmeddelandet för dina ändringar. Rader som inleds\n"
-"med ”%c” kommer ignoreras.\n"
+"med ”%s” kommer ignoreras.\n"
 
 #, 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"
+"with '%s' will be ignored, and an empty message aborts the commit.\n"
 msgstr ""
 "Ange incheckningsmeddelandet för dina ändringar. Rader som inleds\n"
-"med ”%c” kommer ignoreras, och ett tomt meddelande avbryter incheckningen.\n"
+"med ”%s” kommer ignoreras, och ett tomt meddelande avbryter incheckningen.\n"
 
 #, 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"
+"with '%s' will be kept; you may remove them yourself if you want to.\n"
 msgstr ""
 "Ange incheckningsmeddelandet för dina ändringar. Rader som inleds\n"
-"med ”%c” kommer behållas; du kan själv ta bort dem om du vill.\n"
+"med ”%s” kommer behållas; du kan själv ta bort dem om du vill.\n"
 
 #, 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"
+"with '%s' will be kept; you may remove them yourself if you want to.\n"
 "An empty message aborts the commit.\n"
 msgstr ""
 "Ange incheckningsmeddelandet för dina ändringar. Rader som inleds\n"
-"med ”%c” kommer behållas; du kan själv ta bort dem om du vill.\n"
+"med ”%s” kommer behållas; du kan själv ta bort dem om du vill.\n"
 "Ett tomt meddelande avbryter incheckningen.\n"
 
 msgid ""
@@ -5125,6 +5131,9 @@
 msgid "with --get, use default value when missing entry"
 msgstr "med --get, använd standardvärde vid saknad post"
 
+msgid "human-readable comment string (# will be prepended as needed)"
+msgstr "människoläsbar kommentarssträng (# läggs in först efter behov)"
+
 #, c-format
 msgid "wrong number of arguments, should be %d"
 msgstr "fel antal argument, skulle vara %d"
@@ -5217,6 +5226,9 @@
 msgid "--default is only applicable to --get"
 msgstr "--default gäller bara för --get"
 
+msgid "--comment is only applicable to add/set/replace operations"
+msgstr "--comment gäller bara för ”get”/”set”/”replace”-operationerna"
+
 msgid "--fixed-value only applies with 'value-pattern'"
 msgstr "--fixed-value gäller endast med ”värde-mönster”"
 
@@ -5275,7 +5287,7 @@
 
 #, c-format
 msgid "unable to get credential storage lock in %d ms"
-msgstr "kunde inte erhålla låset för lagring av inlogginsuppgifter på %d ms"
+msgstr "kan inte erhålla låset för lagring av inlogginsuppgifter på %d ms"
 
 msgid ""
 "git describe [--all] [--tags] [--contains] [--abbrev=<n>] [<commit-ish>...]"
@@ -5684,7 +5696,7 @@
 msgstr "[uppdaterad tagg]"
 
 msgid "unable to update local ref"
-msgstr "kunde inte uppdatera lokal ref"
+msgstr "kan inte uppdatera lokal ref"
 
 msgid "would clobber existing tag"
 msgstr "skulle skriva över befintlig tagg"
@@ -6052,6 +6064,9 @@
 msgid "read reference patterns from stdin"
 msgstr "läs referensmönster från standard in"
 
+msgid "also include HEAD ref and pseudorefs"
+msgstr "ta också med HEAD- och pseudo-referenser"
+
 msgid "unknown arguments supplied with --stdin"
 msgstr "okända argument angavs tillsammans med --stdin"
 
@@ -6238,7 +6253,7 @@
 
 #, c-format
 msgid "unable to load rev-index for pack '%s'"
-msgstr "kunde inte läsa rev-index för paketfil ”%s”"
+msgstr "kan inte läsa rev-index för paketfil ”%s”"
 
 #, c-format
 msgid "invalid rev-index for pack '%s'"
@@ -6447,11 +6462,11 @@
 
 #, c-format
 msgid "failed to parse gc.logExpiry value %s"
-msgstr "kunde inte tolka värdet %s för gc.logExpiry"
+msgstr "misslyckades tolka värdet %s för gc.logExpiry"
 
 #, c-format
 msgid "failed to parse prune expiry value %s"
-msgstr "kunde inte tolka värdet %s för prune expiry"
+msgstr "misslyckades tolka värdet %s för prune expiry"
 
 #, c-format
 msgid "Auto packing the repository in background for optimum performance.\n"
@@ -6490,19 +6505,19 @@
 msgstr "okänt argument för --schedule, %s"
 
 msgid "failed to write commit-graph"
-msgstr "kunde inte skriva incheckningsgraf"
+msgstr "misslyckades skriva incheckningsgraf"
 
 msgid "failed to prefetch remotes"
-msgstr "kunde inte förhämta fjärrar"
+msgstr "misslyckades förhämta fjärrar"
 
 msgid "failed to start 'git pack-objects' process"
-msgstr "kunde inte starta ”git pack-objects”-process"
+msgstr "misslyckades starta ”git pack-objects”-process"
 
 msgid "failed to finish 'git pack-objects' process"
-msgstr "kunde inte avsluta ”git pack-objects”-process"
+msgstr "misslyckades att avsluta ”git pack-objects”-process"
 
 msgid "failed to write multi-pack-index"
-msgstr "kunde inte skriva multi-pack-index"
+msgstr "misslyckades skriva multi-pack-index"
 
 msgid "'git multi-pack-index expire' failed"
 msgstr "”git multi-pack-index expire” misslyckades"
@@ -6671,12 +6686,12 @@
 msgstr "trådstöd saknas, ignorerar %s"
 
 #, c-format
-msgid "unable to read tree (%s)"
-msgstr "kunde inte läsa träd (%s)"
+msgid "unable to read tree %s"
+msgstr "kan inte läsa trädet %s"
 
 #, c-format
 msgid "unable to grep from object of type %s"
-msgstr "kunde inte ”grep” från objekt av typen %s"
+msgstr "kan inte ”grep” från objekt av typen %s"
 
 #, c-format
 msgid "switch `%c' expects a numerical value"
@@ -6932,7 +6947,7 @@
 msgstr "Misslyckades starta emacsclient."
 
 msgid "Failed to parse emacsclient version."
-msgstr "Kunde inte tolka emacsclient-version."
+msgstr "Misslyckades tolka emacsclient-version."
 
 #, c-format
 msgid "emacsclient version '%d' too old (< 22)."
@@ -6940,7 +6955,7 @@
 
 #, c-format
 msgid "failed to exec '%s'"
-msgstr "exec misslyckades för ”%s”"
+msgstr "”exec” misslyckades för ”%s”"
 
 #, c-format
 msgid ""
@@ -7081,10 +7096,6 @@
 msgstr "SHA1-KOLLISION UPPTÄCKT VID %s !"
 
 #, c-format
-msgid "unable to read %s"
-msgstr "kunde inte läsa %s"
-
-#, c-format
 msgid "cannot read existing object info %s"
 msgstr "kan inte läsa information om befintligt objekt %s"
 
@@ -7129,7 +7140,7 @@
 
 #, c-format
 msgid "unable to create thread: %s"
-msgstr "kunde inte skapa tråd: %s"
+msgstr "kan inte skapa tråd: %s"
 
 msgid "confusion beyond insanity"
 msgstr "förvirrad bortom vanvett"
@@ -7152,7 +7163,7 @@
 
 #, c-format
 msgid "unable to deflate appended object (%d)"
-msgstr "kunde inte utföra ”deflate” på tillagt objekt (%d)"
+msgstr "kan inte utföra ”deflate” på tillagt objekt (%d)"
 
 #, c-format
 msgid "local object %s is corrupt"
@@ -7172,7 +7183,7 @@
 
 #, c-format
 msgid "unable to rename temporary '*.%s' file to '%s'"
-msgstr "kunde inte byta namn på temporär ”*.%s”-fil till ”%s”"
+msgstr "kan inte byta namn på temporär ”*.%s”-fil till ”%s”"
 
 msgid "error while closing pack file"
 msgstr "fel vid stängning av paketfil"
@@ -7224,11 +7235,13 @@
 msgid ""
 "git init [-q | --quiet] [--bare] [--template=<template-directory>]\n"
 "         [--separate-git-dir <git-dir>] [--object-format=<format>]\n"
+"         [--ref-format=<format>]\n"
 "         [-b <branch-name> | --initial-branch=<branch-name>]\n"
 "         [--shared[=<permissions>]] [<directory>]"
 msgstr ""
 "git init [-q | --quiet] [--bare] [--template=<mallkatalog>]\n"
 "         [--separate-git-dir <git-kat>] [--object-format=<format>]\n"
+"         [--ref-format=<format>]\n"
 "         [-b <grennamn> | --initial-branch=<grennamn>]\n"
 "         [--shared[=<behörigheter>]] [<katalog>]"
 
@@ -7272,14 +7285,40 @@
 
 msgid ""
 "git interpret-trailers [--in-place] [--trim-empty]\n"
-"                       [(--trailer (<key>|<keyAlias>)[(=|:)<value>])...]\n"
+"                       [(--trailer (<key>|<key-alias>)[(=|:)<value>])...]\n"
 "                       [--parse] [<file>...]"
 msgstr ""
 "git interpret-trailers [--in-place] [--trim-empty]\n"
-"                       [(--trailer (<nyckel>|<nyckelAlias>)"
+"                       [(--trailer (<nyckel>|<nyckel-alias>)"
 "[(=|:)<värde>])...]\n"
 "                       [--parse] [<fil>...]"
 
+#, c-format
+msgid "could not stat %s"
+msgstr "kunde inte ta status på %s"
+
+#, c-format
+msgid "file %s is not a regular file"
+msgstr "filen %s är inte en normal fil"
+
+#, c-format
+msgid "file %s is not writable by user"
+msgstr "filen %s är inte skrivbar av användaren"
+
+msgid "could not open temporary file"
+msgstr "kunde inte öppna temporär fil"
+
+#, c-format
+msgid "could not read input file '%s'"
+msgstr "kunde inte läsa indatafilen ”%s”"
+
+msgid "could not read from stdin"
+msgstr "kunde inte läsa från standard in"
+
+#, c-format
+msgid "could not rename temporary file to %s"
+msgstr "kunde inte byta namn på temporär fil till %s"
+
 msgid "edit files in place"
 msgstr "redigera filer på plats"
 
@@ -7369,7 +7408,7 @@
 msgstr "Slututdata: %d %s\n"
 
 msgid "unable to create temporary object directory"
-msgstr "kunde inte skapa temporär objektkatalog"
+msgstr "kan inte skapa temporär objektkatalog"
 
 #, c-format
 msgid "git show %s: bad file"
@@ -7436,12 +7475,12 @@
 "please use git branch --set-upstream-to to track a remote branch.\n"
 "Or you could specify base commit by --base=<base-commit-id> manually"
 msgstr ""
-"kunde inte hämta uppström, om du vill lagra basincheckningen automatiskt,\n"
+"misslyckades hämta uppström, om du vill lagra basincheckningen automatiskt,\n"
 "använd git branch --set-upstream-to för att spåra en fjärrgren.\n"
 "Eller så kan du ange basincheckning med --base=<bas-inchecknings-id> manuellt"
 
 msgid "failed to find exact merge base"
-msgstr "kunde inte hitta exakt sammanslagningsbas"
+msgstr "misslyckades hitta exakt sammanslagningsbas"
 
 msgid "base commit should be the ancestor of revision list"
 msgstr "basincheckningen bör vara förfader till revisionslistan"
@@ -7642,7 +7681,7 @@
 
 #, c-format
 msgid "unable to read signature file '%s'"
-msgstr "kunde inte läsa signaturfil ”%s”"
+msgstr "kan inte läsa signaturfil ”%s”"
 
 msgid "Generating patches"
 msgstr "Skapar patchar"
@@ -7662,18 +7701,6 @@
 msgid "could not get object info about '%s'"
 msgstr "kunde inte hämta objektinfo om ”%s”"
 
-#, c-format
-msgid "bad ls-files format: element '%s' does not start with '('"
-msgstr "felaktigt ls-files-format: elementet ”%s” börjar inte med ”(”"
-
-#, c-format
-msgid "bad ls-files format: element '%s' does not end in ')'"
-msgstr "felaktigt ls-files-format: elementet ”%s” slutar inte med ”)”"
-
-#, c-format
-msgid "bad ls-files format: %%%.*s"
-msgstr "felaktigt ls-files-format: %%%.*s"
-
 msgid "git ls-files [<options>] [<file>...]"
 msgstr "git ls-files [<flaggor>] [<fil>...]"
 
@@ -7804,18 +7831,6 @@
 msgid "git ls-tree [<options>] <tree-ish> [<path>...]"
 msgstr "git ls-tree [<flaggor>] <träd-igt> [<sökväg>...]"
 
-#, c-format
-msgid "bad ls-tree format: element '%s' does not start with '('"
-msgstr "felaktigt ls-tree-format: elementet ”%s” börjar inte med ”(”"
-
-#, c-format
-msgid "bad ls-tree format: element '%s' does not end in ')'"
-msgstr "felaktigt ls-tree-format: elementet ”%s” slutar inte med ”)”"
-
-#, c-format
-msgid "bad ls-tree format: %%%.*s"
-msgstr "felaktigt ls-tree-format: %%%.*s"
-
 msgid "only show trees"
 msgstr "visa endast träd"
 
@@ -7927,6 +7942,12 @@
 "git merge-file [<alternativ>] [-L <namn1> [-L <orig> [-L <namn2>]]] <fil1> "
 "<origfil> <fil2>"
 
+msgid ""
+"option diff-algorithm accepts \"myers\", \"minimal\", \"patience\" and "
+"\"histogram\""
+msgstr ""
+"flaggan diff-algorithm godtar ”myers”, ”minimal”, ”patience” och ”histogram”"
+
 msgid "send results to standard output"
 msgstr "sänd resultat till standard ut"
 
@@ -7948,6 +7969,12 @@
 msgid "for conflicts, use a union version"
 msgstr "för konflikter, använd en förenad version"
 
+msgid "<algorithm>"
+msgstr "<algoritm>"
+
+msgid "choose a diff algorithm"
+msgstr "välj en diff-algoritm"
+
 msgid "for conflicts, use this marker size"
 msgstr "för konflikter, använd denna markörstorlek"
 
@@ -7989,6 +8016,10 @@
 msgid "Merging %s with %s\n"
 msgstr "Slår ihop %s med %s\n"
 
+#, c-format
+msgid "could not parse as tree '%s'"
+msgstr "kunde inte tolka som träd ”%s”"
+
 msgid "not something we can merge"
 msgstr "inte något vi kan slå ihop"
 
@@ -8038,9 +8069,6 @@
 msgid "unknown strategy option: -X%s"
 msgstr "okänd strategiflagga: -X%s"
 
-msgid "--merge-base is incompatible with --stdin"
-msgstr "--merge-base är inkompatibel med --stdin"
-
 #, c-format
 msgid "malformed input line: '%s'."
 msgstr "felaktig indatarad: ”%s”."
@@ -8162,14 +8190,14 @@
 msgstr "Felaktig branch.%s.mergeoptions-sträng: %s"
 
 msgid "Unable to write index."
-msgstr "Kunde inte skriva indexet."
+msgstr "Kan inte skriva indexet."
 
 msgid "Not handling anything other than two heads merge."
 msgstr "Hanterar inte något annat än en sammanslagning av två huvuden."
 
 #, c-format
 msgid "unable to write %s"
-msgstr "kunde inte skriva %s"
+msgstr "kan inte skriva %s"
 
 #, c-format
 msgid "Could not read from '%s'"
@@ -8195,10 +8223,10 @@
 
 #, c-format
 msgid ""
-"Lines starting with '%c' will be ignored, and an empty message aborts\n"
+"Lines starting with '%s' will be ignored, and an empty message aborts\n"
 "the commit.\n"
 msgstr ""
-"Rader som inleds med ”%c” kommer ignoreras, och ett tomt meddelande\n"
+"Rader som inleds med ”%s” kommer ignoreras, och ett tomt meddelande\n"
 "avbryter incheckningen.\n"
 
 msgid "Empty commit message."
@@ -8356,9 +8384,6 @@
 msgid "object '%s' tagged as '%s', but is a '%s' type"
 msgstr "objektet ”%s” taggat som ”%s”, men är av typen ”%s”"
 
-msgid "could not read from stdin"
-msgstr "kunde inte läsa från standard in"
-
 msgid "tag on stdin did not pass our strict fsck check"
 msgstr "tagg på stdin godkänns inte av vår strikta fsck-kontroll"
 
@@ -8366,7 +8391,7 @@
 msgstr "taggen på stdin pekar inte på ett giltigt objekt"
 
 msgid "unable to write tag file"
-msgstr "kunde inte skriva tagg-filen"
+msgstr "kan inte skriva tagg-filen"
 
 msgid "input is NUL terminated"
 msgstr "indata är NUL-terminerad"
@@ -8620,22 +8645,18 @@
 msgid "Write/edit the notes for the following object:"
 msgstr "Skriv/redigera anteckningar för följande objekt:"
 
-#, c-format
-msgid "unable to start 'show' for object '%s'"
-msgstr "kunde inte starta ”show” för objektet ”%s”"
-
 msgid "could not read 'show' output"
-msgstr "kunde inte läsa utdata från ”show”"
+msgstr "kan inte läsa utdata från ”show”"
 
 #, c-format
 msgid "failed to finish 'show' for object '%s'"
-msgstr "kunde inte avsluta ”show” för objektet ”%s”"
+msgstr "misslyckades att avsluta ”show” för objektet ”%s”"
 
 msgid "please supply the note contents using either -m or -F option"
 msgstr "ange innehåll för anteckningen med antingen -m eller -F"
 
 msgid "unable to write note object"
-msgstr "kunde inte skriva anteckningsobjekt"
+msgstr "kan inte skriva anteckningsobjekt"
 
 #, c-format
 msgid "the note contents have been left in %s"
@@ -8647,11 +8668,11 @@
 
 #, c-format
 msgid "failed to resolve '%s' as a valid ref."
-msgstr "kunde inte slå upp ”%s” som en giltig referens."
+msgstr "misslyckades slå upp ”%s” som en giltig referens."
 
 #, c-format
 msgid "failed to read object '%s'."
-msgstr "kunde inte läsa objektet ”%s”."
+msgstr "misslyckades läsa objektet ”%s”."
 
 #, c-format
 msgid "cannot read note data from non-blob object '%s'."
@@ -8829,7 +8850,7 @@
 
 #, c-format
 msgid "Failed to resolve '%s' as a valid ref."
-msgstr "Kunde inte slå upp ”%s” som en giltig referens."
+msgstr "Misslyckades slå upp ”%s” som en giltig referens."
 
 #, c-format
 msgid "Object %s has no note\n"
@@ -8935,7 +8956,7 @@
 
 #, c-format
 msgid "unable to parse object header of %s"
-msgstr "kunde inte tolka objekthuvud för %s"
+msgstr "kan inte tolka objekthuvud för %s"
 
 #, c-format
 msgid "object %s cannot be read"
@@ -8958,7 +8979,7 @@
 
 #, c-format
 msgid "unable to get type of object %s"
-msgstr "kunde inte hämta typ för objektet %s"
+msgstr "kan inte hämta typ för objektet %s"
 
 msgid "Compressing objects"
 msgstr "Komprimerar objekt"
@@ -8967,6 +8988,10 @@
 msgstr "deltaräknaren är inkonsekvent"
 
 #, c-format
+msgid "invalid pack.allowPackReuse value: '%s'"
+msgstr "felaktigt värde för pack.allowPackReuse: ”%s”"
+
+#, c-format
 msgid ""
 "value of uploadpack.blobpackfileuri must be of the form '<object-hash> <pack-"
 "hash> <uri>' (got '%s')"
@@ -9219,10 +9244,10 @@
 #, c-format
 msgid ""
 "Total %<PRIu32> (delta %<PRIu32>), reused %<PRIu32> (delta %<PRIu32>), pack-"
-"reused %<PRIu32>"
+"reused %<PRIu32> (from %<PRIuMAX>)"
 msgstr ""
 "Totalt %<PRIu32> (delta %<PRIu32>), återanvände %<PRIu32> (delta %<PRIu32>), "
-"paket-återanvända %<PRIu32>"
+"paket-återanvända %<PRIu32> (från %<PRIuMAX>)"
 
 msgid ""
 "'git pack-redundant' is nominated for removal.\n"
@@ -9241,10 +9266,10 @@
 msgstr "vägrar köra utan --i-still-use-this"
 
 msgid ""
-"git pack-refs [--all] [--no-prune] [--include <pattern>] [--exclude "
+"git pack-refs [--all] [--no-prune] [--auto] [--include <pattern>] [--exclude "
 "<pattern>]"
 msgstr ""
-"git pack-refs [--all] [--no-prune] [--include <mönster>] [--exclude "
+"git pack-refs [--all] [--no-prune] [--auto] [--include <mönster>] [--exclude "
 "<mönster>]"
 
 msgid "pack everything"
@@ -9253,6 +9278,9 @@
 msgid "prune loose refs (default)"
 msgstr "ta bort lösa referenser (standard)"
 
+msgid "auto-pack refs as needed"
+msgstr "packa referenser automatiskt om nödvändigt"
+
 msgid "references to include"
 msgstr "referenser att ta med"
 
@@ -9387,7 +9415,7 @@
 
 #, c-format
 msgid "unable to access commit %s"
-msgstr "kunde inte komma åt incheckningen %s"
+msgstr "kan inte komma åt incheckningen %s"
 
 msgid "ignoring --verify-signatures for rebase"
 msgstr "ignorera --verify-signatures för ombasering"
@@ -9878,7 +9906,7 @@
 msgstr "kunde inte markera som interaktiv"
 
 msgid "could not generate todo list"
-msgstr "Kunde inte skapa attgöra-lista"
+msgstr "kunde inte skapa attgöra-lista"
 
 msgid "a base commit must be provided with --upstream or --onto"
 msgstr "en basincheckning måste anges med --upstream eller --onto"
@@ -9903,19 +9931,6 @@
 msgid "could not remove '%s'"
 msgstr "kunde inte ta bort ”%s”"
 
-msgid ""
-"Resolve all conflicts manually, mark them as resolved with\n"
-"\"git add/rm <conflicted_files>\", then run \"git rebase --continue\".\n"
-"You can instead skip this commit: run \"git rebase --skip\".\n"
-"To abort and get back to the state before \"git rebase\", run \"git rebase --"
-"abort\"."
-msgstr ""
-"Lös alla konflikter manuellt, märk dem som lösta med\n"
-"”git add/rm <filer_i_konflikt>”, kör sedan ”git rebase --continue”.\n"
-"Du kan hoppa över incheckningen istället: kör ”git rebase --skip”.\n"
-"För att avbryta och återgå till där du var före ombaseringen, kör ”git "
-"rebase --abort”."
-
 #, c-format
 msgid ""
 "\n"
@@ -9946,11 +9961,14 @@
 msgstr ""
 "appliceringsflaggor och sammanslagningsflaggor kan inte användas tillsammans"
 
+msgid "--empty=ask is deprecated; use '--empty=stop' instead."
+msgstr "--empty=ask rekommenderas inte; använd ”--empty=stop” istället."
+
 #, c-format
 msgid ""
 "unrecognized empty type '%s'; valid values are \"drop\", \"keep\", and "
-"\"ask\"."
-msgstr "okänd tom-typ ”%s”; giltiga värden är ”drop”, ”keep” och ”ask”."
+"\"stop\"."
+msgstr "okänd tom-typ ”%s”; giltiga värden är ”drop”, ”keep” och ”stop”."
 
 msgid ""
 "--rebase-merges with an empty string argument is deprecated and will stop "
@@ -10129,8 +10147,8 @@
 "Observera: Din inställning för ”pull.rebase” kan också vara satt till\n"
 "”preserve”, som inte längre stöds; använd ”merges” istället"
 
-msgid "No rebase in progress?"
-msgstr "Ingen ombasering pågår?"
+msgid "no rebase in progress"
+msgstr "ingen ombasering pågår"
 
 msgid "The --edit-todo action can only be used during interactive rebase."
 msgstr "Åtgärden --edit-todo kan endast användas under interaktiv ombasering."
@@ -10176,13 +10194,6 @@
 msgstr "flaggan ”C” förväntar ett numeriskt värde"
 
 msgid ""
-"apply options are incompatible with rebase.autoSquash.  Consider adding --no-"
-"autosquash"
-msgstr ""
-"argument för ”apply” är inkompatibla med rebase.autoSquash. Överväg att "
-"lägga till --no-autosquash"
-
-msgid ""
 "apply options are incompatible with rebase.rebaseMerges.  Consider adding --"
 "no-rebase-merges"
 msgstr ""
@@ -10331,6 +10342,9 @@
 msgid "git reflog [show] [<log-options>] [<ref>]"
 msgstr "git reflog [show] [<log-flaggor>] [<ref>]"
 
+msgid "git reflog list"
+msgstr "git reflog list"
+
 msgid ""
 "git reflog expire [--expire=<time>] [--expire-unreachable=<time>]\n"
 "                  [--rewrite] [--updateref] [--stale-fix]\n"
@@ -10356,6 +10370,10 @@
 msgid "invalid timestamp '%s' given to '--%s'"
 msgstr "ogiltig tidsstämpel ”%s” given i ”--%s”"
 
+#, c-format
+msgid "%s does not accept arguments: '%s'"
+msgstr "%s tar inte argument: ”%s”"
+
 msgid "do not actually prune any entries"
 msgstr "rensa faktiskt inte några poster"
 
@@ -10481,8 +10499,8 @@
 "\t --mirror=fetch eller --mirror=push istället"
 
 #, c-format
-msgid "unknown mirror argument: %s"
-msgstr "okänt argument till mirror: %s"
+msgid "unknown --mirror argument: %s"
+msgstr "okänt argument till --mirror: %s"
 
 msgid "fetch the remote branches"
 msgstr "hämta fjärrgrenarna"
@@ -10845,6 +10863,9 @@
 msgid "could not start pack-objects to repack promisor objects"
 msgstr "kunde inte starta pack-objects för att packa om kontraktsobjekt"
 
+msgid "failed to feed promisor objects to pack-objects"
+msgstr "misslyckades sända kontraktsobjekt till pack-objects"
+
 msgid "repack: Expecting full hex object ID lines only from pack-objects."
 msgstr ""
 "repack: Förväntar kompletta hex-objekt-id-rader endast från pack-objects."
@@ -11167,6 +11188,76 @@
 msgid "only one pattern can be given with -l"
 msgstr "endast ett mönster kan anges med -l"
 
+msgid "need some commits to replay"
+msgstr "behöver några incheckningar för omspelning"
+
+msgid "--onto and --advance are incompatible"
+msgstr "--onto och --advance kan inte kombineras"
+
+msgid "all positive revisions given must be references"
+msgstr "alla positiva revisioner som anges måste vara referenser"
+
+msgid "argument to --advance must be a reference"
+msgstr "argumentet till --advance måste vara en referens"
+
+msgid ""
+"cannot advance target with multiple sources because ordering would be ill-"
+"defined"
+msgstr ""
+"kan inte flytta målet framåt när det finns flera källor eftersom ordningen "
+"inte kan fastställas"
+
+msgid ""
+"cannot implicitly determine whether this is an --advance or --onto operation"
+msgstr ""
+"kan inte avgöra om den underförstådda processen är --advance eller --onto"
+
+msgid ""
+"cannot advance target with multiple source branches because ordering would "
+"be ill-defined"
+msgstr ""
+"kan inte flytta målet framåt när det finns flera källgrenar eftersom "
+"ordningen inte kan fastställas"
+
+msgid "cannot implicitly determine correct base for --onto"
+msgstr "kan inte avgöra den underförstådda basen för --onto"
+
+msgid ""
+"(EXPERIMENTAL!) git replay ([--contained] --onto <newbase> | --advance "
+"<branch>) <revision-range>..."
+msgstr ""
+"(EXPERIMENTELLT!) git replay ([--contained] --onto <nybas> | --advance "
+"<gren>) <revisions-intervall>..."
+
+msgid "make replay advance given branch"
+msgstr "låt omspelningen flytta den givna grenen framåt"
+
+msgid "replay onto given commit"
+msgstr "spela om ovanpå en given incheckning"
+
+msgid "advance all branches contained in revision-range"
+msgstr "flytta alla grenar som finns i revisionsintervallet framåt"
+
+msgid "option --onto or --advance is mandatory"
+msgstr "flaggan --onto eller --advance måste anges"
+
+#, c-format
+msgid ""
+"some rev walking options will be overridden as '%s' bit in 'struct rev_info' "
+"will be forced"
+msgstr ""
+"några flaggor för revisionstraversering kommer överstyras eftersom ”%s”-"
+"biten i ”struct rev_info” kommer att tvingas"
+
+msgid "error preparing revisions"
+msgstr "fel när revisioner skulle förberedas"
+
+msgid "replaying down to root commit is not supported yet!"
+msgstr "kan ännu inte spela om hela vägen ned till rotincheckningen!"
+
+msgid "replaying merge commits is not supported yet!"
+msgstr "kan ännu inte spela om sammanslagningsincheckningar!"
+
 msgid ""
 "git rerere [clear | forget <pathspec>... | diff | status | remaining | gc]"
 msgstr ""
@@ -11180,7 +11271,7 @@
 
 #, c-format
 msgid "unable to generate diff for '%s'"
-msgstr "misslyckades skapa diff för ”%s”"
+msgstr "kan inte skapa diff för ”%s”"
 
 msgid ""
 "git reset [--mixed | --soft | --hard | --merge | --keep] [-q] [<commit>]"
@@ -11217,11 +11308,11 @@
 msgstr "Du har inte en giltig HEAD."
 
 msgid "Failed to find tree of HEAD."
-msgstr "Kunde inte hitta trädet för HEAD."
+msgstr "Misslyckades hitta trädet för HEAD."
 
 #, c-format
 msgid "Failed to find tree of %s."
-msgstr "Kunde inte hitta trädet för %s."
+msgstr "Misslyckades hitta trädet för %s."
 
 #, c-format
 msgid "HEAD is now at %s"
@@ -11254,11 +11345,11 @@
 
 #, c-format
 msgid "Failed to resolve '%s' as a valid revision."
-msgstr "Kunde inte slå upp ”%s” som en giltig revision."
+msgstr "Misslyckades slå upp ”%s” som en giltig revision."
 
 #, c-format
 msgid "Failed to resolve '%s' as a valid tree."
-msgstr "Kunde inte slå upp ”%s” som ett giltigt träd."
+msgstr "Misslyckades slå upp ”%s” som ett giltigt träd."
 
 msgid "--mixed with paths is deprecated; use 'git reset -- <paths>' instead."
 msgstr ""
@@ -11369,19 +11460,17 @@
 msgid "--prefix requires an argument"
 msgstr "--prefix kräver ett argument"
 
+msgid "no object format specified"
+msgstr "inget objektformat angavs"
+
+#, c-format
+msgid "unsupported object format: %s"
+msgstr "objektformatet stöds ej: %s"
+
 #, c-format
 msgid "unknown mode for --abbrev-ref: %s"
 msgstr "okänt läge för --abbrev-ref: %s"
 
-msgid "--exclude-hidden cannot be used together with --branches"
-msgstr "--exclude-hidden kan endast användas tillsammans med --branches"
-
-msgid "--exclude-hidden cannot be used together with --tags"
-msgstr "--exclude-hidden kan  kan inte användas tillsammans med --tags"
-
-msgid "--exclude-hidden cannot be used together with --remotes"
-msgstr "--exclude-hidden kan  kan inte användas tillsammans med --remotes"
-
 msgid "this operation must be run in a work tree"
 msgstr "funktionen måste köras i en arbetskatalog"
 
@@ -11459,8 +11548,8 @@
 msgid "allow commits with empty messages"
 msgstr "tillåt incheckningar med tomt meddelande"
 
-msgid "keep redundant, empty commits"
-msgstr "behåll redundanta, tomma incheckningar"
+msgid "deprecated: use --empty=keep instead"
+msgstr "avråds: använd --empty=keep istället"
 
 msgid "use the 'reference' format to refer to commits"
 msgstr "använd ”referens”-format för att referera till incheckningar"
@@ -11784,10 +11873,6 @@
 msgid "show refs from stdin that aren't in local repository"
 msgstr "visa referenser från standard in som inte finns i lokalt arkiv"
 
-#, c-format
-msgid "only one of '%s', '%s' or '%s' can be given"
-msgstr "endast en av ”%s”, ”%s” och ”%s” kan anges"
-
 msgid ""
 "git sparse-checkout (init | list | set | add | reapply | disable | check-"
 "rules) [<options>]"
@@ -11831,7 +11916,7 @@
 
 #, c-format
 msgid "unable to create leading directories of %s"
-msgstr "kunde inte skapa inledande kataloger för %s"
+msgstr "kan inte skapa inledande kataloger för %s"
 
 #, c-format
 msgid "failed to open '%s'"
@@ -11846,7 +11931,7 @@
 msgstr "kan inte ta bort citering av C-sträng ”%s”"
 
 msgid "unable to load existing sparse-checkout patterns"
-msgstr "kunde inte läsa in existerande mönster för gles utcheckning"
+msgstr "kan inte läsa in existerande mönster för gles utcheckning"
 
 msgid "existing sparse-checkout patterns do not use cone mode"
 msgstr "befintliga filter för gles utcheckning använder inte konläge"
@@ -12786,29 +12871,29 @@
 "\n"
 "Write a message for tag:\n"
 "  %s\n"
-"Lines starting with '%c' will be ignored.\n"
+"Lines starting with '%s' will be ignored.\n"
 msgstr ""
 "\n"
 "Skriv ett meddelande för taggen:\n"
 "  %s\n"
-"Rader som inleds med ”%c” ignoreras.\n"
+"Rader som inleds med ”%s” ignoreras.\n"
 
 #, c-format
 msgid ""
 "\n"
 "Write a message for tag:\n"
 "  %s\n"
-"Lines starting with '%c' will be kept; you may remove them yourself if you "
+"Lines starting with '%s' will be kept; you may remove them yourself if you "
 "want to.\n"
 msgstr ""
 "\n"
 "Skriv ett meddelande för taggen:\n"
 "  %s\n"
-"Rader som inleds med ”%c” kommer behållas; du kan själv ta bort dem om\n"
+"Rader som inleds med ”%s” kommer behållas; du kan själv ta bort dem om\n"
 "du vill.\n"
 
 msgid "unable to sign the tag"
-msgstr "kunde inte signera taggen"
+msgstr "kan inte signera taggen"
 
 #, c-format
 msgid ""
@@ -12889,6 +12974,9 @@
 msgid "print only tags of the object"
 msgstr "visa endast taggar för objektet"
 
+msgid "could not start 'git column'"
+msgstr "kunde inte starta ”git column”"
+
 #, c-format
 msgid "the '%s' option is only allowed in list mode"
 msgstr "flaggan ”%s” är endast tillåten i listläge"
@@ -13130,11 +13218,11 @@
 msgid "fsmonitor disabled"
 msgstr "fsmonitor inaktiverat"
 
-msgid "git update-ref [<options>] -d <refname> [<old-val>]"
-msgstr "git update-ref [<flaggor>] -d <refnamn> [<gammaltvärde>]"
+msgid "git update-ref [<options>] -d <refname> [<old-oid>]"
+msgstr "git update-ref [<flaggor>] -d <refnamn> [<gammalt-oid>]"
 
-msgid "git update-ref [<options>]    <refname> <new-val> [<old-val>]"
-msgstr "git update-ref [<flaggor>]    <refnamn> <gammaltvärde> [<nyttvärde>]"
+msgid "git update-ref [<options>]    <refname> <new-oid> [<old-oid>]"
+msgstr "git update-ref [<flaggor>]    <refnamn> <gammalt-oid> [<nytt-oid>]"
 
 msgid "git update-ref [<options>] --stdin [-z]"
 msgstr "git update-ref [<flaggor>] --stdin [-z]"
@@ -13232,13 +13320,13 @@
 
 #, c-format
 msgid ""
-"If you meant to create a worktree containing a new orphan branch\n"
+"If you meant to create a worktree containing a new unborn branch\n"
 "(branch with no commits) for this repository, you can do so\n"
 "using the --orphan flag:\n"
 "\n"
 "    git worktree add --orphan -b %s %s\n"
 msgstr ""
-"Om meningen var att skapa en arbetskatalog från en ny föräldrals\n"
+"Om meningen var att skapa en arbetskatalog från en ny ofödd\n"
 "gren (gren utan incheckningar) för det här arkivet kan du göra\n"
 "det med flaggan --orphan:\n"
 "\n"
@@ -13246,13 +13334,13 @@
 
 #, c-format
 msgid ""
-"If you meant to create a worktree containing a new orphan branch\n"
+"If you meant to create a worktree containing a new unborn branch\n"
 "(branch with no commits) for this repository, you can do so\n"
 "using the --orphan flag:\n"
 "\n"
 "    git worktree add --orphan %s\n"
 msgstr ""
-"Om meningen var att skapa en arbetskatalog från en ny föräldrals\n"
+"Om meningen var att skapa en arbetskatalog från en ny ofödd\n"
 "gren (gren utan incheckningar) för det här arkivet kan du göra\n"
 "det med flaggan --orphan:\n"
 "\n"
@@ -13315,6 +13403,10 @@
 msgstr "initierar"
 
 #, c-format
+msgid "could not find created worktree '%s'"
+msgstr "kunde inte hitta den skapade arbetskatalogen ”%s”"
+
+#, c-format
 msgid "Preparing worktree (new branch '%s')"
 msgstr "Förbereder arbetskatalog (ny gren ”%s”)"
 
@@ -13352,10 +13444,6 @@
 "finns, avslutar; använd ”add -f” för att överstyra eller hämta från en fjärr "
 "först"
 
-#, c-format
-msgid "'%s' and '%s' cannot be used together"
-msgstr "”%s” och ”%s” kan inte användas samtidigt"
-
 msgid "checkout <branch> even if already checked out in other worktree"
 msgstr ""
 "checka ut <gren> även om den redan är utcheckad i en annan arbetskatalog"
@@ -13366,8 +13454,8 @@
 msgid "create or reset a branch"
 msgstr "skapa eller återställ en gren"
 
-msgid "create unborn/orphaned branch"
-msgstr "skapa en ofödd/övergiven gren"
+msgid "create unborn branch"
+msgstr "skapa en ofödd gren"
 
 msgid "populate the new working tree"
 msgstr "befolka den nya arbetskatalogen"
@@ -13389,11 +13477,8 @@
 msgstr "flaggorna ”%s”, ”%s” och ”%s” kan inte användas samtidigt"
 
 #, c-format
-msgid "options '%s', and '%s' cannot be used together"
-msgstr "flaggorna ”%s” och ”%s” kan inte användas samtidigt"
-
-msgid "<commit-ish>"
-msgstr "<incheckning-igt>"
+msgid "option '%s' and commit-ish cannot be used together"
+msgstr "flaggorna ”%s” och incheckning-igt kan inte användas samtidigt"
 
 msgid "added with --lock"
 msgstr "lagt till med --lock"
@@ -13556,7 +13641,7 @@
 
 #, c-format
 msgid "failed to download bundle from URI '%s'"
-msgstr "kunde inte hämta bunt från URI:en ”%s”"
+msgstr "misslyckades hämta bunt från URI:en ”%s”"
 
 #, c-format
 msgid "file at URI '%s' is not a bundle or bundle list"
@@ -14006,6 +14091,11 @@
 msgid "Create, list, delete refs to replace objects"
 msgstr "Skapa, visa, ta bort referenser för att ersätta objekt"
 
+msgid "EXPERIMENTAL: Replay commits on a new base, works with bare repos too"
+msgstr ""
+"EXPERIMENTELLT: Spela om incheckningar ovanpå en ny bas, fungerar även med "
+"nakna arkiv"
+
 msgid "Generates a summary of pending changes"
 msgstr "Skapar en sammanfattning av väntande ändringar"
 
@@ -14243,6 +14333,32 @@
 msgid "commit-graph file is too small"
 msgstr "incheckningsgraffilen %s är för liten"
 
+msgid "commit-graph oid fanout chunk is wrong size"
+msgstr "incheckningsgrafens oid-utbredningsstycke har fel storlek"
+
+msgid "commit-graph fanout values out of order"
+msgstr "incheckningsgrafens utbredningsvärden är i fel ordning"
+
+msgid "commit-graph OID lookup chunk is the wrong size"
+msgstr "incheckningsgrafens OID-uppslagningsstycket har fel storlek"
+
+msgid "commit-graph commit data chunk is wrong size"
+msgstr "incheckningsgrafens incheckningsdatastycke har fel storlek"
+
+msgid "commit-graph generations chunk is wrong size"
+msgstr "incheckningsgrafens generationsstycke har fel storlek"
+
+msgid "commit-graph changed-path index chunk is too small"
+msgstr "incheckningsgrafens ändrade-sökvägar-indexstycke är förö litet"
+
+#, c-format
+msgid ""
+"ignoring too-small changed-path chunk (%<PRIuMAX> < %<PRIuMAX>) in commit-"
+"graph file"
+msgstr ""
+"ignorerar för litet ändrade-sökvägar-stycke (%<PRIuMAX> < %<PRIuMAX>) i "
+"incheckningsgraffilen"
+
 #, c-format
 msgid "commit-graph signature %X does not match signature %X"
 msgstr "incheckningsgrafens signatur %X stämmer inte med signaturen %X"
@@ -14259,6 +14375,18 @@
 msgid "commit-graph file is too small to hold %u chunks"
 msgstr "incheckningsgraffilen är för liten för att innehålla %u stycken"
 
+msgid "commit-graph required OID fanout chunk missing or corrupted"
+msgstr ""
+"incheckningsgrafens nödvändiga OID-utbredningsstycke saknas eller är trasigt"
+
+msgid "commit-graph required OID lookup chunk missing or corrupted"
+msgstr ""
+"incheckningsgrafens nödvändiga OID-uppslagningsstycke saknas eller är trasigt"
+
+msgid "commit-graph required commit data chunk missing or corrupted"
+msgstr ""
+"incheckningsgrafens nödvändiga incheckningsdatastycke saknas eller är trasigt"
+
 msgid "commit-graph has no base graphs chunk"
 msgstr "incheckningsgrafen har inga bas-graf-stycken"
 
@@ -14272,6 +14400,9 @@
 msgid "commit count in base graph too high: %<PRIuMAX>"
 msgstr "antalet incheckningar i basgrafen för högt: %<PRIuMAX>"
 
+msgid "commit-graph chain file too small"
+msgstr "incheckningsgrafens kedjefil är för liten"
+
 #, c-format
 msgid "invalid commit-graph chain: line '%s' not a hash"
 msgstr "ogiltig incheckingsgrafkedja: rad ”%s” är inte ett hash-värde"
@@ -14292,6 +14423,9 @@
 msgid "commit-graph overflow generation data is too small"
 msgstr "incheckningsgrafens spillgenerationsdata är för liten"
 
+msgid "commit-graph extra-edges pointer out of bounds"
+msgstr "incheckningsgrafens extra-kant-pekare är utanför intervallet"
+
 msgid "Loading known commits in commit graph"
 msgstr "Läser in kända incheckningar i incheckningsgraf"
 
@@ -14334,7 +14468,7 @@
 msgstr "Söker ytterligare kanter i incheckingsgraf"
 
 msgid "failed to write correct number of base graph ids"
-msgstr "kunde inte skriva korrekt antal bas-graf-id:n"
+msgstr "misslyckades skriva korrekt antal bas-graf-id:n"
 
 msgid "unable to create temporary graph layer"
 msgstr "kan inte skapa temporärt graflager"
@@ -14350,13 +14484,13 @@
 msgstr[1] "Skriver ut incheckningsgraf i %d pass"
 
 msgid "unable to open commit-graph chain file"
-msgstr "Kunde inte öppna incheckningsgrafkedjefilen"
+msgstr "kan inte öppna incheckningsgrafkedjefilen"
 
 msgid "failed to rename base commit-graph file"
-msgstr "kunde inte byta namn på bas-incheckingsgraffilen"
+msgstr "misslyckades byta namn på bas-incheckingsgraffilen"
 
 msgid "failed to rename temporary commit-graph file"
-msgstr "kunde inte byta namn på temporär incheckningsgraffil"
+msgstr "misslyckades byta namn på temporär incheckningsgraffil"
 
 #, c-format
 msgid "cannot merge graphs with %<PRIuMAX>, %<PRIuMAX> commits"
@@ -14395,12 +14529,12 @@
 
 #, c-format
 msgid "failed to parse commit %s from commit-graph"
-msgstr "kunde inte tolka incheckning %s från incheckningsgraf"
+msgstr "misslyckades tolka incheckningen %s från incheckningsgraf"
 
 #, c-format
 msgid "failed to parse commit %s from object database for commit-graph"
 msgstr ""
-"misslyckades tolka incheckning %s från objektdatabasen för incheckningsgraf"
+"misslyckades tolka incheckningen %s från objektdatabasen för incheckningsgraf"
 
 #, c-format
 msgid "root tree OID for commit %s in commit-graph is %s != %s"
@@ -14443,6 +14577,10 @@
 msgstr "Bekräftar incheckningar i incheckningsgrafen"
 
 #, c-format
+msgid "could not parse commit %s"
+msgstr "kunde inte tolka incheckningen %s"
+
+#, c-format
 msgid "%s %s is not a commit!"
 msgstr "%s %s är inte en incheckning!"
 
@@ -14587,11 +14725,11 @@
 
 #, c-format
 msgid "[GLE %ld] unable to open for read '%ls'"
-msgstr "[GLE %ld] kunde inte öppna ”%ls” för läsning"
+msgstr "[GLE %ld] kan inte öppna ”%ls” för läsning"
 
 #, c-format
 msgid "[GLE %ld] unable to get protocol information for '%ls'"
-msgstr "[GLE %ld] kunde inte hämta protokollinformation för ”%ls”"
+msgstr "[GLE %ld] kan inte hämta protokollinformation för ”%ls”"
 
 #, c-format
 msgid "failed to copy SID (%ld)"
@@ -14870,8 +15008,13 @@
 msgid "bad zlib compression level %d"
 msgstr "felaktigt zlib-komprimeringsgrad %d"
 
-msgid "core.commentChar should only be one ASCII character"
-msgstr "core.commentChar kan bara vara ett ASCII-tecken"
+#, c-format
+msgid "%s cannot contain newline"
+msgstr "%s kan inte innehålla nyradstecken"
+
+#, c-format
+msgid "%s must have at least one character"
+msgstr "%s måste innehålla minst ett tecken"
 
 #, c-format
 msgid "ignoring unknown core.fsyncMethod value '%s'"
@@ -14897,7 +15040,7 @@
 
 #, c-format
 msgid "unable to load config blob object '%s'"
-msgstr "kunde inte läsa konfigurerings-blobobjektet ”%s”"
+msgstr "kan inte läsa konfigurerings-blobobjektet ”%s”"
 
 #, c-format
 msgid "reference '%s' does not point to a blob"
@@ -14924,7 +15067,7 @@
 
 #, c-format
 msgid "unable to parse '%s' from command-line config"
-msgstr "kunde inte tolka värdet ”%s” från kommandoradskonfiguration"
+msgstr "kan inte tolka värdet ”%s” från kommandoradskonfiguration"
 
 #, c-format
 msgid "bad config variable '%s' in file '%s' at line %d"
@@ -14940,7 +15083,11 @@
 
 #, c-format
 msgid "failed to write new configuration file %s"
-msgstr "kan inte skriva nya konfigurationsfilen ”%s”"
+msgstr "misslyckades skriva nya konfigurationsfilen ”%s”"
+
+#, c-format
+msgid "no multi-line comment allowed: '%s'"
+msgstr "inga flerradiga kommentarer tillåtna: ”%s”"
 
 #, c-format
 msgid "could not lock config file %s"
@@ -14960,7 +15107,7 @@
 
 #, c-format
 msgid "unable to mmap '%s'%s"
-msgstr "kunde inte utföra mmap på ”%s”%s"
+msgstr "kan inte utföra mmap på ”%s”%s"
 
 #, c-format
 msgid "chmod on %s failed"
@@ -15058,7 +15205,7 @@
 msgstr "protokollet ”%s” stöds inte"
 
 msgid "unable to set SO_KEEPALIVE on socket"
-msgstr "kunde inte sätta SO_KEEPALIVE på uttaget"
+msgstr "kan inte sätta SO_KEEPALIVE på uttaget"
 
 #, c-format
 msgid "Looking up %s ... "
@@ -15082,7 +15229,7 @@
 "unable to connect to %s:\n"
 "%s"
 msgstr ""
-"kunde inte ansluta till %s:\n"
+"kan inte ansluta till %s:\n"
 "%s"
 
 #. TRANSLATORS: this is the end of "Connecting to %s (port %s) ... "
@@ -15091,7 +15238,7 @@
 
 #, c-format
 msgid "unable to look up %s (%s)"
-msgstr "kunde inte slå upp %s (%s)"
+msgstr "kan inte slå upp %s (%s)"
 
 #, c-format
 msgid "unknown port %s"
@@ -15129,16 +15276,16 @@
 msgstr "konstigt sökvägsnamn ”%s” blockerat"
 
 msgid "unable to fork"
-msgstr "kunde inte grena (fork)"
+msgstr "kan inte grena (fork)"
 
 msgid "Could not run 'git rev-list'"
 msgstr "Kunde inte köra ”git rev-list”"
 
 msgid "failed write to rev-list"
-msgstr "kunde inte skriva till rev-list"
+msgstr "misslyckades skriva till rev-list"
 
 msgid "failed to close rev-list's stdin"
-msgstr "kunde inte stänga rev-list:s standard in"
+msgstr "misslyckades stänga rev-list:s standard in"
 
 #, c-format
 msgid "illegal crlf_action %d"
@@ -15200,7 +15347,7 @@
 
 #, c-format
 msgid "cannot fork to run external filter '%s'"
-msgstr "kan inte grena (fork) för att köra externt filter ”%s”"
+msgstr "kan inte grena (fork) av för att köra externt filter ”%s”"
 
 #, c-format
 msgid "cannot feed the input to external filter '%s'"
@@ -15332,7 +15479,7 @@
 
 #, c-format
 msgid "failed to load island regex for '%s': %s"
-msgstr "kunde inte hämta ö-regex för ”%s”: %s"
+msgstr "misslyckades hämta ö-regex för ”%s”: %s"
 
 #, c-format
 msgid "island regex from config has too many capture groups (max=%d)"
@@ -15431,6 +15578,10 @@
 msgstr "Okänt värde för konfigurationsvariabeln ”diff.submodule”: ”%s”"
 
 #, c-format
+msgid "unknown value for config '%s': %s"
+msgstr "okänt värde för inställningen ”%s”: %s"
+
+#, c-format
 msgid ""
 "Found errors in 'diff.dirstat' config variable:\n"
 "%s"
@@ -15491,7 +15642,7 @@
 
 #, c-format
 msgid "unable to resolve '%s'"
-msgstr "kunde inte slå upp ”%s”"
+msgstr "kan inte slå upp ”%s”"
 
 #, c-format
 msgid "%s expects <n>/<m> form"
@@ -15509,12 +15660,6 @@
 msgid "invalid mode '%s' in --color-moved-ws"
 msgstr "ogiltigt läge %s” i --color-moved-ws"
 
-msgid ""
-"option diff-algorithm accepts \"myers\", \"minimal\", \"patience\" and "
-"\"histogram\""
-msgstr ""
-"flaggan diff-algorithm godtar ”myers”, ”minimal”, ”patience” och ”histogram”"
-
 #, c-format
 msgid "invalid argument to %s"
 msgstr "ogiltigt argument för %s"
@@ -15558,8 +15703,8 @@
 msgid "output only the last line of --stat"
 msgstr "skriv bara ut den sista raden för --stat"
 
-msgid "<param1,param2>..."
-msgstr "<param1,param2>..."
+msgid "<param1>,<param2>..."
+msgstr "<param1>,<param2>..."
 
 msgid ""
 "output the distribution of relative amount of changes for each sub-directory"
@@ -15569,8 +15714,8 @@
 msgid "synonym for --dirstat=cumulative"
 msgstr "synonym för --dirstat=cumulative"
 
-msgid "synonym for --dirstat=files,param1,param2..."
-msgstr "synonym för --dirstat=filer,param1,param2..."
+msgid "synonym for --dirstat=files,<param1>,<param2>..."
+msgstr "synonym för --dirstat=filer,<param1>,<param2>..."
 
 msgid "warn if changes introduce conflict markers or whitespace errors"
 msgstr "varna om ändringar introducerar konfliktmarkörer eller blankstegsfel"
@@ -15744,12 +15889,6 @@
 msgid "generate diff using the \"histogram diff\" algorithm"
 msgstr "skapa diffar med algoritmen ”histogram diff”"
 
-msgid "<algorithm>"
-msgstr "<algoritm>"
-
-msgid "choose a diff algorithm"
-msgstr "välj en diff-algoritm"
-
 msgid "<text>"
 msgstr "<text>"
 
@@ -15886,7 +16025,7 @@
 
 #, c-format
 msgid "failed to read orderfile '%s'"
-msgstr "kunde inte läsa orderfilen ”%s”"
+msgstr "misslyckades läsa orderfilen ”%s”"
 
 msgid "Performing inexact rename detection"
 msgstr "Utför onöjaktig namnbytesdetektering"
@@ -15986,7 +16125,7 @@
 msgstr "git fetch-pack: förväntade ACK/NAK, fick ”%s”"
 
 msgid "unable to write to remote"
-msgstr "kunde inte skriva till fjärren"
+msgstr "kan inte skriva till fjärren"
 
 msgid "Server supports filter"
 msgstr "Servern stöder filter"
@@ -16042,14 +16181,14 @@
 msgstr "har redan %s (%s)"
 
 msgid "fetch-pack: unable to fork off sideband demultiplexer"
-msgstr "fetch-patch: kunde inte grena av sidbandsmultiplexare"
+msgstr "fetch-patch: kan inte grena (fork) av sidbandsmultiplexare"
 
 msgid "protocol error: bad pack header"
 msgstr "protokollfel: felaktigt packhuvud"
 
 #, c-format
 msgid "fetch-pack: unable to fork off %s"
-msgstr "fetch-patch: kunde inte grena av %s"
+msgstr "fetch-patch: kan inte grena (fork) av %s"
 
 msgid "fetch-pack: invalid index-pack output"
 msgstr "fetch-patch: ogiltig utdata från index-pack"
@@ -16102,7 +16241,7 @@
 msgstr "Servern stöder inte grunda förfrågningar"
 
 msgid "unable to write request to remote"
-msgstr "kunde inte skriva anrop till fjärren"
+msgstr "kan inte skriva anrop till fjärren"
 
 #, c-format
 msgid "expected '%s', received '%s'"
@@ -16404,7 +16543,7 @@
 
 #, c-format
 msgid "'%s': unable to read %s"
-msgstr "”%s” kunde inte läsa %s"
+msgstr "”%s”: kan inte läsa %s"
 
 #, c-format
 msgid "'%s': short read"
@@ -16635,14 +16774,14 @@
 
 #, c-format
 msgid "unable to auto-detect email address (got '%s')"
-msgstr "kunde inte autodetektera e-postadress (fick ”%s”)"
+msgstr "kan inte autodetektera e-postadress (fick ”%s”)"
 
 msgid "no name was given and auto-detection is disabled"
 msgstr "inget namn angavs och autodetektering är inaktiverad"
 
 #, c-format
 msgid "unable to auto-detect name (got '%s')"
-msgstr "kunde inte autodetektera namn (fick ”%s”)"
+msgstr "kan inte autodetektera namn (fick ”%s”)"
 
 #, c-format
 msgid "empty ident name (for <%s>) not allowed"
@@ -16677,7 +16816,7 @@
 msgstr "flera filterspecifikationer kan inte kombineras"
 
 msgid "unable to upgrade repository format to support partial clone"
-msgstr "kunde inte uppgradera arkivformat till att stöda delvis klon"
+msgstr "kan inte uppgradera arkivformat till att stöda delvis klon"
 
 msgid "args"
 msgstr "argument"
@@ -16687,11 +16826,11 @@
 
 #, c-format
 msgid "unable to access sparse blob in '%s'"
-msgstr "kunde inte nå gles blob på ”%s”"
+msgstr "kan inte nå gles blob på ”%s”"
 
 #, c-format
 msgid "unable to parse sparse filter data in %s"
-msgstr "kunde inte tolka gles filterdata i %s"
+msgstr "kan inte tolka gles filterdata i %s"
 
 #, c-format
 msgid "entry '%s' in tree %s has tree mode, but is not a tree"
@@ -16703,7 +16842,7 @@
 
 #, c-format
 msgid "unable to load root tree for commit %s"
-msgstr "kunde inte läsa in rot-trädet för incheckningen %s"
+msgstr "kan inte läsa in rot-trädet för incheckningen %s"
 
 #, c-format
 msgid ""
@@ -16729,6 +16868,14 @@
 msgstr "Kunde inte skapa ”%s.lock”: %s"
 
 #, c-format
+msgid "could not write loose object index %s"
+msgstr "kunde inte skriva löst objektindex %s"
+
+#, c-format
+msgid "failed to write loose object index %s\n"
+msgstr "misslyckades skriva löst objektindex %s\n"
+
+#, c-format
 msgid "unexpected line: '%s'"
 msgstr "oväntad rad: ”%s”"
 
@@ -16739,6 +16886,10 @@
 msgstr "citerad CRLF upptäcktes"
 
 #, c-format
+msgid "unable to format message: %s"
+msgstr "kan inte formatera meddelandet: %s"
+
+#, c-format
 msgid "Failed to merge submodule %s (not checked out)"
 msgstr "Misslyckades slå ihop undermodulen %s (ej utcheckad)"
 
@@ -16751,6 +16902,10 @@
 msgstr "Misslyckades slå ihop undermodulen %s (incheckningar saknas)"
 
 #, c-format
+msgid "Failed to merge submodule %s (repository corrupt)"
+msgstr "Misslyckades slå ihop undermodulen %s (arkivet är trasigt)"
+
+#, c-format
 msgid "Failed to merge submodule %s (commits don't follow merge-base)"
 msgstr ""
 "Misslyckades slå ihop undermodulen %s (incheckningar följer inte "
@@ -16783,7 +16938,7 @@
 
 #, c-format
 msgid "unable to add %s to database"
-msgstr "kunde inte lägga till %s till databasen"
+msgstr "kan inte lägga till %s till databasen"
 
 #, c-format
 msgid "Auto-merging %s"
@@ -17217,65 +17372,6 @@
 msgid "failed to read the cache"
 msgstr "misslyckades läsa cachen"
 
-msgid "multi-pack-index OID fanout is of the wrong size"
-msgstr "OID-utbredning för multi-pack-index har fel storlek"
-
-msgid "multi-pack-index OID lookup chunk is the wrong size"
-msgstr "OID-uppslagningsstycket för multi-pack-index har fel storlek"
-
-msgid "multi-pack-index object offset chunk is the wrong size"
-msgstr "objekt-offset-stycket för multi-pack-index har fel storlek"
-
-#, c-format
-msgid "multi-pack-index file %s is too small"
-msgstr "multi-pack-indexfilen %s är för liten"
-
-#, c-format
-msgid "multi-pack-index signature 0x%08x does not match signature 0x%08x"
-msgstr "multi-pack-indexsignaturen 0x%08x stämmer inte med signaturen 0x%08x"
-
-#, c-format
-msgid "multi-pack-index version %d not recognized"
-msgstr "multi-pack-indexversionen %d stöds inte"
-
-#, c-format
-msgid "multi-pack-index hash version %u does not match version %u"
-msgstr "multi-pack-index-hashversionen %u stämmer inte med versionen %u"
-
-msgid "multi-pack-index required pack-name chunk missing or corrupted"
-msgstr ""
-"nödvändigt paketnamn-stycke för multi-pack-index saknas eller är trasigt"
-
-msgid "multi-pack-index required OID fanout chunk missing or corrupted"
-msgstr ""
-"nödvändigt OID-utbredningsstycke för multi-pack-index saknas eller är trasigt"
-
-msgid "multi-pack-index required OID lookup chunk missing or corrupted"
-msgstr ""
-"nödvändigt OID-uppslagningsstycke för multi-pack-index saknas eller är "
-"trasigt"
-
-msgid "multi-pack-index required object offsets chunk missing or corrupted"
-msgstr ""
-"nödvändigt objekt-offsetstycke för multi-pack-index saknas eller är trasigt"
-
-msgid "multi-pack-index pack-name chunk is too short"
-msgstr "paketnamnstycke för multi-pack-index är för kort"
-
-#, c-format
-msgid "multi-pack-index pack names out of order: '%s' before '%s'"
-msgstr "paketnamn för multi-pack-index i fel ordning: ”%s” före ”%s”"
-
-#, c-format
-msgid "bad pack-int-id: %u (%u total packs)"
-msgstr "bad pack-int-id: %u (%u paket totalt)"
-
-msgid "multi-pack-index stores a 64-bit offset, but off_t is too small"
-msgstr "multi-pack-index innehåller 64-bitars offset, men off_t är för liten"
-
-msgid "multi-pack-index large offset out of bounds"
-msgstr "stort offset för mult-pack-index utanför gränsen"
-
 #, c-format
 msgid "failed to add packfile '%s'"
 msgstr "misslyckades läsa paketfilen ”%s”"
@@ -17340,6 +17436,90 @@
 msgid "could not write multi-pack-index"
 msgstr "kunde inte skriva flerpakets-index"
 
+msgid "Counting referenced objects"
+msgstr "Räknar refererade objekt"
+
+msgid "Finding and deleting unreferenced packfiles"
+msgstr "Ser efter och tar bort orefererade packfiler"
+
+msgid "could not start pack-objects"
+msgstr "kunde inte starta pack-objects"
+
+msgid "could not finish pack-objects"
+msgstr "kunde inte avsluta pack-objects"
+
+msgid "multi-pack-index OID fanout is of the wrong size"
+msgstr "OID-utbredning för multi-pack-index har fel storlek"
+
+#, c-format
+msgid ""
+"oid fanout out of order: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]"
+msgstr ""
+"oid-utbredning i fel ordning: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]"
+
+msgid "multi-pack-index OID lookup chunk is the wrong size"
+msgstr "OID-uppslagningsstycket för multi-pack-index har fel storlek"
+
+msgid "multi-pack-index object offset chunk is the wrong size"
+msgstr "objekt-offset-stycket för multi-pack-index har fel storlek"
+
+#, c-format
+msgid "multi-pack-index file %s is too small"
+msgstr "multi-pack-indexfilen %s är för liten"
+
+#, c-format
+msgid "multi-pack-index signature 0x%08x does not match signature 0x%08x"
+msgstr "multi-pack-indexsignaturen 0x%08x stämmer inte med signaturen 0x%08x"
+
+#, c-format
+msgid "multi-pack-index version %d not recognized"
+msgstr "multi-pack-indexversionen %d stöds inte"
+
+#, c-format
+msgid "multi-pack-index hash version %u does not match version %u"
+msgstr "multi-pack-index-hashversionen %u stämmer inte med versionen %u"
+
+msgid "multi-pack-index required pack-name chunk missing or corrupted"
+msgstr ""
+"nödvändigt paketnamn-stycke för multi-pack-index saknas eller är trasigt"
+
+msgid "multi-pack-index required OID fanout chunk missing or corrupted"
+msgstr ""
+"nödvändigt OID-utbredningsstycke för multi-pack-index saknas eller är trasigt"
+
+msgid "multi-pack-index required OID lookup chunk missing or corrupted"
+msgstr ""
+"nödvändigt OID-uppslagningsstycke för multi-pack-index saknas eller är "
+"trasigt"
+
+msgid "multi-pack-index required object offsets chunk missing or corrupted"
+msgstr ""
+"nödvändigt objekt-offsetstycke för multi-pack-index saknas eller är trasigt"
+
+msgid "multi-pack-index pack-name chunk is too short"
+msgstr "paketnamnstycke för multi-pack-index är för kort"
+
+#, c-format
+msgid "multi-pack-index pack names out of order: '%s' before '%s'"
+msgstr "paketnamn för multi-pack-index i fel ordning: ”%s” före ”%s”"
+
+#, c-format
+msgid "bad pack-int-id: %u (%u total packs)"
+msgstr "bad pack-int-id: %u (%u paket totalt)"
+
+msgid "MIDX does not contain the BTMP chunk"
+msgstr "MIDX innehåller inte BTMP-stycket"
+
+#, c-format
+msgid "could not load bitmapped pack %<PRIu32>"
+msgstr "kunde inte läsa det bitmappade paketet %<PRIu32>"
+
+msgid "multi-pack-index stores a 64-bit offset, but off_t is too small"
+msgstr "multi-pack-index innehåller 64-bitars offset, men off_t är för liten"
+
+msgid "multi-pack-index large offset out of bounds"
+msgstr "stort offset för mult-pack-index utanför gränsen"
+
 #, c-format
 msgid "failed to clear multi-pack-index at %s"
 msgstr "misslyckades städa multi-pack-index på %s"
@@ -17353,12 +17533,6 @@
 msgid "Looking for referenced packfiles"
 msgstr "Ser efter refererade packfiler"
 
-#, c-format
-msgid ""
-"oid fanout out of order: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]"
-msgstr ""
-"oid-utbredning i fel ordning: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]"
-
 msgid "the midx contains no oid"
 msgstr "midx saknar oid"
 
@@ -17387,29 +17561,17 @@
 msgid "incorrect object offset for oid[%d] = %s: %<PRIx64> != %<PRIx64>"
 msgstr "felaktigt objekt-offset för oid[%d] = %s: %<PRIx64> != %<PRIx64>"
 
-msgid "Counting referenced objects"
-msgstr "Räknar refererade objekt"
-
-msgid "Finding and deleting unreferenced packfiles"
-msgstr "Ser efter och tar bort orefererade packfiler"
-
-msgid "could not start pack-objects"
-msgstr "kunde inte starta pack-objects"
-
-msgid "could not finish pack-objects"
-msgstr "kunde inte avsluta pack-objects"
-
 #, c-format
 msgid "unable to create lazy_dir thread: %s"
-msgstr "misslyckades skapa lazy_dir-tråd: %s"
+msgstr "kan inte skapa lazy_dir-tråd: %s"
 
 #, c-format
 msgid "unable to create lazy_name thread: %s"
-msgstr "misslyckades skapa lazy_name-tråd: %s"
+msgstr "kan inte skapa lazy_name-tråd: %s"
 
 #, c-format
 msgid "unable to join lazy_name thread: %s"
-msgstr "misslyckades utföra join på lazy_name-tråd: %s"
+msgstr "kan inte utföra join på lazy_name-tråd: %s"
 
 #, c-format
 msgid ""
@@ -17445,13 +17607,32 @@
 msgid "Bad %s value: '%s'"
 msgstr "Felaktigt värde på %s: ”%s”"
 
+msgid "failed to decode tree entry"
+msgstr "misslyckades avkoda trädposten"
+
+#, c-format
+msgid "failed to map tree entry for %s"
+msgstr "misslyckades koppla trädpost för %s"
+
+#, c-format
+msgid "bad %s in commit"
+msgstr "felaktig %s i incheckning"
+
+#, c-format
+msgid "unable to map %s %s in commit object"
+msgstr "kan inte koppla %s %s i incheckningsobjekt"
+
+#, c-format
+msgid "Failed to convert object from %s to %s"
+msgstr "Misslyckades konvertera objekt från %s till %s"
+
 #, c-format
 msgid "object directory %s does not exist; check .git/objects/info/alternates"
 msgstr "objektkatalogen %s finns inte; se .git/objects/info/alternates"
 
 #, c-format
 msgid "unable to normalize alternate object path: %s"
-msgstr "kunde inte normalisera supplerande objektsökväg: %s"
+msgstr "kan inte normalisera supplerande objektsökväg: %s"
 
 #, c-format
 msgid "%s: ignoring alternate object stores, nesting too deep"
@@ -17546,8 +17727,12 @@
 msgstr "packat objekt %s (lagrat i %s) är trasigt"
 
 #, c-format
+msgid "missing mapping of %s to %s"
+msgstr "saknar koppling av %s till %s"
+
+#, c-format
 msgid "unable to write file %s"
-msgstr "kunde inte skriva filen %s"
+msgstr "kan inte skriva filen %s"
 
 #, c-format
 msgid "unable to set permission to '%s'"
@@ -17565,7 +17750,7 @@
 msgstr "kan inte skapa temporär fil"
 
 msgid "unable to write loose object file"
-msgstr "kunde inte skriva fil för löst objekt"
+msgstr "kan inte skriva fil för löst objekt"
 
 #, c-format
 msgid "unable to deflate new object %s (%d)"
@@ -17593,13 +17778,17 @@
 
 #, c-format
 msgid "unable to create directory %s"
-msgstr "kunde inte skapa katalogen %s"
+msgstr "kan inte skapa katalogen %s"
 
 #, c-format
 msgid "cannot read object for %s"
 msgstr "kan inte läsa objekt för %s"
 
 #, c-format
+msgid "cannot map object %s to %s"
+msgstr "kan inte koppla objektet %s till %s"
+
+#, c-format
 msgid "object fails fsck: %s"
 msgstr "objekt klarar inte fsck: %s"
 
@@ -17816,7 +18005,7 @@
 
 #, c-format
 msgid "unable to parse object: %s"
-msgstr "kunde inte tolka objektet: %s"
+msgstr "kan inte tolka objektet: %s"
 
 #, c-format
 msgid "hash mismatch %s"
@@ -17875,6 +18064,9 @@
 msgid "could not open pack %s"
 msgstr "kunde inte öppna paketfilen %s"
 
+msgid "could not determine MIDX preferred pack"
+msgstr "kunde inte bestämma det föredragna MIDX-paketet"
+
 #, c-format
 msgid "preferred pack (%s) is invalid"
 msgstr "föredragen paketfil (%s) är ogiltig"
@@ -17895,6 +18087,13 @@
 msgstr "trasig ewah-bitkarta: avhugget huvud för bitkarta för incheckning ”%s”"
 
 #, c-format
+msgid "unable to load pack: '%s', disabling pack-reuse"
+msgstr "kan inte läsa paketet: ”%s”, inaktiverar återanvändning av paket"
+
+msgid "unable to compute preferred pack, disabling pack-reuse"
+msgstr "kan inte beräkna föredraget paket, inaktiverar återanvändning av paket"
+
+#, c-format
 msgid "object '%s' not found in type bitmaps"
 msgstr "objektet ”%s” hittades inte i typbitkartor"
 
@@ -17985,6 +18184,9 @@
 msgid "multi-pack-index reverse-index chunk is the wrong size"
 msgstr "baklängesindex-stycke för multi-pack-index har fel storlek"
 
+msgid "could not determine preferred pack"
+msgstr "kunde inte bestämma föredraget paket"
+
 msgid "cannot both write and verify reverse index"
 msgstr "kan inte både skriva och bekräfta reverse-index"
 
@@ -17994,7 +18196,7 @@
 
 #, c-format
 msgid "failed to make %s readable"
-msgstr "kunde inte göra %s läsbar"
+msgstr "misslyckades göra %s läsbar"
 
 #, c-format
 msgid "could not write '%s' promisor file"
@@ -18048,10 +18250,6 @@
 msgstr "%s förväntar ett icke-negativt heltalsvärde, med valfritt k/m/g-suffix"
 
 #, c-format
-msgid "%s is incompatible with %s"
-msgstr "%s är inkompatibel med %s"
-
-#, c-format
 msgid "ambiguous option: %s (could be --%s%s or --%s%s)"
 msgstr "tvetydig flagga: %s (kan vara --%s%s eller --%s%s)"
 
@@ -18160,7 +18358,7 @@
 
 #, c-format
 msgid "failed to parse %s"
-msgstr "kunde inte tolka %s"
+msgstr "misslyckades tolka %s"
 
 #, c-format
 msgid "Could not make %s writable by group"
@@ -18239,7 +18437,7 @@
 msgstr "kan inte skriva delim-paket"
 
 msgid "unable to write response end packet"
-msgstr "kunde inte skriva svarsavslutningspaket"
+msgstr "kan inte skriva svarsavslutningspaket"
 
 msgid "flush packet write failed"
 msgstr "fel vid skrivning av ”flush”-paket"
@@ -18280,16 +18478,16 @@
 
 #, c-format
 msgid "unable to create threaded lstat: %s"
-msgstr "kunde inte skapa trådad lstat: %s"
+msgstr "kan inte skapa trådad lstat: %s"
 
 msgid "unable to parse --pretty format"
-msgstr "kunde inte tolka format för --pretty"
+msgstr "kan inte tolka format för --pretty"
 
 msgid "promisor-remote: unable to fork off fetch subprocess"
-msgstr "promisor-remote: kunde inte starta (fork) underprocessen för fetch"
+msgstr "promisor-remote: kan inte grena (fork) av underprocessen för fetch"
 
 msgid "promisor-remote: could not write to fetch subprocess"
-msgstr "promisor-remote: kunde skriva till underprocessen för fetch"
+msgstr "promisor-remote: kan skriva till underprocessen för fetch"
 
 msgid "promisor-remote: could not close stdin to fetch subprocess"
 msgstr ""
@@ -18365,10 +18563,6 @@
 msgstr "kan inte lägga till ”%s” till indexet"
 
 #, c-format
-msgid "unable to stat '%s'"
-msgstr "kan inte ta status på ”%s”"
-
-#, c-format
 msgid "'%s' appears as both a file and as a directory"
 msgstr "”%s” finns både som en fil och en katalog"
 
@@ -18431,11 +18625,11 @@
 
 #, c-format
 msgid "unable to create load_cache_entries thread: %s"
-msgstr "kunde inte skapa tråd för load_cache_entries: %s"
+msgstr "kan inte skapa tråd för load_cache_entries: %s"
 
 #, c-format
 msgid "unable to join load_cache_entries thread: %s"
-msgstr "kunde inte ansluta till tråden för load_cache_entries: %s"
+msgstr "kan inte ansluta till tråden för load_cache_entries: %s"
 
 #, c-format
 msgid "%s: index file open failed"
@@ -18455,11 +18649,11 @@
 
 #, c-format
 msgid "unable to create load_index_extensions thread: %s"
-msgstr "kunde inte skapa load_index_extensions-tråden: %s"
+msgstr "kan inte skapa load_index_extensions-tråden: %s"
 
 #, c-format
 msgid "unable to join load_index_extensions thread: %s"
-msgstr "kunde inte utföra join på load_index_extensions-tråden: %s"
+msgstr "kan inte utföra join på load_index_extensions-tråden: %s"
 
 #, c-format
 msgid "could not freshen shared index '%s'"
@@ -18477,11 +18671,11 @@
 
 #, c-format
 msgid "unable to open git dir: %s"
-msgstr "kunde inte öppna git-katalog: %s"
+msgstr "kan inte öppna git-katalog: %s"
 
 #, c-format
 msgid "unable to unlink: %s"
-msgstr "misslyckades ta bort länken: %s"
+msgstr "kan inte ta bort länken: %s"
 
 #, c-format
 msgid "cannot fix permission bits on '%s'"
@@ -18941,10 +19135,6 @@
 msgstr "kan inte hantera ”%s” och ”%s” samtidigt"
 
 #, c-format
-msgid "could not remove reference %s"
-msgstr "kunde inte ta bort referensen %s"
-
-#, c-format
 msgid "could not delete reference %s: %s"
 msgstr "kunde inte ta bort referensen %s: %s"
 
@@ -18953,6 +19143,72 @@
 msgstr "kunde inte ta bort referenser: %s"
 
 #, c-format
+msgid "refname is dangerous: %s"
+msgstr "refnamnet är farligt: %s"
+
+#, c-format
+msgid "trying to write ref '%s' with nonexistent object %s"
+msgstr "försöker skriva referensen ”%s” med icke-existerande objektet %s"
+
+#, c-format
+msgid "trying to write non-commit object %s to branch '%s'"
+msgstr "försöker skriva objektet %s som inte är incheckning till grenen ”%s”"
+
+#, c-format
+msgid ""
+"multiple updates for 'HEAD' (including one via its referent '%s') are not "
+"allowed"
+msgstr ""
+"flera uppdateringar för ”HEAD” (inklusive en via dess referent ”%s”) tillåts "
+"inte"
+
+#, c-format
+msgid "cannot lock ref '%s': unable to resolve reference '%s'"
+msgstr "kan inte låsa referensen ”%s”: kan inte slå upp referensen ”%s”"
+
+#, c-format
+msgid "cannot lock ref '%s': error reading reference"
+msgstr "kan inte låsa referensen ”%s”: fel vid läsning av referensen"
+
+#, c-format
+msgid ""
+"multiple updates for '%s' (including one via symref '%s') are not allowed"
+msgstr ""
+"flera uppdateringar för ”%s” (inklusive en via symrefen ”%s”) tillåts inte"
+
+#, c-format
+msgid "cannot lock ref '%s': reference already exists"
+msgstr "kan inte låsa referensen ”%s”: referensen finns redan"
+
+#, c-format
+msgid "cannot lock ref '%s': reference is missing but expected %s"
+msgstr "kan inte låsa referensen ”%s”: referensen saknas men förväntade %s"
+
+#, c-format
+msgid "cannot lock ref '%s': is at %s but expected %s"
+msgstr "kan inte låsa referensen ”%s”: är vid %s men förväntade %s"
+
+#, c-format
+msgid "reftable: transaction prepare: %s"
+msgstr "referenstabell: förbereder transaktion: %s"
+
+#, c-format
+msgid "reftable: transaction failure: %s"
+msgstr "referenstabell: transaktionen misslyckades: %s"
+
+#, c-format
+msgid "unable to compact stack: %s"
+msgstr "kan inte kompaktera stack: %s"
+
+#, c-format
+msgid "refname %s not found"
+msgstr "referensnamnet %s hittades inte"
+
+#, c-format
+msgid "refname %s is a symbolic ref, copying it is not supported"
+msgstr "referensnamnet %s är en symbolisk referens, kopiering stöds inte"
+
+#, c-format
 msgid "invalid refspec '%s'"
 msgstr "felaktig referensspecifikation: ”%s”"
 
@@ -18961,6 +19217,10 @@
 msgstr "felaktig citering på värde för push-option: ”%s”"
 
 #, c-format
+msgid "unknown value for object-format: %s"
+msgstr "okänt värde för object-format: %s"
+
+#, c-format
 msgid "%sinfo/refs not valid: is this a git repository?"
 msgstr "%sinfo/refs inte giltig: är detta ett git-arkiv?"
 
@@ -18998,7 +19258,7 @@
 msgstr "fjärrservern sände oväntat svarsavslutningspaketet"
 
 msgid "unable to rewind rpc post data - try increasing http.postBuffer"
-msgstr "kunde inte spola tillbaka rpc-postdata - försök öka http.postBuffer"
+msgstr "kan inte spola tillbaka rpc-postdata - försök öka http.postBuffer"
 
 #, c-format
 msgid "remote-curl: bad line length character: %.4s"
@@ -19138,7 +19398,7 @@
 "- Se efter en referens som motsvarar ”%s” på fjärrsidan.\n"
 "- Se om <källan> som sänds (”%s”)\n"
 "  är en referens i ”refs/{heads,tags}/”. Om så lägger vi till\n"
-"  motsvarande refs/{heads,tags}/-prefix på fjärrsidan.\n"
+"  motsvarande ”refs/{heads,tags}/”-prefix på fjärrsidan.\n"
 "\n"
 "Inget av dem fungerade, så vi gav upp. Ange fullständig referens."
 
@@ -19233,7 +19493,7 @@
 
 #, c-format
 msgid "couldn't find remote ref %s"
-msgstr "Kunde inte hitta fjärr-referensen %s"
+msgstr "kunde inte hitta fjärr-referensen %s"
 
 #, c-format
 msgid "* Ignoring funny ref '%s' locally"
@@ -19321,7 +19581,7 @@
 msgstr "trasig MERGE_RR"
 
 msgid "unable to write rerere record"
-msgstr "kunde inte skriva rerere-post"
+msgstr "kan inte skriva rerere-post"
 
 #, c-format
 msgid "there were errors while writing '%s' (%s)"
@@ -19386,7 +19646,7 @@
 
 #, c-format
 msgid "failed to find tree of %s"
-msgstr "kunde inte hitta trädet för %s."
+msgstr "misslyckades hitta trädet för %s."
 
 #, c-format
 msgid "unsupported section for hidden refs: %s"
@@ -19400,15 +19660,26 @@
 msgstr "resolve-undo registrerar ”%s” som saknas"
 
 #, c-format
-msgid "could not get commit for ancestry-path argument %s"
-msgstr "kunde inte hämta incheckning för ”ancestry-path”-argumentet %s"
+msgid "%s exists but is a symbolic ref"
+msgstr "%s finns men är en symbolisk referens"
+
+msgid ""
+"--merge requires one of the pseudorefs MERGE_HEAD, CHERRY_PICK_HEAD, "
+"REVERT_HEAD or REBASE_HEAD"
+msgstr ""
+"--merge kräver en av pseudoreferenserna MERGE_HEAD, CHERRY_PICK_HEAD, "
+"REVERT_HEAD eller REBASE_HEAD"
+
+#, c-format
+msgid "could not get commit for --ancestry-path argument %s"
+msgstr "kunde inte hämta incheckning för ”--ancestry-path”-argumentet %s"
 
 msgid "--unpacked=<packfile> no longer supported"
 msgstr "--unpacked=<paketfil> stöds inte längre"
 
 #, c-format
 msgid "invalid option '%s' in --stdin mode"
-msgstr "ogiltig flagga ”%s” i --stdin-läge"
+msgstr "ogiltig flagga ”%s” i ”--stdin”-läge"
 
 msgid "your current branch appears to be broken"
 msgstr "din nuvarande gren verkar vara trasig"
@@ -19630,7 +19901,7 @@
 
 #, c-format
 msgid "unable to parse remote unpack status: %s"
-msgstr "kunde inte tolka fjärruppackningsstatus: %s"
+msgstr "kan inte tolka fjärruppackningsstatus: %s"
 
 #, c-format
 msgid "remote unpack failed: %s"
@@ -19640,7 +19911,7 @@
 msgstr "misslyckades underteckna push-certifikatet"
 
 msgid "send-pack: unable to fork off fetch subprocess"
-msgstr "send-pack: kunde inte starta (fork) underprocessen för fetch"
+msgstr "send-pack: kan inte grena (fork) av underprocessen för fetch"
 
 msgid "push negotiation failed; proceeding anyway with push"
 msgstr "sänd-förhandling misslyckades; fortsätter ändå med sändningen"
@@ -19686,6 +19957,19 @@
 msgstr "okänd funktion: %d"
 
 msgid ""
+"Resolve all conflicts manually, mark them as resolved with\n"
+"\"git add/rm <conflicted_files>\", then run \"git rebase --continue\".\n"
+"You can instead skip this commit: run \"git rebase --skip\".\n"
+"To abort and get back to the state before \"git rebase\", run \"git rebase --"
+"abort\"."
+msgstr ""
+"Lös alla konflikter manuellt, märk dem som lösta med\n"
+"”git add/rm <filer_i_konflikt>”, kör sedan ”git rebase --continue”.\n"
+"Du kan hoppa över incheckningen istället: kör ”git rebase --skip”.\n"
+"För att avbryta och återgå till där du var före ombaseringen, kör ”git "
+"rebase --abort”."
+
+msgid ""
 "after resolving the conflicts, mark the corrected paths\n"
 "with 'git add <paths>' or 'git rm <paths>'"
 msgstr ""
@@ -19872,7 +20156,7 @@
 msgstr "kunde inte tolka en precis skapad incheckning"
 
 msgid "unable to resolve HEAD after creating commit"
-msgstr "kunde inte bestämma HEAD efter att ha skapat incheckning"
+msgstr "kan inte bestämma HEAD efter att ha skapat incheckning"
 
 msgid "detached HEAD"
 msgstr "frånkopplad HEAD"
@@ -19888,11 +20172,11 @@
 msgstr "HEAD %s är inte en incheckning!"
 
 msgid "unable to parse commit author"
-msgstr "kunde inte tolka incheckningens författare"
+msgstr "kan inte tolka incheckningens författare"
 
 #, c-format
 msgid "unable to read commit message from '%s'"
-msgstr "kunde inte läsa incheckningsmeddelande från ”%s”"
+msgstr "kan inte läsa incheckningsmeddelande från ”%s”"
 
 #, c-format
 msgid "invalid author identity '%s'"
@@ -19906,10 +20190,6 @@
 msgstr "kunde inte uppdatera %s"
 
 #, c-format
-msgid "could not parse commit %s"
-msgstr "kunde inte tolka incheckningen %s"
-
-#, c-format
 msgid "could not parse parent commit %s"
 msgstr "kunde inte tolka föräldraincheckningen %s"
 
@@ -20013,10 +20293,6 @@
 msgstr "ogiltigt kommando ”%.*s”"
 
 #, c-format
-msgid "%s does not accept arguments: '%s'"
-msgstr "%s tar inte argument: ”%s”"
-
-#, c-format
 msgid "missing arguments for %s"
 msgstr "argument saknas för %s"
 
@@ -20114,7 +20390,7 @@
 msgstr "ingen ”cherry-pick” pågår"
 
 msgid "failed to skip the commit"
-msgstr "kunde inte hoppa över incheckningen"
+msgstr "misslyckades hoppa över incheckningen"
 
 msgid "there is nothing to skip"
 msgstr "ingenting att hoppa över"
@@ -20299,6 +20575,9 @@
 msgid "Autostash exists; creating a new stash entry."
 msgstr "Autostash finns; skapar ny stash-post."
 
+msgid "autostash reference is a symref"
+msgstr "autostash-referensen är en symbolisk referens"
+
 msgid "could not detach HEAD"
 msgstr "kunde inte koppla från HEAD"
 
@@ -20468,6 +20747,10 @@
 msgstr "kan inte skapa arbetskatalog med felaktig konfiguration"
 
 #, c-format
+msgid "'%s' already specified as '%s'"
+msgstr "”%s” har redan angivits som ”%s”"
+
+#, c-format
 msgid "Expected git repo version <= %d, found %d"
 msgstr "Förväntade git-arkivversion <= %d, hittade %d"
 
@@ -20611,6 +20894,10 @@
 msgstr "ogiltigt namn på första gren: ”%s”"
 
 #, c-format
+msgid "re-init: ignored --initial-branch=%s"
+msgstr "re-init: ignorerade --initial-branch=%s"
+
+#, c-format
 msgid "unable to handle file type %d"
 msgstr "kan inte hantera filtyp %d"
 
@@ -20621,15 +20908,15 @@
 msgid "attempt to reinitialize repository with different hash"
 msgstr "försöker initiera arkivet på nytt med annan hash"
 
+msgid ""
+"attempt to reinitialize repository with different reference storage format"
+msgstr "försöker initiera arkivet på nytt med annat referenslagringsformat"
+
 #, c-format
 msgid "%s already exists"
 msgstr "%s finns redan"
 
 #, c-format
-msgid "re-init: ignored --initial-branch=%s"
-msgstr "re-init: ignorerade --initial-branch=%s"
-
-#, c-format
 msgid "Reinitialized existing shared Git repository in %s%s\n"
 msgstr "Ominitierade befintligt delat Git-arkiv i %s%s\n"
 
@@ -20652,6 +20939,21 @@
 msgid "cannot use split index with a sparse index"
 msgstr "kan inte dela indexet med ett glest index"
 
+#. TRANSLATORS: The first %s is a command like "ls-tree".
+#, c-format
+msgid "bad %s format: element '%s' does not start with '('"
+msgstr "felaktigt %s-format: elementet ”%s” börjar inte med ”(”"
+
+#. TRANSLATORS: The first %s is a command like "ls-tree".
+#, c-format
+msgid "bad %s format: element '%s' does not end in ')'"
+msgstr "felaktigt %s-format: elementet ”%s” slutar inte med ”)”"
+
+#. TRANSLATORS: %s is a command like "ls-tree".
+#, c-format
+msgid "bad %s format: %%%.*s"
+msgstr "felaktigt %s-format: %%%.*s"
+
 #. TRANSLATORS: IEC 80000-13:2008 gibibyte
 #, c-format
 msgid "%u.%2.2u GiB"
@@ -20709,11 +21011,11 @@
 
 #, c-format
 msgid "Could not update .gitmodules entry %s"
-msgstr "Kunde inte uppdatera .gitmodules-posten %s"
+msgstr "Kunde inte uppdatera ”.gitmodules”-posten %s"
 
 msgid "Cannot change unmerged .gitmodules, resolve merge conflicts first"
 msgstr ""
-"Kan inte ändra .gitmodules-fil som inte slagits ihop, lös "
+"Kan inte ändra ”.gitmodules”-fil som inte slagits ihop, lös "
 "sammanslagningskonflikter först"
 
 #, c-format
@@ -20722,7 +21024,7 @@
 
 #, c-format
 msgid "Could not remove .gitmodules entry for %s"
-msgstr "Kunde inte ta bort .gitmodules-posten för %s"
+msgstr "Kunde inte ta bort ”.gitmodules”-posten för %s"
 
 msgid "staging updated .gitmodules failed"
 msgstr "misslyckades köa uppdaterad .gitmodules"
@@ -20785,7 +21087,7 @@
 
 #, c-format
 msgid "Fetching submodule %s%s at commit %s\n"
-msgstr "Hämtar undermodulen %s%s vvid incheckningen %s\n"
+msgstr "Hämtar undermodulen %s%s vid incheckningen %s\n"
 
 #, c-format
 msgid ""
@@ -20893,12 +21195,6 @@
 msgid "number of entries in the cache tree to invalidate (default 0)"
 msgstr "antal poster i cacheträdet att ogiltigförklara (förval är 0)"
 
-msgid "unhandled options"
-msgstr "flaggor som inte hanterats"
-
-msgid "error preparing revisions"
-msgstr "fel när revisioner skulle förberedas"
-
 #, c-format
 msgid "commit %s is not marked reachable"
 msgstr "incheckning %s är inte märkt nåbar"
@@ -20980,29 +21276,6 @@
 msgid "empty trailer token in trailer '%.*s'"
 msgstr "tom släpradssymbol i släpraden ”%.*s”"
 
-#, c-format
-msgid "could not read input file '%s'"
-msgstr "kunde inte läsa indatafilen ”%s”"
-
-#, c-format
-msgid "could not stat %s"
-msgstr "kunde inte ta status på %s"
-
-#, c-format
-msgid "file %s is not a regular file"
-msgstr "filen %s är inte en normal fil"
-
-#, c-format
-msgid "file %s is not writable by user"
-msgstr "filen %s är inte skrivbar av användaren"
-
-msgid "could not open temporary file"
-msgstr "kunde inte öppna temporär fil"
-
-#, c-format
-msgid "could not rename temporary file to %s"
-msgstr "kunde inte byta namn på temporär fil till %s"
-
 msgid "full write to remote helper failed"
 msgstr "komplett skrivning till fjärrhjälpare misslyckades"
 
@@ -21054,9 +21327,6 @@
 msgid "invalid remote service path"
 msgstr "felaktig sökväg till fjärrtjänst"
 
-msgid "operation not supported by protocol"
-msgstr "funktionen stöds inte av protokollet"
-
 #, c-format
 msgid "can't connect to subservice %s"
 msgstr "kan inte ansluta till undertjänsten %s"
@@ -21103,8 +21373,8 @@
 msgstr "fjärrhjälparen stöder inte push; referensspecifikation krävs"
 
 #, c-format
-msgid "helper %s does not support 'force'"
-msgstr "hjälparen %s stöder inte ”force”"
+msgid "helper %s does not support '--force'"
+msgstr "hjälparen %s stöder inte ”--force”"
 
 msgid "couldn't run fast-export"
 msgstr "kunde inte köra fast-export"
@@ -21187,10 +21457,6 @@
 msgstr "stöd för protokoll v2 ännu ej implementerat"
 
 #, c-format
-msgid "unknown value for config '%s': %s"
-msgstr "okänt värde för inställningen ”%s”: %s"
-
-#, c-format
 msgid "transport '%s' not allowed"
 msgstr "transporten ”%s” tillåts inte"
 
@@ -21235,7 +21501,7 @@
 msgstr "Avbryter."
 
 msgid "failed to push all needed submodules"
-msgstr "kunde inte sända alla nödvändiga undermoduler"
+msgstr "misslyckades sända alla nödvändiga undermoduler"
 
 msgid "bundle-uri operation not supported by protocol"
 msgstr "bundle-uri-funktionen stöds inte av protokollet"
@@ -21243,6 +21509,9 @@
 msgid "could not retrieve server-advertised bundle-uri list"
 msgstr "kunde inte hämta bundle-uri-listan som servern annonserade"
 
+msgid "operation not supported by protocol"
+msgstr "funktionen stöds inte av protokollet"
+
 msgid "too-short tree object"
 msgstr "trädobjekt för kort"
 
@@ -21522,6 +21791,10 @@
 msgid "invalid '..' path segment"
 msgstr "felaktigt ”..”-sökvägssegment"
 
+#, c-format
+msgid "error: unable to format message: %s\n"
+msgstr "fel: kan inte formatera meddelande: %s\n"
+
 msgid "usage: "
 msgstr "användning: "
 
@@ -21569,13 +21842,13 @@
 msgstr "inte en giltig sökväg"
 
 msgid "unable to locate repository; .git is not a file"
-msgstr "hittar inte arkivet; .git är inte en fil"
+msgstr "kan inte hitta arkivet; .git är inte en fil"
 
 msgid "unable to locate repository; .git file does not reference a repository"
-msgstr "hittar inte arkivet; .git-filen hänvisar inte till ett arkiv"
+msgstr "kan inte hitta arkivet; ”.git”-filen hänvisar inte till ett arkiv"
 
 msgid "unable to locate repository; .git file broken"
-msgstr "hittar inte arkivet; .git-filen är trasig"
+msgstr "kan inte hitta arkivet; ”.git”-filen är trasig"
 
 msgid "gitdir unreadable"
 msgstr "gitdir är oläsbar"
@@ -21587,21 +21860,21 @@
 msgstr "inte i en giltig katalog"
 
 msgid "gitdir file does not exist"
-msgstr "gitdir-filen existerar inte"
+msgstr "”gitdir”-filen existerar inte"
 
 #, c-format
 msgid "unable to read gitdir file (%s)"
-msgstr "kunde inte läsa gitdir-filen (%s)"
+msgstr "kan inte läsa ”gitdir”-filen (%s)"
 
 #, c-format
 msgid "short read (expected %<PRIuMAX> bytes, read %<PRIuMAX>)"
 msgstr "kort läsning (förväntade %<PRIuMAX> byte, läste %<PRIuMAX>)"
 
 msgid "invalid gitdir file"
-msgstr "ogiltig gitdir-fil"
+msgstr "ogiltig ”gitdir”-fil"
 
 msgid "gitdir file points to non-existent location"
-msgstr "gitdir-filen pekar på en ickeexisterande plats"
+msgstr "”gitdir”-filen pekar på en ickeexisterande plats"
 
 #, c-format
 msgid "unable to set %s in '%s'"
@@ -21620,7 +21893,7 @@
 
 #, c-format
 msgid "unable to create '%s'"
-msgstr "kunde inte skapa ”%s”"
+msgstr "kan inte skapa ”%s”"
 
 #, c-format
 msgid "could not open '%s' for reading and writing"
@@ -21634,7 +21907,7 @@
 msgstr "kan inte hämta aktuell arbetskatalog"
 
 msgid "unable to get random bytes"
-msgstr "kunde inte hämta slumpdata"
+msgstr "kan inte hämta slumpdata"
 
 msgid "Unmerged paths:"
 msgstr "Ej sammanslagna sökvägar:"
@@ -22066,6 +22339,10 @@
 msgid "cannot %s: Your index contains uncommitted changes."
 msgstr "kan inte %s: Ditt index innehåller ändringar som inte checkats in."
 
+#, c-format
+msgid "unknown style '%s' given for '%s'"
+msgstr "okänd stil ”%s” angavs för ”%s”"
+
 msgid ""
 "Error: Your local changes to the following files would be overwritten by "
 "merge"
@@ -22104,7 +22381,7 @@
 
 #, sh-format
 msgid "Cannot chdir to $cdup, the toplevel of the working tree"
-msgstr "Kunde inte byta katalog till $cdup, toppnivån på arbetskatalogen"
+msgstr "Kan inte byta katalog till $cdup, toppnivån på arbetskatalogen"
 
 #, sh-format
 msgid "fatal: $program_name cannot be used without a working tree."
@@ -22234,7 +22511,7 @@
 
 #, perl-format
 msgid "Failed to open for writing %s: %s"
-msgstr "Kunde inte öppna för skrivning %s: %s"
+msgstr "Misslyckades öppna för skrivning %s: %s"
 
 msgid ""
 "Lines beginning in \"GIT:\" will be removed.\n"
@@ -22299,7 +22576,7 @@
 
 #, perl-format
 msgid "error: unable to extract a valid address from: %s\n"
-msgstr "fel: kunde inte få fram en giltig adress från: %s\n"
+msgstr "fel: kan inte få fram en giltig adress från: %s\n"
 
 #. TRANSLATORS: Make sure to include [q] [d] [e] in your
 #. translation. The program will only accept English input
@@ -22437,7 +22714,7 @@
 
 #, perl-format
 msgid "unable to open %s: %s\n"
-msgstr "kunde inte öppna %s: %s\n"
+msgstr "kan inte öppna %s: %s\n"
 
 #, perl-format
 msgid ""
diff --git a/po/tr.po b/po/tr.po
index f01962d..0e220e1 100644
--- a/po/tr.po
+++ b/po/tr.po
@@ -1,8 +1,8 @@
 # Turkish translations for Git
 # Git Türkçe çevirileri
-# Copyright (C) 2020-2023 Emir SARI <emir_sari@icloud.com>
+# Copyright (C) 2020-2024 Emir SARI <emir_sari@icloud.com>
 # This file is distributed under the same license as the Git package.
-# Emir SARI <emir_sari@icloud.com>, 2020-2023
+# Emir SARI <emir_sari@icloud.com>, 2020-2024
 #
 # ######################################################### #
 #     Git Türkçe kavramlar dizini / Git Turkish Glossary    #
@@ -20,13 +20,14 @@
 # clone                       | klon(lamak)                 #
 # commit (ad)                 | işleme                      #
 # commit (eyl.)               | işlemek                     #
-# commitish                   | işlememsi                   #
+# commit-ish                  | işlememsi                   #
 # conflict                    | çakışma                     #
 # cruft                       | süprüntü                    #
 # dangling object             | sallanan nesne              #
 # detached HEAD               | ayrık HEAD                  #
 # dirty                       | kirli                       #
 # evil merge                  | uğursuz birleştirme         #
+# fanout                      | çıkış sayısı                #
 # fast-forward                | ileri sarım/sarmak          #
 # fetch                       | getirme(k)                  #
 # fixup                       | düzeltmek                   #
@@ -48,10 +49,10 @@
 # pathspec                    | yol belirteci               #
 # pattern                     | dizgi                       #
 # porcelain                   | okunabilir                  #
-# prune                       | budamak                     #
-# pseudoref                   | yalancıktan başvuru         #
-# pull                        | çekme(k)                    #
-# push                        | itme(k)                     #
+# prune                       | buda(mak)                   #
+# pseudoref                   | yalancı başvuru             #
+# pull                        | çek(mek)                    #
+# push                        | it(mek)                     #
 # rebase                      | yeniden temellendirme(k)    #
 # record                      | kayıt yaz(mak)              #
 # ref                         | başvuru                     #
@@ -85,6 +86,7 @@
 # trailer                     | artbilgi                    #
 # tree                        | ağaç                        #
 # treeish                     | ağacımsı                    #
+# unborn                      | henüz doğmamış (dal)        #
 # unstage                     | hazırlıktan çıkar(mak)      #
 # upstream                    | üstkaynak                   #
 # worktree/working tree       | çalışma ağacı               #
@@ -94,8 +96,8 @@
 msgstr ""
 "Project-Id-Version: Git Turkish Localization Project\n"
 "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2023-11-09 11:15+0300\n"
-"PO-Revision-Date: 2023-11 13:00+0300\n"
+"POT-Creation-Date: 2024-04-29 01:09+0300\n"
+"PO-Revision-Date: 2024-04-29 01:10+0300\n"
 "Last-Translator: Emir SARI <emir_sari@icloud.com>\n"
 "Language-Team: Turkish (https://github.com/bitigchi/git-po/)\n"
 "Language: tr\n"
@@ -578,12 +580,12 @@
 "---\n"
 "To remove '%c' lines, make them ' ' lines (context).\n"
 "To remove '%c' lines, delete them.\n"
-"Lines starting with %c will be removed.\n"
+"Lines starting with %s will be removed.\n"
 msgstr ""
 "---\n"
 "'%c' satır kaldırmak için onları ' ' satır yapın (bağlam).\n"
 "'%c' satır kaldırmak için onları silin.\n"
-"%c kaldırılacak.\n"
+"%s ile başlayan satırlar kaldırılacak.\n"
 
 msgid ""
 "If it does not apply cleanly, you will be given an opportunity to\n"
@@ -630,6 +632,7 @@
 "/ - search for a hunk matching the given regex\n"
 "s - split the current hunk into smaller hunks\n"
 "e - manually edit the current hunk\n"
+"p - print the current hunk\n"
 "? - print help\n"
 msgstr ""
 "j - bu parça için sonra karar ver, bir sonraki karar verilmemiş parçayı gör\n"
@@ -640,6 +643,7 @@
 "/ - verilen düzenli ifade ile eşleşen bir parça ara\n"
 "s - geçerli parçayı daha ufak parçalara böl\n"
 "e - geçerli parçayı el ile düzenle\n"
+"p - geçerli parçalı yazdır\n"
 "? - yardımı yazdır\n"
 
 msgid "No previous hunk"
@@ -702,8 +706,8 @@
 "Bu iletiyi \"git config advice.%s false\" ile devre dışı bırakın"
 
 #, c-format
-msgid "%shint: %.*s%s\n"
-msgstr "%sipucu: %.*s%s\n"
+msgid "%shint:%s%.*s%s\n"
+msgstr "%sipucu: %s%.*s%s\n"
 
 msgid "Cherry-picking is not possible because you have unmerged files."
 msgstr "Seç-al yapılamaz; birleştirmesi tamamlanmamış dosyalarınız var."
@@ -1201,10 +1205,6 @@
 msgstr[1] "%%s yaması %d geri çevirme ile uygulanıyor..."
 
 #, c-format
-msgid "truncating .rej filename to %.*s.rej"
-msgstr ".rej dosya adı %.*s.rej olarak kısaltılıyor"
-
-#, c-format
 msgid "cannot open %s"
 msgstr "%s açılamıyor"
 
@@ -1500,6 +1500,10 @@
 msgstr "Beklenmedik seçenek --output"
 
 #, c-format
+msgid "extra command line parameter '%s'"
+msgstr "fazladan komut satırı parametresi '%s'"
+
+#, c-format
 msgid "Unknown archive format '%s'"
 msgstr "Bilinmeyen arşiv biçimi '%s'"
 
@@ -1545,6 +1549,14 @@
 msgstr "hatalı --attr-source veya GIT_ATTR_SOURCE"
 
 #, c-format
+msgid "unable to stat '%s'"
+msgstr "'%s' dosyasının bilgileri alınamıyor"
+
+#, c-format
+msgid "unable to read %s"
+msgstr "%s okunamıyor"
+
+#, c-format
 msgid "Badly quoted content in file '%s': %s"
 msgstr "'%s' dosyasında hatalı tırnağa alınmış içerik: %s"
 
@@ -1613,6 +1625,10 @@
 msgstr "'%s' dosyası oluşturulamadı"
 
 #, c-format
+msgid "unable to start 'show' for object '%s'"
+msgstr "'%s' nesnesi için 'show' başlatılamıyor"
+
+#, c-format
 msgid "could not read file '%s'"
 msgstr "'%s' dosyası okunamadı"
 
@@ -1764,6 +1780,9 @@
 msgid "'%s' is not a valid branch name"
 msgstr "'%s' geçerli bir dal adı değil"
 
+msgid "See `man git check-ref-format`"
+msgstr "'man git check-ref-format' kılavuz sayfasına bakın"
+
 #, c-format
 msgid "a branch named '%s' already exists"
 msgstr "'%s' adında bir dal halihazırda var"
@@ -1959,14 +1978,8 @@
 msgid "adding embedded git repository: %s"
 msgstr "gömülü git deposu ekleniyor: %s"
 
-msgid ""
-"Use -f if you really want to add them.\n"
-"Turn this message off by running\n"
-"\"git config advice.addIgnoredFile false\""
-msgstr ""
-"Gerçekten eklemek istiyorsanız -f kullanın.\n"
-"Bu iletiyi 'git config advice.addIgnoredFile false'\n"
-"yaparak kapatabilirsiniz"
+msgid "Use -f if you really want to add them."
+msgstr "Onları gerçekten eklemek istiyorsanız -f kullanın."
 
 msgid "adding files failed"
 msgstr "dosya ekleme başarısız"
@@ -1983,14 +1996,8 @@
 msgid "Nothing specified, nothing added.\n"
 msgstr "Hiçbir şey belirtilmedi, hiçbir şey eklenmedi.\n"
 
-msgid ""
-"Maybe you wanted to say 'git add .'?\n"
-"Turn this message off by running\n"
-"\"git config advice.addEmptyPathspec false\""
-msgstr ""
-"'git add .' mı demek istediniz?\n"
-"Bu iletiyi 'git config advice.addEmptyPathspec false'\n"
-"yaparak kapatabilirsiniz"
+msgid "Maybe you wanted to say 'git add .'?"
+msgstr "'git add .' mi demek istediniz?"
 
 msgid "index file corrupt"
 msgstr "indeks dosyası hasarlı"
@@ -2067,24 +2074,25 @@
 msgstr "Yamalar parçalanıp bölünemedi."
 
 #, c-format
-msgid "When you have resolved this problem, run \"%s --continue\"."
-msgstr "Bu sorunu çözdüğünüzde \"%s --continue\" çalıştırın."
+msgid "When you have resolved this problem, run \"%s --continue\".\n"
+msgstr "Bu sorunu çözdüğünüzde \"%s --continue\" çalıştırın.\n"
 
 #, c-format
-msgid "If you prefer to skip this patch, run \"%s --skip\" instead."
-msgstr "Eğer bu yamayı atlamayı yeğliyorsanız \"%s --skip\" çalıştırın."
+msgid "If you prefer to skip this patch, run \"%s --skip\" instead.\n"
+msgstr "Eğer bu yamayı atlamayı yeğliyorsanız \"%s --skip\" çalıştırın.\n"
 
 #, c-format
-msgid "To record the empty patch as an empty commit, run \"%s --allow-empty\"."
+msgid ""
+"To record the empty patch as an empty commit, run \"%s --allow-empty\".\n"
 msgstr ""
 "Boş yamayı boş işleme kaydı olarak yazmak için \"%s --allow-empty\" "
-"çalıştırın."
+"çalıştırın.\n"
 
 #, c-format
 msgid "To restore the original branch and stop patching, run \"%s --abort\"."
 msgstr ""
 "İlk dalı eski durumuna getirip yamalamayı durdurmak için \"%s --abort\" "
-"çalıştır."
+"çalıştırın."
 
 msgid "Patch sent with format=flowed; space at the end of lines might be lost."
 msgstr ""
@@ -2823,12 +2831,12 @@
 msgstr "'%s' için işleme nesnesi aranamadı"
 
 #, c-format
-msgid ""
-"the branch '%s' is not fully merged.\n"
-"If you are sure you want to delete it, run 'git branch -D %s'"
-msgstr ""
-"'%s' dalı tümüyle birleştirilmemiş.\n"
-"Eğer silmek istediğinizden eminseniz 'git branch -D %s' çalıştırın."
+msgid "the branch '%s' is not fully merged"
+msgstr "'%s' dalı tümüyle birleştirilmedi"
+
+#, c-format
+msgid "If you are sure you want to delete it, run 'git branch -D %s'"
+msgstr "Onu silmek istediğinizden eminseniz 'git branch -D %s' çalıştırın."
 
 msgid "update of config-file failed"
 msgstr "config-file güncellenemedi"
@@ -2927,11 +2935,11 @@
 msgid ""
 "Please edit the description for the branch\n"
 "  %s\n"
-"Lines starting with '%c' will be stripped.\n"
+"Lines starting with '%s' will be stripped.\n"
 msgstr ""
-"Lütfen dal açıklamasını düzenleyin:\n"
+"Lütfen dal açıklamasını düzenleyin\n"
 "\t%s\n"
-"'%c' ile başlayan satırlar çıkarılacaktır.\n"
+"'%s' ile başlayan satırlar soyulacaktır.\n"
 
 msgid "Generic options"
 msgstr "Genel seçenekler"
@@ -3132,10 +3140,12 @@
 msgstr "bir git deposundan çalıştırılmadı - gösterilecek kanca yok\n"
 
 msgid ""
-"git bugreport [(-o | --output-directory) <path>] [(-s | --suffix) <format>]\n"
+"git bugreport [(-o | --output-directory) <path>]\n"
+"              [(-s | --suffix) <format> | --no-suffix]\n"
 "              [--diagnose[=<mode>]]"
 msgstr ""
-"git bugreport [(-o | --output-directory) <yol>] [(-s | --suffix) <biçim>]\n"
+"git bugreport [(-o | --output-directory) <yol>]\n"
+"              [(-s | --suffix) <biçim> | --no-suffix]\n"
 "              [--diagnose[=<kip>]]"
 
 msgid ""
@@ -3616,6 +3626,10 @@
 msgid "path '%s' is unmerged"
 msgstr "'%s' yolu birleştirilmemiş"
 
+#, c-format
+msgid "unable to read tree (%s)"
+msgstr "ağaç okunamıyor (%s)"
+
 msgid "you need to resolve your current index first"
 msgstr "önce geçerli indeksinizi çözmelisiniz"
 
@@ -3845,6 +3859,10 @@
 msgid "missing branch or commit argument"
 msgstr "dal veya işleme argümanı eksik"
 
+#, c-format
+msgid "unknown conflict style '%s'"
+msgstr "bilinmeyen çakışma stili '%s'"
+
 msgid "perform a 3-way merge with the new branch"
 msgstr "yeni dal ile bir 3 yönlü birleştirme gerçekleştir"
 
@@ -3863,8 +3881,8 @@
 msgid "new-branch"
 msgstr "yeni dal"
 
-msgid "new unparented branch"
-msgstr "yeni üst ögesi olmayan dal"
+msgid "new unborn branch"
+msgstr "yeni henüz doğmamış dal"
 
 msgid "update ignored files (default)"
 msgstr "yok sayılan dosyaları güncelle (öntanımlı)"
@@ -4101,22 +4119,10 @@
 msgid "remove only ignored files"
 msgstr "yalnızca yok sayılan dosyaları kaldır"
 
-msgid ""
-"clean.requireForce set to true and neither -i, -n, nor -f given; refusing to "
-"clean"
+msgid "clean.requireForce is true and -f not given: refusing to clean"
 msgstr ""
-"clean.requireForce 'true' olarak ayarlanmış ve ne -i ne -n ne de -f "
-"verilmiş; temizleme reddediliyor"
-
-msgid ""
-"clean.requireForce defaults to true and neither -i, -n, nor -f given; "
-"refusing to clean"
-msgstr ""
-"clean.requireForce öntanımlı olarak 'true' ve ne -i ne -n ne de -f verilmiş; "
-"temizleme reddediliyor"
-
-msgid "-x and -X cannot be used together"
-msgstr "-x ve -X birlikte kullanılamaz"
+"clean.requireForce 'true' olarak ayarlı ve -f verilmedi; temizlik "
+"reddediliyor"
 
 msgid "git clone [<options>] [--] <repo> [<dir>]"
 msgstr "git clone [<seçenekler>] [--] <depo> [<dizin>]"
@@ -4130,8 +4136,8 @@
 msgid "create a bare repository"
 msgstr "çıplak bir depo oluştur"
 
-msgid "create a mirror repository (implies bare)"
-msgstr "bir yansı depo oluştur (çıplak ima eder)"
+msgid "create a mirror repository (implies --bare)"
+msgstr "bir yansı depo oluştur (--bare ima eder)"
 
 msgid "to clone from a local repository"
 msgstr "bir yerel depodan klonla"
@@ -4205,6 +4211,9 @@
 msgid "separate git dir from working tree"
 msgstr "git dizinini çalışma ağacından ayır"
 
+msgid "specify the reference format to use"
+msgstr "kullanılacak başvuru biçimini belirt"
+
 msgid "key=value"
 msgstr "anahtar=değer"
 
@@ -4248,7 +4257,7 @@
 
 #, c-format
 msgid "'%s' is a symlink, refusing to clone with --local"
-msgstr "'%s' bir sembolik bağlantı; --local ile klonlama reddediliyor"
+msgstr "'%s' bir sembolik bağ; --local ile klonlama reddediliyor"
 
 #, c-format
 msgid "failed to start iterator over '%s'"
@@ -4256,7 +4265,7 @@
 
 #, c-format
 msgid "symlink '%s' exists, refusing to clone with --local"
-msgstr "'%s' sembolik bağlantısı var, --local ile klonlama reddediliyor"
+msgstr "'%s' sembolik bağı var, --local ile klonlama reddediliyor"
 
 #, c-format
 msgid "failed to unlink '%s'"
@@ -4322,11 +4331,9 @@
 msgid "You must specify a repository to clone."
 msgstr "Klonlamak için bir depo belirtmelisiniz."
 
-msgid ""
-"--bundle-uri is incompatible with --depth, --shallow-since, and --shallow-"
-"exclude"
-msgstr ""
-"--bundle-uri; --depth, --shallow-since ve --shallow-exclude ile uyumsuz"
+#, c-format
+msgid "unknown ref storage format '%s'"
+msgstr "bilinmeyen başvuru depolama biçimi '%s'"
 
 #, c-format
 msgid "repository '%s' does not exist"
@@ -4440,6 +4447,10 @@
 msgid "padding space between columns"
 msgstr "sütunlar arasındaki dolgu boşluğu"
 
+#, c-format
+msgid "%s must be non-negative"
+msgstr "%s negatif dışı bir değer olmalı"
+
 msgid "--command must be the first argument"
 msgstr "--command ilk argüman olmalı"
 
@@ -4454,11 +4465,11 @@
 "--stdin-commits]\n"
 "                       [--changed-paths] [--[no-]max-new-filters <n>] [--"
 "[no-]progress]\n"
-"                       <split options>"
+"                       <split-options>"
 msgstr ""
 "git commit-graph write [--object-dir <dizin>] [--append]\n"
-"                       [--split[=<<strateji>]] [--reachable | --stdin-packs "
-"| --stdin-commits]\n"
+"                       [--split[=<strateji>]] [--reachable | --stdin-packs | "
+"--stdin-commits]\n"
 "                       [--changed-paths] [--[no-]max-new-filters <n>] [--"
 "[no-]progress]\n"
 "                       <bölme-seçenekleri>"
@@ -4753,34 +4764,34 @@
 #, c-format
 msgid ""
 "Please enter the commit message for your changes. Lines starting\n"
-"with '%c' will be ignored.\n"
+"with '%s' will be ignored.\n"
 msgstr ""
-"Lütfen değişiklikleriniz için bir işleme iletisi girin. '%c' ile başlayan\n"
+"Lütfen değişiklikleriniz için bir işleme iletisi girin. '%s' ile başlayan\n"
 "satırlar yok sayılacaktır.\n"
 
 #, 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"
+"with '%s' will be ignored, and an empty message aborts the commit.\n"
 msgstr ""
-"Lütfen değişiklikleriniz için bir işleme iletisi girin. '%c' ile başlayan\n"
+"Lütfen değişiklikleriniz için bir işleme iletisi girin. '%s' ile başlayan\n"
 "satırlar yok sayılacaktır. Boş bir ileti işlemeyi iptal eder.\n"
 
 #, 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"
+"with '%s' will be kept; you may remove them yourself if you want to.\n"
 msgstr ""
-"Lütfen değişiklikleriniz için bir işleme iletisi girin. '%c' ile başlayan\n"
+"Lütfen değişiklikleriniz için bir işleme iletisi girin. '%s' ile başlayan\n"
 "satırlar tutulacaktır; isterseniz onları kaldırabilirsiniz.\n"
 
 #, 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"
+"with '%s' will be kept; you may remove them yourself if you want to.\n"
 "An empty message aborts the commit.\n"
 msgstr ""
-"Lütfen değişiklikleriniz için bir işleme iletisi girin. '%c' ile başlayan\n"
+"Lütfen değişiklikleriniz için bir işleme iletisi girin. '%s' ile başlayan\n"
 "satırlar tutulacaktır; isterseniz onları kaldırabilirsiniz.\n"
 "Boş bir ileti işlemeyi iptal eder.\n"
 
@@ -5229,6 +5240,9 @@
 msgid "with --get, use default value when missing entry"
 msgstr "--get ile girdi verilmemişse öntanımlı değeri kullan"
 
+msgid "human-readable comment string (# will be prepended as needed)"
+msgstr "kişi tarafından okunabilir yorum satırı (gerekirse önüne # koyulur)"
+
 #, c-format
 msgid "wrong number of arguments, should be %d"
 msgstr "yanlış argüman sayısı, %d olmalı"
@@ -5320,7 +5334,10 @@
 "ve --list"
 
 msgid "--default is only applicable to --get"
-msgstr "--default yalnızca şuna uygulanabilir: --get"
+msgstr "--default yalnızca --get için uygulanabilir"
+
+msgid "--comment is only applicable to add/set/replace operations"
+msgstr "--comment yalnızca ekle/ayarla/değiştir işlemlerine uygulanabilir"
 
 msgid "--fixed-value only applies with 'value-pattern'"
 msgstr "--fixed-value yalnızca 'değer-dizgisi' ile uygulanır"
@@ -6162,6 +6179,9 @@
 msgid "read reference patterns from stdin"
 msgstr "başvuru dizgilerini stdin'den oku"
 
+msgid "also include HEAD ref and pseudorefs"
+msgstr "ayrıca HEAD ve yalancı başvuruları içer"
+
 msgid "unknown arguments supplied with --stdin"
 msgstr "--stdin ile bilinmeyen argümanlar verilmiş"
 
@@ -6774,8 +6794,8 @@
 msgstr "iş parçacığı desteği yok, %s yok sayılıyor"
 
 #, c-format
-msgid "unable to read tree (%s)"
-msgstr "ağaç okunamıyor (%s)"
+msgid "unable to read tree %s"
+msgstr "%s ağacı okunamıyor"
 
 #, c-format
 msgid "unable to grep from object of type %s"
@@ -7190,10 +7210,6 @@
 msgstr "%s İLE SHA1 ÇARPIŞMASI BULUNDU!"
 
 #, c-format
-msgid "unable to read %s"
-msgstr "%s okunamıyor"
-
-#, c-format
 msgid "cannot read existing object info %s"
 msgstr "var olan nesne bilgisi %s okunamıyor"
 
@@ -7333,13 +7349,15 @@
 msgid ""
 "git init [-q | --quiet] [--bare] [--template=<template-directory>]\n"
 "         [--separate-git-dir <git-dir>] [--object-format=<format>]\n"
+"         [--ref-format=<format>]\n"
 "         [-b <branch-name> | --initial-branch=<branch-name>]\n"
 "         [--shared[=<permissions>]] [<directory>]"
 msgstr ""
 "git init [-q | --quiet] [--bare] [--template=<şablon-dizini>]\n"
 "         [--separate-git-dir <git-dizini>] [--object-format=<biçim>]\n"
+"         [--ref-format=<biçim>]\n"
 "         [-b <dal-adı> | --initial-branch=<dal-adı>]\n"
-"         [--shared[=<izinler>]] [<dizin>]"
+"         [--shared[=<izin>]] [<dizin>]"
 
 msgid "permissions"
 msgstr "izinler"
@@ -7381,14 +7399,39 @@
 
 msgid ""
 "git interpret-trailers [--in-place] [--trim-empty]\n"
-"                       [(--trailer (<key>|<keyAlias>)[(=|:)<value>])...]\n"
+"                       [(--trailer (<key>|<key-alias>)[(=|:)<value>])...]\n"
 "                       [--parse] [<file>...]"
 msgstr ""
 "git interpret-trailers [--in-place] [--trim-empty]\n"
-"                       [(--trailer (<anahtar>|<anArması>)"
-"[(=|:)<değer>])...]\n"
+"                       [(--trailer (<anahtar>|<arma>)[(=|:)<değer>])...]\n"
 "                       [--parse] [<dosya>...]"
 
+#, c-format
+msgid "could not stat %s"
+msgstr "%s dosya bilgileri alınamadı"
+
+#, c-format
+msgid "file %s is not a regular file"
+msgstr "%s dosyası sıradan bir dosya değil"
+
+#, c-format
+msgid "file %s is not writable by user"
+msgstr "%s dosyası kullanıcı tarafından yazılabilir değil"
+
+msgid "could not open temporary file"
+msgstr "geçici dosya açılamadı"
+
+#, c-format
+msgid "could not read input file '%s'"
+msgstr "'%s' girdi dosyası okunamadı"
+
+msgid "could not read from stdin"
+msgstr "stdin'den okunamadı"
+
+#, c-format
+msgid "could not rename temporary file to %s"
+msgstr "geçici dosya adı %s olarak değiştirilemedi"
+
 msgid "edit files in place"
 msgstr "dosyaları yerinde düzenle"
 
@@ -7774,18 +7817,6 @@
 msgid "could not get object info about '%s'"
 msgstr "'%s' hakkında nesne bilgisi alınamadı"
 
-#, c-format
-msgid "bad ls-files format: element '%s' does not start with '('"
-msgstr "hatalı ls-files biçimi: '%s' ögesi, '(' ile başlamıyor"
-
-#, c-format
-msgid "bad ls-files format: element '%s' does not end in ')'"
-msgstr "hatalı ls-files biçimi: '%s' ögesi, ')' ile sonlanmıyor"
-
-#, c-format
-msgid "bad ls-files format: %%%.*s"
-msgstr "hatalı ls-files biçimi: %%%.*s"
-
 msgid "git ls-files [<options>] [<file>...]"
 msgstr "git ls-files [<seçenekler>] [<dosya>...]"
 
@@ -7916,18 +7947,6 @@
 msgid "git ls-tree [<options>] <tree-ish> [<path>...]"
 msgstr "git ls-tree [<seçenekler>] <ağacımsı> [<yol>...]"
 
-#, c-format
-msgid "bad ls-tree format: element '%s' does not start with '('"
-msgstr "hatalı ls-tree biçimi: '%s' ögesi '(' ile başlamıyor"
-
-#, c-format
-msgid "bad ls-tree format: element '%s' does not end in ')'"
-msgstr "hatalı ls-tree biçimi: '%s' ögesi ')' ile sonlanmıyor"
-
-#, c-format
-msgid "bad ls-tree format: %%%.*s"
-msgstr "hatalı ls-tree biçimi: %%%.*s"
-
 msgid "only show trees"
 msgstr "yalnızca ağaçları göster"
 
@@ -8039,6 +8058,13 @@
 "git merge-file [<seçenekler>] [-L <ad1> [-L <orij> [-L <ad2>]]] <dosya1> "
 "<orij-dosya> <dosya2>"
 
+msgid ""
+"option diff-algorithm accepts \"myers\", \"minimal\", \"patience\" and "
+"\"histogram\""
+msgstr ""
+"diff-algorithm seçeneği şunları kabul eder: \"myers\", \"minimal\", "
+"\"patience\" ve \"histogram\""
+
 msgid "send results to standard output"
 msgstr "sonuçları standart çıktıya gönder"
 
@@ -8060,6 +8086,12 @@
 msgid "for conflicts, use a union version"
 msgstr "çakışmalarda birlik olmuş bir sürüm kullan"
 
+msgid "<algorithm>"
+msgstr "<algoritma>"
+
+msgid "choose a diff algorithm"
+msgstr "bir diff algoritması seç"
+
 msgid "for conflicts, use this marker size"
 msgstr "çakışmalarda bu imleyici boyutunu kullan"
 
@@ -8101,6 +8133,10 @@
 msgid "Merging %s with %s\n"
 msgstr "%s, %s ile birleştiriliyor\n"
 
+#, c-format
+msgid "could not parse as tree '%s'"
+msgstr "'%s' ağacı olarak ayrıştırılamadı"
+
 msgid "not something we can merge"
 msgstr "birleştirebileceğimiz bir şey değil"
 
@@ -8150,9 +8186,6 @@
 msgid "unknown strategy option: -X%s"
 msgstr "bilinmeyen strateji seçeneği: -X%s"
 
-msgid "--merge-base is incompatible with --stdin"
-msgstr "--merge-base, --stdin ile uyumsuz"
-
 #, c-format
 msgid "malformed input line: '%s'."
 msgstr "hatalı oluşturulmuş girdi satırı: '%s'."
@@ -8306,10 +8339,10 @@
 
 #, c-format
 msgid ""
-"Lines starting with '%c' will be ignored, and an empty message aborts\n"
+"Lines starting with '%s' will be ignored, and an empty message aborts\n"
 "the commit.\n"
 msgstr ""
-"'%c' ile başlayan satırlar yok sayılacaktır. Boş bir ileti işlemeyi\n"
+"'%s' ile başlayan satırlar yok sayılacaktır. Boş bir ileti işlemeyi\n"
 "iptal eder.\n"
 
 msgid "Empty commit message."
@@ -8466,9 +8499,6 @@
 msgid "object '%s' tagged as '%s', but is a '%s' type"
 msgstr "'%s' nesnesi '%s' olarak etiketlenmiş; ancak bir '%s' türü"
 
-msgid "could not read from stdin"
-msgstr "stdin'den okunamadı"
-
 msgid "tag on stdin did not pass our strict fsck check"
 msgstr "stdin üzerindeki etiket bizim sıkı fsck denetimimizi geçemedi"
 
@@ -8729,10 +8759,6 @@
 msgid "Write/edit the notes for the following object:"
 msgstr "Aşağıdaki nesneler için not yaz/düzenle:"
 
-#, c-format
-msgid "unable to start 'show' for object '%s'"
-msgstr "'%s' nesnesi için 'show' başlatılamıyor"
-
 msgid "could not read 'show' output"
 msgstr "'show' çıktısı okunamadı"
 
@@ -9078,6 +9104,10 @@
 msgstr "delta sayımında tutarsızlık"
 
 #, c-format
+msgid "invalid pack.allowPackReuse value: '%s'"
+msgstr "geçersiz pack.allowPackReuse değeri: '%s'"
+
+#, c-format
 msgid ""
 "value of uploadpack.blobpackfileuri must be of the form '<object-hash> <pack-"
 "hash> <uri>' (got '%s')"
@@ -9332,10 +9362,10 @@
 #, c-format
 msgid ""
 "Total %<PRIu32> (delta %<PRIu32>), reused %<PRIu32> (delta %<PRIu32>), pack-"
-"reused %<PRIu32>"
+"reused %<PRIu32> (from %<PRIuMAX>)"
 msgstr ""
 "Toplam %<PRIu32> (delta %<PRIu32>), yeniden kullanılan %<PRIu32> (delta "
-"%<PRIu32>), yeniden kullanılan paket %<PRIu32>"
+"%<PRIu32>), yeniden kullanılan paket %<PRIu32> (%<PRIuMAX> konumundan)"
 
 msgid ""
 "'git pack-redundant' is nominated for removal.\n"
@@ -9355,11 +9385,11 @@
 msgstr "--i-still-use-this olmadan çalıştırma reddediliyor"
 
 msgid ""
-"git pack-refs [--all] [--no-prune] [--include <pattern>] [--exclude "
+"git pack-refs [--all] [--no-prune] [--auto] [--include <pattern>] [--exclude "
 "<pattern>]"
 msgstr ""
-"git pack-refs [--all] [--no-prune]git pack-refs [--all] [--no-prune] [--"
-"include <dizgi>] [--exclude <dizgi>]"
+"git pack-refs [--all] [--no-prune] [--auto] [--include <dizgi>] [--exclude "
+"<dizgi>]"
 
 msgid "pack everything"
 msgstr "her şeyi paketle"
@@ -9367,6 +9397,9 @@
 msgid "prune loose refs (default)"
 msgstr "gevşek başvuruları buda (öntanımlı)"
 
+msgid "auto-pack refs as needed"
+msgstr "gerekirse başvuruları paketle"
+
 msgid "references to include"
 msgstr "içerilecek başvurular"
 
@@ -10019,19 +10052,6 @@
 msgid "could not remove '%s'"
 msgstr "'%s' kaldırılamadı"
 
-msgid ""
-"Resolve all conflicts manually, mark them as resolved with\n"
-"\"git add/rm <conflicted_files>\", then run \"git rebase --continue\".\n"
-"You can instead skip this commit: run \"git rebase --skip\".\n"
-"To abort and get back to the state before \"git rebase\", run \"git rebase --"
-"abort\"."
-msgstr ""
-"Tüm çakışmaları el ile çözün, onları \"git add/rm <çakışan-dosyalar>\"\n"
-"ile tamam olarak imleyin, ardından \"git rebase --continue\"\n"
-"çalıştırın. Bunun yerine bu işlemeyi atlayabilirsiniz: \"git rebase\n"
-"--skip\" yapın. İptal edip \"git rebase\" öncesine geri dönmek için\n"
-"\"git rebase --abort\" çalıştırın."
-
 #, c-format
 msgid ""
 "\n"
@@ -10061,12 +10081,15 @@
 msgid "apply options and merge options cannot be used together"
 msgstr "uygulama seçenekleri ve birleştirme seçenekleri birlikte kullanılamaz"
 
+msgid "--empty=ask is deprecated; use '--empty=stop' instead."
+msgstr "--empty=ask artık kullanılmıyor; yerine '--empty=stop' kullanın."
+
 #, c-format
 msgid ""
 "unrecognized empty type '%s'; valid values are \"drop\", \"keep\", and "
-"\"ask\"."
+"\"stop\"."
 msgstr ""
-"Tanımlanamayan boş tür '%s'; geçerli türler: \"drop\", \"keep\" ve \"ask\"."
+"Tanımlanamayan boş tür '%s'; geçerli türler: \"drop\", \"keep\" ve \"stop\"."
 
 msgid ""
 "--rebase-merges with an empty string argument is deprecated and will stop "
@@ -10250,8 +10273,8 @@
 "Not: `pull.rebase` yapılandırmanız, artık desteklenmeyen'\n"
 "'preserve' olarak ayarlı olabilir; yerine 'merges' kullanın"
 
-msgid "No rebase in progress?"
-msgstr "Sürmekte olan bir yeniden temellendirme yok"
+msgid "no rebase in progress"
+msgstr "sürmekte olan yeniden temellendirme yok"
 
 msgid "The --edit-todo action can only be used during interactive rebase."
 msgstr ""
@@ -10299,13 +10322,6 @@
 msgstr "'C' anahtarı sayısal bir değer bekliyor"
 
 msgid ""
-"apply options are incompatible with rebase.autoSquash.  Consider adding --no-"
-"autosquash"
-msgstr ""
-"seçenekleri uygula, rebase.autoSquash ile uyumlu değil. --no-autosquash "
-"eklemeyi düşünün"
-
-msgid ""
 "apply options are incompatible with rebase.rebaseMerges.  Consider adding --"
 "no-rebase-merges"
 msgstr ""
@@ -10454,6 +10470,9 @@
 msgid "git reflog [show] [<log-options>] [<ref>]"
 msgstr "git reflog [show] [<günlük-seçenekleri>] [<başvuru>]"
 
+msgid "git reflog list"
+msgstr "git reflog list"
+
 msgid ""
 "git reflog expire [--expire=<time>] [--expire-unreachable=<time>]\n"
 "                  [--rewrite] [--updateref] [--stale-fix]\n"
@@ -10479,6 +10498,10 @@
 msgid "invalid timestamp '%s' given to '--%s'"
 msgstr "geçersiz zaman damgası '%s', '--%s' argümanına verildi"
 
+#, c-format
+msgid "%s does not accept arguments: '%s'"
+msgstr "%s argüman kabul etmiyor: '%s'"
+
 msgid "do not actually prune any entries"
 msgstr "özünde, hiçbir girdiyi budama"
 
@@ -10606,8 +10629,8 @@
 "\t yerine --mirror=fetch veya --mirror=push kullanın"
 
 #, c-format
-msgid "unknown mirror argument: %s"
-msgstr "bilinmeyen yansı argümanı: %s"
+msgid "unknown --mirror argument: %s"
+msgstr "bilinmeyen --mirror argümanı: %s"
 
 msgid "fetch the remote branches"
 msgstr "uzak konum dallarını getir"
@@ -10717,10 +10740,10 @@
 "Note: Some branches outside the refs/remotes/ hierarchy were not removed;\n"
 "to delete them, use:"
 msgstr[0] ""
-"Not: refs/remotes hiyerarşisi dışındaki bir dal kaldırılmadı;\n"
+"Not: refs/remotes/ hiyerarşisi dışındaki bir dal kaldırılmadı;\n"
 "onu silmek için şunu kullanın:"
 msgstr[1] ""
-"Not: refs/remotes hiyerarşisi dışındaki bazı dallar kaldırılmadı;\n"
+"Not: refs/remotes/ hiyerarşisi dışındaki bazı dallar kaldırılmadı;\n"
 "onları silmek için şunu kullanın:"
 
 #, c-format
@@ -10976,6 +10999,9 @@
 msgid "could not start pack-objects to repack promisor objects"
 msgstr "vaatçi nesneleri yeniden paketleme için pack-objects başlatılamadı"
 
+msgid "failed to feed promisor objects to pack-objects"
+msgstr "vaatçi nesneleri pack-objects'e beslenemedi"
+
 msgid "repack: Expecting full hex object ID lines only from pack-objects."
 msgstr ""
 "repack: Onaltılı tam nesne no satırları yalnızca pack-objects'ten bekleniyor."
@@ -11298,6 +11324,76 @@
 msgid "only one pattern can be given with -l"
 msgstr "-l ile yalnızca bir dizgi verilebilir"
 
+msgid "need some commits to replay"
+msgstr "yeniden oynatmak için birkaç işleme gerekli"
+
+msgid "--onto and --advance are incompatible"
+msgstr "--onto ve --advance birbiriyle uyumsuz"
+
+msgid "all positive revisions given must be references"
+msgstr "verilen tüm pozitif revizyonlar, başvuru olmalı"
+
+msgid "argument to --advance must be a reference"
+msgstr "--advance'a olan argüman bir başvuru olmalı"
+
+msgid ""
+"cannot advance target with multiple sources because ordering would be ill-"
+"defined"
+msgstr ""
+"birden çok kaynaklı hedef ilerletilemiyor; çünkü sıralama hatalı tanımlanmış "
+"olurdu"
+
+msgid ""
+"cannot implicitly determine whether this is an --advance or --onto operation"
+msgstr ""
+"bunun --advance veya --onto işlemi olup olmadığı örtük olarak algılanamıyor"
+
+msgid ""
+"cannot advance target with multiple source branches because ordering would "
+"be ill-defined"
+msgstr ""
+"birden çok kaynak dallı hedef ilerletilemiyor; çünkü sıralama hatalı "
+"tanımlanmış olurdu"
+
+msgid "cannot implicitly determine correct base for --onto"
+msgstr "--onto için olan doğru temel örtük olarak algılanamıyor"
+
+msgid ""
+"(EXPERIMENTAL!) git replay ([--contained] --onto <newbase> | --advance "
+"<branch>) <revision-range>..."
+msgstr ""
+"(DENEYSEL!) git replay ([--contained] --onto <yeni-temel> | --advance <dal>) "
+"<revizyon-erimi>..."
+
+msgid "make replay advance given branch"
+msgstr "verilen dalı önceden yeniden oynat"
+
+msgid "replay onto given commit"
+msgstr "verilen işlemeye yeniden oynat"
+
+msgid "advance all branches contained in revision-range"
+msgstr "revizyon eriminde içerilen tüm dalları ilerlet"
+
+msgid "option --onto or --advance is mandatory"
+msgstr "--onto veya --advance seçeneğinin kullanımı zorunlu"
+
+#, c-format
+msgid ""
+"some rev walking options will be overridden as '%s' bit in 'struct rev_info' "
+"will be forced"
+msgstr ""
+"'struct rev_info' içindeki '%s' biti zorlanacağından kimi revizyon yürütme "
+"seçenekleri geçersiz kılınacak"
+
+msgid "error preparing revisions"
+msgstr "revizyonlar hazırlanırken hata"
+
+msgid "replaying down to root commit is not supported yet!"
+msgstr "kök işlemeye kadar yeniden oynatma henüz desteklenmiyor!"
+
+msgid "replaying merge commits is not supported yet!"
+msgstr "birleştirme işlemelerini yeniden oynatma henüz desteklenmiyor!"
+
 msgid ""
 "git rerere [clear | forget <pathspec>... | diff | status | remaining | gc]"
 msgstr ""
@@ -11502,19 +11598,17 @@
 msgid "--prefix requires an argument"
 msgstr "--prefix bir argüman gerektiriyor"
 
+msgid "no object format specified"
+msgstr "belirtilen nesne biçimi yok"
+
+#, c-format
+msgid "unsupported object format: %s"
+msgstr "desteklenmeyen nesne biçimi: %s"
+
 #, c-format
 msgid "unknown mode for --abbrev-ref: %s"
 msgstr "--abbrev-ref için bilinmeyen kip: %s"
 
-msgid "--exclude-hidden cannot be used together with --branches"
-msgstr "--exclude-hidden, --branches ile birlikte kullanılamıyor"
-
-msgid "--exclude-hidden cannot be used together with --tags"
-msgstr "--exclude-hidden, --tags ile birlikte kullanılamıyor"
-
-msgid "--exclude-hidden cannot be used together with --remotes"
-msgstr "--exclude-hidden, --remotes ile birlikte kullanılamıyor"
-
 msgid "this operation must be run in a work tree"
 msgstr "bu işlem bir çalışma ağacı içinde çalıştırılmalı"
 
@@ -11592,8 +11686,8 @@
 msgid "allow commits with empty messages"
 msgstr "boş iletili işlemelere izin ver"
 
-msgid "keep redundant, empty commits"
-msgstr "gereksiz, boş işlemeleri tut"
+msgid "deprecated: use --empty=keep instead"
+msgstr "kullanılmıyor: Yerine --empty=keep kullanın"
 
 msgid "use the 'reference' format to refer to commits"
 msgstr "işlemelere başvurmak için 'reference' biçimini kullan"
@@ -11920,9 +12014,6 @@
 msgid "show refs from stdin that aren't in local repository"
 msgstr "stdin'den yerel bir depoda olmayan başvuruları göster"
 
-msgid "only one of '%s', '%s' or '%s' can be given"
-msgstr "yalnızca '%s', '%s' veya '%s' arasından biri verilebilir"
-
 msgid ""
 "git sparse-checkout (init | list | set | add | reapply | disable | check-"
 "rules) [<options>]"
@@ -12920,25 +13011,25 @@
 "\n"
 "Write a message for tag:\n"
 "  %s\n"
-"Lines starting with '%c' will be ignored.\n"
+"Lines starting with '%s' will be ignored.\n"
 msgstr ""
 "\n"
 "Etiket için bir ileti yazın:\n"
 "  %s\n"
-"'%c' ile başlayan satırlar yok sayılacaktır.\n"
+"'%s' ile başlayan satırlar yok sayılacaktır.\n"
 
 #, c-format
 msgid ""
 "\n"
 "Write a message for tag:\n"
 "  %s\n"
-"Lines starting with '%c' will be kept; you may remove them yourself if you "
+"Lines starting with '%s' will be kept; you may remove them yourself if you "
 "want to.\n"
 msgstr ""
 "\n"
 "Etiket için bir ileti yazın:\n"
 "  %s\n"
-"'%c' ile başlayan satırlar tutulacaktır; isterseniz onları "
+"'%s' ile başlayan satırlar tutulacaktır; isterseniz onları "
 "kaldırabilirsiniz.\n"
 
 msgid "unable to sign the tag"
@@ -13023,6 +13114,9 @@
 msgid "print only tags of the object"
 msgstr "yalnızca nesnenin etiketlerini yazdır"
 
+msgid "could not start 'git column'"
+msgstr "'git column' başlatılamadı"
+
 #, c-format
 msgid "the '%s' option is only allowed in list mode"
 msgstr "'%s' seçeneğine yalnızca liste kipinde izin verilir"
@@ -13264,12 +13358,12 @@
 msgid "fsmonitor disabled"
 msgstr "dosya sistemi monitörü devre dışı"
 
-msgid "git update-ref [<options>] -d <refname> [<old-val>]"
-msgstr "git update-ref [<seçenekler>] -d <bşvr-adı> [<eski-değer>]"
+msgid "git update-ref [<options>] -d <refname> [<old-oid>]"
+msgstr "git update-ref [<seçenekler>] -d <bşvr-adı> [<eski-nesne-kimliği>]"
 
-msgid "git update-ref [<options>]    <refname> <new-val> [<old-val>]"
+msgid "git update-ref [<options>]    <refname> <new-oid> [<old-oid>]"
 msgstr ""
-"git update-ref [<seçenekler>]    <bşvr-adı> <yeni-değer> [<eski-değer>]"
+"git update-ref [<seçenekler>]    <bşvr-adı> <yeni-n-kiml> [<eski-n-kiml>]"
 
 msgid "git update-ref [<options>] --stdin [-z]"
 msgstr "git update-ref [<seçenekler>] --stdin [-z]"
@@ -13366,29 +13460,29 @@
 
 #, c-format
 msgid ""
-"If you meant to create a worktree containing a new orphan branch\n"
+"If you meant to create a worktree containing a new unborn branch\n"
 "(branch with no commits) for this repository, you can do so\n"
 "using the --orphan flag:\n"
 "\n"
 "    git worktree add --orphan -b %s %s\n"
 msgstr ""
-"Bu depo için yeni bir yetim dal içeren (işlemesiz dal) bir\n"
-"çalışma ağacı oluşturmak istediyseniz bunu --orphan bayrağı\n"
-"ile yapabilirsiniz:\n"
+"Bu depo için henüz doğmamış bir dal (işleme içermeyen dal) içeren\n"
+"bir çalışma ağacı oluşturmak istediyseniz bunu --orphan bayrağını\n"
+"kullanarak yapabilirsiniz:\n"
 "\n"
 "    git worktree add --orphan -b %s %s\n"
 
 #, c-format
 msgid ""
-"If you meant to create a worktree containing a new orphan branch\n"
+"If you meant to create a worktree containing a new unborn branch\n"
 "(branch with no commits) for this repository, you can do so\n"
 "using the --orphan flag:\n"
 "\n"
 "    git worktree add --orphan %s\n"
 msgstr ""
-"Bu depo için yeni bir yetim dal içeren (işlemesiz dal) bir\n"
-"çalışma ağacı oluşturmak istediyseniz bunu --orphan bayrağı\n"
-"ile yapabilirsiniz:\n"
+"Bu depo için henüz doğmamış bir dal (işleme içermeyen dal) içeren\n"
+"bir çalışma ağacı oluşturmak istediyseniz bunu --orphan bayrağını\n"
+"kullanarak yapabilirsiniz:\n"
 "\n"
 "    git worktree add --orphan %s\n"
 
@@ -13447,6 +13541,10 @@
 msgstr "ilklendiriliyor"
 
 #, c-format
+msgid "could not find created worktree '%s'"
+msgstr "oluşturulan '%s' çalışma ağacı bulunamadı"
+
+#, c-format
 msgid "Preparing worktree (new branch '%s')"
 msgstr "Çalışma ağacı hazırlanıyor (yeni dal '%s')"
 
@@ -13483,10 +13581,6 @@
 "Bir uzak konum olmasına rağmen hiçbir yerel/uzak başvuru yok, durduruluyor;\n"
 "geçersiz kılmak veya önce bir uzak konum getirmek için 'add -f' kullanın"
 
-#, c-format
-msgid "'%s' and '%s' cannot be used together"
-msgstr "'%s' ve '%s' birlikte kullanılamaz"
-
 msgid "checkout <branch> even if already checked out in other worktree"
 msgstr "diğer çalışma ağacında çıkış yapılmış olsa bile <dal> çıkışını yap"
 
@@ -13496,8 +13590,8 @@
 msgid "create or reset a branch"
 msgstr "yeni bir dal oluştur veya sıfırla"
 
-msgid "create unborn/orphaned branch"
-msgstr "doğmamış/yetim bırakılmış dal oluştur"
+msgid "create unborn branch"
+msgstr "henüz doğmamış dal oluştur"
 
 msgid "populate the new working tree"
 msgstr "yeni çalışma ağacını doldur"
@@ -13519,11 +13613,8 @@
 msgstr "'%s', '%s' ve '%s' seçenekleri birlikte kullanılamaz"
 
 #, c-format
-msgid "options '%s', and '%s' cannot be used together"
-msgstr "'%s' ve '%s' seçenekleri birlikte kullanılamaz"
-
-msgid "<commit-ish>"
-msgstr "<işlememsi>"
+msgid "option '%s' and commit-ish cannot be used together"
+msgstr "'%s' seçeneği ve işlememsiler birlikte kullanılamaz"
 
 msgid "added with --lock"
 msgstr "--lock ile eklendi"
@@ -14135,6 +14226,10 @@
 msgid "Create, list, delete refs to replace objects"
 msgstr "Nesne değiştirmek için başvurular oluştur, sil, listele"
 
+msgid "EXPERIMENTAL: Replay commits on a new base, works with bare repos too"
+msgstr ""
+"DENEYSEL: İşlemeleri yeni temelde yeniden oynat, çıplak depolarla da çalışır"
+
 msgid "Generates a summary of pending changes"
 msgstr "Bekleyen değişikliklerin bir özetini çıkart"
 
@@ -14373,6 +14468,32 @@
 msgid "commit-graph file is too small"
 msgstr "commit-graph dosyası pek küçük"
 
+msgid "commit-graph oid fanout chunk is wrong size"
+msgstr "commit-graph OID çıkış sayısı iri parçası boyutu yanlış"
+
+msgid "commit-graph fanout values out of order"
+msgstr "commit-graph çıkış sayısı değerleri sırasız: fanout[%d] = %u != %u"
+
+msgid "commit-graph OID lookup chunk is the wrong size"
+msgstr "commit-graph OID arama iri parçası boyutu yanlış"
+
+msgid "commit-graph commit data chunk is wrong size"
+msgstr "commit-graph işleme verisi iri parçası boyutu yanlış"
+
+msgid "commit-graph generations chunk is wrong size"
+msgstr "commit-graph kuşaklar iri parçası boyutu yanlış"
+
+msgid "commit-graph changed-path index chunk is too small"
+msgstr "commit-graph changed-path indeksi iri parçası boyutu pek küçük"
+
+#, c-format
+msgid ""
+"ignoring too-small changed-path chunk (%<PRIuMAX> < %<PRIuMAX>) in commit-"
+"graph file"
+msgstr ""
+"commit-graph dosyasındaki pek küçük changed-path iri parçası (%<PRIuMAX> < "
+"%<PRIuMAX>) yok sayılıyor"
+
 #, c-format
 msgid "commit-graph signature %X does not match signature %X"
 msgstr "commit-graph imzası %X, %X ile eşleşmiyor"
@@ -14389,6 +14510,17 @@
 msgid "commit-graph file is too small to hold %u chunks"
 msgstr "commit-graph dosyası %u iri parça tutmak için pek küçük"
 
+msgid "commit-graph required OID fanout chunk missing or corrupted"
+msgstr ""
+"commit-graph'ten gerekli OID çıkış sayısı iri parçası eksik veya hasarlı"
+
+msgid "commit-graph required OID lookup chunk missing or corrupted"
+msgstr "commit-graph'ten gerekli OID arama iri parçası eksik veya hasarlı"
+
+msgid "commit-graph required commit data chunk missing or corrupted"
+msgstr ""
+"commit-graph'ten gerekli OID çıkış sayısı iri parçası eksik veya hasarlı"
+
 msgid "commit-graph has no base graphs chunk"
 msgstr "commit-graph temel grafiği iri parçasına iye değil"
 
@@ -14402,6 +14534,9 @@
 msgid "commit count in base graph too high: %<PRIuMAX>"
 msgstr "temel grafikteki işleme sayısı pek yüksek: %<PRIuMAX>"
 
+msgid "commit-graph chain file too small"
+msgstr "commit-graph zincir dosyası pek küçük"
+
 #, c-format
 msgid "invalid commit-graph chain: line '%s' not a hash"
 msgstr "geçersiz commit-graph zinciri: '%s'. satır bir sağlama değil"
@@ -14422,6 +14557,9 @@
 msgid "commit-graph overflow generation data is too small"
 msgstr "commit-graph, taşım üretim verisi pek küçük"
 
+msgid "commit-graph extra-edges pointer out of bounds"
+msgstr "commit-graph extra-edges işaretçisi sınırlar dışında"
+
 msgid "Loading known commits in commit graph"
 msgstr "İşleme grafiğindeki bilinen işlemeler yükleniyor"
 
@@ -14569,6 +14707,10 @@
 msgstr "İşleme grafiğindeki işlemeler doğrulanıyor"
 
 #, c-format
+msgid "could not parse commit %s"
+msgstr "%s işlemesi ayrıştırılamadı"
+
+#, c-format
 msgid "%s %s is not a commit!"
 msgstr "%s %s bir işleme değil!"
 
@@ -14999,8 +15141,13 @@
 msgid "bad zlib compression level %d"
 msgstr "hatalı zlib sıkıştırma düzeyi %d"
 
-msgid "core.commentChar should only be one ASCII character"
-msgstr "core.commentChar yalnızca bir ASCII karakter olmalı"
+#, c-format
+msgid "%s cannot contain newline"
+msgstr "%s yenisatır içeremez"
+
+#, c-format
+msgid "%s must have at least one character"
+msgstr "%s, en az bir karaktere iye olmalı"
 
 #, c-format
 msgid "ignoring unknown core.fsyncMethod value '%s'"
@@ -15071,6 +15218,10 @@
 msgstr "yeni yapılandırma dosyası %s yazılamadı"
 
 #, c-format
+msgid "no multi-line comment allowed: '%s'"
+msgstr "çok satırlı işlemeye izin verilmiyor: '%s'"
+
+#, c-format
 msgid "could not lock config file %s"
 msgstr "%s yapılandırma dosyası kilitlenemedi"
 
@@ -15563,6 +15714,10 @@
 msgstr "'diff.submodule' yapılandırma değişkeni için bilinmeyen değer: '%s'"
 
 #, c-format
+msgid "unknown value for config '%s': %s"
+msgstr "'%s' yapılandırması için bilinmeyen değer: %s"
+
+#, c-format
 msgid ""
 "Found errors in 'diff.dirstat' config variable:\n"
 "%s"
@@ -15642,13 +15797,6 @@
 msgid "invalid mode '%s' in --color-moved-ws"
 msgstr "--color-moved-ws içinde geçersiz kip '%s'"
 
-msgid ""
-"option diff-algorithm accepts \"myers\", \"minimal\", \"patience\" and "
-"\"histogram\""
-msgstr ""
-"diff-algorithm seçeneği şunları kabul eder: \"myers\", \"minimal\", "
-"\"patience\" ve \"histogram\""
-
 #, c-format
 msgid "invalid argument to %s"
 msgstr "%s için geçersiz argüman"
@@ -15692,8 +15840,8 @@
 msgid "output only the last line of --stat"
 msgstr "--stat'ın yalnızca son satırını çıktı ver"
 
-msgid "<param1,param2>..."
-msgstr "<param1,param2>..."
+msgid "<param1>,<param2>..."
+msgstr "<param1>,<param2>..."
 
 msgid ""
 "output the distribution of relative amount of changes for each sub-directory"
@@ -15703,8 +15851,8 @@
 msgid "synonym for --dirstat=cumulative"
 msgstr "--dirstat=cumulative eşanlamlısı"
 
-msgid "synonym for --dirstat=files,param1,param2..."
-msgstr "--dirstat=files,param1,param2... eşanlamlısı"
+msgid "synonym for --dirstat=files,<param1>,<param2>..."
+msgstr "--dirstat=files,<param1>,<param2>... eşanlamlısı"
 
 msgid "warn if changes introduce conflict markers or whitespace errors"
 msgstr ""
@@ -15879,12 +16027,6 @@
 msgid "generate diff using the \"histogram diff\" algorithm"
 msgstr "diff'i \"histogram diff\" algoritmasını kullanarak oluştur"
 
-msgid "<algorithm>"
-msgstr "<algoritma>"
-
-msgid "choose a diff algorithm"
-msgstr "bir diff algoritması seç"
-
 msgid "<text>"
 msgstr "<metin>"
 
@@ -16871,6 +17013,14 @@
 msgstr "'%s.lock' oluşturulamıyor: %s"
 
 #, c-format
+msgid "could not write loose object index %s"
+msgstr "gevşek nesne indeksi %s yazılamadı"
+
+#, c-format
+msgid "failed to write loose object index %s\n"
+msgstr "gevşek nesne indeksi %s yazımı başarısız\n"
+
+#, c-format
 msgid "unexpected line: '%s'"
 msgstr "beklenmedik satır: '%s'"
 
@@ -16881,6 +17031,10 @@
 msgstr "alıntılanmış CRLF algılandı"
 
 #, c-format
+msgid "unable to format message: %s"
+msgstr "ileti biçimlendirilemiyor: %s"
+
+#, c-format
 msgid "Failed to merge submodule %s (not checked out)"
 msgstr "%s altmodülü birleştirilemedi (çıkış yapılmadı)"
 
@@ -16893,6 +17047,10 @@
 msgstr "%s altmodülü birleştirilemedi (işlemeler yok)"
 
 #, c-format
+msgid "Failed to merge submodule %s (repository corrupt)"
+msgstr "%s altmodülü birleştirilemedi (depo hasarlı)"
+
+#, c-format
 msgid "Failed to merge submodule %s (commits don't follow merge-base)"
 msgstr "%s altmodülü birleştirilemedi (işlemeler merge-base'i takip etmiyor)"
 
@@ -17366,61 +17524,6 @@
 msgid "failed to read the cache"
 msgstr "önbellek okunamadı"
 
-msgid "multi-pack-index OID fanout is of the wrong size"
-msgstr "multi-pack-index OID ikiye bölümünün boyutu hatalı"
-
-msgid "multi-pack-index OID lookup chunk is the wrong size"
-msgstr "multi-pack-index OID arama iri parçası yanlış boyutlu"
-
-msgid "multi-pack-index object offset chunk is the wrong size"
-msgstr "multi-pack-index OID nesne ofseti iri parçası yanlış boyutlu"
-
-#, c-format
-msgid "multi-pack-index file %s is too small"
-msgstr "multi-pack-index dosyası %s pek küçük"
-
-#, c-format
-msgid "multi-pack-index signature 0x%08x does not match signature 0x%08x"
-msgstr "multi-pack-index imzası 0x%08x, 0x%08x imzası ile eşleşmiyor"
-
-#, c-format
-msgid "multi-pack-index version %d not recognized"
-msgstr "multi-pack-index sürümü %d tanımlanamıyor"
-
-#, c-format
-msgid "multi-pack-index hash version %u does not match version %u"
-msgstr "multi-pack-index sağlama sürümü %u, %u sürümü ile eşleşmiyor"
-
-msgid "multi-pack-index required pack-name chunk missing or corrupted"
-msgstr "multi-pack-index'ten gerekli pack-name iri parçası eksik veya hasarlı"
-
-msgid "multi-pack-index required OID fanout chunk missing or corrupted"
-msgstr "multi-pack-index'ten gerekli OID fanout iri parçası eksik veya hasarlı"
-
-msgid "multi-pack-index required OID lookup chunk missing or corrupted"
-msgstr "multi-pack-index'ten gerekli OID arama iri parçası eksik veya hasarlı"
-
-msgid "multi-pack-index required object offsets chunk missing or corrupted"
-msgstr ""
-"multi-pack-index'ten gerekli nesne ofsetleri iri parçası eksik veya hasarlı"
-
-msgid "multi-pack-index pack-name chunk is too short"
-msgstr "multi-pack-index pack-name iri parçası pek kısa"
-
-#, c-format
-msgid "multi-pack-index pack names out of order: '%s' before '%s'"
-msgstr "multi-pack-index paket adlarının sırasız: '%s' şundan önce: '%s'"
-
-#, c-format
-msgid "bad pack-int-id: %u (%u total packs)"
-msgstr "hatalı pack-int-id: %u (%u toplam paket)"
-
-msgid "multi-pack-index stores a 64-bit offset, but off_t is too small"
-msgstr "multi-pack-index bir 64 bit ofset depoluyor; ancak off_t pek küçük"
-
-msgid "multi-pack-index large offset out of bounds"
-msgstr "multi-pack-index geniş ofseti sınırlar dışında"
-
 #, c-format
 msgid "failed to add packfile '%s'"
 msgstr "paket dosyası '%s' eklenemedi"
@@ -17485,6 +17588,86 @@
 msgid "could not write multi-pack-index"
 msgstr "multi-pack-index yazılamadı"
 
+msgid "Counting referenced objects"
+msgstr "Başvurulmuş nesneler sayılıyor"
+
+msgid "Finding and deleting unreferenced packfiles"
+msgstr "Başvurulmamış paket dosyaları bulunuyor ve siliniyor"
+
+msgid "could not start pack-objects"
+msgstr "pack-objects başlatılamadı"
+
+msgid "could not finish pack-objects"
+msgstr "pack-objects bitirilemedi"
+
+msgid "multi-pack-index OID fanout is of the wrong size"
+msgstr "multi-pack-index OID çıkış sayısı boyutu yanlış"
+
+#, c-format
+msgid ""
+"oid fanout out of order: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]"
+msgstr ""
+"oid çıkış sayısı sırasız: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]"
+
+msgid "multi-pack-index OID lookup chunk is the wrong size"
+msgstr "multi-pack-index OID arama iri parçası yanlış boyutlu"
+
+msgid "multi-pack-index object offset chunk is the wrong size"
+msgstr "multi-pack-index OID nesne ofseti iri parçası yanlış boyutlu"
+
+#, c-format
+msgid "multi-pack-index file %s is too small"
+msgstr "multi-pack-index dosyası %s pek küçük"
+
+#, c-format
+msgid "multi-pack-index signature 0x%08x does not match signature 0x%08x"
+msgstr "multi-pack-index imzası 0x%08x, 0x%08x imzası ile eşleşmiyor"
+
+#, c-format
+msgid "multi-pack-index version %d not recognized"
+msgstr "multi-pack-index sürümü %d tanımlanamıyor"
+
+#, c-format
+msgid "multi-pack-index hash version %u does not match version %u"
+msgstr "multi-pack-index sağlama sürümü %u, %u sürümü ile eşleşmiyor"
+
+msgid "multi-pack-index required pack-name chunk missing or corrupted"
+msgstr "multi-pack-index'ten gerekli pack-name iri parçası eksik veya hasarlı"
+
+msgid "multi-pack-index required OID fanout chunk missing or corrupted"
+msgstr "multi-pack-index'ten gerekli OID fanout iri parçası eksik veya hasarlı"
+
+msgid "multi-pack-index required OID lookup chunk missing or corrupted"
+msgstr "multi-pack-index'ten gerekli OID arama iri parçası eksik veya hasarlı"
+
+msgid "multi-pack-index required object offsets chunk missing or corrupted"
+msgstr ""
+"multi-pack-index'ten gerekli nesne ofsetleri iri parçası eksik veya hasarlı"
+
+msgid "multi-pack-index pack-name chunk is too short"
+msgstr "multi-pack-index pack-name iri parçası pek kısa"
+
+#, c-format
+msgid "multi-pack-index pack names out of order: '%s' before '%s'"
+msgstr "multi-pack-index paket adlarının sırasız: '%s' şundan önce: '%s'"
+
+#, c-format
+msgid "bad pack-int-id: %u (%u total packs)"
+msgstr "hatalı pack-int-id: %u (%u toplam paket)"
+
+msgid "MIDX does not contain the BTMP chunk"
+msgstr "MIDX, BTMP iri parçasını içermiyor"
+
+#, c-format
+msgid "could not load bitmapped pack %<PRIu32>"
+msgstr "biteşlemli %<PRIu32> paketi yüklenemedi"
+
+msgid "multi-pack-index stores a 64-bit offset, but off_t is too small"
+msgstr "multi-pack-index bir 64 bit ofset depoluyor; ancak off_t pek küçük"
+
+msgid "multi-pack-index large offset out of bounds"
+msgstr "multi-pack-index geniş ofseti sınırlar dışında"
+
 #, c-format
 msgid "failed to clear multi-pack-index at %s"
 msgstr "multi-pack-index %s konumunda temizlenemedi"
@@ -17498,11 +17681,6 @@
 msgid "Looking for referenced packfiles"
 msgstr "Başvurulmuş paket dosyaları aranıyor"
 
-#, c-format
-msgid ""
-"oid fanout out of order: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]"
-msgstr "oid fanout sırasız: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]"
-
 msgid "the midx contains no oid"
 msgstr "midx bir oid içermiyor"
 
@@ -17531,18 +17709,6 @@
 msgid "incorrect object offset for oid[%d] = %s: %<PRIx64> != %<PRIx64>"
 msgstr "şunun için yanlış nesne ofseti: oid[%d] = %s: %<PRIx64> != %<PRIx64>"
 
-msgid "Counting referenced objects"
-msgstr "Başvurulmuş nesneler sayılıyor"
-
-msgid "Finding and deleting unreferenced packfiles"
-msgstr "Başvurulmamış paket dosyaları bulunuyor ve siliniyor"
-
-msgid "could not start pack-objects"
-msgstr "pack-objects başlatılamadı"
-
-msgid "could not finish pack-objects"
-msgstr "pack-objects bitirilemedi"
-
 #, c-format
 msgid "unable to create lazy_dir thread: %s"
 msgstr "lazy_dir iş parçacığı oluşturulamıyor: %s"
@@ -17589,6 +17755,25 @@
 msgid "Bad %s value: '%s'"
 msgstr "Hatalı %s değeri: '%s'"
 
+msgid "failed to decode tree entry"
+msgstr "ağaç girdisinin kodu çözülemedi"
+
+#, c-format
+msgid "failed to map tree entry for %s"
+msgstr "%s için olan ağaç girdisi eşlemlenemedi"
+
+#, c-format
+msgid "bad %s in commit"
+msgstr "işlemede hatalı %s"
+
+#, c-format
+msgid "unable to map %s %s in commit object"
+msgstr "işleme nesnesinde %s %s eşlemlenemiyor"
+
+#, c-format
+msgid "Failed to convert object from %s to %s"
+msgstr "Nesne, %s -> %s olarak dönüştürülemedi"
+
 #, c-format
 msgid "object directory %s does not exist; check .git/objects/info/alternates"
 msgstr "nesne dizini %s yok; şurayı denetleyin: .git/objects/info/alternates"
@@ -17691,6 +17876,10 @@
 msgstr "paketlenmiş nesne %s (%s içinde depolanıyor) hasarlı"
 
 #, c-format
+msgid "missing mapping of %s to %s"
+msgstr "%s ögesinin %s ögesine eksik eşlemlemesi"
+
+#, c-format
 msgid "unable to write file %s"
 msgstr "%s dosyası yazılamıyor"
 
@@ -17744,6 +17933,10 @@
 msgstr "%s için nesne okunamıyor"
 
 #, c-format
+msgid "cannot map object %s to %s"
+msgstr "%s nesnesi %s ögesine eşlemlenemiyor"
+
+#, c-format
 msgid "object fails fsck: %s"
 msgstr "nesne fsck'yi başarısız ediyor: %s"
 
@@ -18022,9 +18215,12 @@
 msgid "could not open pack %s"
 msgstr "%s paketi açılamadı"
 
+msgid "could not determine MIDX preferred pack"
+msgstr "MIDX yeğlenen paketi algılanamadı"
+
 #, c-format
 msgid "preferred pack (%s) is invalid"
-msgstr "tercih edilen (%s) paket geçersiz"
+msgstr "yeğlenen paket (%s) geçersiz"
 
 msgid "corrupt bitmap lookup table: triplet position out of index"
 msgstr "hasarlı biteşlem arama tablosu: üçlü konum indeks dışında"
@@ -18042,6 +18238,13 @@
 "hasarlı ewah biteşlemi: \"%s\" işlemesinin biteşleminde kısaltılmış üstbilgi"
 
 #, c-format
+msgid "unable to load pack: '%s', disabling pack-reuse"
+msgstr "paket yüklenemiyor: '%s', pack-reuse devre dışı bırakılıyor"
+
+msgid "unable to compute preferred pack, disabling pack-reuse"
+msgstr "yeğlenen paket hesaplanamıyor, pack-reuse devre dışı bırakılıyor"
+
+#, c-format
 msgid "object '%s' not found in type bitmaps"
 msgstr "'%s' nesnesi, tür biteşlemlerinde bulunamadı"
 
@@ -18132,6 +18335,9 @@
 msgid "multi-pack-index reverse-index chunk is the wrong size"
 msgstr "multi-pack-index reverse-index iri parçası yanlış boyutlu"
 
+msgid "could not determine preferred pack"
+msgstr "yeğlenen paket algılanamadı"
+
 msgid "cannot both write and verify reverse index"
 msgstr "ters indeks dosyası hem yazılıp hem doğrulanamıyor"
 
@@ -18195,10 +18401,6 @@
 msgstr "%s negatif olmayan bir tamsayı bekliyor, isteğe bağlı k/m/g eki ile"
 
 #, c-format
-msgid "%s is incompatible with %s"
-msgstr "%s, %s ile uyumsuz"
-
-#, c-format
 msgid "ambiguous option: %s (could be --%s%s or --%s%s)"
 msgstr "belirsiz seçenek: %s (--%s%s veya --%s%s olabilir)"
 
@@ -18512,10 +18714,6 @@
 msgstr "'%s' indekse eklenemiyor"
 
 #, c-format
-msgid "unable to stat '%s'"
-msgstr "'%s' dosyasının bilgileri alınamıyor"
-
-#, c-format
 msgid "'%s' appears as both a file and as a directory"
 msgstr "'%s' hem bir dosya hem de bir dizin olarak görünüyor"
 
@@ -19087,10 +19285,6 @@
 msgstr "'%s' ve '%s' aynı anda işlenemiyor"
 
 #, c-format
-msgid "could not remove reference %s"
-msgstr "%s başvurusu kaldırılamadı"
-
-#, c-format
 msgid "could not delete reference %s: %s"
 msgstr "%s başvurusu silinemedi: %s"
 
@@ -19099,6 +19293,73 @@
 msgstr "başvurular silinemedi: %s"
 
 #, c-format
+msgid "refname is dangerous: %s"
+msgstr "başvuru adı tehlikeli: %s"
+
+#, c-format
+msgid "trying to write ref '%s' with nonexistent object %s"
+msgstr "'%s' başvurusu, var olmayan %s nesnesiyle yazılmaya çalışılıyor"
+
+#, c-format
+msgid "trying to write non-commit object %s to branch '%s'"
+msgstr "işleme olmayan %s nesnesi '%s' dalına yazılmaya çalışılıyor"
+
+#, c-format
+msgid ""
+"multiple updates for 'HEAD' (including one via its referent '%s') are not "
+"allowed"
+msgstr ""
+"'HEAD' için birden çok güncellemeye (ona başvuran '%s' ile olan bir tanesini "
+"de içeren) izin verilmiyor"
+
+#, c-format
+msgid "cannot lock ref '%s': unable to resolve reference '%s'"
+msgstr "'%s' başvurusu kilitlenemiyor: '%s' başvurusu çözülemiyor"
+
+#, c-format
+msgid "cannot lock ref '%s': error reading reference"
+msgstr "'%s' başvurusu kilitlenemiyor: Başvuruyu okurken hata"
+
+#, c-format
+msgid ""
+"multiple updates for '%s' (including one via symref '%s') are not allowed"
+msgstr ""
+"'%s' için birden çok güncellemeye ('%s' sembolik bağlantısı ile olan bir "
+"tanesini de içeren) izin verilmiyor"
+
+#, c-format
+msgid "cannot lock ref '%s': reference already exists"
+msgstr "'%s' başvurusu kilitlenemiyor: Başvuru halihazırda var"
+
+#, c-format
+msgid "cannot lock ref '%s': reference is missing but expected %s"
+msgstr "'%s' başvurusu kilitlenemiyor: Başvuru eksik; ancak %s bekleniyordu"
+
+#, c-format
+msgid "cannot lock ref '%s': is at %s but expected %s"
+msgstr "'%s' başvurusu kilitlenemiyor: %s üzerinde; ancak %s bekleniyordu"
+
+#, c-format
+msgid "reftable: transaction prepare: %s"
+msgstr "reftable: İşlem hazırlığı: %s"
+
+#, c-format
+msgid "reftable: transaction failure: %s"
+msgstr "reftable: İşlem başarısız: %s"
+
+#, c-format
+msgid "unable to compact stack: %s"
+msgstr "yığın kompaktlaştırılamıyor: %s"
+
+#, c-format
+msgid "refname %s not found"
+msgstr "başvuru adı %s bulunamadı"
+
+#, c-format
+msgid "refname %s is a symbolic ref, copying it is not supported"
+msgstr "başvuru adı %s bir sembolik bağlantı, onu kopyalamak desteklenmiyor"
+
+#, c-format
 msgid "invalid refspec '%s'"
 msgstr "geçersiz başvuru belirteci '%s'"
 
@@ -19107,6 +19368,10 @@
 msgstr "push-option değerinde geçersiz tırnak içine alım: '%s'"
 
 #, c-format
+msgid "unknown value for object-format: %s"
+msgstr "object-format için bilinmeyen değer: %s"
+
+#, c-format
 msgid "%sinfo/refs not valid: is this a git repository?"
 msgstr "%sinfo/refs geçerli değil: bu bir git deposu mu?"
 
@@ -19549,8 +19814,19 @@
 msgstr "resolve-undo, kayıp olan '%s' ögesini kaydetmiş"
 
 #, c-format
-msgid "could not get commit for ancestry-path argument %s"
-msgstr "soy yolu argümanı %s için işleme alınamadı"
+msgid "%s exists but is a symbolic ref"
+msgstr "%s var; ancak bir sembolik bağ"
+
+msgid ""
+"--merge requires one of the pseudorefs MERGE_HEAD, CHERRY_PICK_HEAD, "
+"REVERT_HEAD or REBASE_HEAD"
+msgstr ""
+"--merge; MERGE_HEAD, CHERRY_PICK_HEAD, REVERT_HEAD veya REBASE_HEAD yalancı "
+"başvurularından birini gerektiriyor"
+
+#, c-format
+msgid "could not get commit for --ancestry-path argument %s"
+msgstr "--ancestry-path argümanı %s için olan işleme alınamadı"
 
 msgid "--unpacked=<packfile> no longer supported"
 msgstr "--unpacked=<paketdosyası> artık desteklenmiyor"
@@ -19835,6 +20111,19 @@
 msgstr "bilinmeyen eylem: %d"
 
 msgid ""
+"Resolve all conflicts manually, mark them as resolved with\n"
+"\"git add/rm <conflicted_files>\", then run \"git rebase --continue\".\n"
+"You can instead skip this commit: run \"git rebase --skip\".\n"
+"To abort and get back to the state before \"git rebase\", run \"git rebase --"
+"abort\"."
+msgstr ""
+"Tüm çakışmaları el ile çözün, onları \"git add/rm <çakışan-dosyalar>\"\n"
+"ile tamam olarak imleyin, ardından \"git rebase --continue\"\n"
+"çalıştırın. Bunun yerine bu işlemeyi atlayabilirsiniz: \"git rebase\n"
+"--skip\" yapın. İptal edip \"git rebase\" öncesine geri dönmek için\n"
+"\"git rebase --abort\" çalıştırın."
+
+msgid ""
 "after resolving the conflicts, mark the corrected paths\n"
 "with 'git add <paths>' or 'git rm <paths>'"
 msgstr ""
@@ -20054,10 +20343,6 @@
 msgstr "%s güncellenemedi"
 
 #, c-format
-msgid "could not parse commit %s"
-msgstr "%s işlemesi ayrıştırılamadı"
-
-#, c-format
 msgid "could not parse parent commit %s"
 msgstr "üst işleme %s ayrıştırılamadı"
 
@@ -20162,10 +20447,6 @@
 msgstr "geçersiz komut %.*s"
 
 #, c-format
-msgid "%s does not accept arguments: '%s'"
-msgstr "%s argüman kabul etmiyor: '%s'"
-
-#, c-format
 msgid "missing arguments for %s"
 msgstr "%s için eksik argüman"
 
@@ -20446,6 +20727,9 @@
 msgid "Autostash exists; creating a new stash entry."
 msgstr "Kendiliğinden zulalama mevcut; yeni bir zula girdisi oluşturuluyor."
 
+msgid "autostash reference is a symref"
+msgstr "kendiliğinden zulalama başvurusu bir sembol başvurusu"
+
 msgid "could not detach HEAD"
 msgstr "HEAD ayrılamadı"
 
@@ -20614,6 +20898,10 @@
 msgstr "geçersiz yapılandırma kullanılarak çalışma ağacı kurulamıyor"
 
 #, c-format
+msgid "'%s' already specified as '%s'"
+msgstr "'%s', halihazırda '%s' olarak belirtilmiş"
+
+#, c-format
 msgid "Expected git repo version <= %d, found %d"
 msgstr "Beklenen git repo sürümü <= %d, %d bulundu"
 
@@ -20757,6 +21045,10 @@
 msgstr "geçersiz başlangıç dalı adı: '%s'"
 
 #, c-format
+msgid "re-init: ignored --initial-branch=%s"
+msgstr "re-init: --initial-branch=%s yok sayıldı"
+
+#, c-format
 msgid "unable to handle file type %d"
 msgstr "%d dosya türü ele alınamıyor"
 
@@ -20767,15 +21059,16 @@
 msgid "attempt to reinitialize repository with different hash"
 msgstr "depoyu başka bir sağlama ile yeniden ilklendirme deneniyor"
 
+msgid ""
+"attempt to reinitialize repository with different reference storage format"
+msgstr ""
+"depo başka bir başvuru depolama biçimiyle yeniden ilklendirilmeye çalışılıyor"
+
 #, c-format
 msgid "%s already exists"
 msgstr "%s halihazırda var"
 
 #, c-format
-msgid "re-init: ignored --initial-branch=%s"
-msgstr "re-init: --initial-branch=%s yok sayıldı"
-
-#, c-format
 msgid "Reinitialized existing shared Git repository in %s%s\n"
 msgstr "%s%s içindeki var olan paylaşılan Git deposu yeniden ilklendirildi\n"
 
@@ -20798,6 +21091,21 @@
 msgid "cannot use split index with a sparse index"
 msgstr "bir aralıklı indeksle bölünmüş indeks kullanılamıyor"
 
+#. TRANSLATORS: The first %s is a command like "ls-tree".
+#, c-format
+msgid "bad %s format: element '%s' does not start with '('"
+msgstr "hatalı %s biçimi: '%s' ögesi '(' ile başlamıyor"
+
+#. TRANSLATORS: The first %s is a command like "ls-tree".
+#, c-format
+msgid "bad %s format: element '%s' does not end in ')'"
+msgstr "hatalı %s biçimi: '%s' ögesi ')' ile sonlanmıyor"
+
+#. TRANSLATORS: %s is a command like "ls-tree".
+#, c-format
+msgid "bad %s format: %%%.*s"
+msgstr "hatalı %s biçimi: %%%.*s"
+
 #. TRANSLATORS: IEC 80000-13:2008 gibibyte
 #, c-format
 msgid "%u.%2.2u GiB"
@@ -21039,12 +21347,6 @@
 msgid "number of entries in the cache tree to invalidate (default 0)"
 msgstr "önbellek ağacındaki geçersizleştirilecek girdi sayısı (öntanımlı 0)"
 
-msgid "unhandled options"
-msgstr "beklenmeyen seçenekler"
-
-msgid "error preparing revisions"
-msgstr "revizyonlar hazırlanırken hata"
-
 #, c-format
 msgid "commit %s is not marked reachable"
 msgstr "%s işlemesi ulaşılabilir olarak imlenmedi"
@@ -21126,29 +21428,6 @@
 msgid "empty trailer token in trailer '%.*s'"
 msgstr "'%.*s' artbilgisi içinde boş artbilgi jetonu"
 
-#, c-format
-msgid "could not read input file '%s'"
-msgstr "'%s' girdi dosyası okunamadı"
-
-#, c-format
-msgid "could not stat %s"
-msgstr "%s dosya bilgileri alınamadı"
-
-#, c-format
-msgid "file %s is not a regular file"
-msgstr "%s dosyası sıradan bir dosya değil"
-
-#, c-format
-msgid "file %s is not writable by user"
-msgstr "%s dosyası kullanıcı tarafından yazılabilir değil"
-
-msgid "could not open temporary file"
-msgstr "geçici dosya açılamadı"
-
-#, c-format
-msgid "could not rename temporary file to %s"
-msgstr "geçici dosya adı %s olarak değiştirilemedi"
-
 msgid "full write to remote helper failed"
 msgstr "uzak konum yardımcısına tam yazım başarısız"
 
@@ -21198,9 +21477,6 @@
 msgid "invalid remote service path"
 msgstr "geçersiz uzak konum servis yolu"
 
-msgid "operation not supported by protocol"
-msgstr "işlem protokol tarafından desteklenmiyor"
-
 #, c-format
 msgid "can't connect to subservice %s"
 msgstr "%s altservisine bağlanılamıyor"
@@ -21247,8 +21523,8 @@
 msgstr "remote-helper itme desteklemiyor; başvuru belirteci gerekli"
 
 #, c-format
-msgid "helper %s does not support 'force'"
-msgstr "%s yardımcısı 'force' desteklemiyor"
+msgid "helper %s does not support '--force'"
+msgstr "%s yardımcısı '--force' desteklemiyor"
 
 msgid "couldn't run fast-export"
 msgstr "fast-export çalıştırılamadı"
@@ -21331,10 +21607,6 @@
 msgstr "protokol v2 desteği henüz yerine getirilmedi"
 
 #, c-format
-msgid "unknown value for config '%s': %s"
-msgstr "'%s' yapılandırması için bilinmeyen değer: %s"
-
-#, c-format
 msgid "transport '%s' not allowed"
 msgstr "'%s' taşıyıcısına izin verilmiyor"
 
@@ -21387,6 +21659,9 @@
 msgid "could not retrieve server-advertised bundle-uri list"
 msgstr "sunucu tarafından tanıtılan bundle-uri listesi alınamadı"
 
+msgid "operation not supported by protocol"
+msgstr "işlem protokol tarafından desteklenmiyor"
+
 msgid "too-short tree object"
 msgstr "ağaç nesnesi çok kısa"
 
@@ -21662,6 +21937,10 @@
 msgid "invalid '..' path segment"
 msgstr "geçersiz '..' yol kesimi"
 
+#, c-format
+msgid "error: unable to format message: %s\n"
+msgstr "hata: ileti biçimlendirilemiyor: %s\n"
+
 msgid "usage: "
 msgstr "kullanım: "
 
@@ -22210,6 +22489,10 @@
 msgid "cannot %s: Your index contains uncommitted changes."
 msgstr "%s yapılamıyor: İndeksiniz işlenmemiş değişiklikler içeriyor."
 
+#, c-format
+msgid "unknown style '%s' given for '%s'"
+msgstr "'%s' bilinmeyen biçemi şunun için verildi: '%s'"
+
 msgid ""
 "Error: Your local changes to the following files would be overwritten by "
 "merge"
diff --git a/po/uk.po b/po/uk.po
index 0868905..528a3dc 100644
--- a/po/uk.po
+++ b/po/uk.po
@@ -6,10 +6,10 @@
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: Git v2.43\n"
+"Project-Id-Version: Git v2.45\n"
 "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2023-11-09 14:26-0800\n"
-"PO-Revision-Date: 2023-11-09 14:34-0800\n"
+"POT-Creation-Date: 2024-04-27 09:55-0700\n"
+"PO-Revision-Date: 2024-04-15 15:55-0700\n"
 "Last-Translator: Arkadii Yakovets <ark@cho.red>\n"
 "Language-Team: Ukrainian <https://github.com/arkid15r/git-uk-l10n/>\n"
 "Language: uk\n"
@@ -18,7 +18,7 @@
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
 "n%10<=4 && (n%100<12 || n%100>14) ? 1 : 2);\n"
-"X-Generator: Poedit 3.4.1\n"
+"X-Generator: Poedit 3.4.2\n"
 
 #, c-format
 msgid "Huh (%s)?"
@@ -496,12 +496,12 @@
 "---\n"
 "To remove '%c' lines, make them ' ' lines (context).\n"
 "To remove '%c' lines, delete them.\n"
-"Lines starting with %c will be removed.\n"
+"Lines starting with %s will be removed.\n"
 msgstr ""
 "---\n"
 "Щоб видалити рядки \"%c\", зробіть їх рядками \" \" (контекст).\n"
 "Щоб видалити рядки \"%c\", вилучіть їх.\n"
-"Буде видалено рядки, що починаються з %c.\n"
+"Рядки, що починаються з %s, будуть видалені.\n"
 
 msgid ""
 "If it does not apply cleanly, you will be given an opportunity to\n"
@@ -549,6 +549,7 @@
 "/ - search for a hunk matching the given regex\n"
 "s - split the current hunk into smaller hunks\n"
 "e - manually edit the current hunk\n"
+"p - print the current hunk\n"
 "? - print help\n"
 msgstr ""
 "j - залишити цей шматок невизначеним, перейти до наступного невизначеного "
@@ -561,6 +562,7 @@
 "/ - шукати шматок, що відповідає заданому регвиру\n"
 "s - розбити поточний шматок на менші шматки\n"
 "e - редагувати поточний шматок вручну\n"
+"p - показати поточний шматок\n"
 "? - показати довідку\n"
 
 msgid "No previous hunk"
@@ -624,8 +626,8 @@
 "Вимкнути це повідомлення можна за допомогою \"git config advice.%s false\""
 
 #, c-format
-msgid "%shint: %.*s%s\n"
-msgstr "%sпідказка: %.*s%s\n"
+msgid "%shint:%s%.*s%s\n"
+msgstr "%sпідказка:%s%.*s%s\n"
 
 msgid "Cherry-picking is not possible because you have unmerged files."
 msgstr "Висмикування неможливе, оскільки у вас є не злиті файли."
@@ -1138,10 +1140,6 @@
 msgstr[2] "Застосування латки %%s з %d відкиданнями..."
 
 #, c-format
-msgid "truncating .rej filename to %.*s.rej"
-msgstr "скорочення назви файлу .rej до %.*s.rej"
-
-#, c-format
 msgid "cannot open %s"
 msgstr "неможливо відкрити %s"
 
@@ -1444,6 +1442,10 @@
 msgstr "Неочікувана опція --output"
 
 #, c-format
+msgid "extra command line parameter '%s'"
+msgstr "зайвий параметр командного рядка: \"%s\""
+
+#, c-format
 msgid "Unknown archive format '%s'"
 msgstr "Невідомий формат архіву \"%s\""
 
@@ -1489,6 +1491,14 @@
 msgstr "невірний --attr-source або GIT_ATTR_SOURCE"
 
 #, c-format
+msgid "unable to stat '%s'"
+msgstr "не вдалося виконати stat для \"%s\""
+
+#, c-format
+msgid "unable to read %s"
+msgstr "не вдалося прочитати %s"
+
+#, c-format
 msgid "Badly quoted content in file '%s': %s"
 msgstr "Невірно процитований вміст у файлі \"%s\": %s"
 
@@ -1558,6 +1568,10 @@
 msgstr "не вдалося створити файл \"%s\""
 
 #, c-format
+msgid "unable to start 'show' for object '%s'"
+msgstr "не вдалося запустити \"show\" для об’єкта \"%s\""
+
+#, c-format
 msgid "could not read file '%s'"
 msgstr "не вдалося прочитати файл \"%s\""
 
@@ -1666,10 +1680,12 @@
 msgid "not tracking: ambiguous information for ref '%s'"
 msgstr "не відстежується: неоднозначна інформація для посилання \"%s\""
 
+#. #-#-#-#-#  branch.c.po  #-#-#-#-#
 #. TRANSLATORS: This is a line listing a remote with duplicate
 #. refspecs in the advice message below. For RTL languages you'll
 #. probably want to swap the "%s" and leading "  " space around.
 #.
+#. #-#-#-#-#  object-name.c.po  #-#-#-#-#
 #. TRANSLATORS: This is line item of ambiguous object output
 #. from describe_ambiguous_object() above. For RTL languages
 #. you'll probably want to swap the "%s" and leading " " space
@@ -1708,6 +1724,9 @@
 msgid "'%s' is not a valid branch name"
 msgstr "\"%s\" не є допустимою назвою гілки"
 
+msgid "See `man git check-ref-format`"
+msgstr "Дивіться \"man git check-ref-format\""
+
 #, c-format
 msgid "a branch named '%s' already exists"
 msgstr "гілка з ім’ям \"%s\" вже існує"
@@ -1904,14 +1923,8 @@
 msgid "adding embedded git repository: %s"
 msgstr "додавання вбудованого git сховища: %s"
 
-msgid ""
-"Use -f if you really want to add them.\n"
-"Turn this message off by running\n"
-"\"git config advice.addIgnoredFile false\""
-msgstr ""
-"Використовуйте -f, якщо ви дійсно хочете їх додати.\n"
-"Щоб вимкнути це повідомлення, виконайте\n"
-"\"git config advice.addIgnoredFile false\""
+msgid "Use -f if you really want to add them."
+msgstr "Скористайтесь -f, якщо ви дійсно хочете їх додати."
 
 msgid "adding files failed"
 msgstr "додавання файлів завершилося невдало"
@@ -1928,14 +1941,8 @@
 msgid "Nothing specified, nothing added.\n"
 msgstr "Нічого не зазначено, нічого не додано.\n"
 
-msgid ""
-"Maybe you wanted to say 'git add .'?\n"
-"Turn this message off by running\n"
-"\"git config advice.addEmptyPathspec false\""
-msgstr ""
-"Можливо, ви хотіли вказати \"git add .\"?\n"
-"Щоб вимкнути це повідомлення, виконайте\n"
-"\"git config advice.addEmptyPathspec false\""
+msgid "Maybe you wanted to say 'git add .'?"
+msgstr "Можливо, ви хотіли вказати \"git add .\"?"
 
 msgid "index file corrupt"
 msgstr "індексний файл пошкоджено"
@@ -2012,18 +2019,20 @@
 msgstr "Не вдалося розщепити латки."
 
 #, c-format
-msgid "When you have resolved this problem, run \"%s --continue\"."
-msgstr "Коли ви вирішите цю проблему, виконайте \"%s --continue\"."
+msgid "When you have resolved this problem, run \"%s --continue\".\n"
+msgstr "Коли ви вирішите цю проблему, виконайте \"%s --continue\".\n"
 
 #, c-format
-msgid "If you prefer to skip this patch, run \"%s --skip\" instead."
+msgid "If you prefer to skip this patch, run \"%s --skip\" instead.\n"
 msgstr ""
-"Якщо ви бажаєте пропустити цю латку, виконайте \"%s --skip\" замість цього."
+"Якщо ви бажаєте пропустити цю латку, виконайте \"%s --skip\" замість цього.\n"
 
 #, c-format
-msgid "To record the empty patch as an empty commit, run \"%s --allow-empty\"."
+msgid ""
+"To record the empty patch as an empty commit, run \"%s --allow-empty\".\n"
 msgstr ""
-"Щоб записати порожню латку як порожній коміт, виконайте \"%s --allow-empty\"."
+"Щоб записати порожню латку як порожній коміт, виконайте \"%s --allow-"
+"empty\".\n"
 
 #, c-format
 msgid "To restore the original branch and stop patching, run \"%s --abort\"."
@@ -2325,7 +2334,7 @@
 "git bisect start [--term-(new|bad)=<term> --term-(old|good)=<term>]    [--no-"
 "checkout] [--first-parent] [<bad> [<good>...]] [--]    [<pathspec>...]"
 msgstr ""
-"git bisect start [--term-{new,bad}=<термін> --term-{old,good}=<термін>]    "
+"git bisect start [--term-(new,bad)=<термін> --term-(old,good)=<термін>]    "
 "[--no-checkout] [--first-parent] [<поганий> [<добрий>...]] [--]    "
 "[<визначник шляху>...]"
 
@@ -2785,11 +2794,12 @@
 msgstr "не вдалося знайти об’єкт коміту для \"%s\""
 
 #, c-format
-msgid ""
-"the branch '%s' is not fully merged.\n"
-"If you are sure you want to delete it, run 'git branch -D %s'"
+msgid "the branch '%s' is not fully merged"
+msgstr "гілка \"%s\" злита не повністю"
+
+#, c-format
+msgid "If you are sure you want to delete it, run 'git branch -D %s'"
 msgstr ""
-"гілка \"%s\" злита не повністю.\n"
 "Якщо ви впевнені, що хочете її видалити, виконайте \"git branch -D %s\""
 
 msgid "update of config-file failed"
@@ -2856,11 +2866,11 @@
 
 #, c-format
 msgid "no commit on branch '%s' yet"
-msgstr "поки що немає комітів в гілці \"%s\""
+msgstr "поки що немає комітів у гілці \"%s\""
 
 #, c-format
 msgid "no branch named '%s'"
-msgstr "немає гілки з ім’ям \"%s\""
+msgstr "немає гілки з назвою \"%s\""
 
 msgid "branch rename failed"
 msgstr "не вдалося перейменувати гілку"
@@ -2890,11 +2900,11 @@
 msgid ""
 "Please edit the description for the branch\n"
 "  %s\n"
-"Lines starting with '%c' will be stripped.\n"
+"Lines starting with '%s' will be stripped.\n"
 msgstr ""
 "Будь ласка, відредагуйте опис гілки\n"
 "  %s\n"
-"Рядки, що починаються з \"%c\", будуть вилучені.\n"
+"Рядки, що починаються з \"%s\", будуть вилучені.\n"
 
 msgid "Generic options"
 msgstr "Загальні опції"
@@ -3078,7 +3088,7 @@
 "'--set-upstream-to' instead"
 msgstr ""
 "опція \"--set-upstream\" більше не підтримується. Будь ласка, використовуйте "
-"\"--track\" або \"--set-upstream-to\""
+"\"--track\" або \"--set-upstream-to\" замість неї"
 
 msgid "git version:\n"
 msgstr "версія git:\n"
@@ -3097,10 +3107,12 @@
 msgstr "запущено не з git сховища - немає гачків для показу\n"
 
 msgid ""
-"git bugreport [(-o | --output-directory) <path>] [(-s | --suffix) <format>]\n"
+"git bugreport [(-o | --output-directory) <path>]\n"
+"              [(-s | --suffix) <format> | --no-suffix]\n"
 "              [--diagnose[=<mode>]]"
 msgstr ""
-"git bugreport [(-o | --output-directory) <шлях>] [(-s | --suffix) <формат>]\n"
+"git bugreport [(-o | --output-directory) <шлях>]\n"
+"              [(-s | --suffix) <формат> | --no-suffix]\n"
 "              [--diagnose[=<режим>]]"
 
 msgid ""
@@ -3588,6 +3600,10 @@
 msgid "path '%s' is unmerged"
 msgstr "шлях '%s' не злитий"
 
+#, c-format
+msgid "unable to read tree (%s)"
+msgstr "не вдалося прочитати дерево (%s)"
+
 msgid "you need to resolve your current index first"
 msgstr "спочатку потрібно розібратись з вашим поточним індексом"
 
@@ -3830,6 +3846,10 @@
 msgid "missing branch or commit argument"
 msgstr "відсутня гілка або коміт"
 
+#, c-format
+msgid "unknown conflict style '%s'"
+msgstr "невідомий стиль конфлікту \"%s\""
+
 msgid "perform a 3-way merge with the new branch"
 msgstr "здійснити 3-стороннє злиття з новою гілкою"
 
@@ -3848,8 +3868,8 @@
 msgid "new-branch"
 msgstr "нова-гілка"
 
-msgid "new unparented branch"
-msgstr "нова гілка без джерела"
+msgid "new unborn branch"
+msgstr "нова ненароджена гілка"
 
 msgid "update ignored files (default)"
 msgstr "оновити ігноровані файли (за замовчуванням)"
@@ -4086,22 +4106,9 @@
 msgid "remove only ignored files"
 msgstr "видалити лише ігноровані файли"
 
-msgid ""
-"clean.requireForce set to true and neither -i, -n, nor -f given; refusing to "
-"clean"
+msgid "clean.requireForce is true and -f not given: refusing to clean"
 msgstr ""
-"clean.requireForce встановлено у true і не задано ні -i, ні -n, ні -f; "
-"відмовлено в прибиранні"
-
-msgid ""
-"clean.requireForce defaults to true and neither -i, -n, nor -f given; "
-"refusing to clean"
-msgstr ""
-"clean.requireForce встановлено у true за замовчуванням і не задано ні -i, ні "
-"-n, ні -f; відмовлено в прибиранні"
-
-msgid "-x and -X cannot be used together"
-msgstr "-x та -X не можна використовувати разом"
+"clean.requireForce встановлено у true і -f не задано: відмовлено в прибиранні"
 
 msgid "git clone [<options>] [--] <repo> [<dir>]"
 msgstr "git clone [<опції>] [--] <сховище> [<директорія>]"
@@ -4115,8 +4122,8 @@
 msgid "create a bare repository"
 msgstr "створити порожнє сховище"
 
-msgid "create a mirror repository (implies bare)"
-msgstr "створити дзеркальне сховище (включає опцію bare)"
+msgid "create a mirror repository (implies --bare)"
+msgstr "створити дзеркальне сховище (включає опцію --bare)"
 
 msgid "to clone from a local repository"
 msgstr "клонувати з локального сховища"
@@ -4193,6 +4200,9 @@
 msgid "separate git dir from working tree"
 msgstr "відокремити git-директорію від робочого дерева"
 
+msgid "specify the reference format to use"
+msgstr "вкажіть формат посилання, який потрібно використовувати"
+
 msgid "key=value"
 msgstr "ключ=значення"
 
@@ -4311,11 +4321,9 @@
 msgid "You must specify a repository to clone."
 msgstr "Треба вказати сховище для клонування."
 
-msgid ""
-"--bundle-uri is incompatible with --depth, --shallow-since, and --shallow-"
-"exclude"
-msgstr ""
-"--bundle-uri несумісний з --depth, --shallow-since та --shallow-exclude"
+#, c-format
+msgid "unknown ref storage format '%s'"
+msgstr "невідомий формат зберігання посилань \"%s\""
 
 #, c-format
 msgid "repository '%s' does not exist"
@@ -4435,6 +4443,10 @@
 msgid "padding space between columns"
 msgstr "відступ між стовпчиками"
 
+#, c-format
+msgid "%s must be non-negative"
+msgstr "%s має бути невідʼємним значенням"
+
 msgid "--command must be the first argument"
 msgstr "--command має бути першим аргументом"
 
@@ -4450,7 +4462,7 @@
 "--stdin-commits]\n"
 "                       [--changed-paths] [--[no-]max-new-filters <n>] [--"
 "[no-]progress]\n"
-"                       <split options>"
+"                       <split-options>"
 msgstr ""
 "git commit-graph write [--object-dir <директорія>] [--append] [--object-dir "
 "<директорія>] [--append] [--object-dir <директорія>] [--append\n"
@@ -4458,7 +4470,7 @@
 "| --stdin-commits]\n"
 "                       [--changed-paths] [--[no-]max-new-filters <число>] [--"
 "[no-]progress]\n"
-"                       <опції розділення>"
+"                       <опції-розділення>"
 
 msgid "dir"
 msgstr "директорія"
@@ -4748,35 +4760,35 @@
 #, c-format
 msgid ""
 "Please enter the commit message for your changes. Lines starting\n"
-"with '%c' will be ignored.\n"
+"with '%s' will be ignored.\n"
 msgstr ""
 "Будь ласка, введіть допис до коміту для ваших змін. Рядки, що починаються з\n"
-" \"%c\" будуть проігноровані.\n"
+" \"%s\" будуть проігноровані.\n"
 
 #, 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"
+"with '%s' will be ignored, and an empty message aborts the commit.\n"
 msgstr ""
 "Будь ласка, введіть допис до коміту для ваших змін. Рядки, що починаються з\n"
-" \"%c\" будуть проігноровані, а порожній допис перерве коміт.\n"
+" \"%s\" будуть проігноровані, а порожній допис перерве коміт.\n"
 
 #, 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"
+"with '%s' will be kept; you may remove them yourself if you want to.\n"
 msgstr ""
 "Будь ласка, введіть допис до коміту для ваших змін. Рядки, що починаються з\n"
-" \"%c\" будуть збережені; ви можете вилучити їх самостійно, якщо захочете.\n"
+" \"%s\" будуть збережені; ви можете вилучити їх самостійно, якщо захочете.\n"
 
 #, 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"
+"with '%s' will be kept; you may remove them yourself if you want to.\n"
 "An empty message aborts the commit.\n"
 msgstr ""
 "Будь ласка, введіть допис до коміту для ваших змін. Рядки, що починаються з\n"
-" \"%c\" будуть збережені; ви можете вилучити їх самостійно, якщо захочете.\n"
+" \"%s\" будуть збережені; ви можете вилучити їх самостійно, якщо захочете.\n"
 "Порожній допис перериває коміт.\n"
 
 msgid ""
@@ -5222,6 +5234,10 @@
 msgstr ""
 "з --get використовувати значення за замовчуванням, якщо запис відсутній"
 
+msgid "human-readable comment string (# will be prepended as needed)"
+msgstr ""
+"зрозумілий для людини рядок коментаря (# буде додано перед за потребою)"
+
 #, c-format
 msgid "wrong number of arguments, should be %d"
 msgstr "невірна кількість аргументів, має бути %d"
@@ -5316,6 +5332,9 @@
 msgid "--default is only applicable to --get"
 msgstr "--default застосовується лише до --get"
 
+msgid "--comment is only applicable to add/set/replace operations"
+msgstr "--comment застосовується лише до add/set/replace операцій"
+
 msgid "--fixed-value only applies with 'value-pattern'"
 msgstr "--fixed-value застосовується лише з \"шаблоном-значення\""
 
@@ -6166,6 +6185,9 @@
 msgid "read reference patterns from stdin"
 msgstr "читати шаблони посилань з stdin"
 
+msgid "also include HEAD ref and pseudorefs"
+msgstr "також включити HEAD та псевдопосилання"
+
 msgid "unknown arguments supplied with --stdin"
 msgstr "невідомі аргументи надані через --stdin"
 
@@ -6757,7 +6779,7 @@
 msgstr "планувальник для запуску обслуговування git"
 
 msgid "failed to set up maintenance schedule"
-msgstr "не вдалося встановити графік обслуговування"
+msgstr "не вдалося встановити розклад обслуговування"
 
 msgid "failed to add repo to global config"
 msgstr "не вдалося додати сховище до глобальної конфігурації"
@@ -6776,6 +6798,7 @@
 msgid "invalid number of threads specified (%d) for %s"
 msgstr "невірно вказана кількість потоків (%d) для %s"
 
+#. #-#-#-#-#  grep.c.po  #-#-#-#-#
 #. TRANSLATORS: %s is the configuration
 #. variable for tweaking threads, currently
 #. grep.threads
@@ -6785,8 +6808,8 @@
 msgstr "немає підтримки потоків, ігнорування %s"
 
 #, c-format
-msgid "unable to read tree (%s)"
-msgstr "не вдалося прочитати дерево (%s)"
+msgid "unable to read tree %s"
+msgstr "не вдалося прочитати дерево %s"
 
 #, c-format
 msgid "unable to grep from object of type %s"
@@ -7201,10 +7224,6 @@
 msgstr "ВИЯВЛЕНО SHA1 КОЛІЗІЮ З %s!"
 
 #, c-format
-msgid "unable to read %s"
-msgstr "не вдалося прочитати %s"
-
-#, c-format
 msgid "cannot read existing object info %s"
 msgstr "неможливо прочитати інформацію про існуючий об’єкт %s"
 
@@ -7348,11 +7367,13 @@
 msgid ""
 "git init [-q | --quiet] [--bare] [--template=<template-directory>]\n"
 "         [--separate-git-dir <git-dir>] [--object-format=<format>]\n"
+"         [--ref-format=<format>]\n"
 "         [-b <branch-name> | --initial-branch=<branch-name>]\n"
 "         [--shared[=<permissions>]] [<directory>]"
 msgstr ""
 "git init [-q | --quiet] [--bare] [--template=<шаблон-директорія>]\n"
 "         [--separate-git-dir <git-директорія>] [--object-format=<формат>]\n"
+"         [--ref-format=<формат>]\n"
 "         [-b <назва-гілки> | --initial-branch=<назва-гілки>]\n"
 "         [--shared[=<дозволи>]] [<директорія>]"
 
@@ -7396,14 +7417,40 @@
 
 msgid ""
 "git interpret-trailers [--in-place] [--trim-empty]\n"
-"                       [(--trailer (<key>|<keyAlias>)[(=|:)<value>])...]\n"
+"                       [(--trailer (<key>|<key-alias>)[(=|:)<value>])...]\n"
 "                       [--parse] [<file>...]"
 msgstr ""
 "git interpret-trailers [--in-place] [--trim-empty]\n"
-"                       [(--trailer (<ключ>|<аліасКлюча>)"
-"[(=|:)<значення>])...]\n"
+"                       [(--trailer <ключ>|"
+"<аліасКлюча>[(=|:)<значення>])...]\n"
 "                       [--parse] [<файл>...]"
 
+#, c-format
+msgid "could not stat %s"
+msgstr "не вдалося виконати stat для %s"
+
+#, c-format
+msgid "file %s is not a regular file"
+msgstr "файл %s не є звичайним файлом"
+
+#, c-format
+msgid "file %s is not writable by user"
+msgstr "файл %s не доступний для запису користувачем"
+
+msgid "could not open temporary file"
+msgstr "не вдалося відкрити тимчасовий файл"
+
+#, c-format
+msgid "could not read input file '%s'"
+msgstr "не вдалося прочитати вхідний файл \"%s\""
+
+msgid "could not read from stdin"
+msgstr "не вдалося прочитати з stdin"
+
+#, c-format
+msgid "could not rename temporary file to %s"
+msgstr "не вдалося перейменувати тимчасовий файл на %s"
+
 msgid "edit files in place"
 msgstr "редагувати файли на місцях"
 
@@ -7411,7 +7458,7 @@
 msgstr "обрізати порожні причепи"
 
 msgid "placement"
-msgstr "розташування"
+msgstr "розміщення"
 
 msgid "where to place the new trailer"
 msgstr "де розмістити новий причіп"
@@ -7797,18 +7844,6 @@
 msgid "could not get object info about '%s'"
 msgstr "не вдалося отримати інформацію про обʼєкт \"%s\""
 
-#, c-format
-msgid "bad ls-files format: element '%s' does not start with '('"
-msgstr "невірний ls-files формат: елемент \"%s\" не починається з \"(\""
-
-#, c-format
-msgid "bad ls-files format: element '%s' does not end in ')'"
-msgstr "невірний ls-files формат: елемент \"%s\" не закінчується на \")\""
-
-#, c-format
-msgid "bad ls-files format: %%%.*s"
-msgstr "невірний ls-files формат: %%%.*s"
-
 msgid "git ls-files [<options>] [<file>...]"
 msgstr "git ls-files [<опції>] [<файл>...]"
 
@@ -7940,18 +7975,6 @@
 msgid "git ls-tree [<options>] <tree-ish> [<path>...]"
 msgstr "git ls-tree [<опції>] <деревоподібне-джерело> [<шлях>...]"
 
-#, c-format
-msgid "bad ls-tree format: element '%s' does not start with '('"
-msgstr "невірний формат ls-tree: елемент \"%s\" не починається з \"(\""
-
-#, c-format
-msgid "bad ls-tree format: element '%s' does not end in ')'"
-msgstr "невірний формат ls-tree: елемент \"%s\" не закінчується на \")\""
-
-#, c-format
-msgid "bad ls-tree format: %%%.*s"
-msgstr "невірний формат ls-tree: %%%.*s"
-
 msgid "only show trees"
 msgstr "показувати тільки дерева"
 
@@ -8065,11 +8088,18 @@
 "git merge-file [<опції>] [-L <назва1> [-L <оріг> [-L <назва2>]]] <файл1> "
 "<оріг-файл> <файл2>"
 
+msgid ""
+"option diff-algorithm accepts \"myers\", \"minimal\", \"patience\" and "
+"\"histogram\""
+msgstr ""
+"опція diff-algorithm приймає значення \"myers\", \"minimal\", \"patience\" "
+"та \"histogram\""
+
 msgid "send results to standard output"
 msgstr "надсилати результати до стандартного виводу"
 
 msgid "use object IDs instead of filenames"
-msgstr "використовувати ID обʼєктів замість назв файлів"
+msgstr "використовувати ідентифікатори обʼєктів замість назв файлів"
 
 msgid "use a diff3 based merge"
 msgstr "використовувати злиття на основі diff3"
@@ -8086,6 +8116,12 @@
 msgid "for conflicts, use a union version"
 msgstr "у разі конфліктів використовувати об’єднану версію"
 
+msgid "<algorithm>"
+msgstr "<алгоритм>"
+
+msgid "choose a diff algorithm"
+msgstr "вибрати алгоритм різниці"
+
 msgid "for conflicts, use this marker size"
 msgstr "у разі конфліктів використовувати цей розмір маркера"
 
@@ -8097,7 +8133,7 @@
 
 #, c-format
 msgid "object '%s' does not exist"
-msgstr "обʼєкт \"%s\" не існує"
+msgstr "об’єкт \"%s\" не існує"
 
 msgid "Could not write object file"
 msgstr "Не вдалося записати файл обʼєкта"
@@ -8128,6 +8164,11 @@
 msgid "Merging %s with %s\n"
 msgstr "Злиття %s з %s\n"
 
+# c-format
+#, c-format
+msgid "could not parse as tree '%s'"
+msgstr "не вдалося розібрати дерево з \"%s\""
+
 msgid "not something we can merge"
 msgstr "не те, що ми в змозі об’єднати"
 
@@ -8177,9 +8218,6 @@
 msgid "unknown strategy option: -X%s"
 msgstr "невідомий варіант стратегії: -X%s"
 
-msgid "--merge-base is incompatible with --stdin"
-msgstr "--merge-base несумісна з --stdin"
-
 #, c-format
 msgid "malformed input line: '%s'."
 msgstr "невірно сформований рядок вводу: \"%s\"."
@@ -8333,10 +8371,10 @@
 
 #, c-format
 msgid ""
-"Lines starting with '%c' will be ignored, and an empty message aborts\n"
+"Lines starting with '%s' will be ignored, and an empty message aborts\n"
 "the commit.\n"
 msgstr ""
-"Рядки, що починаються з \"%c\", будуть проігноровані, а порожній допис "
+"Рядки, що починаються з \"%s\", будуть проігноровані, а порожній допис "
 "перерве\n"
 "процес коміту.\n"
 
@@ -8497,9 +8535,6 @@
 msgid "object '%s' tagged as '%s', but is a '%s' type"
 msgstr "об’єкт \"%s\", позначений як \"%s\", але має тип \"%s\""
 
-msgid "could not read from stdin"
-msgstr "не вдалося прочитати з stdin"
-
 msgid "tag on stdin did not pass our strict fsck check"
 msgstr "тег з stdin не пройшов нашу сувору перевірку fsck"
 
@@ -8763,10 +8798,6 @@
 msgid "Write/edit the notes for the following object:"
 msgstr "Записати/відредагувати нотатки для наступного обʼєкта:"
 
-#, c-format
-msgid "unable to start 'show' for object '%s'"
-msgstr "не вдалося запустити \"show\" для об’єкта \"%s\""
-
 msgid "could not read 'show' output"
 msgstr "не вдалося прочитати вивід \"show\""
 
@@ -9113,6 +9144,10 @@
 msgstr "неспівпадіння з підрахунком дельти"
 
 #, c-format
+msgid "invalid pack.allowPackReuse value: '%s'"
+msgstr "неприпустиме значення pack.allowPackReuse: \"%s\""
+
+#, c-format
 msgid ""
 "value of uploadpack.blobpackfileuri must be of the form '<object-hash> <pack-"
 "hash> <uri>' (got '%s')"
@@ -9368,10 +9403,10 @@
 #, c-format
 msgid ""
 "Total %<PRIu32> (delta %<PRIu32>), reused %<PRIu32> (delta %<PRIu32>), pack-"
-"reused %<PRIu32>"
+"reused %<PRIu32> (from %<PRIuMAX>)"
 msgstr ""
 "Всього %<PRIu32> (дельта %<PRIu32>), повторно використано %<PRIu32> (дельта "
-"%<PRIu32>), повторно використано пакунків %<PRIu32>"
+"%<PRIu32>), повторно використано пакунків %<PRIu32> (з %<PRIuMAX>)"
 
 msgid ""
 "'git pack-redundant' is nominated for removal.\n"
@@ -9391,10 +9426,11 @@
 msgstr "відмовлено в запуску без --i-still-use-this"
 
 msgid ""
-"git pack-refs [--all] [--no-prune] [--include <pattern>] [--exclude "
+"git pack-refs [--all] [--no-prune] [--auto] [--include <pattern>] [--exclude "
 "<pattern>]"
 msgstr ""
-"git pack-refs [--all] [--no-prune] [--include <шаблон>] [--exclude <шаблон>]"
+"git pack-refs [--all] [--no-prune] [--auto] [--include <шаблон>] [--exclude "
+"<шаблон>]"
 
 msgid "pack everything"
 msgstr "запакувати все"
@@ -9402,6 +9438,9 @@
 msgid "prune loose refs (default)"
 msgstr "видалити вивільнені посилання (за замовчуванням)"
 
+msgid "auto-pack refs as needed"
+msgstr "автопакування посилань за потреби"
+
 msgid "references to include"
 msgstr "посилання для включення"
 
@@ -10073,21 +10112,6 @@
 msgid "could not remove '%s'"
 msgstr "не вдалося видалити \"%s\""
 
-msgid ""
-"Resolve all conflicts manually, mark them as resolved with\n"
-"\"git add/rm <conflicted_files>\", then run \"git rebase --continue\".\n"
-"You can instead skip this commit: run \"git rebase --skip\".\n"
-"To abort and get back to the state before \"git rebase\", run \"git rebase --"
-"abort\"."
-msgstr ""
-"Вирішіть усі конфлікти вручну, позначте їх як вирішені за допомогою\n"
-"\"git add/rm <конфліктні_файли>\", а потім виконайте \"git rebase --"
-"continue\".\n"
-"Замість цього ви можете пропустити цей коміт: виконайте \"git rebase --"
-"skip\".\n"
-"Щоб перервати процес і повернутися до стану перед \"git rebase\", виконайте "
-"\"git rebase --abort\"."
-
 #, c-format
 msgid ""
 "\n"
@@ -10117,13 +10141,16 @@
 msgid "apply options and merge options cannot be used together"
 msgstr "apply опції не можна використовувати разом з merge опціями"
 
+msgid "--empty=ask is deprecated; use '--empty=stop' instead."
+msgstr "--empty=ask застаріло; використовуйте \"--empty=stop\" замість цього."
+
 #, c-format
 msgid ""
 "unrecognized empty type '%s'; valid values are \"drop\", \"keep\", and "
-"\"ask\"."
+"\"stop\"."
 msgstr ""
 "нерозпізнаний порожній тип \"%s\"; припустимими значеннями є \"drop\", "
-"\"keep\" та \"ask\"."
+"\"keep\" та \"stop\"."
 
 msgid ""
 "--rebase-merges with an empty string argument is deprecated and will stop "
@@ -10311,8 +10338,8 @@
 "значення \"preserve\",\n"
 "який більше не підтримується; натомість використовуйте \"merges\""
 
-msgid "No rebase in progress?"
-msgstr "Перебазування не відбувається?"
+msgid "no rebase in progress"
+msgstr "перебазування не відбувається"
 
 msgid "The --edit-todo action can only be used during interactive rebase."
 msgstr ""
@@ -10361,13 +10388,6 @@
 msgstr "перемикач \"C\" очікує числове значення"
 
 msgid ""
-"apply options are incompatible with rebase.autoSquash.  Consider adding --no-"
-"autosquash"
-msgstr ""
-"apply опції несумісні з rebase.autoSquash.  Розгляньте можливість додавання "
-"--no-autosquash"
-
-msgid ""
 "apply options are incompatible with rebase.rebaseMerges.  Consider adding --"
 "no-rebase-merges"
 msgstr ""
@@ -10517,6 +10537,9 @@
 msgid "git reflog [show] [<log-options>] [<ref>]"
 msgstr "git reflog [show] [<лог-опції>] [<посилання>]"
 
+msgid "git reflog list"
+msgstr "git reflog list"
+
 msgid ""
 "git reflog expire [--expire=<time>] [--expire-unreachable=<time>]\n"
 "                  [--rewrite] [--updateref] [--stale-fix]\n"
@@ -10542,6 +10565,10 @@
 msgid "invalid timestamp '%s' given to '--%s'"
 msgstr "неприпустима позначка часу \"%s\" передана до \"--%s\""
 
+#, c-format
+msgid "%s does not accept arguments: '%s'"
+msgstr "%s не приймає аргументів: \"%s\""
+
 msgid "do not actually prune any entries"
 msgstr "насправді не видаляти жодного запису"
 
@@ -10670,8 +10697,8 @@
 "\t скористайтесь --mirror=fetch або --mirror=push"
 
 #, c-format
-msgid "unknown mirror argument: %s"
-msgstr "невідомий аргумент дзеркала: %s"
+msgid "unknown --mirror argument: %s"
+msgstr "невідомий --mirror аргумент: %s"
 
 msgid "fetch the remote branches"
 msgstr "отримати віддалені гілки"
@@ -11047,6 +11074,9 @@
 msgid "could not start pack-objects to repack promisor objects"
 msgstr "не вдалося розпочати pack-objects для перепакування promisor обʼєктів"
 
+msgid "failed to feed promisor objects to pack-objects"
+msgstr "не вдалося передати promisor обʼєкти обʼєктам пакунків"
+
 msgid "repack: Expecting full hex object ID lines only from pack-objects."
 msgstr ""
 "перепакування: очікуються повні рядки hex ідентифікаторів обʼєктів тільки "
@@ -11156,7 +11186,7 @@
 msgstr "записати multi-pack-index результуючих пакунків"
 
 msgid "pack prefix to store a pack containing pruned objects"
-msgstr "префікс пакунка для зберігання пакунка з обрізаними обʼєктами"
+msgstr "префікс для зберігання пакунка з обрізаними обʼєктами"
 
 msgid "pack prefix to store a pack containing filtered out objects"
 msgstr "префікс для зберігання пакунка з відфільтрованими  обʼєктами"
@@ -11166,7 +11196,7 @@
 
 #, c-format
 msgid "option '%s' can only be used along with '%s'"
-msgstr "опцію \"%s\" можна використовувати тільки разом з \"%s\""
+msgstr "опція \"%s\" може бути використана тільки разом з \"%s\""
 
 msgid "Nothing new to pack."
 msgstr "Немає нічого нового для пакування."
@@ -11371,6 +11401,75 @@
 msgid "only one pattern can be given with -l"
 msgstr "тільки один шаблон може бути заданий з -l"
 
+msgid "need some commits to replay"
+msgstr "потрібні деякі комміти для відтворення"
+
+msgid "--onto and --advance are incompatible"
+msgstr "--onto та --advance несумісні"
+
+msgid "all positive revisions given must be references"
+msgstr "всі надані позитивні ревізії мають бути посиланнями"
+
+msgid "argument to --advance must be a reference"
+msgstr "аргумент до --advance має бути посиланням"
+
+msgid ""
+"cannot advance target with multiple sources because ordering would be ill-"
+"defined"
+msgstr ""
+"неможливо просунути посилання з декількома джерелами, тому що впорядкування "
+"буде нечітко визначеним"
+
+msgid ""
+"cannot implicitly determine whether this is an --advance or --onto operation"
+msgstr "неможливо неявно визначити, чи це операція --advance або --onto"
+
+msgid ""
+"cannot advance target with multiple source branches because ordering would "
+"be ill-defined"
+msgstr ""
+"неможливо просунути посилання з декількома джерельними гілками, тому що "
+"впорядкування буде нечітко визначеним"
+
+msgid "cannot implicitly determine correct base for --onto"
+msgstr "неможливо неявно визначити вірну базу для --onto"
+
+msgid ""
+"(EXPERIMENTAL!) git replay ([--contained] --onto <newbase> | --advance "
+"<branch>) <revision-range>..."
+msgstr ""
+"(ЕКСПЕРИМЕНТАЛЬНО!) git replay ([--contained] --onto <нова-база> | --advance "
+"<гілка>) <діапазон-ревізій>..."
+
+msgid "make replay advance given branch"
+msgstr "зробити відтворення з просуванням даної гілки"
+
+msgid "replay onto given commit"
+msgstr "відтворити на заданий коміт"
+
+msgid "advance all branches contained in revision-range"
+msgstr "просунути всі гілки, що містяться в діапазоні ревізій"
+
+msgid "option --onto or --advance is mandatory"
+msgstr "опція --onto або --advance є обовʼязковою"
+
+#, c-format
+msgid ""
+"some rev walking options will be overridden as '%s' bit in 'struct rev_info' "
+"will be forced"
+msgstr ""
+"деякі опції проходження по ревізіям будуть перевизначені, оскільки біт "
+"\"%s\" у \"struct rev_info\" буде примусово використано"
+
+msgid "error preparing revisions"
+msgstr "помилка при підготовці ревізій"
+
+msgid "replaying down to root commit is not supported yet!"
+msgstr "відтворення до кореневого коміту поки що не підтримується!"
+
+msgid "replaying merge commits is not supported yet!"
+msgstr "відтворення коммітів злиття поки що не підтримується!"
+
 msgid ""
 "git rerere [clear | forget <pathspec>... | diff | status | remaining | gc]"
 msgstr ""
@@ -11579,19 +11678,17 @@
 msgid "--prefix requires an argument"
 msgstr "--prefix потребує аргументу"
 
+msgid "no object format specified"
+msgstr "не зазначено формат обʼєкту"
+
+#, c-format
+msgid "unsupported object format: %s"
+msgstr "непідтримуваний формат обʼєкту: %s"
+
 #, c-format
 msgid "unknown mode for --abbrev-ref: %s"
 msgstr "невідомий режим для --abbrev-ref: %s"
 
-msgid "--exclude-hidden cannot be used together with --branches"
-msgstr "--exclude-hidden не можна використовувати разом з --branches"
-
-msgid "--exclude-hidden cannot be used together with --tags"
-msgstr "--exclude-hidden неможливо використовувати разом з --tags"
-
-msgid "--exclude-hidden cannot be used together with --remotes"
-msgstr "--exclude-hidden неможливо використовувати разом з --remotes"
-
 msgid "this operation must be run in a work tree"
 msgstr "цю операцію треба виконувати в робочому дереві"
 
@@ -11669,8 +11766,8 @@
 msgid "allow commits with empty messages"
 msgstr "дозволити коміти з порожніми дописами"
 
-msgid "keep redundant, empty commits"
-msgstr "зберігати зайві порожні коміти"
+msgid "deprecated: use --empty=keep instead"
+msgstr "застаріле: використовуйте --empty=keep замість цього"
 
 msgid "use the 'reference' format to refer to commits"
 msgstr "використовувати \"reference\" формат для посилань на коміти"
@@ -12005,10 +12102,6 @@
 msgid "show refs from stdin that aren't in local repository"
 msgstr "показати посилання з stdin, яких немає в локальному сховищі"
 
-#, c-format
-msgid "only one of '%s', '%s' or '%s' can be given"
-msgstr "можна вказати тільки один з \"%s\", \"%s\" або \"%s\""
-
 msgid ""
 "git sparse-checkout (init | list | set | add | reapply | disable | check-"
 "rules) [<options>]"
@@ -12820,7 +12913,7 @@
 "branch] [--] [<шлях>...]"
 
 msgid "Failed to resolve HEAD as a valid ref."
-msgstr "Не вдалося розпізнати HEAD як дійсне посилання."
+msgstr "Не вдалося розвʼязати HEAD в дійсне посилання."
 
 msgid "git submodule absorbgitdirs [<options>] [<path>...]"
 msgstr "git submodule absorbgitdirs [<опції>] [<шлях>...]"
@@ -13029,25 +13122,25 @@
 "\n"
 "Write a message for tag:\n"
 "  %s\n"
-"Lines starting with '%c' will be ignored.\n"
+"Lines starting with '%s' will be ignored.\n"
 msgstr ""
 "\n"
 "Напишіть допис до тегу:\n"
 "  %s\n"
-"Рядки, що починаються з \"%c\", будуть проігноровані.\n"
+"Рядки, що починаються з \"%s\", будуть проігноровані.\n"
 
 #, c-format
 msgid ""
 "\n"
 "Write a message for tag:\n"
 "  %s\n"
-"Lines starting with '%c' will be kept; you may remove them yourself if you "
+"Lines starting with '%s' will be kept; you may remove them yourself if you "
 "want to.\n"
 msgstr ""
 "\n"
 "Напишіть допис до тегу:\n"
 "  %s\n"
-"Рядки, що починаються з \"%c\", будуть збережені; ви можете вилучити їх "
+"Рядки, що починаються з \"%s\", будуть збережені; ви можете вилучити їх "
 "самостійно, якщо захочете.\n"
 
 msgid "unable to sign the tag"
@@ -13133,6 +13226,9 @@
 msgid "print only tags of the object"
 msgstr "вивести тільки теги обʼєкта"
 
+msgid "could not start 'git column'"
+msgstr "не вдалося виконати \"git column\""
+
 #, c-format
 msgid "the '%s' option is only allowed in list mode"
 msgstr "опція \"%s\" дозволена лише в режимі виводу"
@@ -13325,7 +13421,7 @@
 
 #, c-format
 msgid "index-version: was %d, set to %d"
-msgstr "index-version: було %d, стало %d"
+msgstr "версія індексу: була %d, стала %d"
 
 msgid ""
 "core.splitIndex is set to false; remove or change it, if you really want to "
@@ -13379,12 +13475,12 @@
 msgid "fsmonitor disabled"
 msgstr "fsmonitor вимкнено"
 
-msgid "git update-ref [<options>] -d <refname> [<old-val>]"
-msgstr "git update-ref [<опції>] -d <назва посилання> [<старе значення>]"
+msgid "git update-ref [<options>] -d <refname> [<old-oid>]"
+msgstr "git update-ref [<опції>] -d <назва-посилання> [<старий-oid>]"
 
-msgid "git update-ref [<options>]    <refname> <new-val> [<old-val>]"
+msgid "git update-ref [<options>]    <refname> <new-oid> [<old-oid>]"
 msgstr ""
-"git update-ref [<опції>] <назва-посилання> <нове-значення> [<старе-значення>]"
+"git update-ref [<опції>]    <назва-посилання> <новий-oid> [<старий-oid>]"
 
 msgid "git update-ref [<options>] --stdin [-z]"
 msgstr "git update-ref [<опції>] --stdin [-z]"
@@ -13482,13 +13578,13 @@
 
 #, c-format
 msgid ""
-"If you meant to create a worktree containing a new orphan branch\n"
+"If you meant to create a worktree containing a new unborn branch\n"
 "(branch with no commits) for this repository, you can do so\n"
 "using the --orphan flag:\n"
 "\n"
 "    git worktree add --orphan -b %s %s\n"
 msgstr ""
-"Якщо ви хочете створити робоче дерево, що містить нову сирітську гілку\n"
+"Якщо ви хочете створити робоче дерево, що містить нову ненароджену гілку\n"
 "(гілку без комітів) для цього сховища, ви можете зробити це\n"
 "за допомогою прапорця --orphan:\n"
 "\n"
@@ -13496,13 +13592,13 @@
 
 #, c-format
 msgid ""
-"If you meant to create a worktree containing a new orphan branch\n"
+"If you meant to create a worktree containing a new unborn branch\n"
 "(branch with no commits) for this repository, you can do so\n"
 "using the --orphan flag:\n"
 "\n"
 "    git worktree add --orphan %s\n"
 msgstr ""
-"Якщо ви хочете створити робоче дерево, що містить нову сирітську гілку\n"
+"Якщо ви хочете створити робоче дерево, що містить нову ненароджену гілку\n"
 "(гілку без комітів) для цього сховища, ви можете зробити це\n"
 "за допомогою прапорця --orphan:\n"
 "\n"
@@ -13566,6 +13662,10 @@
 msgstr "ініціалізація"
 
 #, c-format
+msgid "could not find created worktree '%s'"
+msgstr "не вдалося знайти створене робоче дерево \"%s\""
+
+#, c-format
 msgid "Preparing worktree (new branch '%s')"
 msgstr "Підготовка робочого дерева (нова гілка \"%s\")"
 
@@ -13601,12 +13701,8 @@
 msgstr ""
 "Не існує локальних або віддалених посилань, незважаючи на наявність "
 "принаймні одного віддаленого\n"
-"призначення, зупинка; скористайтесь \"add -f\" для перевизначення або "
-"спочатку виконайте отримання віддаленого посилання"
-
-#, c-format
-msgid "'%s' and '%s' cannot be used together"
-msgstr "\"%s\" і \"%s\" не можна використовувати разом"
+"призначення, зупинка; скористайтесь \"add -f\", щоб перевизначити, або "
+"спочатку виконайте отримання з віддаленного сховища"
 
 msgid "checkout <branch> even if already checked out in other worktree"
 msgstr ""
@@ -13618,8 +13714,8 @@
 msgid "create or reset a branch"
 msgstr "створити або скинути гілку"
 
-msgid "create unborn/orphaned branch"
-msgstr "створити ненароджену/сирітську гілку"
+msgid "create unborn branch"
+msgstr "створити ненароджену гілку"
 
 msgid "populate the new working tree"
 msgstr "заповнити нове робоче дерево"
@@ -13642,11 +13738,8 @@
 msgstr "опції \"%s\", \"%s\" та \"%s\" не можна використовувати разом"
 
 #, c-format
-msgid "options '%s', and '%s' cannot be used together"
-msgstr "опції \"%s\" і \"%s\" не можна використовувати разом"
-
-msgid "<commit-ish>"
-msgstr "<комітоподібне>"
+msgid "option '%s' and commit-ish cannot be used together"
+msgstr "опцію \"%s\" не можна використовувати разом з комітоподібними"
 
 msgid "added with --lock"
 msgstr "додано з --lock"
@@ -13926,7 +14019,7 @@
 
 #, c-format
 msgid "chunk id %<PRIx32> not %d-byte aligned"
-msgstr "шматок в id %<PRIx32> не %d-byte впорядкований"
+msgstr "шматок id %<PRIx32> не є %d-byte впорядкованим"
 
 #, c-format
 msgid "improper chunk offset(s) %<PRIx64> and %<PRIx64>"
@@ -13981,7 +14074,7 @@
 msgstr "Перенести архів обʼєктів та посилань"
 
 msgid "Provide contents or details of repository objects"
-msgstr "Показати вміст або інформацію про обʼєкти сховища"
+msgstr "Надавати вміст або деталі обʼєктів сховища"
 
 msgid "Display gitattributes information"
 msgstr "Відобразити інформацію про gitattributes"
@@ -14269,6 +14362,11 @@
 msgid "Create, list, delete refs to replace objects"
 msgstr "Створити, показати, видалити посилання для об’єктів заміни"
 
+msgid "EXPERIMENTAL: Replay commits on a new base, works with bare repos too"
+msgstr ""
+"ЕКСПЕРИМЕНТАЛЬНО: Відтворення коммітів на новій базі також працює з "
+"порожніми сховищами"
+
 msgid "Generates a summary of pending changes"
 msgstr "Створює підсумок змін для розгляду"
 
@@ -14391,7 +14489,7 @@
 msgstr "Показати інформацію про версію Git"
 
 msgid "Show logs with differences each commit introduces"
-msgstr "Показати журнал з різницею, яку вносить кожен з комітів"
+msgstr "Показати журнал з різницями, які вносить кожен коміт"
 
 msgid "Manage multiple working trees"
 msgstr "Керувати кількома робочими деревами"
@@ -14507,6 +14605,32 @@
 msgid "commit-graph file is too small"
 msgstr "файл коміт-графа занадто малий"
 
+msgid "commit-graph oid fanout chunk is wrong size"
+msgstr "шматок oid fanout коміт-графа має невірний розмір"
+
+msgid "commit-graph fanout values out of order"
+msgstr "значення fanout коміт-графа впорядковані невірно"
+
+msgid "commit-graph OID lookup chunk is the wrong size"
+msgstr "шматок OID lookup коміт-графа має невірний розмір"
+
+msgid "commit-graph commit data chunk is wrong size"
+msgstr "шматок commit data коміт-графа має невірний розмір"
+
+msgid "commit-graph generations chunk is wrong size"
+msgstr "шматок generations коміт-графа має невірний розмір"
+
+msgid "commit-graph changed-path index chunk is too small"
+msgstr "шматок changed-path index коміт-графа має невірний розмір"
+
+#, c-format
+msgid ""
+"ignoring too-small changed-path chunk (%<PRIuMAX> < %<PRIuMAX>) in commit-"
+"graph file"
+msgstr ""
+"ігнорування занадто малого шматка changed-path (%<PRIuMAX> < %<PRIuMAX>) "
+"файла коміт-графа"
+
 #, c-format
 msgid "commit-graph signature %X does not match signature %X"
 msgstr "підпис коміт-графа %X не збігається з підписом %X"
@@ -14523,11 +14647,20 @@
 msgid "commit-graph file is too small to hold %u chunks"
 msgstr "файл коміт-графа занадто малий, щоб вмістити %u шматків"
 
+msgid "commit-graph required OID fanout chunk missing or corrupted"
+msgstr "необхідний шматок OID fanout коміт-графа відсутній або пошкоджений"
+
+msgid "commit-graph required OID lookup chunk missing or corrupted"
+msgstr "необхідний шматок OID lookup коміт-графа відсутній або пошкоджений"
+
+msgid "commit-graph required commit data chunk missing or corrupted"
+msgstr "необхідний шматок commit data коміт-графа відсутній або пошкоджений"
+
 msgid "commit-graph has no base graphs chunk"
 msgstr "коміт-граф не має шматка базових графів"
 
 msgid "commit-graph base graphs chunk is too small"
-msgstr "занадто малий шматок базових графів коміт-графа"
+msgstr "шматок base graphs коміт-графа занадто малий"
 
 msgid "commit-graph chain does not match"
 msgstr "ланцюжок коміт-графа не співпадає"
@@ -14536,6 +14669,9 @@
 msgid "commit count in base graph too high: %<PRIuMAX>"
 msgstr "кількість комітів у базовому графі занадто велика: %<PRIuMAX>"
 
+msgid "commit-graph chain file too small"
+msgstr "файл ланцюжка коміт-графа занадто малий"
+
 #, c-format
 msgid "invalid commit-graph chain: line '%s' not a hash"
 msgstr "неприпустимий ланцюжок коміт-графа: рядок \"%s\" не є хешем"
@@ -14551,10 +14687,13 @@
 msgstr "не вдалося знайти коміт %s"
 
 msgid "commit-graph requires overflow generation data but has none"
-msgstr "коміт-граф потребує даних генерації переповнення, але їх немаєданих"
+msgstr "коміт-граф потребує даних генерації переповнення, але не має їх"
 
 msgid "commit-graph overflow generation data is too small"
-msgstr "занадто мало даних про переповнення коміт-граф генерації"
+msgstr "занадто мало даних генерації переповнення коміт-графа"
+
+msgid "commit-graph extra-edges pointer out of bounds"
+msgstr "extra-edges pointer коміт-графа виходить за межі"
 
 msgid "Loading known commits in commit graph"
 msgstr "Завантаження відомих комітів у коміт-графі"
@@ -14692,12 +14831,17 @@
 "commit-graph has both zero and non-zero generations (e.g., commits '%s' and "
 "'%s')"
 msgstr ""
-"коміт-граф має як нульові, так і ненульові генерації (коміти \"%s\" і \"%s\")"
+"коміт-граф має як нульові, так і ненульові генерації (наприклад, коміти "
+"\"%s\" і \"%s\")"
 
 msgid "Verifying commits in commit graph"
 msgstr "Перевірка комітів у коміт-графі"
 
 #, c-format
+msgid "could not parse commit %s"
+msgstr "не вдалося розібрати коміт %s"
+
+#, c-format
 msgid "%s %s is not a commit!"
 msgstr "%s %s не є комітом!"
 
@@ -15128,8 +15272,13 @@
 msgid "bad zlib compression level %d"
 msgstr "невірний рівень zlib компресії %d"
 
-msgid "core.commentChar should only be one ASCII character"
-msgstr "core.commentChar має бути лише одним символом ASCII"
+#, c-format
+msgid "%s cannot contain newline"
+msgstr "%s не може містити символи нового рядка"
+
+#, c-format
+msgid "%s must have at least one character"
+msgstr "%s повинен мати принаймні один символ"
 
 #, c-format
 msgid "ignoring unknown core.fsyncMethod value '%s'"
@@ -15201,6 +15350,10 @@
 msgstr "не вдалося записати новий конфігураційний файл %s"
 
 #, c-format
+msgid "no multi-line comment allowed: '%s'"
+msgstr "багаторядкові коментарі не дозволяються: \"%s\""
+
+#, c-format
 msgid "could not lock config file %s"
 msgstr "не вдалося зафіксувати файл конфігурації %s"
 
@@ -15385,7 +15538,7 @@
 
 #, c-format
 msgid "strange pathname '%s' blocked"
-msgstr "дивне імʼя шляху \"%s\" заблоковано"
+msgstr "дивна назва шляху \"%s\" заблокована"
 
 msgid "unable to fork"
 msgstr "неможливо розгалужити"
@@ -15703,6 +15856,10 @@
 msgstr "Невідоме значення конфігураційної змінної \"diff.submodule\": \"%s\""
 
 #, c-format
+msgid "unknown value for config '%s': %s"
+msgstr "невідоме значення для конфігурації \"%s\": %s"
+
+#, c-format
 msgid ""
 "Found errors in 'diff.dirstat' config variable:\n"
 "%s"
@@ -15782,13 +15939,6 @@
 msgid "invalid mode '%s' in --color-moved-ws"
 msgstr "неприпустимий режим \"%s\" у --color-moved-ws"
 
-msgid ""
-"option diff-algorithm accepts \"myers\", \"minimal\", \"patience\" and "
-"\"histogram\""
-msgstr ""
-"опція diff-algorithm приймає значення \"myers\", \"minimal\", \"patience\" "
-"та \"histogram\""
-
 #, c-format
 msgid "invalid argument to %s"
 msgstr "неприпустимий аргумент до %s"
@@ -15832,8 +15982,8 @@
 msgid "output only the last line of --stat"
 msgstr "вивести лише останній рядок --stat"
 
-msgid "<param1,param2>..."
-msgstr "<параметр1,параметр2>..."
+msgid "<param1>,<param2>..."
+msgstr "<параметр1>,<параметр2>..."
 
 msgid ""
 "output the distribution of relative amount of changes for each sub-directory"
@@ -15842,8 +15992,8 @@
 msgid "synonym for --dirstat=cumulative"
 msgstr "синонім для --dirstat=cumulative"
 
-msgid "synonym for --dirstat=files,param1,param2..."
-msgstr "синонім для --dirstat=files,параметр1,параметр2..."
+msgid "synonym for --dirstat=files,<param1>,<param2>..."
+msgstr "синонім для --dirstat=files,<параметр1>,<параметр2>..."
 
 msgid "warn if changes introduce conflict markers or whitespace errors"
 msgstr ""
@@ -16019,12 +16169,6 @@
 msgid "generate diff using the \"histogram diff\" algorithm"
 msgstr "згенерувати різницю за алгоритмом \"histogram diff\""
 
-msgid "<algorithm>"
-msgstr "<алгоритм>"
-
-msgid "choose a diff algorithm"
-msgstr "вибрати алгоритм різниці"
-
 msgid "<text>"
 msgstr "<текст>"
 
@@ -17020,6 +17164,14 @@
 msgstr "Не вдалося створити \"%s.lock\": %s"
 
 #, c-format
+msgid "could not write loose object index %s"
+msgstr "не вдалося записати індекс вільного обʼєкта %s"
+
+#, c-format
+msgid "failed to write loose object index %s\n"
+msgstr "не вдалося записати індекс вільного обʼєкта %s\n"
+
+#, c-format
 msgid "unexpected line: '%s'"
 msgstr "неочікуваний рядок: \"%s\""
 
@@ -17030,6 +17182,10 @@
 msgstr "виявлено цитований CRLF"
 
 #, c-format
+msgid "unable to format message: %s"
+msgstr "не вдалося відформатувати допис: %s"
+
+#, c-format
 msgid "Failed to merge submodule %s (not checked out)"
 msgstr "Не вдалося обʼєднати підмодуль %s (не активне)"
 
@@ -17042,6 +17198,10 @@
 msgstr "Не вдалося злити підмодуль %s (відсутні коміти)"
 
 #, c-format
+msgid "Failed to merge submodule %s (repository corrupt)"
+msgstr "Не вдалося обʼєднати підмодуль %s (сховище пошкоджено)"
+
+#, c-format
 msgid "Failed to merge submodule %s (commits don't follow merge-base)"
 msgstr "Не вдалося злити підмодуль %s (коміти не відповідають базі)"
 
@@ -17224,7 +17384,7 @@
 #. conflict in a submodule. The first argument is the submodule
 #. name, and the second argument is the abbreviated id of the
 #. commit that needs to be merged.  For example:
-#. - go to submodule (mysubmodule), and either merge commit abc1234"
+#.  - go to submodule (mysubmodule), and either merge commit abc1234"
 #.
 #, c-format
 msgid ""
@@ -17510,69 +17670,6 @@
 msgid "failed to read the cache"
 msgstr "не вдалося прочитати кеш"
 
-msgid "multi-pack-index OID fanout is of the wrong size"
-msgstr "multi-pack-index OID розсіювання має невірний розмір"
-
-msgid "multi-pack-index OID lookup chunk is the wrong size"
-msgstr "multi-pack-index шматок пошуку OID має невірний розмір"
-
-msgid "multi-pack-index object offset chunk is the wrong size"
-msgstr ""
-"multi-pack-index необхідній шматок зміщення обʼєкта має невірний розмір"
-
-#, c-format
-msgid "multi-pack-index file %s is too small"
-msgstr "multi-pack-index файл %s занадто малий"
-
-#, c-format
-msgid "multi-pack-index signature 0x%08x does not match signature 0x%08x"
-msgstr "multi-pack-index підпис 0x%08x не збігається з підписом 0x%08x"
-
-#, c-format
-msgid "multi-pack-index version %d not recognized"
-msgstr "multi-pack-index версія %d не розпізнана"
-
-#, c-format
-msgid "multi-pack-index hash version %u does not match version %u"
-msgstr "версія хешу multi-pack-index %u не збігається з версією %u"
-
-msgid "multi-pack-index required pack-name chunk missing or corrupted"
-msgstr ""
-"multi-pack-index необхідний шматок імені пакунка відсутній або пошкоджений"
-
-msgid "multi-pack-index required OID fanout chunk missing or corrupted"
-msgstr ""
-"multi-pack-index необхідний шматок розсіювання OID відсутній або пошкоджений"
-
-msgid "multi-pack-index required OID lookup chunk missing or corrupted"
-msgstr ""
-"multi-pack-index необхідний шматок пошуку OID відсутній або пошкоджений"
-
-msgid "multi-pack-index required object offsets chunk missing or corrupted"
-msgstr ""
-"multi-pack-index необхідний шматок зміщення обʼєктів відсутній або "
-"пошкоджений"
-
-msgid "multi-pack-index pack-name chunk is too short"
-msgstr "multi-pack-index  pack-name шматок занадто малий"
-
-#, c-format
-msgid "multi-pack-index pack names out of order: '%s' before '%s'"
-msgstr ""
-"multi-pack-index назви пакунків знаходяться у невірній послідовності: \"%s\" "
-"перед \"%s\""
-
-#, c-format
-msgid "bad pack-int-id: %u (%u total packs)"
-msgstr "невірний pack-int-id: %u (%u всього пакунків)"
-
-msgid "multi-pack-index stores a 64-bit offset, but off_t is too small"
-msgstr ""
-"multi-pack-index зберігає 64-бітне зміщення, але значення off_t занадто мале"
-
-msgid "multi-pack-index large offset out of bounds"
-msgstr "multi-pack-index large зсув виходить за межі"
-
 #, c-format
 msgid "failed to add packfile '%s'"
 msgstr "не вдалося додати packfile \"%s\""
@@ -17583,7 +17680,7 @@
 
 #, c-format
 msgid "failed to locate object %d in packfile"
-msgstr "не вдалося знайти обʼєкт %d у файлі пакунка"
+msgstr "не вдалося знайти обʼєкт %d у packfile"
 
 msgid "cannot store reverse index file"
 msgstr "неможливо зберегти файл зворотнього індексу"
@@ -17601,7 +17698,7 @@
 "ігнорування існуючого multi-pack-index; невідповідність контрольних сум"
 
 msgid "could not load pack"
-msgstr "не вдалося завантажити пакет"
+msgstr "не вдалося завантажити пакунок"
 
 #, c-format
 msgid "could not open index for %s"
@@ -17620,11 +17717,11 @@
 
 #, c-format
 msgid "did not see pack-file %s to drop"
-msgstr "не побачив файл пакунка %s, який потрібно скинути"
+msgstr "не знайдено файл пакунка %s для скидання"
 
 #, c-format
 msgid "preferred pack '%s' is expired"
-msgstr "у бажаного пакета \"%s\" закінчився термін дії"
+msgstr "у бажаного пакунка \"%s\" закінчився термін дії"
 
 msgid "no pack files to index."
 msgstr "немає файлів пакунків для індексації."
@@ -17638,6 +17735,92 @@
 msgid "could not write multi-pack-index"
 msgstr "не вдалося записати multi-pack-index"
 
+msgid "Counting referenced objects"
+msgstr "Підрахунок обʼєктів, на які є посилання"
+
+msgid "Finding and deleting unreferenced packfiles"
+msgstr "Пошук і видалення файлів пакунків без посилань"
+
+msgid "could not start pack-objects"
+msgstr "не вдалося розпочати pack-objects"
+
+msgid "could not finish pack-objects"
+msgstr "не вдалося завершити pack-objects"
+
+msgid "multi-pack-index OID fanout is of the wrong size"
+msgstr "multi-pack-index OID розсіювання має невірний розмір"
+
+#, c-format
+msgid ""
+"oid fanout out of order: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]"
+msgstr ""
+"невірна послідовність oid fanout: fanout[%d] = %<PRIx32> > %<PRIx32> = "
+"fanout[%d]"
+
+msgid "multi-pack-index OID lookup chunk is the wrong size"
+msgstr "multi-pack-index OID lookup шматок має невірний розмір"
+
+msgid "multi-pack-index object offset chunk is the wrong size"
+msgstr "multi-pack-index object offset шматок має невірний розмір"
+
+#, c-format
+msgid "multi-pack-index file %s is too small"
+msgstr "multi-pack-index файл %s занадто малий"
+
+#, c-format
+msgid "multi-pack-index signature 0x%08x does not match signature 0x%08x"
+msgstr "multi-pack-index підпис 0x%08x не збігається з підписом 0x%08x"
+
+#, c-format
+msgid "multi-pack-index version %d not recognized"
+msgstr "multi-pack-index версія %d не розпізнана"
+
+#, c-format
+msgid "multi-pack-index hash version %u does not match version %u"
+msgstr "версія хешу multi-pack-index %u не збігається з версією %u"
+
+msgid "multi-pack-index required pack-name chunk missing or corrupted"
+msgstr "необхідний шматок pack-name multi-pack-index відсутній або пошкоджений"
+
+msgid "multi-pack-index required OID fanout chunk missing or corrupted"
+msgstr ""
+"необхідний шматок OID fanout multi-pack-index відсутній або пошкоджений"
+
+msgid "multi-pack-index required OID lookup chunk missing or corrupted"
+msgstr ""
+"необхідний шматок OID lookup multi-pack-index відсутній або пошкоджений"
+
+msgid "multi-pack-index required object offsets chunk missing or corrupted"
+msgstr ""
+"необхідний шматок object offsets multi-pack-index відсутній або пошкоджений"
+
+msgid "multi-pack-index pack-name chunk is too short"
+msgstr "шматок pack-name multi-pack-index занадто малий"
+
+#, c-format
+msgid "multi-pack-index pack names out of order: '%s' before '%s'"
+msgstr ""
+"multi-pack-index назви пакунків знаходяться у невірній послідовності: \"%s\" "
+"перед \"%s\""
+
+#, c-format
+msgid "bad pack-int-id: %u (%u total packs)"
+msgstr "невірний pack-int-id: %u (%u всього пакунків)"
+
+msgid "MIDX does not contain the BTMP chunk"
+msgstr "MIDX не містить шматок BTMP"
+
+#, c-format
+msgid "could not load bitmapped pack %<PRIu32>"
+msgstr "не вдалося завантажити бітмаповий пакунок %<PRIu32>"
+
+msgid "multi-pack-index stores a 64-bit offset, but off_t is too small"
+msgstr ""
+"multi-pack-index зберігає 64-бітне зміщення, але значення off_t занадто мале"
+
+msgid "multi-pack-index large offset out of bounds"
+msgstr "large offset multi-pack-index виходить за межі"
+
 #, c-format
 msgid "failed to clear multi-pack-index at %s"
 msgstr "не вдалося очистити multi-pack-index при %s"
@@ -17651,13 +17834,6 @@
 msgid "Looking for referenced packfiles"
 msgstr "Пошук файлів пакунків, на які є посилання"
 
-#, c-format
-msgid ""
-"oid fanout out of order: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]"
-msgstr ""
-"невірна послідовність oid розсіювання: fanout[%d] = %<PRIx32> > %<PRIx32> = "
-"fanout[%d]"
-
 msgid "the midx contains no oid"
 msgstr "midx не містить oid"
 
@@ -17686,18 +17862,6 @@
 msgid "incorrect object offset for oid[%d] = %s: %<PRIx64> != %<PRIx64>"
 msgstr "невірне зміщення обʼєкта для oid[%d] = %s: %<PRIx64> != %<PRIx64>"
 
-msgid "Counting referenced objects"
-msgstr "Підрахунок обʼєктів, на які є посилання"
-
-msgid "Finding and deleting unreferenced packfiles"
-msgstr "Пошук і видалення файлів пакунків без посилань"
-
-msgid "could not start pack-objects"
-msgstr "не вдалося розпочати pack-objects"
-
-msgid "could not finish pack-objects"
-msgstr "не вдалося завершити pack-objects"
-
 #, c-format
 msgid "unable to create lazy_dir thread: %s"
 msgstr "не вдалося створити lazy_dir потік: %s"
@@ -17744,6 +17908,25 @@
 msgid "Bad %s value: '%s'"
 msgstr "Невірне %s значення: \"%s\""
 
+msgid "failed to decode tree entry"
+msgstr "не вдалося декодувати запис дерева"
+
+#, c-format
+msgid "failed to map tree entry for %s"
+msgstr "не вдалося зіставити запис у дереві для %s"
+
+#, c-format
+msgid "bad %s in commit"
+msgstr "невірній %s у коміті"
+
+#, c-format
+msgid "unable to map %s %s in commit object"
+msgstr "не вдалося зіставити %s %s в обʼєкті коміту"
+
+#, c-format
+msgid "Failed to convert object from %s to %s"
+msgstr "Не вдалося перетворити обʼєкт з \"%s\" на \"%s\""
+
 #, c-format
 msgid "object directory %s does not exist; check .git/objects/info/alternates"
 msgstr "директорія об’єкта %s не існує; перевірте .git/objects/info/alternates"
@@ -17847,6 +18030,10 @@
 msgstr "упакований обʼєкт %s (що зберігається у %s) пошкоджено"
 
 #, c-format
+msgid "missing mapping of %s to %s"
+msgstr "відсутнє зіставлення %s до %s"
+
+#, c-format
 msgid "unable to write file %s"
 msgstr "не вдалося записати файл %s"
 
@@ -17900,6 +18087,10 @@
 msgstr "неможливо прочитати обʼєкт для %s"
 
 #, c-format
+msgid "cannot map object %s to %s"
+msgstr "неможливо зіставити обʼєкт %s з %s"
+
+#, c-format
 msgid "object fails fsck: %s"
 msgstr "об’єкт не пройшов перевірку fsck: %s"
 
@@ -17961,7 +18152,7 @@
 #. TRANSLATORS: This is a line of ambiguous commit
 #. object output. E.g.:
 #. *
-#. "deadbeef commit 2021-01-01 - Some Commit Message"
+#.    "deadbeef commit 2021-01-01 - Some Commit Message"
 #.
 #, c-format
 msgid "%s commit %s - %s"
@@ -17970,7 +18161,7 @@
 #. TRANSLATORS: This is a line of ambiguous
 #. tag object output. E.g.:
 #. *
-#. "deadbeef tag 2022-01-01 - Some Tag Message"
+#.    "deadbeef tag 2022-01-01 - Some Tag Message"
 #. *
 #. The second argument is the YYYY-MM-DD found
 #. in the tag.
@@ -17986,7 +18177,7 @@
 #. tag object output where we couldn't parse
 #. the tag itself. E.g.:
 #. *
-#. "deadbeef [bad tag, could not parse it]"
+#.    "deadbeef [bad tag, could not parse it]"
 #.
 #, c-format
 msgid "%s [bad tag, could not parse it]"
@@ -18182,6 +18373,9 @@
 msgid "could not open pack %s"
 msgstr "не вдалося відкрити пакунок %s"
 
+msgid "could not determine MIDX preferred pack"
+msgstr "не вдалося визначити бажаний пакунок MIDX"
+
 #, c-format
 msgid "preferred pack (%s) is invalid"
 msgstr "бажаний пакунок (%s) є неприпустимим"
@@ -18203,6 +18397,17 @@
 msgstr "пошкоджений ewah bitmap: урізаний заголовок для bitmap коміту \"%s\""
 
 #, c-format
+msgid "unable to load pack: '%s', disabling pack-reuse"
+msgstr ""
+"не вдалося завантажити пакунок: \"%s\", вимкнення повторного використання "
+"пакунків"
+
+msgid "unable to compute preferred pack, disabling pack-reuse"
+msgstr ""
+"не вдалося обчислити бажаний пакунок, вимкнення повторного використання "
+"пакунків"
+
+#, c-format
 msgid "object '%s' not found in type bitmaps"
 msgstr "обʼєкт \"%s\" не знайдено в типах bitmap"
 
@@ -18296,6 +18501,9 @@
 msgid "multi-pack-index reverse-index chunk is the wrong size"
 msgstr "multi-pack-index reverse-index шматок має невірний розмір"
 
+msgid "could not determine preferred pack"
+msgstr "не вдалося визначити бажаний пакунок"
+
 msgid "cannot both write and verify reverse index"
 msgstr "неможливо одночасно записувати та звіряти зворотний індекс"
 
@@ -18359,10 +18567,6 @@
 msgstr "%s очікує невід'ємне ціле значення з опціональним суфіксом k/m/g"
 
 #, c-format
-msgid "%s is incompatible with %s"
-msgstr "%s несумісний з %s"
-
-#, c-format
 msgid "ambiguous option: %s (could be --%s%s or --%s%s)"
 msgstr "неоднозначна опція: %s (може бути --%s%s або --%s%s)"
 
@@ -18469,7 +18673,7 @@
 
 #, c-format
 msgid "bad boolean environment value '%s' for '%s'"
-msgstr "невірне булеве значення конфігурації \"%s\" для \"%s\""
+msgstr "невірне булеве значення оточення \"%s\" для \"%s\""
 
 #, c-format
 msgid "failed to parse %s"
@@ -18684,10 +18888,6 @@
 msgstr "не вдалося додати \"%s\" до індексу"
 
 #, c-format
-msgid "unable to stat '%s'"
-msgstr "не вдалося виконати stat для \"%s\""
-
-#, c-format
 msgid "'%s' appears as both a file and as a directory"
 msgstr "\"%s\" відображається як файл і як каталог"
 
@@ -19261,10 +19461,6 @@
 msgstr "неможливо обробити \"%s\" і \"%s\" одночасно"
 
 #, c-format
-msgid "could not remove reference %s"
-msgstr "не вдалося видалити посилання %s"
-
-#, c-format
 msgid "could not delete reference %s: %s"
 msgstr "не вдалося видалити посилання %s: %s"
 
@@ -19273,6 +19469,79 @@
 msgstr "не вдалося видалити посилання: %s"
 
 #, c-format
+msgid "refname is dangerous: %s"
+msgstr "refname є небезпечним: %s"
+
+#, c-format
+msgid "trying to write ref '%s' with nonexistent object %s"
+msgstr "спроба записати посилання \"%s\" з неіснуючим обʼєктом %s"
+
+#, c-format
+msgid "trying to write non-commit object %s to branch '%s'"
+msgstr "спроба записати не коміт обʼєкт %s у гілку \"%s\""
+
+#, c-format
+msgid ""
+"multiple updates for 'HEAD' (including one via its referent '%s') are not "
+"allowed"
+msgstr ""
+"багаторазові оновлення для \"HEAD\" (включаючи через посилання з \"%s\") не "
+"дозволені"
+
+#, c-format
+msgid "cannot lock ref '%s': unable to resolve reference '%s'"
+msgstr ""
+"неможливо зафіксуваті посилання \"%s\": не вдалось розвʼязати посилання "
+"\"%s\""
+
+#, c-format
+msgid "cannot lock ref '%s': error reading reference"
+msgstr ""
+"неможливо зафіксувати посилання \"%s\": помилка при зчитуванні посилання"
+
+#, c-format
+msgid ""
+"multiple updates for '%s' (including one via symref '%s') are not allowed"
+msgstr ""
+"багаторазові оновлення для \"%s\" (включаючи символьні посилання з \"%s\") "
+"не дозволені"
+
+#, c-format
+msgid "cannot lock ref '%s': reference already exists"
+msgstr "неможливо зафіксувати посилання \"%s\": посилання вже існує"
+
+#, c-format
+msgid "cannot lock ref '%s': reference is missing but expected %s"
+msgstr ""
+"неможливо зафіксувати посилання \"%s\": посилання відсутнє, але очікуване %s"
+
+#, c-format
+msgid "cannot lock ref '%s': is at %s but expected %s"
+msgstr ""
+"неможливо зафіксувати посилання \"%s\": становить %s, але очікується %s"
+
+#, c-format
+msgid "reftable: transaction prepare: %s"
+msgstr "таблиця посилань: підготовка транзакції: \"%s\""
+
+#, c-format
+msgid "reftable: transaction failure: %s"
+msgstr "таблиця посилань: помилка транзакції: \"%s\""
+
+#, c-format
+msgid "unable to compact stack: %s"
+msgstr "не вдалося стиснути стек: %s"
+
+#, c-format
+msgid "refname %s not found"
+msgstr "назва посилання %s не знайдена"
+
+#, c-format
+msgid "refname %s is a symbolic ref, copying it is not supported"
+msgstr ""
+"назва посилання %s є символьним посиланням, копіювання якого не підтримується"
+
+#, c-format
 msgid "invalid refspec '%s'"
 msgstr "неприпустимий визначник посилання \"%s\""
 
@@ -19281,6 +19550,10 @@
 msgstr "неприпустимі лапки у значенні push-опції: \"%s\""
 
 #, c-format
+msgid "unknown value for object-format: %s"
+msgstr "невідоме значення для object-format: %s"
+
+#, c-format
 msgid "%sinfo/refs not valid: is this a git repository?"
 msgstr "%sinfo/refs не дійсні: це git сховище?"
 
@@ -19742,8 +20015,19 @@
 msgstr "resolve-undo записує \"%s\", який відсутній"
 
 #, c-format
-msgid "could not get commit for ancestry-path argument %s"
-msgstr "не вдалося отримати коміт для ancestry-path аргументу %s"
+msgid "%s exists but is a symbolic ref"
+msgstr "%s існує але є символьним посиланням"
+
+msgid ""
+"--merge requires one of the pseudorefs MERGE_HEAD, CHERRY_PICK_HEAD, "
+"REVERT_HEAD or REBASE_HEAD"
+msgstr ""
+"--merge вимагає одне з псевдопосилань MERGE_HEAD, CHERRY_PICK_HEAD, "
+"REVERT_HEAD або REBASE_HEAD"
+
+#, c-format
+msgid "could not get commit for --ancestry-path argument %s"
+msgstr "не вдалося отримати коміт для --ancestry-path аргументу %s"
 
 msgid "--unpacked=<packfile> no longer supported"
 msgstr "--unpacked=<файл пакунка> більше не підтримується"
@@ -20031,6 +20315,21 @@
 msgstr "невідома дія: %d"
 
 msgid ""
+"Resolve all conflicts manually, mark them as resolved with\n"
+"\"git add/rm <conflicted_files>\", then run \"git rebase --continue\".\n"
+"You can instead skip this commit: run \"git rebase --skip\".\n"
+"To abort and get back to the state before \"git rebase\", run \"git rebase --"
+"abort\"."
+msgstr ""
+"Вирішіть усі конфлікти вручну, позначте їх як вирішені за допомогою\n"
+"\"git add/rm <конфліктні_файли>\", а потім виконайте \"git rebase --"
+"continue\".\n"
+"Замість цього ви можете пропустити цей коміт: виконайте \"git rebase --"
+"skip\".\n"
+"Щоб перервати процес і повернутися до стану перед \"git rebase\", виконайте "
+"\"git rebase --abort\"."
+
+msgid ""
 "after resolving the conflicts, mark the corrected paths\n"
 "with 'git add <paths>' or 'git rm <paths>'"
 msgstr ""
@@ -20258,10 +20557,6 @@
 msgstr "не вдалося оновити %s"
 
 #, c-format
-msgid "could not parse commit %s"
-msgstr "не вдалося розібрати коміт %s"
-
-#, c-format
 msgid "could not parse parent commit %s"
 msgstr "не вдалося розібрати джерельний коміт %s"
 
@@ -20366,10 +20661,6 @@
 msgstr "неприпустима команда \"%.*s\""
 
 #, c-format
-msgid "%s does not accept arguments: '%s'"
-msgstr "%s не приймає аргументи: \"%s\""
-
-#, c-format
 msgid "missing arguments for %s"
 msgstr "відсутні аргументи для %s"
 
@@ -20651,6 +20942,9 @@
 msgid "Autostash exists; creating a new stash entry."
 msgstr "Автосхов існує; створення нового запису схову."
 
+msgid "autostash reference is a symref"
+msgstr "посилання автосхову є символьним посиланням"
+
 msgid "could not detach HEAD"
 msgstr "не вдалося відʼєднати HEAD"
 
@@ -20824,6 +21118,10 @@
 "конфігурацію"
 
 #, c-format
+msgid "'%s' already specified as '%s'"
+msgstr "\"%s\" вже зазначено як \"%s\""
+
+#, c-format
 msgid "Expected git repo version <= %d, found %d"
 msgstr "Очікувалось git сховищe версії <= %d, знайдено %d"
 
@@ -20972,6 +21270,10 @@
 msgstr "неприпустиме початкове ім’я гілки: \"%s\""
 
 #, c-format
+msgid "re-init: ignored --initial-branch=%s"
+msgstr "re-init: ігноровано --initial-branch=%s"
+
+#, c-format
 msgid "unable to handle file type %d"
 msgstr "не вдалося обробити тип файлу %d"
 
@@ -20982,15 +21284,15 @@
 msgid "attempt to reinitialize repository with different hash"
 msgstr "спроба переініціалізувати репозиторій з іншим хеш-алгоритмом"
 
+msgid ""
+"attempt to reinitialize repository with different reference storage format"
+msgstr "спроба переініціалізувати сховище з іншим форматом зберігання"
+
 #, c-format
 msgid "%s already exists"
 msgstr "%s вже існує"
 
 #, c-format
-msgid "re-init: ignored --initial-branch=%s"
-msgstr "re-init: ігноровано --initial-branch=%s"
-
-#, c-format
 msgid "Reinitialized existing shared Git repository in %s%s\n"
 msgstr "Переініціалізовано існуюче спільне Git сховище в %s%s\n"
 
@@ -21013,6 +21315,21 @@
 msgid "cannot use split index with a sparse index"
 msgstr "неможливо використовувати розділений індекс з розрідженим індексом"
 
+#. TRANSLATORS: The first %s is a command like "ls-tree".
+#, c-format
+msgid "bad %s format: element '%s' does not start with '('"
+msgstr "невірний формат %s: елемент \"%s\" не починається з \"(\""
+
+#. TRANSLATORS: The first %s is a command like "ls-tree".
+#, c-format
+msgid "bad %s format: element '%s' does not end in ')'"
+msgstr "невірний формат %s: елемент \"%s\" не закінчується на \")\""
+
+#. TRANSLATORS: %s is a command like "ls-tree".
+#, c-format
+msgid "bad %s format: %%%.*s"
+msgstr "невірний формат %s: %%%.*s"
+
 #. TRANSLATORS: IEC 80000-13:2008 gibibyte
 #, c-format
 msgid "%u.%2.2u GiB"
@@ -21261,12 +21578,6 @@
 msgstr ""
 "кількість записів у дереві кешу, які потрібно анулювати (за замовчуванням 0)"
 
-msgid "unhandled options"
-msgstr "необроблені опції"
-
-msgid "error preparing revisions"
-msgstr "помилка при підготовці ревізій"
-
 #, c-format
 msgid "commit %s is not marked reachable"
 msgstr "коміт %s не позначений як досяжний"
@@ -21351,29 +21662,6 @@
 msgid "empty trailer token in trailer '%.*s'"
 msgstr "порожній токен трейлера в трейлері \"%.*s\""
 
-#, c-format
-msgid "could not read input file '%s'"
-msgstr "не вдалося прочитати вхідний файл \"%s\""
-
-#, c-format
-msgid "could not stat %s"
-msgstr "не вдалося прочитати %s"
-
-#, c-format
-msgid "file %s is not a regular file"
-msgstr "файл %s не є звичайним файлом"
-
-#, c-format
-msgid "file %s is not writable by user"
-msgstr "файл %s не доступний для запису користувачем"
-
-msgid "could not open temporary file"
-msgstr "не вдалося відкрити тимчасовий файл"
-
-#, c-format
-msgid "could not rename temporary file to %s"
-msgstr "не вдалося перейменувати тимчасовий файл на %s"
-
 msgid "full write to remote helper failed"
 msgstr "не вдалося виконати повний запис до віддаленого помічника"
 
@@ -21423,9 +21711,6 @@
 msgid "invalid remote service path"
 msgstr "неприпустимий шлях до віддаленої служби"
 
-msgid "operation not supported by protocol"
-msgstr "операція не підтримується протоколом"
-
 #, c-format
 msgid "can't connect to subservice %s"
 msgstr "неможливо підключитися до підсервісу %s"
@@ -21472,8 +21757,8 @@
 msgstr "remote-helper не підтримує push; потрібен refspec"
 
 #, c-format
-msgid "helper %s does not support 'force'"
-msgstr "помічник %s не підтримує \"force\""
+msgid "helper %s does not support '--force'"
+msgstr "помічник %s не підтримує \"--force\""
 
 msgid "couldn't run fast-export"
 msgstr "не вдалося запустити fast-export"
@@ -21558,10 +21843,6 @@
 msgstr "підтримка протоколу v2 ще не запроваджена"
 
 #, c-format
-msgid "unknown value for config '%s': %s"
-msgstr "невідоме значення для конфігурації \"%s\": %s"
-
-#, c-format
 msgid "transport '%s' not allowed"
 msgstr "засіб передачі \"%s\" не дозволений"
 
@@ -21613,6 +21894,9 @@
 msgid "could not retrieve server-advertised bundle-uri list"
 msgstr "не вдалося отримати список адрес пакетів, оголошений сервером"
 
+msgid "operation not supported by protocol"
+msgstr "операція не підтримується протоколом"
+
 msgid "too-short tree object"
 msgstr "занадто короткий обʼєкт дерева"
 
@@ -21897,6 +22181,10 @@
 msgid "invalid '..' path segment"
 msgstr "неприпустимий \"..\" сегмент шляху"
 
+#, c-format
+msgid "error: unable to format message: %s\n"
+msgstr "помилка: не вдалося відформатувати допис: %s\n"
+
 msgid "usage: "
 msgstr "використання: "
 
@@ -22014,7 +22302,7 @@
 msgstr "не вдалося отримати випадкові байти"
 
 msgid "Unmerged paths:"
-msgstr "не злиті шляхи:"
+msgstr "Не злиті шляхи:"
 
 msgid "  (use \"git restore --staged <file>...\" to unstage)"
 msgstr ""
@@ -22466,6 +22754,10 @@
 msgid "cannot %s: Your index contains uncommitted changes."
 msgstr "неможливо виконати %s: Ваш індекс містить незакомічені зміни."
 
+#, c-format
+msgid "unknown style '%s' given for '%s'"
+msgstr "невідомий стиль \"%s\" наданий для \"%s\""
+
 msgid ""
 "Error: Your local changes to the following files would be overwritten by "
 "merge"
diff --git a/po/vi.po b/po/vi.po
index d673745..965e79e 100644
--- a/po/vi.po
+++ b/po/vi.po
@@ -2,32 +2,33 @@
 # Bản dịch tiếng Việt dành cho GIT-CORE.
 # This file is distributed under the same license as the git-core package.
 # https://raw.githubusercontent.com/git-l10n/git-po/pot/main/po/git.pot
+# Copyright (C) 2012-2022, Translation Project, Vietnamese Team <http://translationproject.org/team/vi.html>
+# Copyright (C) 2024, Vũ Tiến Hưng <newcomerminecraft@gmail.com>
 # Nguyễn Thái Ngọc Duy <pclouds@gmail.com>, 2012.
 # Đoàn Trần Công Danh <congdanhqx@gmail.com>, 2020.
 # Trần Ngọc Quân <vnwildman@gmail.com>, 2012-2022.
+# Vũ Tiến Hưng <newcomerminecraft@gmail.com>, 2024.
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: git v2.37.0\n"
+"Project-Id-Version: git 2.45\n"
 "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2022-06-21 20:20+0000\n"
-"PO-Revision-Date: 2022-06-25 08:37+0700\n"
-"Last-Translator: Trần Ngọc Quân <vnwildman@gmail.com>\n"
-"Language-Team: Vietnamese <translation-team-vi@lists.sourceforge.net>\n"
+"POT-Creation-Date: 2024-04-25 18:57+0000\n"
+"PO-Revision-Date: 2024-04-28 14:01+0700\n"
+"Last-Translator: Vũ Tiến Hưng <newcomerminecraft@gmail.com>\n"
+"Language-Team: Vietnamese <https://github.com/Nekosha/git-po>\n"
 "Language: vi\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=1; plural=0\n"
-"X-Language-Team-Website: <http://translationproject.org/team/vi.html>\n"
-"X-Generator: Gtranslator 42.0\n"
 
 #, c-format
 msgid "Huh (%s)?"
 msgstr "Hả (%s)?"
 
 msgid "could not read index"
-msgstr "không thể đọc bảng mục lục"
+msgstr "không thể đọc chỉ mục"
 
 msgid "binary"
 msgstr "nhị phân"
@@ -43,31 +44,31 @@
 
 #, c-format
 msgid "could not stage '%s'"
-msgstr "không thể đưa “%s” lên bệ phóng"
+msgstr "không thể đưa '%s' lên bệ phóng"
 
 msgid "could not write index"
-msgstr "không thể ghi bảng mục lục"
+msgstr "không thể ghi chỉ mục"
 
-#, c-format, perl-format
+#, c-format
 msgid "updated %d path\n"
 msgid_plural "updated %d paths\n"
 msgstr[0] "đã cập nhật %d đường dẫn\n"
 
-#, c-format, perl-format
+#, c-format
 msgid "note: %s is untracked now.\n"
-msgstr "chú ý: %s giờ đã bỏ theo dõi.\n"
+msgstr "chú ý: đã bỏ theo dõi %s.\n"
 
 #, c-format
 msgid "make_cache_entry failed for path '%s'"
-msgstr "make_cache_entry gặp lỗi đối với đường dẫn “%s”"
+msgstr "make_cache_entry gặp lỗi đối với đường dẫn '%s'"
 
 msgid "Revert"
 msgstr "Hoàn nguyên"
 
 msgid "Could not parse HEAD^{tree}"
-msgstr "Không thể phân tích cú pháp HEAD^{tree}"
+msgstr "Không hiểu cú pháp HEAD^{tree}"
 
-#, c-format, perl-format
+#, c-format
 msgid "reverted %d path\n"
 msgid_plural "reverted %d paths\n"
 msgstr[0] "đã hoàn nguyên %d đường dẫn\n"
@@ -77,33 +78,33 @@
 msgstr "Không có tập tin nào chưa được theo dõi.\n"
 
 msgid "Add untracked"
-msgstr "Thêm các cái chưa được theo dõi"
+msgstr "Thêm các tập tin chưa được theo dõi"
 
-#, c-format, perl-format
+#, c-format
 msgid "added %d path\n"
 msgid_plural "added %d paths\n"
 msgstr[0] "đã thêm %d đường dẫn\n"
 
 #, c-format
 msgid "ignoring unmerged: %s"
-msgstr "bỏ qua những thứ chưa hòa trộn: %s"
+msgstr "bỏ qua những tập tin chưa hòa trộn: %s"
 
 #, c-format
 msgid "Only binary files changed.\n"
-msgstr "Chỉ có các tập tin nhị phân là thay đổi.\n"
+msgstr "Chỉ có các tập tin nhị phân thay đổi.\n"
 
 #, c-format
 msgid "No changes.\n"
 msgstr "Không có thay đổi nào.\n"
 
 msgid "Patch update"
-msgstr "Cập nhật miếng vá"
+msgstr "Cập nhật bản vá"
 
 msgid "Review diff"
-msgstr "Xem xét lại diff"
+msgstr "Xem xét lại thay đổi"
 
 msgid "show paths with changes"
-msgstr "hiển thị đường dẫn với các thay đổi"
+msgstr "hiển thị các đường dẫn có thay đổi"
 
 msgid "add working tree state to the staged set of changes"
 msgstr ""
@@ -116,10 +117,10 @@
 "bản HEAD"
 
 msgid "pick hunks and update selectively"
-msgstr "chọn các “khúc” và cập nhật có tuyển chọn"
+msgstr "chọn các khúc và cập nhật có lựa chọn"
 
 msgid "view diff between HEAD and index"
-msgstr "xem khác biệt giữa HEAD và mục lục"
+msgstr "xem khác biệt giữa HEAD và chỉ mục"
 
 msgid "add contents of untracked files to the staged set of changes"
 msgstr ""
@@ -139,7 +140,7 @@
 msgstr "chọn nhiều vùng"
 
 msgid "select item based on unique prefix"
-msgstr "chọn mục dựa trên tiền tố duy nhất"
+msgstr "chọn mục dựa trên tiền tố độc nhất"
 
 msgid "unselect specified items"
 msgstr "bỏ chọn các mục đã cho"
@@ -151,7 +152,7 @@
 msgstr "(để trống) hoàn tất chọn lựa"
 
 msgid "select a numbered item"
-msgstr "tùy chọn mục bằng số"
+msgstr "lựa chọn mục bằng số"
 
 msgid "(empty) select nothing"
 msgstr "(để trống) không chọn gì"
@@ -172,25 +173,25 @@
 msgstr "đường-dẫn"
 
 msgid "could not refresh index"
-msgstr "không thể đọc lại bảng mục lục"
+msgstr "không thể đọc lại chỉ mục"
 
 #, c-format
 msgid "Bye.\n"
 msgstr "Tạm biệt.\n"
 
-#, c-format, perl-format
+#, c-format
 msgid "Stage mode change [y,n,q,a,d%s,?]? "
-msgstr "Thay đổi chế độ bệ phóng [y,n,q,a,d%s,?]? "
+msgstr "Đưa lên bệ phóng thay đổi chế độ [y,n,q,a,d%s,?]? "
 
-#, c-format, perl-format
+#, c-format
 msgid "Stage deletion [y,n,q,a,d%s,?]? "
-msgstr "Xóa khỏi bệ phóng [y,n,q,a,d%s,?]? "
+msgstr "Đưa lên bệ phóng thao tác xoá [y,n,q,a,d%s,?]? "
 
-#, c-format, perl-format
+#, c-format
 msgid "Stage addition [y,n,q,a,d%s,?]? "
-msgstr "Thêm vào bệ phóng [y,n,q,a,d%s,?]? "
+msgstr "Đưa lên bệ phóng thao tác thêm [y,n,q,a,d%s,?]? "
 
-#, c-format, perl-format
+#, c-format
 msgid "Stage this hunk [y,n,q,a,d%s,?]? "
 msgstr "Đưa lên bệ phóng khúc này [y,n,q,a,d%s,?]? "
 
@@ -198,7 +199,7 @@
 "If the patch applies cleanly, the edited hunk will immediately be marked for "
 "staging."
 msgstr ""
-"Nếu miếng vá được áp dụng sạch sẽ, khúc đã sửa sẽ ngay lập tức được đánh dấu "
+"Nếu bản vá được áp dụng hoàn toàn, khúc đã sửa sẽ ngay lập tức được đánh dấu "
 "để chuyển lên bệ phóng."
 
 msgid ""
@@ -210,24 +211,23 @@
 msgstr ""
 "y - đưa lên bệ phóng khúc này\n"
 "n - đừng đưa lên bệ phóng khúc này\n"
-"q - thoát; đừng đưa lên bệ phóng khúc này cũng như bất kỳ cái nào còn lại\n"
+"q - thoát; đừng đưa lên bệ phóng khúc này hay bất kỳ cái nào còn lại\n"
 "a - đưa lên bệ phóng khúc này và tất cả các khúc sau này trong tập tin\n"
-"d - đừng đưa lên bệ phóng khúc này cũng như bất kỳ cái nào còn lại trong tập "
-"tin\n"
+"d - đừng đưa lên bệ phóng khúc này hay bất kỳ cái nào còn lại trong tập tin\n"
 
-#, c-format, perl-format
+#, c-format
 msgid "Stash mode change [y,n,q,a,d%s,?]? "
-msgstr "Thay đổi chế độ tạm cất đi [y,n,q,a,d%s,?]? "
+msgstr "Tạm cất thay đổi chế độ [y,n,q,a,d%s,?]? "
 
-#, c-format, perl-format
+#, c-format
 msgid "Stash deletion [y,n,q,a,d%s,?]? "
-msgstr "Xóa tạm cất [y,n,q,a,d%s,?]? "
+msgstr "Tạm cất thao tác xoá [y,n,q,a,d%s,?]? "
 
-#, c-format, perl-format
+#, c-format
 msgid "Stash addition [y,n,q,a,d%s,?]? "
-msgstr "Thêm vào tạm cất [y,n,q,a,d%s,?]? "
+msgstr "Tạm cất thao tác thêm [y,n,q,a,d%s,?]? "
 
-#, c-format, perl-format
+#, c-format
 msgid "Stash this hunk [y,n,q,a,d%s,?]? "
 msgstr "Tạm cất khúc này [y,n,q,a,d%s,?]? "
 
@@ -235,7 +235,7 @@
 "If the patch applies cleanly, the edited hunk will immediately be marked for "
 "stashing."
 msgstr ""
-"Nếu miếng vá được áp dụng sạch sẽ, khúc đã sửa sẽ ngay lập tức được đánh dấu "
+"Nếu bản vá được áp dụng hoàn toàn, khúc đã sửa sẽ ngay lập tức được đánh dấu "
 "để tạm cất."
 
 msgid ""
@@ -247,23 +247,23 @@
 msgstr ""
 "y - tạm cất khúc này\n"
 "n - đừng tạm cất khúc này\n"
-"q - thoát; đừng tạm cất khúc này cũng như bất kỳ cái nào còn lại\n"
+"q - thoát; đừng tạm cất khúc này hay bất kỳ cái nào còn lại\n"
 "a - tạm cất khúc này và tất cả các khúc sau này trong tập tin\n"
-"d - đừng tạm cất khúc này cũng như bất kỳ cái nào còn lại trong tập tin\n"
+"d - đừng tạm cất khúc này hay bất kỳ cái nào còn lại trong tập tin\n"
 
-#, c-format, perl-format
+#, c-format
 msgid "Unstage mode change [y,n,q,a,d%s,?]? "
-msgstr "Thay đổi chế độ bỏ ra khỏi bệ phóng [y,n,q,a,d%s,?]? "
+msgstr "Bỏ ra khỏi bệ phóng thay đổi chế độ [y,n,q,a,d%s,?]? "
 
-#, c-format, perl-format
+#, c-format
 msgid "Unstage deletion [y,n,q,a,d%s,?]? "
-msgstr "Xóa bỏ việc bỏ ra khỏi bệ phóng [y,n,q,a,d%s,?]? "
+msgstr "Bỏ ra khỏi bệ phóng thao tác xoá [y,n,q,a,d%s,?]? "
 
-#, c-format, perl-format
+#, c-format
 msgid "Unstage addition [y,n,q,a,d%s,?]? "
-msgstr "Thêm vào việc bỏ ra khỏi bệ phóng [y,n,q,a,d%s,?]? "
+msgstr "Bỏ ra khỏi bệ phóng thao tác thêm [y,n,q,a,d%s,?]? "
 
-#, c-format, perl-format
+#, c-format
 msgid "Unstage this hunk [y,n,q,a,d%s,?]? "
 msgstr "Bỏ ra khỏi bệ phóng khúc này [y,n,q,a,d%s,?]? "
 
@@ -271,7 +271,7 @@
 "If the patch applies cleanly, the edited hunk will immediately be marked for "
 "unstaging."
 msgstr ""
-"Nếu miếng vá được áp dụng sạch sẽ, khúc đã sửa sẽ ngay lập tức được đánh dấu "
+"Nếu bản vá được áp dụng hoàn toàn, khúc đã sửa sẽ ngay lập tức được đánh dấu "
 "để bỏ ra khỏi bệ phóng."
 
 msgid ""
@@ -283,33 +283,32 @@
 msgstr ""
 "y - đưa ra khỏi bệ phóng khúc này\n"
 "n - đừng đưa ra khỏi bệ phóng khúc này\n"
-"q - thoát; đừng đưa ra khỏi bệ phóng khúc này cũng như bất kỳ cái nào còn "
-"lại\n"
+"q - thoát; đừng đưa ra khỏi bệ phóng khúc này hay bất kỳ cái nào còn lại\n"
 "a - đưa ra khỏi bệ phóng khúc này và tất cả các khúc sau này trong tập tin\n"
-"d - đừng đưa ra khỏi bệ phóng khúc này cũng như bất kỳ cái nào còn lại trong "
-"tập tin\n"
+"d - đừng đưa ra khỏi bệ phóng khúc này hay bất kỳ cái nào còn lại trong tập "
+"tin\n"
 
-#, c-format, perl-format
+#, c-format
 msgid "Apply mode change to index [y,n,q,a,d%s,?]? "
-msgstr "Áp dụng thay đổi chế độ cho mục lục [y,n,q,a,d%s,?]? "
+msgstr "Áp dụng thay đổi chế độ vào chỉ mục [y,n,q,a,d%s,?]? "
 
-#, c-format, perl-format
+#, c-format
 msgid "Apply deletion to index [y,n,q,a,d%s,?]? "
-msgstr "Áp dụng việc xóa vào mục lục [y,n,q,a,d%s,?]? "
+msgstr "Áp dụng thao tác xóa vào chỉ mục [y,n,q,a,d%s,?]? "
 
-#, c-format, perl-format
+#, c-format
 msgid "Apply addition to index [y,n,q,a,d%s,?]? "
-msgstr "Áp dụng các thêm vào mục lục [y,n,q,a,d%s,?]? "
+msgstr "Áp dụng thao tác thêm vào chỉ mục [y,n,q,a,d%s,?]? "
 
-#, c-format, perl-format
+#, c-format
 msgid "Apply this hunk to index [y,n,q,a,d%s,?]? "
-msgstr "Áo dụng khúc này vào mục lục [y,n,q,a,d%s,?]? "
+msgstr "Áo dụng khúc này vào chỉ mục [y,n,q,a,d%s,?]? "
 
 msgid ""
 "If the patch applies cleanly, the edited hunk will immediately be marked for "
 "applying."
 msgstr ""
-"Nếu miếng vá được áp dụng sạch sẽ, khúc đã sửa sẽ ngay lập tức được đánh dấu "
+"Nếu bản vá được áp dụng hoàn toàn, khúc đã sửa sẽ ngay lập tức được đánh dấu "
 "để áp dụng."
 
 msgid ""
@@ -319,25 +318,25 @@
 "a - apply this hunk and all later hunks in the file\n"
 "d - do not apply this hunk or any of the later hunks in the file\n"
 msgstr ""
-"y - áp dụng khúc này vào mục lục\n"
-"n - đừng áp dụng khúc này vào mục lục\n"
-"q - thoát; đừng áp dụng khúc này cũng như bất kỳ cái nào còn lại\n"
+"y - áp dụng khúc này vào chỉ mục\n"
+"n - đừng áp dụng khúc này vào chỉ mục\n"
+"q - thoát; đừng áp dụng khúc này hay bất kỳ cái nào còn lại\n"
 "a - áp dụng khúc này và tất cả các khúc sau này trong tập tin\n"
-"d - đừng áp dụng khúc này cũng như bất kỳ cái nào sau này trong tập tin\n"
+"d - đừng áp dụng khúc này hay bất kỳ cái nào sau này trong tập tin\n"
 
-#, c-format, perl-format
+#, c-format
 msgid "Discard mode change from worktree [y,n,q,a,d%s,?]? "
-msgstr "Loại bỏ các thay đổi chế độ từ cây làm việc [y,n,q,a,d%s,?]? "
+msgstr "Loại bỏ thay đổi chế độ khỏi cây làm việc [y,n,q,a,d%s,?]? "
 
-#, c-format, perl-format
+#, c-format
 msgid "Discard deletion from worktree [y,n,q,a,d%s,?]? "
-msgstr "Loại bỏ việc xóa khỏi cây làm việc [y,n,q,a,d%s,?]? "
+msgstr "Loại bỏ thao tác xóa khỏi cây làm việc [y,n,q,a,d%s,?]? "
 
-#, c-format, perl-format
+#, c-format
 msgid "Discard addition from worktree [y,n,q,a,d%s,?]? "
-msgstr "Thêm các loại bỏ khỏi cây làm việc [y,n,q,a,d%s,?]? "
+msgstr "Loại bỏ thao tác thêm khỏi cây làm việc [y,n,q,a,d%s,?]? "
 
-#, c-format, perl-format
+#, c-format
 msgid "Discard this hunk from worktree [y,n,q,a,d%s,?]? "
 msgstr "Loại bỏ khúc này khỏi cây làm việc [y,n,q,a,d%s,?]? "
 
@@ -345,7 +344,7 @@
 "If the patch applies cleanly, the edited hunk will immediately be marked for "
 "discarding."
 msgstr ""
-"Nếu miếng vá được áp dụng sạch sẽ, khúc đã sửa sẽ ngay lập tức được đánh dấu "
+"Nếu bản vá được áp dụng hoàn toàn, khúc đã sửa sẽ ngay lập tức được đánh dấu "
 "để loại bỏ."
 
 msgid ""
@@ -357,25 +356,25 @@
 msgstr ""
 "y - loại bỏ khúc này khỏi cây làm việc\n"
 "n - đừng loại bỏ khúc khỏi cây làm việc\n"
-"q - thoát; đừng loại bỏ khúc này cũng như bất kỳ cái nào còn lại\n"
+"q - thoát; đừng loại bỏ khúc này hay bất kỳ cái nào còn lại\n"
 "a - loại bỏ khúc này và tất cả các khúc sau này trong tập tin\n"
-"d - đừng loại bỏ khúc này cũng như bất kỳ cái nào sau này trong tập tin\n"
+"d - đừng loại bỏ khúc này hay bất kỳ cái nào sau này trong tập tin\n"
 
-#, c-format, perl-format
+#, c-format
 msgid "Discard mode change from index and worktree [y,n,q,a,d%s,?]? "
-msgstr "Loại bỏ thay đổi chế độ từ mục lục và cây làm việc [y,n,q,a,d%s,?]? "
+msgstr "Loại bỏ thay đổi chế độ khỏi chỉ mục và cây làm việc [y,n,q,a,d%s,?]? "
 
-#, c-format, perl-format
+#, c-format
 msgid "Discard deletion from index and worktree [y,n,q,a,d%s,?]? "
-msgstr "Loại bỏ việc xóa khỏi mục lục và cây làm việc [y,n,q,a,d%s,?]? "
+msgstr "Loại bỏ thao tác xóa khỏi chỉ mục và cây làm việc [y,n,q,a,d%s,?]? "
 
-#, c-format, perl-format
+#, c-format
 msgid "Discard addition from index and worktree [y,n,q,a,d%s,?]? "
-msgstr "Thêm các loại bỏ từ mục lục và cây làm việc [y,n,q,a,d%s,?]? "
+msgstr "Loại bỏ thao tác thêm khỏi chỉ mục và cây làm việc [y,n,q,a,d%s,?]? "
 
-#, c-format, perl-format
+#, c-format
 msgid "Discard this hunk from index and worktree [y,n,q,a,d%s,?]? "
-msgstr "Loại bỏ khúc này khỏi mục lục và cây làm việc [y,n,q,a,d%s,?]? "
+msgstr "Loại bỏ khúc này khỏi chỉ mục và cây làm việc [y,n,q,a,d%s,?]? "
 
 msgid ""
 "y - discard this hunk from index and worktree\n"
@@ -384,27 +383,27 @@
 "a - discard this hunk and all later hunks in the file\n"
 "d - do not discard this hunk or any of the later hunks in the file\n"
 msgstr ""
-"y - loại bỏ khúc này khỏi mục lục và cây làm việc\n"
-"n - đừng loại bỏ khúc khỏi mục lục và cây làm việc\n"
-"q - thoát; đừng loại bỏ khúc này cũng như bất kỳ cái nào còn lại\n"
+"y - loại bỏ khúc này khỏi chỉ mục và cây làm việc\n"
+"n - đừng loại bỏ khúc khỏi chỉ mục và cây làm việc\n"
+"q - thoát; đừng loại bỏ khúc này hay bất kỳ cái nào còn lại\n"
 "a - loại bỏ khúc này và tất cả các khúc sau này trong tập tin\n"
-"d - đừng loại bỏ khúc này cũng như bất kỳ cái nào sau này trong tập tin\n"
+"d - đừng loại bỏ khúc này hay bất kỳ cái nào sau này trong tập tin\n"
 
-#, c-format, perl-format
+#, c-format
 msgid "Apply mode change to index and worktree [y,n,q,a,d%s,?]? "
-msgstr "Áp dụng thay đổi chế độ cho mục lục và cây làm việc [y,n,q,a,d%s,?]? "
+msgstr "Áp dụng thay đổi chế độ cho chỉ mục và cây làm việc [y,n,q,a,d%s,?]? "
 
-#, c-format, perl-format
+#, c-format
 msgid "Apply deletion to index and worktree [y,n,q,a,d%s,?]? "
-msgstr "Áp dụng việc xóa vào mục lục và cây làm việc [y,n,q,a,d%s,?]? "
+msgstr "Áp dụng thao tác xóa vào chỉ mục và cây làm việc [y,n,q,a,d%s,?]? "
 
-#, c-format, perl-format
+#, c-format
 msgid "Apply addition to index and worktree [y,n,q,a,d%s,?]? "
-msgstr "Áp dụng thêm vào mục lục và cây làm việc [y,n,q,a,d%s,?]? "
+msgstr "Áp dụng thao tác thêm vào chỉ mục và cây làm việc [y,n,q,a,d%s,?]? "
 
-#, c-format, perl-format
+#, c-format
 msgid "Apply this hunk to index and worktree [y,n,q,a,d%s,?]? "
-msgstr "Áp dụng khúc này vào mục lục và cây làm việc [y,n,q,a,d%s,?]? "
+msgstr "Áp dụng khúc này vào chỉ mục và cây làm việc [y,n,q,a,d%s,?]? "
 
 msgid ""
 "y - apply this hunk to index and worktree\n"
@@ -413,11 +412,27 @@
 "a - apply this hunk and all later hunks in the file\n"
 "d - do not apply this hunk or any of the later hunks in the file\n"
 msgstr ""
-"y - áp dụng khúc này vào mục lục và cây làm việc\n"
-"n - đừng áp dụng khúc vào mục lục và cây làm việc\n"
-"q - thoát; đừng áp dụng khúc này cũng như bất kỳ cái nào còn lại\n"
+"y - áp dụng khúc này vào chỉ mục và cây làm việc\n"
+"n - đừng áp dụng khúc vào chỉ mục và cây làm việc\n"
+"q - thoát; đừng áp dụng khúc này hay bất kỳ cái nào còn lại\n"
 "a - áp dụng khúc này và tất cả các khúc sau này trong tập tin\n"
-"d - đừng áp dụng khúc này cũng như bất kỳ cái nào sau này trong tập tin\n"
+"d - đừng áp dụng khúc này hay bất kỳ cái nào sau này trong tập tin\n"
+
+#, c-format
+msgid "Apply mode change to worktree [y,n,q,a,d%s,?]? "
+msgstr "Áp dụng thay đổi chế độ cho cây làm việc [y,n,q,a,d%s,?]? "
+
+#, c-format
+msgid "Apply deletion to worktree [y,n,q,a,d%s,?]? "
+msgstr "Áp dụng thao tác xóa cho cây làm việc [y,n,q,a,d%s,?]? "
+
+#, c-format
+msgid "Apply addition to worktree [y,n,q,a,d%s,?]? "
+msgstr "Áp dụng thao tác thêm cho cây làm việc [y,n,q,a,d%s,?]? "
+
+#, c-format
+msgid "Apply this hunk to worktree [y,n,q,a,d%s,?]? "
+msgstr "Áp dụng khúc này vào cây làm việc [y,n,q,a,d%s,?]? "
 
 msgid ""
 "y - apply this hunk to worktree\n"
@@ -428,36 +443,32 @@
 msgstr ""
 "y - áp dụng khúc này vào cây làm việc\n"
 "n - đừng áp dụng khúc vào cây làm việc\n"
-"q - thoát; đừng áp dụng khúc này cũng như bất kỳ cái nào còn lại\n"
+"q - thoát; đừng áp dụng khúc này hay bất kỳ cái nào còn lại\n"
 "a - áp dụng khúc này và tất cả các khúc sau này trong tập tin\n"
-"d - đừng áp dụng khúc này cũng như bất kỳ cái nào sau này trong tập tin\n"
+"d - đừng áp dụng khúc này hay bất kỳ cái nào sau này trong tập tin\n"
 
 #, c-format
 msgid "could not parse hunk header '%.*s'"
-msgstr "không thể phân tích cú pháp phần đầu của khúc “%.*s”"
-
-#, c-format
-msgid "could not parse colored hunk header '%.*s'"
-msgstr "không thể phân tích cú pháp phần đầu khúc đã tô màu “%.*s”"
+msgstr "không thể đọc phần đầu của khúc '%.*s'"
 
 msgid "could not parse diff"
-msgstr "không thể phân tích cú pháp khác biệt"
+msgstr "không thể đọc diff"
 
 msgid "could not parse colored diff"
-msgstr "không thể phân tích khác biệt được tô màu"
+msgstr "không thể đọc diff có màu"
 
 #, c-format
 msgid "failed to run '%s'"
-msgstr "gặp lỗi khi chạy “%s”"
+msgstr "gặp lỗi khi chạy '%s'"
 
 msgid "mismatched output from interactive.diffFilter"
-msgstr "đầu ra không khớp từ interactive.diffFilter"
+msgstr "đầu ra không khớp nhau từ interactive.diffFilter"
 
 msgid ""
 "Your filter must maintain a one-to-one correspondence\n"
 "between its input and output lines."
 msgstr ""
-"Bộ lọc của bạn phải duy trì một quan hệ một-đến-một\n"
+"Bộ lọc của bạn phải duy trì quan hệ một-một\n"
 "giữa các dòng đầu vào và đầu ra của nó."
 
 #, c-format
@@ -465,7 +476,7 @@
 "expected context line #%d in\n"
 "%.*s"
 msgstr ""
-"cần dòng ngữ cảnh #%d trong\n"
+"cần dòng ngữ cảnh số %d trong\n"
 "%.*s"
 
 #, c-format
@@ -481,51 +492,42 @@
 "%.*s"
 
 msgid "Manual hunk edit mode -- see bottom for a quick guide.\n"
-msgstr "Chế độ sửa khúc bằng tay -- xem ở đáy để có hướng dẫn sử dụng nhanh.\n"
+msgstr ""
+"Chế độ sửa khúc bằng tay -- xem ở dưới để có hướng dẫn sử dụng nhanh.\n"
 
 #, c-format
 msgid ""
 "---\n"
 "To remove '%c' lines, make them ' ' lines (context).\n"
 "To remove '%c' lines, delete them.\n"
-"Lines starting with %c will be removed.\n"
+"Lines starting with %s will be removed.\n"
 msgstr ""
 "---\n"
-"Để gỡ bỏ dòng “%c”, sửa chúng thành những dòng “ ” (ngữ cảnh).\n"
-"Để gõ bỏ dòng “%c”, xóa chúng đi.\n"
-"Những dòng bắt đầu bằng %c sẽ bị loại bỏ.\n"
+"Để gỡ bỏ dòng '%c', sửa chúng thành những dòng ' ' (ngữ cảnh).\n"
+"Để gõ bỏ dòng '%c', xóa chúng đi.\n"
+"Những dòng bắt đầu bằng %s sẽ bị loại bỏ.\n"
 
-#. #-#-#-#-#  git-add--interactive.perl.po  #-#-#-#-#
-#. TRANSLATORS: 'it' refers to the patch mentioned in the previous messages.
 msgid ""
 "If it does not apply cleanly, you will be given an opportunity to\n"
 "edit again.  If all lines of the hunk are removed, then the edit is\n"
 "aborted and the hunk is left unchanged.\n"
 msgstr ""
-"Nếu miếng vá không được áp dụng sạch sẽ, bạn sẽ có một cơ hội\n"
-"để sửa lần nữa. Nếu mọi dòng của khúc bị xóa bỏ, thế thì những\n"
-"sửa dổi sẽ bị loại bỏ, và khúc vẫn giữ nguyên.\n"
+"Nếu bản vá không được áp dụng hoàn toàn, bạn sẽ có cơ hội\n"
+"để sửa lại. Nếu mọi dòng của khúc bị xóa bỏ, thì những\n"
+"sửa đổi sẽ bị loại bỏ, và khúc vẫn giữ nguyên.\n"
 
 msgid "could not parse hunk header"
-msgstr "không thể phân tích cú pháp phần đầu khúc"
+msgstr "không hiểu cú pháp phần đầu khúc"
 
 msgid "'git apply --cached' failed"
-msgstr "“git apply --cached” gặp lỗi"
+msgstr "'git apply --cached' gặp lỗi"
 
-#. #-#-#-#-#  add-patch.c.po  #-#-#-#-#
 #. TRANSLATORS: do not translate [y/n]
 #. The program will only accept that input at this point.
 #. Consider translating (saying "no" discards!) as
 #. (saying "n" for "no" discards!) if the translation
 #. of the word "no" does not start with n.
 #.
-#. #-#-#-#-#  git-add--interactive.perl.po  #-#-#-#-#
-#. TRANSLATORS: do not translate [y/n]
-#. The program will only accept that input
-#. at this point.
-#. Consider translating (saying "no" discards!) as
-#. (saying "n" for "no" discards!) if the translation
-#. of the word "no" does not start with n.
 msgid ""
 "Your edited hunk does not apply. Edit again (saying \"no\" discards!) [y/n]? "
 msgstr ""
@@ -533,7 +535,7 @@
 "bỏ!) [y/n]? "
 
 msgid "The selected hunks do not apply to the index!"
-msgstr "Các khúc đã chọn không được áp dụng vào bảng mục lục!"
+msgstr "Các khúc đã chọn không được áp dụng vào chỉ mục!"
 
 msgid "Apply them to the worktree anyway? "
 msgstr "Vẫn áp dụng chúng cho cây làm việc? "
@@ -550,6 +552,7 @@
 "/ - search for a hunk matching the given regex\n"
 "s - split the current hunk into smaller hunks\n"
 "e - manually edit the current hunk\n"
+"p - print the current hunk\n"
 "? - print help\n"
 msgstr ""
 "j - để lại khúc này là chưa quyết định, xem khúc chưa quyết định kế tiếp\n"
@@ -557,9 +560,10 @@
 "k - để lại khúc này là chưa quyết định, xem khúc chưa quyết định kế trước\n"
 "K - để lại khúc này là chưa quyết định, xem khúc kế trước\n"
 "g - chọn một khúc muốn tới\n"
-"/ - tìm một khúc khớp với biểu thức chính quy đưa ra\n"
+"/ - tìm một khúc khớp với biểu thức chính quy\n"
 "s - chia khúc hiện tại thành các khúc nhỏ hơn\n"
 "e - sửa bằng tay khúc hiện hành\n"
+"p - in ra khúc hiện hành\n"
 "? - hiển thị trợ giúp\n"
 
 msgid "No previous hunk"
@@ -569,48 +573,48 @@
 msgstr "Không có khúc kế tiếp"
 
 msgid "No other hunks to goto"
-msgstr "Không còn khúc nào để mà nhảy đến"
+msgstr "Không còn khúc nào để nhảy đến"
 
 msgid "go to which hunk (<ret> to see more)? "
-msgstr "nhảy đến khúc nào (<ret> để xem thêm)? "
+msgstr "nhảy đến khúc nào (<Enter> để xem thêm)? "
 
 msgid "go to which hunk? "
 msgstr "nhảy đến khúc nào? "
 
 #, c-format
 msgid "Invalid number: '%s'"
-msgstr "Số không hợp lệ: “%s”"
+msgstr "Số không hợp lệ: '%s'"
 
 #, c-format
 msgid "Sorry, only %d hunk available."
 msgid_plural "Sorry, only %d hunks available."
-msgstr[0] "Rất tiếc, chỉ có sẵn %d khúc."
+msgstr[0] "Chỉ có %d khúc."
 
 msgid "No other hunks to search"
-msgstr "Không còn khúc nào để mà tìm kiếm"
+msgstr "Không còn khúc nào để tìm kiếm"
 
 msgid "search for regex? "
-msgstr "tìm kiếm cho biểu thức chính quy? "
+msgstr "tìm kiếm cho biểu thức chính quy (regex)? "
 
 #, c-format
 msgid "Malformed search regexp %s: %s"
-msgstr "Định dạng tìm kiếm của biểu thức chính quy không đúng %s: %s"
+msgstr "Định dạng tìm kiếm của biểu thức chính quy (regex) bất thường %s: %s"
 
 msgid "No hunk matches the given pattern"
 msgstr "Không thấy khúc nào khớp mẫu đã cho"
 
 msgid "Sorry, cannot split this hunk"
-msgstr "Rất tiếc, không thể chia nhỏ khúc này"
+msgstr "Không thể chia nhỏ khúc này"
 
 #, c-format
 msgid "Split into %d hunks."
-msgstr "Chi nhỏ thành %d khúc."
+msgstr "Chia nhỏ thành %d khúc."
 
 msgid "Sorry, cannot edit this hunk"
-msgstr "Rất tiếc, không thể sửa khúc này"
+msgstr "Không thể sửa khúc này"
 
 msgid "'git apply' failed"
-msgstr "“git apply” gặp lỗi"
+msgstr "'git apply' gặp lỗi"
 
 #, c-format
 msgid ""
@@ -621,47 +625,41 @@
 "Tắt lời nhắn này bằng \"git config advice.%s false\""
 
 #, c-format
-msgid "%shint: %.*s%s\n"
-msgstr "%sgợi ý: %.*s%s\n"
+msgid "%shint:%s%.*s%s\n"
+msgstr "%sgợi ý:%s%.*s%s\n"
 
 msgid "Cherry-picking is not possible because you have unmerged files."
 msgstr ""
-"Cherry-picking là không thể thực hiện bởi vì bạn có những tập tin chưa được "
-"hòa trộn."
+"Không thể thực hiện cherry-pick vì bạn có những tập tin chưa được hòa trộn."
 
 msgid "Committing is not possible because you have unmerged files."
 msgstr ""
-"Không thể thực hiện chuyển giao được bởi vì bạn có những tập tin chưa được "
-"hòa trộn."
+"Không thể thực hiện chuyển giao vì bạn có những tập tin chưa được hòa trộn."
 
 msgid "Merging is not possible because you have unmerged files."
 msgstr ""
-"Không thể thực hiện hòa trộn bởi vì bạn có những tập tin chưa được hòa trộn."
+"Không thể thực hiện hòa trộn vì bạn có những tập tin chưa được hòa trộn."
 
 msgid "Pulling is not possible because you have unmerged files."
-msgstr ""
-"Không thể thực hiện kéo về bởi vì bạn có những tập tin chưa được hòa trộn."
+msgstr "Không thể thực hiện kéo về vì bạn có những tập tin chưa được hòa trộn."
 
 msgid "Reverting is not possible because you have unmerged files."
 msgstr ""
-"Không thể thực hiện hoàn nguyên bởi vì bạn có những tập tin chưa được hòa "
-"trộn."
+"Không thể thực hiện hoàn nguyên vì bạn có những tập tin chưa được hòa trộn."
 
-#, c-format
-msgid "It is not possible to %s because you have unmerged files."
+msgid "Rebasing is not possible because you have unmerged files."
 msgstr ""
-"Việc này không thể thực hiện với %s bởi vì bạn có những tập tin chưa được "
-"hòa trộn."
+"Không thể thực hiện hoàn nguyên vì bạn có những tập tin chưa được hòa trộn."
 
 msgid ""
 "Fix them up in the work tree, and then use 'git add/rm <file>'\n"
 "as appropriate to mark resolution and make a commit."
 msgstr ""
-"Sửa chúng trong cây làm việc, và sau đó dùng lệnh “git add/rm <tập-tin>”\n"
-"dành riêng cho việc đánh dấu cần giải quyết và tạo lần chuyển giao."
+"Sửa chúng trong cây làm việc, và sau đó dùng lệnh 'git add/rm <tập-tin>'\n"
+"để chọn cách giải quyết và tiến hành chuyển giao."
 
 msgid "Exiting because of an unresolved conflict."
-msgstr "Thoát ra bởi vì xung đột không thể giải quyết."
+msgstr "Thoát vì không thể giải quyết xung đột."
 
 msgid "You have not concluded your merge (MERGE_HEAD exists)."
 msgstr "Bạn chưa kết thúc việc hòa trộn (MERGE_HEAD vẫn tồn tại)."
@@ -670,10 +668,27 @@
 msgstr "Vui lòng chuyển giao các thay đổi trước khi hòa trộn."
 
 msgid "Exiting because of unfinished merge."
-msgstr "Thoát ra bởi vì việc hòa trộn không hoàn tất."
+msgstr "Thoát vì việc hòa trộn còn dang dở."
+
+msgid ""
+"Diverging branches can't be fast-forwarded, you need to either:\n"
+"\n"
+"\tgit merge --no-ff\n"
+"\n"
+"or:\n"
+"\n"
+"\tgit rebase\n"
+msgstr ""
+"Không thể chuyển-tiếp-nhanh các nhánh phân kỳ, bạn cần dùng:\n"
+"\n"
+"\tgit merge --no-ff\n"
+"\n"
+"hoặc:\n"
+"\n"
+"\tgit rebase\n"
 
 msgid "Not possible to fast-forward, aborting."
-msgstr "Thực hiện lệnh chuyển-tiếp-nhanh là không thể được, đang bỏ qua."
+msgstr "Không thể chuyển-tiếp-nhanh, đang huỷ lệnh."
 
 #, c-format
 msgid ""
@@ -683,7 +698,7 @@
 msgstr ""
 "Các đường dẫn và/hoặc đặc tả đường dẫn sau đây khớp với các đường dẫn tồn "
 "tại\n"
-"bên ngoài định nghĩa “sparse-checkout” của bạn, vì vậy sẽ không\n"
+"bên ngoài định nghĩa 'sparse-checkout' của bạn, vì vậy sẽ không\n"
 "cập nhật trong chỉ mục:\n"
 
 msgid ""
@@ -693,7 +708,7 @@
 msgstr ""
 "Nếu bạn có ý định cập nhật các mục như vậy, hãy thử một trong các mục sau:\n"
 "* Sử dụng tùy chọn --sparse.\n"
-"* Vô hiệu hóa hoặc sửa đổi các quy tắc thưa thớt."
+"* Vô hiệu hóa hoặc sửa đổi sparse rules (luật thưa)."
 
 #, c-format
 msgid ""
@@ -716,14 +731,14 @@
 "false\n"
 "\n"
 msgstr ""
-"Chú ý: đang chuyển sang “%s”.\n"
+"Chú ý: đang chuyển sang '%s'.\n"
 "\n"
-"Bạn đang ở tình trạng “detached HEAD”. Bạn có thể xem qua, tạo các thay\n"
-"đổi thử nghiệm và chuyển giao chúng, bạn có thể loại bỏ bất kỳ lần chuyển\n"
-"giao nào trong tình trạng này mà không cần đụng chạm đến bất kỳ nhánh nào\n"
+"Bạn đang ở tình trạng 'detached HEAD'. Bạn có thể xem qua, tạo và\n"
+"chuyển giao các thay đổi thử nghiệm, và bạn có thể loại bỏ các lần chuyển\n"
+"giao trong trạng thái này mà không ảnh hưởng đến bất kỳ nhánh nào\n"
 "bằng cách chuyển trở lại một nhánh.\n"
 "\n"
-"Nếu bạn muốn tạo một nhánh mới để giữ lại các lần chuyển giao bạn tạo,\n"
+"Nếu bạn muốn tạo một nhánh mới để giữ lại các lần chuyển giao đã tạo,\n"
 "bạn có thể làm thế (ngay bây giờ hay sau này) bằng cách dùng tùy chọn\n"
 "dòng lệnh -c. Ví dụ:\n"
 "\n"
@@ -736,19 +751,41 @@
 "Tắt hướng dẫn này bằng cách đặt biến advice.detachedHead thành false\n"
 "\n"
 
+#, c-format
+msgid ""
+"The following paths have been moved outside the\n"
+"sparse-checkout definition but are not sparse due to local\n"
+"modifications.\n"
+msgstr ""
+"Các đường dẫn sau đã được di chuyển ra ngoài định nghĩa\n"
+"sparse-checkout nhưng không còn thuộc loại sparse (thưa) vì có\n"
+"thay đổi nội bộ.\n"
+
+msgid ""
+"To correct the sparsity of these paths, do the following:\n"
+"* Use \"git add --sparse <paths>\" to update the index\n"
+"* Use \"git sparse-checkout reapply\" to apply the sparsity rules"
+msgstr ""
+"Để sửa lại đúng loại sprase (thưa) của các tập này, hãy thực hiện:\n"
+"* Chạy \"git add --sparse <đường-dẫn>\" để cập nhật chỉ mục\n"
+"* Chạy \"git sparse-checkout reapply\" để áp dụng luật thưa"
+
 msgid "cmdline ends with \\"
-msgstr "cmdline kết thúc với \\"
+msgstr "cuối dòng lệnh có \\"
 
 msgid "unclosed quote"
 msgstr "chưa có dấu nháy đóng"
 
+msgid "too many arguments"
+msgstr "có quá nhiều đối số"
+
 #, c-format
 msgid "unrecognized whitespace option '%s'"
-msgstr "không nhận ra tùy chọn về khoảng trắng “%s”"
+msgstr "không nhận ra tùy chọn về khoảng trắng '%s'"
 
 #, c-format
 msgid "unrecognized whitespace ignore option '%s'"
-msgstr "không nhận ra tùy chọn bỏ qua khoảng trắng “%s”"
+msgstr "không nhận ra tùy chọn bỏ qua khoảng trắng '%s'"
 
 #, c-format
 msgid "options '%s' and '%s' cannot be used together"
@@ -756,13 +793,17 @@
 
 #, c-format
 msgid "'%s' outside a repository"
-msgstr "'%s' ở ngoài một kho chứa"
+msgstr "'%s' ở ngoài kho chứa"
+
+msgid "failed to read patch"
+msgstr "gặp lỗi khi đọc bản vá"
+
+msgid "patch too large"
+msgstr "bản vá quá lớn"
 
 #, c-format
 msgid "Cannot prepare timestamp regexp %s"
-msgstr ""
-"Không thể chuẩn bị biểu thức chính qui dấu vết thời gian (timestamp regexp) "
-"%s"
+msgstr "Không thể chuẩn bị biểu thức chính quy dấu thời gian%s"
 
 #, c-format
 msgid "regexec returned %d for input: %s"
@@ -770,12 +811,11 @@
 
 #, c-format
 msgid "unable to find filename in patch at line %d"
-msgstr "không thể tìm thấy tên tập tin trong miếng vá tại dòng %d"
+msgstr "không thể tìm thấy tên tập tin trong bản vá tại dòng %d"
 
 #, c-format
 msgid "git apply: bad git-diff - expected /dev/null, got %s on line %d"
-msgstr ""
-"git apply: git-diff sai - cần /dev/null, nhưng lại nhận được %s trên dòng %d"
+msgstr "git apply: git-diff sai - cần /dev/null, nhưng lại có %s trên dòng %d"
 
 #, c-format
 msgid "git apply: bad git-diff - inconsistent new filename on line %d"
@@ -787,7 +827,7 @@
 
 #, c-format
 msgid "git apply: bad git-diff - expected /dev/null on line %d"
-msgstr "git apply: git-diff sai - cần “/dev/null” trên dòng %d"
+msgstr "git apply: git-diff sai - cần '/dev/null' trên dòng %d"
 
 #, c-format
 msgid "invalid mode on line %d: %s"
@@ -795,7 +835,7 @@
 
 #, c-format
 msgid "inconsistent header lines %d and %d"
-msgstr "phần đầu mâu thuẫn dòng %d và %d"
+msgstr "phần đầu không nhất quán tại dòng %d và %d"
 
 #, c-format
 msgid ""
@@ -805,8 +845,8 @@
 "git diff header lacks filename information when removing %d leading pathname "
 "components (line %d)"
 msgstr[0] ""
-"phần đầu diff cho git  thiếu thông tin tên tập tin khi gỡ bỏ đi %d trong "
-"thành phần dẫn đầu tên của đường dẫn (dòng %d)"
+"phần đầu diff cho git thiếu thông tin tên tập tin khi xoá đi %d mục dẫn đầu "
+"trong tên của đường dẫn (dòng %d)"
 
 #, c-format
 msgid "git diff header lacks filename information (line %d)"
@@ -814,11 +854,11 @@
 
 #, c-format
 msgid "recount: unexpected line: %.*s"
-msgstr "chi tiết: dòng không cần: %.*s"
+msgstr "recount: dòng bất thường %.*s"
 
 #, c-format
 msgid "patch fragment without header at line %d: %.*s"
-msgstr "miếng vá phân mảnh mà không có phần đầu tại dòng %d: %.*s"
+msgstr "bản vá không có phần đầu tại dòng %d: %.*s"
 
 msgid "new file depends on old contents"
 msgstr "tập tin mới phụ thuộc vào nội dung cũ"
@@ -828,7 +868,7 @@
 
 #, c-format
 msgid "corrupt patch at line %d"
-msgstr "miếng vá hỏng tại dòng %d"
+msgstr "bản vá hỏng tại dòng %d"
 
 #, c-format
 msgid "new file %s depends on old contents"
@@ -844,15 +884,15 @@
 
 #, c-format
 msgid "corrupt binary patch at line %d: %.*s"
-msgstr "miếng vá định dạng nhị phân sai hỏng tại dòng %d: %.*s"
+msgstr "bản vá nhị phân hỏng tại dòng %d: %.*s"
 
 #, c-format
 msgid "unrecognized binary patch at line %d"
-msgstr "miếng vá định dạng nhị phân không được nhận ra tại dòng %d"
+msgstr "bản vá nhị phân không thể nhận diện tại dòng %d"
 
 #, c-format
 msgid "patch with only garbage at line %d"
-msgstr "vá chỉ với “rác” tại dòng %d"
+msgstr "bản vá chứa 'rác' tại dòng %d"
 
 #, c-format
 msgid "unable to read symlink %s"
@@ -864,64 +904,59 @@
 
 #, c-format
 msgid "invalid start of line: '%c'"
-msgstr "sai khởi đầu dòng: “%c”"
+msgstr "sai khởi đầu dòng: '%c'"
 
 #, c-format
 msgid "Hunk #%d succeeded at %d (offset %d line)."
 msgid_plural "Hunk #%d succeeded at %d (offset %d lines)."
-msgstr[0] "Khối dữ liệu #%d thành công tại %d (offset %d dòng)."
+msgstr[0] "Khối thứ %d thành công tại %d (offset %d dòng)."
 
 #, c-format
 msgid "Context reduced to (%ld/%ld) to apply fragment at %d"
-msgstr "Ngữ cảnh bị giảm xuống còn (%ld/%ld) để áp dụng mảnh dữ liệu tại %d"
+msgstr "Ngữ cảnh bị giảm xuống còn (%ld/%ld) để áp dụng bản vá tại %d"
 
 #, c-format
 msgid ""
 "while searching for:\n"
 "%.*s"
 msgstr ""
-"trong khi đang tìm kiếm cho:\n"
+"trong khi đang tìm kiếm:\n"
 "%.*s"
 
 #, c-format
 msgid "missing binary patch data for '%s'"
-msgstr "thiếu dữ liệu của miếng vá định dạng nhị phân cho “%s”"
+msgstr "thiếu dữ liệu của bản vá nhị phân cho '%s'"
 
 #, c-format
 msgid "cannot reverse-apply a binary patch without the reverse hunk to '%s'"
-msgstr ""
-"không thể reverse-apply một miếng vá nhị phân mà không đảo ngược khúc thành "
-"“%s”"
+msgstr "không thể đảo ngược bản vá nhị phân mà không có khúc ngược cho '%s'"
 
 #, c-format
 msgid "cannot apply binary patch to '%s' without full index line"
 msgstr ""
-"không thể áp dụng miếng vá nhị phân thành “%s” mà không có dòng chỉ mục đầy "
-"đủ"
+"không thể áp dụng bản vá nhị phân cho '%s' mà không có dòng chỉ mục đầy đủ"
 
 #, c-format
 msgid ""
 "the patch applies to '%s' (%s), which does not match the current contents."
-msgstr ""
-"miếng vá áp dụng cho “%s” (%s), cái mà không khớp với các nội dung hiện tại."
+msgstr "bản vá áp dụng cho '%s' (%s), nhưng không khớp với nội dung hiện tại."
 
 #, c-format
 msgid "the patch applies to an empty '%s' but it is not empty"
-msgstr "miếng vá áp dụng cho một “%s” trống rỗng nhưng nó lại không trống"
+msgstr "bản vá áp dụng cho '%s' trống rỗng nhưng nó lại không trống"
 
 #, c-format
 msgid "the necessary postimage %s for '%s' cannot be read"
-msgstr "không thể đọc postimage %s cần thiết cho “%s”"
+msgstr "không thể đọc hậu ảnh %s cần thiết cho '%s'"
 
 #, c-format
 msgid "binary patch does not apply to '%s'"
-msgstr "miếng vá định dạng nhị phân không được áp dụng cho “%s”"
+msgstr "bản vá nhị phân không được áp dụng cho '%s'"
 
 #, c-format
 msgid "binary patch to '%s' creates incorrect result (expecting %s, got %s)"
 msgstr ""
-"vá nhị phân cho “%s” tạo ra kết quả không chính xác (mong chờ %s, lại nhận "
-"%s)"
+"bản vá nhị phân cho '%s' cho ra kết quả không chính xác (cần %s, lại nhận %s)"
 
 #, c-format
 msgid "patch failed: %s:%ld"
@@ -929,7 +964,7 @@
 
 #, c-format
 msgid "cannot checkout %s"
-msgstr "không thể lấy ra %s"
+msgstr "không thể checkout %s"
 
 #, c-format
 msgid "failed to read %s"
@@ -937,7 +972,7 @@
 
 #, c-format
 msgid "reading from '%s' beyond a symbolic link"
-msgstr "đọc từ “%s” vượt ra ngoài liên kết mềm"
+msgstr "đọc từ '%s' đứng sau liên kết mềm"
 
 #, c-format
 msgid "path %s has been renamed/deleted"
@@ -945,41 +980,42 @@
 
 #, c-format
 msgid "%s: does not exist in index"
-msgstr "%s: không tồn tại trong bảng mục lục"
+msgstr "%s: không tồn tại trong chỉ mục"
 
 #, c-format
 msgid "%s: does not match index"
-msgstr "%s: không khớp trong mục lục"
+msgstr "%s: không khớp với chỉ mục"
 
 msgid "repository lacks the necessary blob to perform 3-way merge."
-msgstr "kho thiếu đối tượng blob cần thiết để thực hiện hòa trộn “3-way”."
+msgstr ""
+"kho thiếu đối tượng blob cần thiết để thực hiện hòa trộn kiểu three-way."
 
 #, c-format
 msgid "Performing three-way merge...\n"
-msgstr "Đang thực hiện hòa trộn “3-đường”…\n"
+msgstr "Đang thực hiện hòa trộn three-way...\n"
 
 #, c-format
 msgid "cannot read the current contents of '%s'"
-msgstr "không thể đọc nội dung hiện hành của “%s”"
+msgstr "không thể đọc nội dung hiện hành của '%s'"
 
 #, c-format
 msgid "Failed to perform three-way merge...\n"
-msgstr "Gặp lỗi khi thực hiện hòa trộn kiểu “three-way”…\n"
+msgstr "Gặp lỗi khi thực hiện hòa trộn kiểu three-way...\n"
 
 #, c-format
 msgid "Applied patch to '%s' with conflicts.\n"
-msgstr "Đã áp dụng miếng vá %s với các xung đột.\n"
+msgstr "Áp dụng bản vá '%s' còn các xung đột.\n"
 
 #, c-format
 msgid "Applied patch to '%s' cleanly.\n"
-msgstr "Đã áp dụng miếng vá %s một cách sạch sẽ.\n"
+msgstr "Áp dụng bản vá %s một cách hoàn toàn.\n"
 
 #, c-format
 msgid "Falling back to direct application...\n"
-msgstr "Đang trở lại ứng dụng chi phối…\n"
+msgstr "Đang trở về cách áp dụng trực tiếp..\n"
 
 msgid "removal patch leaves file contents"
-msgstr "loại bỏ miếng vá để lại nội dung tập tin"
+msgstr "bản vá để lại tập tin còn nội dung"
 
 #, c-format
 msgid "%s: wrong type"
@@ -991,15 +1027,15 @@
 
 #, c-format
 msgid "invalid path '%s'"
-msgstr "đường dẫn không hợp lệ “%s”"
+msgstr "đường dẫn không hợp lệ '%s'"
 
 #, c-format
 msgid "%s: already exists in index"
-msgstr "%s: đã có từ trước trong bảng mục lục"
+msgstr "%s: đã sẵn có trong chỉ mục"
 
 #, c-format
 msgid "%s: already exists in working directory"
-msgstr "%s: đã sẵn có trong thư mục đang làm việc"
+msgstr "%s: đã sẵn có trong thư mục làm việc"
 
 #, c-format
 msgid "new mode (%o) of %s does not match old mode (%o)"
@@ -1011,15 +1047,15 @@
 
 #, c-format
 msgid "affected file '%s' is beyond a symbolic link"
-msgstr "tập tin chịu tác động “%s” vượt ra ngoài liên kết mềm"
+msgstr "tập tin chịu tác động '%s' đứng sau liên kết mềm"
 
 #, c-format
 msgid "%s: patch does not apply"
-msgstr "%s: miếng vá không được áp dụng"
+msgstr "%s: bản vá không được áp dụng"
 
 #, c-format
 msgid "Checking patch %s..."
-msgstr "Đang kiểm tra miếng vá %s…"
+msgstr "Đang kiểm tra bản vá %s..."
 
 #, c-format
 msgid "sha1 information is lacking or useless for submodule %s"
@@ -1027,35 +1063,35 @@
 
 #, c-format
 msgid "mode change for %s, which is not in current HEAD"
-msgstr "thay đổi chế độ cho %s, cái mà không phải là HEAD hiện tại"
+msgstr "thay đổi chế độ cho %s, nhưng nó không nằm trong HEAD hiện tại"
 
 #, c-format
 msgid "sha1 information is lacking or useless (%s)."
-msgstr "thông tin sha1 còn thiếu hay không dùng được(%s)."
+msgstr "thông tin sha1 còn thiếu hay không dùng được (%s)."
 
 #, c-format
 msgid "could not add %s to temporary index"
-msgstr "không thể thêm %s vào chỉ mục tạm thời"
+msgstr "không thể thêm %s vào chỉ mục tạm"
 
 #, c-format
 msgid "could not write temporary index to %s"
-msgstr "không thể ghi mục lục tạm vào %s"
+msgstr "không thể ghi chỉ mục tạm vào %s"
 
 #, c-format
 msgid "unable to remove %s from index"
-msgstr "không thể gỡ bỏ %s từ mục lục"
+msgstr "không thể gỡ bỏ %s từ chỉ mục"
 
 #, c-format
 msgid "corrupt patch for submodule %s"
-msgstr "miếng vá sai hỏng cho mô-đun-con %s"
+msgstr "bản vá hỏng cho mô-đun-con %s"
 
 #, c-format
 msgid "unable to stat newly created file '%s'"
-msgstr "không thể lấy thống kê về tập tin %s mới hơn đã được tạo"
+msgstr "không thể stat tập tin '%s' mới tạo"
 
 #, c-format
 msgid "unable to create backing store for newly created file %s"
-msgstr "không thể tạo “kho lưu đằng sau” cho tập tin được tạo mới hơn %s"
+msgstr "không thể tạo 'backing store' cho tập tin mới tạo %s"
 
 #, c-format
 msgid "unable to add cache entry for %s"
@@ -1063,19 +1099,19 @@
 
 #, c-format
 msgid "failed to write to '%s'"
-msgstr "gặp lỗi khi ghi vào “%s”"
+msgstr "gặp lỗi khi ghi vào '%s'"
 
 #, c-format
 msgid "closing file '%s'"
-msgstr "đang đóng tập tin “%s”"
+msgstr "đang đóng tập tin '%s'"
 
 #, c-format
 msgid "unable to write file '%s' mode %o"
-msgstr "không thể ghi vào tập tin “%s” chế độ %o"
+msgstr "không thể ghi vào tập tin '%s' chế độ %o"
 
 #, c-format
 msgid "Applied patch %s cleanly."
-msgstr "Đã áp dụng miếng vá %s một cách sạch sẽ."
+msgstr "Đã áp dụng bản vá %s một cách hoàn toàn."
 
 msgid "internal error"
 msgstr "lỗi nội bộ"
@@ -1083,43 +1119,43 @@
 #, c-format
 msgid "Applying patch %%s with %d reject..."
 msgid_plural "Applying patch %%s with %d rejects..."
-msgstr[0] "Đang áp dụng miếng vá %%s với %d lần từ chối…"
-
-#, c-format
-msgid "truncating .rej filename to %.*s.rej"
-msgstr "đang cắt ngắn tên tập tin .rej thành %.*s.rej"
+msgstr[0] "Đang áp dụng bản vá %%s với %d lần từ chối..."
 
 #, c-format
 msgid "cannot open %s"
-msgstr "không mở được “%s”"
+msgstr "không thể mở '%s'"
+
+#, c-format
+msgid "cannot unlink '%s'"
+msgstr "không thể unlink '%s'"
 
 #, c-format
 msgid "Hunk #%d applied cleanly."
-msgstr "Khối nhớ #%d được áp dụng gọn gàng."
+msgstr "Khúc #%d được áp dụng hoàn toàn."
 
 #, c-format
 msgid "Rejected hunk #%d."
-msgstr "Đoạn dữ liệu #%d bị từ chối."
+msgstr "Khúc #%d bị từ chối."
 
 #, c-format
 msgid "Skipped patch '%s'."
-msgstr "Bỏ qua đường dẫn “%s”."
+msgstr "Bỏ qua đường dẫn '%s'."
 
 msgid "No valid patches in input (allow with \"--allow-empty\")"
 msgstr ""
-"Không có miếng vá hợp lệ nào trong đầu vào (cho phép với \"--allow-empty\")"
+"Không có bản vá hợp lệ nào trong đầu vào (cho phép với \"--allow-empty\")"
 
 msgid "unable to read index file"
-msgstr "không thể đọc tập tin lưu bảng mục lục"
+msgstr "không thể đọc tập tin chỉ mục"
 
 #, c-format
 msgid "can't open patch '%s': %s"
-msgstr "không thể mở miếng vá “%s”: %s"
+msgstr "không thể mở bản vá '%s': %s"
 
 #, c-format
 msgid "squelched %d whitespace error"
 msgid_plural "squelched %d whitespace errors"
-msgstr[0] "đã chấm dứt %d lỗi khoảng trắng"
+msgstr[0] "đã xử lý %d lỗi khoảng trắng"
 
 #, c-format
 msgid "%d line adds whitespace errors."
@@ -1132,7 +1168,7 @@
 msgstr[0] "%d dòng được áp dụng sau khi sửa các lỗi khoảng trắng."
 
 msgid "Unable to write new index file"
-msgstr "Không thể ghi tập tin lưu bảng mục lục mới"
+msgstr "Không thể ghi tập tin chỉ mục mới"
 
 msgid "don't apply changes matching the given path"
 msgstr "không áp dụng các thay đổi khớp với đường dẫn đã cho"
@@ -1144,52 +1180,46 @@
 msgstr "số"
 
 msgid "remove <num> leading slashes from traditional diff paths"
-msgstr "gỡ bỏ <số> dấu gạch chéo dẫn đầu từ đường dẫn diff cổ điển"
+msgstr "gỡ bỏ <số> dấu gạch chéo dẫn đầu từ đường dẫn diff"
 
 msgid "ignore additions made by the patch"
-msgstr "lờ đi phần bổ xung được tạo ra bởi miếng vá"
+msgstr "bỏ qua các bổ sung trong bản vá"
 
 msgid "instead of applying the patch, output diffstat for the input"
-msgstr ""
-"thay vì áp dụng một miếng vá, kết xuất kết quả từ lệnh diffstat cho đầu ra"
+msgstr "thay vì áp dụng bản vá, xuất kết quả diffstat cho đầu vào"
 
 msgid "show number of added and deleted lines in decimal notation"
-msgstr ""
-"hiển thị số lượng các dòng được thêm vào và xóa đi theo ký hiệu thập phân"
+msgstr "hiển thị số lượng các dòng được thêm vào và xóa đi theo hệ thập phân"
 
 msgid "instead of applying the patch, output a summary for the input"
-msgstr "thay vì áp dụng một miếng vá, kết xuất kết quả cho đầu vào"
+msgstr "thay vì áp dụng bản vá, xuất tóm tắt kết quả cho đầu vào"
 
 msgid "instead of applying the patch, see if the patch is applicable"
-msgstr "thay vì áp dụng miếng vá, hãy xem xem miếng vá có thích hợp không"
+msgstr "thay vì áp dụng bản vá, xem xem bản vá có thích hợp không"
 
 msgid "make sure the patch is applicable to the current index"
-msgstr "hãy chắc chắn là miếng vá thích hợp với bảng mục lục hiện hành"
+msgstr "kiểm tra chắc chắn là bản vá thích hợp với chỉ mục hiện hành"
 
 msgid "mark new files with `git add --intent-to-add`"
-msgstr "đánh dấu các tập tin mới với “git add --intent-to-add”"
+msgstr "đánh dấu các tập tin mới với 'git add --intent-to-add'"
 
 msgid "apply a patch without touching the working tree"
-msgstr "áp dụng một miếng vá mà không động chạm đến cây làm việc"
+msgstr "áp dụng bản vá mà không động chạm đến cây làm việc"
 
 msgid "accept a patch that touches outside the working area"
-msgstr "chấp nhận một miếng vá mà không động chạm đến cây làm việc"
+msgstr "chấp nhận bản vá có động chạm đến ngoài cây làm việc"
 
 msgid "also apply the patch (use with --stat/--summary/--check)"
-msgstr ""
-"đồng thời áp dụng miếng vá (dùng với tùy chọn --stat/--summary/--check)"
+msgstr "đồng thời áp dụng bản vá (dùng với tùy chọn --stat/--summary/--check)"
 
 msgid "attempt three-way merge, fall back on normal patch if that fails"
-msgstr ""
-"thử hòa trộn kiểu three-way, quay lại dán bình thường nếu không thể thực "
-"hiện được"
+msgstr "thử hòa trộn kiểu three-way, quay lại kiểu bình thường nếu thất bại"
 
 msgid "build a temporary index based on embedded index information"
-msgstr ""
-"xây dựng bảng mục lục tạm thời trên cơ sở thông tin bảng mục lục được nhúng"
+msgstr "xây dựng chỉ mục tạm thời dựa trên thông tin chỉ mục được nhúng"
 
 msgid "paths are separated with NUL character"
-msgstr "các đường dẫn bị ngăn cách bởi ký tự NULL"
+msgstr "các đường dẫn được ngăn cách bởi ký tự NULL"
 
 msgid "ensure at least <n> lines of context match"
 msgstr "đảm bảo rằng có ít nhất <n> dòng ngữ cảnh khớp"
@@ -1198,22 +1228,22 @@
 msgstr "hành động"
 
 msgid "detect new or modified lines that have whitespace errors"
-msgstr "tìm thấy một dòng mới hoặc bị sửa đổi mà nó có lỗi do khoảng trắng"
+msgstr "tìm thấy dòng mới hoặc dòng bị sửa đổi có lỗi khoảng trắng"
 
 msgid "ignore changes in whitespace when finding context"
-msgstr "lờ đi sự thay đổi do khoảng trắng gây ra khi tìm ngữ cảnh"
+msgstr "bỏ qua sự thay đổi do khoảng trắng gây ra khi tìm ngữ cảnh"
 
 msgid "apply the patch in reverse"
-msgstr "áp dụng miếng vá theo chiều ngược"
+msgstr "áp dụng bản vá theo chiều ngược"
 
 msgid "don't expect at least one line of context"
 msgstr "đừng hy vọng có ít nhất một dòng ngữ cảnh"
 
 msgid "leave the rejected hunks in corresponding *.rej files"
-msgstr "để lại khối dữ liệu bị từ chối trong các tập tin *.rej tương ứng"
+msgstr "để lại khối bị từ chối trong các tập tin *.rej tương ứng"
 
 msgid "allow overlapping hunks"
-msgstr "cho phép chồng khối nhớ"
+msgstr "cho phép chồng khối"
 
 msgid "tolerate incorrectly detected missing new-line at the end of file"
 msgstr ""
@@ -1226,65 +1256,69 @@
 msgstr "gốc"
 
 msgid "prepend <root> to all filenames"
-msgstr "treo thêm <root> vào tất cả các tên tập tin"
+msgstr "thêm <gốc> vào trước tất cả các tên tập tin"
 
 msgid "don't return error for empty patches"
-msgstr "đừng trả về lỗi khi các miếng vá trống rỗng"
+msgstr "đừng trả về lỗi khi các bản vá trống rỗng"
 
 #, c-format
 msgid "cannot stream blob %s"
-msgstr "không thể stream blob “%s”"
+msgstr "không thể stream blob '%s'"
 
 #, c-format
 msgid "unsupported file mode: 0%o (SHA1: %s)"
 msgstr "chế độ tập tin không được hỗ trợ: 0%o (SHA1: %s)"
 
 #, c-format
+msgid "deflate error (%d)"
+msgstr "lỗi giải nén (%d)"
+
+#, c-format
 msgid "unable to start '%s' filter"
-msgstr "không thể bắt đầu bộ lọc “%s”"
+msgstr "không thể khởi chạy bộ lọc '%s'"
 
 msgid "unable to redirect descriptor"
-msgstr "không thể chuyển hướng mô tả"
+msgstr "không thể chuyển hướng vào/ra"
 
 #, c-format
 msgid "'%s' filter reported error"
-msgstr "bộ lọc “%s” đã báo cáo lỗi"
+msgstr "bộ lọc '%s' đã báo lỗi"
 
 #, c-format
 msgid "path is not valid UTF-8: %s"
-msgstr "đường dẫn không hợp lệ UTF-8: %s"
+msgstr "đường dẫn không hợp lệ theo UTF-8: %s"
 
 #, c-format
 msgid "path too long (%d chars, SHA1: %s): %s"
 msgstr "đường dẫn quá dài (%d ký tự, SHA1: %s): %s"
 
 #, c-format
-msgid "deflate error (%d)"
-msgstr "lỗi giải nén (%d)"
-
-#, c-format
 msgid "timestamp too large for this system: %<PRIuMAX>"
-msgstr "dấu vết thời gian là quá lớn cho hệ thống này: %<PRIuMAX>"
+msgstr "dấu thời gian là quá lớn cho hệ thống này: %<PRIuMAX>"
 
 msgid "git archive [<options>] <tree-ish> [<path>...]"
-msgstr "git archive [<các tùy chọn>] <tree-ish> [</đường/dẫn>…]"
+msgstr "git archive [<các tùy chọn>] <tree-ish> [</đường/dẫn>...]"
 
 msgid ""
 "git archive --remote <repo> [--exec <cmd>] [<options>] <tree-ish> [<path>...]"
 msgstr ""
 "git archive --remote <kho> [--exec <lệnh>] [<các tùy chọn>] <tree-ish> [</"
-"đường/dẫn>…]"
+"đường/dẫn>...]"
 
 msgid "git archive --remote <repo> [--exec <cmd>] --list"
 msgstr "git archive --remote <kho> [--exec <lệnh>] --list"
 
 #, c-format
 msgid "cannot read '%s'"
-msgstr "không thể đọc “%s”"
+msgstr "không thể đọc '%s'"
+
+#, c-format
+msgid "pathspec '%s' matches files outside the current directory"
+msgstr "đặc tả đường dẫn '%s' nằm ngoài thư mục hiện hành"
 
 #, c-format
 msgid "pathspec '%s' did not match any files"
-msgstr "đặc tả đường dẫn “%s” không khớp với bất kỳ tập tin nào"
+msgstr "đặc tả đường dẫn '%s' không khớp với bất kỳ tập tin nào"
 
 #, c-format
 msgid "no such ref: %.*s"
@@ -1292,14 +1326,11 @@
 
 #, c-format
 msgid "not a valid object name: %s"
-msgstr "không phải là tên đối tượng hợp lệ: “%s”"
+msgstr "không phải là tên đối tượng hợp lệ: %s"
 
 #, c-format
 msgid "not a tree object: %s"
-msgstr "không phải là đối tượng cây: “%s”"
-
-msgid "current working directory is untracked"
-msgstr "thư mục làm việc hiện hành chưa được theo dõi"
+msgstr "không phải là đối tượng cây: %s"
 
 #, c-format
 msgid "File not found: %s"
@@ -1307,7 +1338,7 @@
 
 #, c-format
 msgid "Not a regular file: %s"
-msgstr "Không phải một tập tin thường: %s"
+msgstr "Không phải tập tin thường: %s"
 
 #, c-format
 msgid "unclosed quote: '%s'"
@@ -1315,26 +1346,26 @@
 
 #, c-format
 msgid "missing colon: '%s'"
-msgstr "thiếu dấu hai chấm: “%s”"
+msgstr "thiếu dấu hai chấm: '%s'"
 
 #, c-format
 msgid "empty file name: '%s'"
-msgstr "tên tập tin trống rỗng: “%s”"
+msgstr "tên tập tin trống: '%s'"
 
 msgid "fmt"
-msgstr "định_dạng"
+msgstr "định-dạng"
 
 msgid "archive format"
 msgstr "định dạng lưu trữ"
 
 msgid "prefix"
-msgstr "tiền_tố"
+msgstr "tiền tố"
 
 msgid "prepend prefix to each pathname in the archive"
 msgstr "nối thêm tiền tố vào từng đường dẫn tập tin trong kho lưu"
 
 msgid "file"
-msgstr "tập_tin"
+msgstr "tập tin"
 
 msgid "add untracked file to archive"
 msgstr "thêm các tập tin không được theo dõi vào kho lưu"
@@ -1349,7 +1380,13 @@
 msgstr "đọc .gitattributes trong thư mục làm việc"
 
 msgid "report archived files on stderr"
-msgstr "liệt kê các tập tin được lưu trữ vào stderr (đầu ra lỗi tiêu chuẩn)"
+msgstr "liệt kê các tập tin được lưu trữ ra stderr"
+
+msgid "time"
+msgstr "thời-gian"
+
+msgid "set modification time of archive entries"
+msgstr "đặt thời điểm sửa đổi của các mục nén"
 
 msgid "set compression level"
 msgstr "đặt mức nén"
@@ -1370,27 +1407,38 @@
 msgstr "đường dẫn đến lệnh git-upload-archive trên máy chủ"
 
 msgid "Unexpected option --remote"
-msgstr "Gặp tùy chọn không cần --remote"
+msgstr "Gặp tùy chọn bất thường --remote"
 
 #, c-format
 msgid "the option '%s' requires '%s'"
-msgstr "tùy chọn “%s” yêu cầu “%s”"
+msgstr "tùy chọn '%s' yêu cầu '%s'"
 
 msgid "Unexpected option --output"
-msgstr "Gặp tùy chọn không cần --output"
+msgstr "Gặp tùy chọn bất thường --output"
+
+#, c-format
+msgid "extra command line parameter '%s'"
+msgstr "thừa tham số dòng lệnh '%s'"
 
 #, c-format
 msgid "Unknown archive format '%s'"
-msgstr "Không hiểu định dạng “%s”"
+msgstr "Không hiểu định dạng lưu trữ '%s'"
 
 #, c-format
 msgid "Argument not supported for format '%s': -%d"
-msgstr "Tham số không được hỗ trợ cho định dạng “%s”: -%d"
+msgstr "Tham số không được hỗ trợ cho định dạng '%s': -%d"
 
 #, c-format
 msgid "%.*s is not a valid attribute name"
 msgstr "%.*s không phải tên thuộc tính hợp lệ"
 
+msgid "unable to add additional attribute"
+msgstr "Không thể thêm thuộc tính"
+
+#, c-format
+msgid "ignoring overly long attributes line %d"
+msgstr "bỏ qua dòng thuộc tính thứ %d quá dài"
+
 #, c-format
 msgid "%s not allowed: %s:%d"
 msgstr "%s không được phép: %s:%d"
@@ -1399,16 +1447,39 @@
 "Negative patterns are ignored in git attributes\n"
 "Use '\\!' for literal leading exclamation."
 msgstr ""
-"Các mẫu dạng phủ định bị cấm dùng cho các thuộc tính của git\n"
-"Dùng “\\!” cho các chuỗi văn bản có dấu chấm than dẫn đầu."
+"Các mẫu dạng phủ định bị cấm dùng cho git attribute\n"
+"Dùng '\\!' cho tên có dấu chấm than dẫn đầu."
+
+#, c-format
+msgid "cannot fstat gitattributes file '%s'"
+msgstr "không thể fstat tập tin gitattributes '%s'"
+
+#, c-format
+msgid "ignoring overly large gitattributes file '%s'"
+msgstr "bỏ qua tập tin gitattributes quá lớn '%s'"
+
+#, c-format
+msgid "ignoring overly large gitattributes blob '%s'"
+msgstr "bỏ qua blob gitattributes quá lớn '%s'"
+
+msgid "bad --attr-source or GIT_ATTR_SOURCE"
+msgstr "--attr-source hoặc GIT_ATTR_SOURCE sai"
+
+#, c-format
+msgid "unable to stat '%s'"
+msgstr "không thể stat '%s'"
+
+#, c-format
+msgid "unable to read %s"
+msgstr "không thể đọc %s"
 
 #, c-format
 msgid "Badly quoted content in file '%s': %s"
-msgstr "Nội dung được trích dẫn sai trong tập tin “%s”: %s"
+msgstr "Nội dung được trích dẫn sai trong tập tin '%s': %s"
 
 #, c-format
 msgid "We cannot bisect more!\n"
-msgstr "Chúng tôi không bisect thêm nữa!\n"
+msgstr "Không bisect thêm nữa!\n"
 
 #, c-format
 msgid "Not a valid commit name %s"
@@ -1419,16 +1490,16 @@
 "The merge base %s is bad.\n"
 "This means the bug has been fixed between %s and [%s].\n"
 msgstr ""
-"Hòa trộn trên %s là sai.\n"
-"Điều đó có nghĩa là lỗi đã được sửa chữa giữa %s và [%s].\n"
+"Gốc hòa trộn trên %s là sai.\n"
+"Có nghĩa là lỗi đã được sửa chữa giữa %s và [%s].\n"
 
 #, c-format
 msgid ""
 "The merge base %s is new.\n"
 "The property has changed between %s and [%s].\n"
 msgstr ""
-"Hòa trộn trên %s là mới.\n"
-"Gần như chắc chắn là có thay đổi giữa %s và [%s].\n"
+"Gốc hòa trộn trên %s là mới.\n"
+"Đã có thay đổi thuộc tính giữa %s và [%s].\n"
 
 #, c-format
 msgid ""
@@ -1436,7 +1507,7 @@
 "This means the first '%s' commit is between %s and [%s].\n"
 msgstr ""
 "Hòa trộn trên %s là %s.\n"
-"Điều đó có nghĩa là lần chuyển giao “%s” đầu tiên là giữa %s và [%s].\n"
+"Có nghĩa là lần chuyển giao '%s' đầu tiên là giữa %s và [%s].\n"
 
 #, c-format
 msgid ""
@@ -1445,7 +1516,7 @@
 "Maybe you mistook %s and %s revs?\n"
 msgstr ""
 "Một số điểm xét duyệt %s không phải tổ tiên của điểm xét duyệt %s.\n"
-"git bisect không thể làm việc đúng đắn trong trường hợp này.\n"
+"git bisect không thể làm việc đúng trong trường hợp này.\n"
 "Liệu có phải bạn nhầm lẫn các điểm %s và %s không?\n"
 
 #, c-format
@@ -1454,14 +1525,13 @@
 "So we cannot be sure the first %s commit is between %s and %s.\n"
 "We continue anyway."
 msgstr ""
-"hòa trộn trên cơ sở giữa %s và [%s] phải bị bỏ qua.\n"
-"Do vậy chúng tôi không thể chắc lần chuyển giao đầu tiên %s là giữa %s và "
-"%s.\n"
-"Chúng tôi vẫn cứ tiếp tục."
+"gốc hòa trộn giữa %s và [%s] phải bị bỏ qua.\n"
+"Do vậy không thể chắc chắn lần chuyển giao %s đầu tiên là giữa %s và %s.\n"
+"Vẫn tiếp tục."
 
 #, c-format
 msgid "Bisecting: a merge base must be tested\n"
-msgstr "Bisecting: nền hòa trộn cần phải được kiểm tra\n"
+msgstr "Đang bisect: gốc hòa trộn cần phải được kiểm tra\n"
 
 #, c-format
 msgid "a %s revision is needed"
@@ -1469,11 +1539,15 @@
 
 #, c-format
 msgid "could not create file '%s'"
-msgstr "không thể tạo tập tin “%s”"
+msgstr "không thể tạo tập tin '%s'"
+
+#, c-format
+msgid "unable to start 'show' for object '%s'"
+msgstr "không thể khởi chạy 'show' cho đối tượng '%s'"
 
 #, c-format
 msgid "could not read file '%s'"
-msgstr "không thể đọc tập tin “%s”"
+msgstr "không thể đọc tập tin '%s'"
 
 msgid "reading bisect refs failed"
 msgstr "việc đọc tham chiếu bisect gặp lỗi"
@@ -1487,13 +1561,13 @@
 "No testable commit found.\n"
 "Maybe you started with bad path arguments?\n"
 msgstr ""
-"Không tìm thấy lần chuyển giao kiểm tra được nào.\n"
+"Không tìm thấy lần chuyển giao nào kiểm tra được.\n"
 "Có lẽ bạn bắt đầu với các tham số đường dẫn sai?\n"
 
 #, c-format
 msgid "(roughly %d step)"
 msgid_plural "(roughly %d steps)"
-msgstr[0] "(ước chừng %d bước)"
+msgstr[0] "(cần khoảng chừng %d bước)"
 
 #. TRANSLATORS: the last %s will be replaced with "(roughly %d
 #. steps)" translation.
@@ -1501,13 +1575,10 @@
 #, c-format
 msgid "Bisecting: %d revision left to test after this %s\n"
 msgid_plural "Bisecting: %d revisions left to test after this %s\n"
-msgstr[0] "Bisecting: còn %d điểm xét duyệt để kiểm sau %s này\n"
+msgstr[0] "Bisecting: còn %d điểm xét duyệt để kiểm tra %s\n"
 
 msgid "--contents and --reverse do not blend well."
-msgstr "tùy chọn --contents và --reverse không được trộn vào nhau."
-
-msgid "cannot use --contents with final commit object name"
-msgstr "không thể dùng --contents với tên đối tượng chuyển giao cuối cùng"
+msgstr "tùy chọn --contents và --reverse không nên đi với nhau."
 
 msgid "--reverse and --first-parent together require specified latest commit"
 msgstr ""
@@ -1519,16 +1590,16 @@
 msgid ""
 "--reverse --first-parent together require range along first-parent chain"
 msgstr ""
-"cùng sử dụng --reverse --first-parent yêu cầu vùng cùng với chuỗi cha-mẹ-đầu-"
-"tiên"
+"cùng sử dụng --reverse và --first-parent yêu cầu vùng cùng với chuỗi cha-mẹ-"
+"đầu-tiên"
 
 #, c-format
 msgid "no such path %s in %s"
-msgstr "không có đường dẫn %s trong “%s”"
+msgstr "không có đường dẫn %s trong '%s'"
 
 #, c-format
 msgid "cannot read blob %s for path %s"
-msgstr "không thể đọc blob %s cho đường dẫn “%s”"
+msgstr "không thể đọc blob %s cho đường dẫn '%s'"
 
 msgid ""
 "cannot inherit upstream tracking configuration of multiple refs when "
@@ -1539,19 +1610,19 @@
 
 #, c-format
 msgid "not setting branch '%s' as its own upstream"
-msgstr "không cài đặt nhánh '%s' như là thượng nguồn của nó"
+msgstr "không đặt nhánh '%s' là thượng nguồn của chính nó"
 
 #, c-format
 msgid "branch '%s' set up to track '%s' by rebasing."
-msgstr "nhánh “%s” cài đặt để theo dõi “%s” bằng cách rebase."
+msgstr "nhánh '%s' cài đặt để theo dõi '%s' bằng cách rebase."
 
 #, c-format
 msgid "branch '%s' set up to track '%s'."
-msgstr "nhánh “%s” cài đặt để theo dõi “%s”."
+msgstr "nhánh '%s' cài đặt để theo dõi '%s'."
 
 #, c-format
 msgid "branch '%s' set up to track:"
-msgstr "nhánh “%s” cài đặt để theo dõi:"
+msgstr "nhánh '%s' cài đặt để theo dõi:"
 
 msgid "unable to write upstream branch configuration"
 msgstr "không thể ghi cấu hình nhánh thượng nguồn"
@@ -1562,19 +1633,17 @@
 "the remote tracking information by invoking:"
 msgstr ""
 "\n"
-"Sau khi sửa nguyên nhân gây lỗi bạn có lẻ cần thử sửa\n"
+"Sau khi sửa nguyên nhân gây lỗi bạn có thể thử sửa\n"
 "thông tin theo dõi máy chủ bằng cách gọi lệnh:"
 
 #, c-format
 msgid "asked to inherit tracking from '%s', but no remote is set"
-msgstr ""
-"đã hỏi để kế thừa theo dõi từ '%s', nhưng không có máy chủ nào được đặt"
+msgstr "đã yêu cầu kế thừa theo dõi từ '%s', nhưng chưa cấu hình máy chủ nào"
 
 #, c-format
 msgid "asked to inherit tracking from '%s', but no merge configuration is set"
 msgstr ""
-"đã hỏi để kế thừa theo dõi từ '%s', nhưng không có cấu hình hòa trộn nào "
-"được đặt"
+"đã yêu cầu kế thừa theo dõi từ '%s', nhưng không có cấu hình hòa trộn nào"
 
 #, c-format
 msgid "not tracking: ambiguous information for ref '%s'"
@@ -1609,8 +1678,8 @@
 "different remotes' fetch refspecs map into different\n"
 "tracking namespaces."
 msgstr ""
-"Có nhiều máy chủ những cái lấy ánh xạ refspecs tham chiếu theo\n"
-"dõi máy chủ '%s':\n"
+"Có nhiều máy chủ có fetch refspec ánh xạ tới refspecs tham chiếu\n"
+"theo dõi máy chủ '%s':\n"
 "%s\n"
 "Đây thường là lỗi cấu hình.\n"
 "\n"
@@ -1620,25 +1689,29 @@
 
 #, c-format
 msgid "'%s' is not a valid branch name"
-msgstr "“%s” không phải là một tên nhánh hợp lệ"
+msgstr "'%s' không phải là một tên nhánh hợp lệ"
+
+msgid "See `man git check-ref-format`"
+msgstr "Đọc `man git check-ref-format`"
 
 #, c-format
 msgid "a branch named '%s' already exists"
-msgstr "đã có nhánh mang tên “%s”"
+msgstr "đã có nhánh mang tên '%s'"
 
 #, c-format
-msgid "cannot force update the branch '%s' checked out at '%s'"
-msgstr "không thể ép buộc cập nhật nhánh “%s” đã được lấy ra tại “%s”"
+msgid "cannot force update the branch '%s' used by worktree at '%s'"
+msgstr ""
+"không thể ép buộc cập nhật nhánh '%s' đang được sử dụng tại cây làm việc '%s'"
 
 #, c-format
 msgid "cannot set up tracking information; starting point '%s' is not a branch"
 msgstr ""
-"không thể cài đặt thông tin theo dõi; điểm bắt đầu “%s” không phải là một "
+"không thể cài đặt thông tin theo dõi; điểm bắt đầu '%s' không phải là một "
 "nhánh"
 
 #, c-format
 msgid "the requested upstream branch '%s' does not exist"
-msgstr "nhánh thượng nguồn đã yêu cầu “%s” không tồn tại"
+msgstr "nhánh thượng nguồn đã yêu cầu '%s' không tồn tại"
 
 msgid ""
 "\n"
@@ -1651,95 +1724,83 @@
 "\"git push -u\" to set the upstream config as you push."
 msgstr ""
 "\n"
-"Nếu bạn có ý định “cải tổ” công việc của bạn trên nhánh thượng nguồn\n"
-"(upstream) cái mà đã sẵn có trên máy chủ, bạn cần chạy\n"
+"Nếu bạn có ý định bắt đầu công việc của bạn trên nhánh thượng nguồn\n"
+"(upstream) đã sẵn có trên máy chủ, bạn cần chạy\n"
 "lệnh \"git fetch\" để lấy nó về.\n"
 "\n"
-"Nếu bạn có ý định đẩy lên lên một nhánh nội bộ mới cái mà\n"
-"sẽ theo dõi bản đối chiếu máy chủ của nó, bạn cần dùng lệnh\n"
-"\"git push -u\" để đặt cấu hình thượng nguồn bạn muốn push."
+"Nếu bạn có ý định đẩy một nhánh nội bộ mới mà\n"
+"sẽ theo dõi nhánh trên máy chủ, bạn cần dùng lệnh\n"
+"\"git push -u\" để đặt cấu hình thượng nguồn khi push."
 
 #, c-format
 msgid "not a valid object name: '%s'"
-msgstr "không phải là tên đối tượng hợp lệ: “%s”"
+msgstr "không phải là tên đối tượng hợp lệ: '%s'"
 
 #, c-format
 msgid "ambiguous object name: '%s'"
-msgstr "tên đối tượng chưa rõ ràng: “%s”."
+msgstr "tên đối tượng chưa rõ ràng: '%s'."
 
 #, c-format
 msgid "not a valid branch point: '%s'"
-msgstr "không phải là một điểm nhánh hợp lệ: “%s”"
+msgstr "không phải là một điểm nhánh hợp lệ: '%s'"
 
 #, c-format
 msgid "submodule '%s': unable to find submodule"
-msgstr "mô-đun-con “%s”: không thể tìm thấy mô-đun-con"
+msgstr "mô-đun-con '%s': không thể tìm thấy mô-đun-con"
 
 #, c-format
 msgid ""
-"You may try updating the submodules using 'git checkout %s && git submodule "
-"update --init'"
+"You may try updating the submodules using 'git checkout --no-recurse-"
+"submodules %s && git submodule update --init'"
 msgstr ""
-"Bạn có thể thử cập nhật các mô-đun-con bằng cách sử dụng 'git checkout %s && "
-"git submodule update --init'"
+"Bạn có thể thử cập nhật các mô-đun-con bằng cách sử dụng 'git checkout --no-"
+"recurse-submodules %s && git submodule update --init'"
 
 #, c-format
 msgid "submodule '%s': cannot create branch '%s'"
-msgstr "mô-đun-con “%s”: không thể tạo nhánh “%s”"
+msgstr "mô-đun-con '%s': không thể tạo nhánh '%s'"
 
 #, c-format
-msgid "'%s' is already checked out at '%s'"
-msgstr "“%s” đã được lấy ra tại “%s” rồi"
-
-#, c-format
-msgid "HEAD of working tree %s is not updated"
-msgstr "HEAD của cây làm việc %s chưa được cập nhật"
+msgid "'%s' is already used by worktree at '%s'"
+msgstr "'%s' đang được sử dụng tại cây làm việc '%s'"
 
 msgid "git add [<options>] [--] <pathspec>..."
-msgstr "git add [<các tùy chọn>] [--]  <pathspec>…"
+msgstr "git add [<các tùy chọn>] [--]  <pathspec>..."
 
 #, c-format
 msgid "cannot chmod %cx '%s'"
-msgstr "không thể chmod %cx “%s”"
-
-#, c-format
-msgid "unexpected diff status %c"
-msgstr "trạng thái lệnh diff không như mong đợi %c"
-
-msgid "updating files failed"
-msgstr "cập nhật tập tin gặp lỗi"
-
-#, c-format
-msgid "remove '%s'\n"
-msgstr "gỡ bỏ “%s”\n"
+msgstr "không thể chmod %cx '%s'"
 
 msgid "Unstaged changes after refreshing the index:"
+msgstr "Đưa ra khỏi bệ phóng các thay đổi sau khi làm mới lại chỉ mục:"
+
+msgid ""
+"the add.interactive.useBuiltin setting has been removed!\n"
+"See its entry in 'git help config' for details."
 msgstr ""
-"Đưa ra khỏi bệ phóng các thay đổi sau khi làm tươi mới lại bảng mục lục:"
+"mục cài đặt add.interactive.useBuiltin đã không còn!\n"
+"Xem mục tin của nó trong 'git help config' để biết chi tiết."
 
-msgid "Could not read the index"
-msgstr "Không thể đọc bảng mục lục"
-
-msgid "Could not write patch"
-msgstr "Không thể ghi ra miếng vá"
+msgid "could not read the index"
+msgstr "Không thể đọc chỉ mục"
 
 msgid "editing patch failed"
-msgstr "gặp lỗi khi sửa miếng vá"
+msgstr "gặp lỗi khi sửa bản vá"
 
 #, c-format
-msgid "Could not stat '%s'"
-msgstr "Không thể lấy thông tin thống kê về “%s”"
+msgid "could not stat '%s'"
+msgstr "không thể stat '%s'"
 
-msgid "Empty patch. Aborted."
-msgstr "Miếng vá trống rỗng. Nên bỏ qua."
+msgid "empty patch. aborted"
+msgstr "bản vá trống rỗng. huỷ bỏ"
 
 #, c-format
-msgid "Could not apply '%s'"
-msgstr "Không thể áp dụng miếng vá “%s”"
+msgid "could not apply '%s'"
+msgstr "không thể áp dụng bản vá '%s'"
 
 msgid "The following paths are ignored by one of your .gitignore files:\n"
 msgstr ""
-"Các đường dẫn theo sau đây sẽ bị lờ đi bởi một trong các tập tin .gitignore "
+"Các đường dẫn theo sau đây sẽ bị bỏ qua bởi một trong các tập tin .gitignore "
 "của bạn:\n"
 
 msgid "dry run"
@@ -1752,7 +1813,7 @@
 msgstr "sửa bằng cách tương tác"
 
 msgid "select hunks interactively"
-msgstr "chọn “hunks” theo kiểu tương tác"
+msgstr "chọn 'hunks' theo kiểu tương tác"
 
 msgid "edit current diff and apply"
 msgstr "sửa diff hiện nay và áp dụng nó"
@@ -1764,22 +1825,19 @@
 msgstr "cập nhật các tập tin được theo dõi"
 
 msgid "renormalize EOL of tracked files (implies -u)"
-msgstr "thường hóa lại EOL của các tập tin được theo dõi (ý là -u)"
+msgstr "thường hóa lại EOL của các tập tin được theo dõi (ngụ ý -u)"
 
 msgid "record only the fact that the path will be added later"
 msgstr "chỉ ghi lại sự việc mà đường dẫn sẽ được thêm vào sau"
 
 msgid "add changes from all tracked and untracked files"
-msgstr ""
-"thêm các thay đổi từ tất cả các tập tin có cũng như không được theo dõi dấu "
-"vết"
+msgstr "thêm các thay đổi từ tất cả các tập tin dù được theo dõi hay không"
 
 msgid "ignore paths removed in the working tree (same as --no-all)"
-msgstr ""
-"lờ đi các đường dẫn bị gỡ bỏ trong cây thư mục làm việc (giống với --no-all)"
+msgstr "bỏ qua các đường dẫn bị xoá bỏ trong cây làm việc (giống với --no-all)"
 
 msgid "don't add, only refresh the index"
-msgstr "không thêm, chỉ làm tươi mới bảng mục lục"
+msgstr "không thêm, chỉ làm mới chỉ mục"
 
 msgid "just skip files which cannot be added because of errors"
 msgstr "chie bỏ qua những tập tin mà nó không thể được thêm vào bởi vì gặp lỗi"
@@ -1789,10 +1847,11 @@
 "kiểm tra xem - thậm chí thiếu - tập tin bị bỏ qua trong quá trình chạy thử"
 
 msgid "allow updating entries outside of the sparse-checkout cone"
-msgstr "cho phép cập nhật các mục ở ngoài “sparse-checkout cone”"
+msgstr ""
+"cho phép cập nhật các mục ở ngoài 'sparse-checkout cone' (nón checkout thưa)"
 
 msgid "override the executable bit of the listed files"
-msgstr "ghi đè lên bít thi hành của các tập tin được liệt kê"
+msgstr "ghi đè lên executable bit (bít thực thi) của các tập tin được liệt kê"
 
 msgid "warn when adding an embedded repository"
 msgstr "cảnh báo khi thêm một kho nhúng"
@@ -1820,8 +1879,8 @@
 "\n"
 "\tgit submodule add <url> %s\n"
 "\n"
-"Nếu bạn đã thêm miếng vá này chỉ là sai sót, bạn có thể xóa bỏ\n"
-"nó khỏi mục lục bằng:\n"
+"Nếu bạn đã thêm bản vá này chỉ là sai sót, bạn có thể xóa bỏ\n"
+"nó khỏi chỉ mục bằng:\n"
 "\n"
 "\tgit rm --cached %s\n"
 "\n"
@@ -1831,21 +1890,15 @@
 msgid "adding embedded git repository: %s"
 msgstr "thêm cần một kho git nhúng: %s"
 
-msgid ""
-"Use -f if you really want to add them.\n"
-"Turn this message off by running\n"
-"\"git config advice.addIgnoredFile false\""
-msgstr ""
-"Sử dụng -f nếu bạn thực sự muốn thêm chúng.\n"
-"Tắt thông báo này bằng cách chạy lệnh\n"
-"\"git config advice.addIgnoredFile false\""
+msgid "Use -f if you really want to add them."
+msgstr "Dùng -f nếu bạn thực sự muốn thêm chúng"
 
 msgid "adding files failed"
 msgstr "thêm tập tin gặp lỗi"
 
 #, c-format
 msgid "--chmod param '%s' must be either -x or +x"
-msgstr "--chmod tham số “%s” phải hoặc là -x hay +x"
+msgstr "--chmod tham số '%s' phải hoặc là -x hay +x"
 
 #, c-format
 msgid "'%s' and pathspec arguments cannot be used together"
@@ -1855,21 +1908,18 @@
 msgid "Nothing specified, nothing added.\n"
 msgstr "Không có gì được chỉ ra, không có gì được thêm vào.\n"
 
-msgid ""
-"Maybe you wanted to say 'git add .'?\n"
-"Turn this message off by running\n"
-"\"git config advice.addEmptyPathspec false\""
-msgstr ""
-"Có lẽ bạn muốn chạy “git add .”?\n"
-"Tắt thông báo này bằng cách chạy lệnh\n"
-"\"git config advice.addEmptyPathspec false\""
+msgid "Maybe you wanted to say 'git add .'?"
+msgstr "Có lẽ là bạn muốn dùng 'git add .'?"
 
 msgid "index file corrupt"
-msgstr "tập tin ghi bảng mục lục bị hỏng"
+msgstr "tập tin ghi chỉ mục bị hỏng"
+
+msgid "unable to write new index file"
+msgstr "không thể ghi tập tin chỉ mục mới"
 
 #, c-format
 msgid "bad action '%s' for '%s'"
-msgstr "thao tác sai “%s” cho “%s”"
+msgstr "thao tác sai '%s' cho '%s'"
 
 #, c-format
 msgid "invalid value for '%s': '%s'"
@@ -1877,44 +1927,44 @@
 
 #, c-format
 msgid "could not read '%s'"
-msgstr "không thể đọc “%s”"
+msgstr "không thể đọc '%s'"
 
 msgid "could not parse author script"
-msgstr "không thể phân tích cú pháp văn lệnh tác giả"
+msgstr "không hiểu cú pháp author script"
 
 #, c-format
 msgid "could not parse %s"
-msgstr "không thể phân tích cú pháp %s"
+msgstr "không hiểu cú pháp %s"
 
 #, c-format
 msgid "'%s' was deleted by the applypatch-msg hook"
-msgstr "“%s” bị xóa bởi móc applypatch-msg"
+msgstr "'%s' bị xóa bởi móc applypatch-msg"
 
 #, c-format
 msgid "Malformed input line: '%s'."
-msgstr "Dòng đầu vào dị hình: “%s”."
+msgstr "Dòng đầu vào sai quy cách: '%s'."
 
 #, c-format
 msgid "Failed to copy notes from '%s' to '%s'"
-msgstr "Gặp lỗi khi sao chép ghi chú (note) từ “%s” tới “%s”"
+msgstr "Gặp lỗi khi sao chép ghi chú (note) từ '%s' tới '%s'"
 
 msgid "fseek failed"
 msgstr "fseek gặp lỗi"
 
 #, c-format
 msgid "could not open '%s' for reading"
-msgstr "không thể mở “%s” để đọc"
+msgstr "không thể mở '%s' để đọc"
 
 #, c-format
 msgid "could not open '%s' for writing"
-msgstr "không thể mở “%s” để ghi"
+msgstr "không thể mở '%s' để ghi"
 
 #, c-format
 msgid "could not parse patch '%s'"
-msgstr "không thể phân tích cú pháp “%s”"
+msgstr "không hiểu cú pháp '%s'"
 
 msgid "Only one StGIT patch series can be applied at once"
-msgstr "Chỉ có một sê-ri miếng vá StGIT được áp dụng một lúc"
+msgstr "Chỉ có một sê-ri bản vá StGIT được áp dụng một lúc"
 
 msgid "invalid timestamp"
 msgstr "dấu thời gian không hợp lệ"
@@ -1926,29 +1976,30 @@
 msgstr "độ lệch múi giờ không hợp lệ"
 
 msgid "Patch format detection failed."
-msgstr "Dò tìm định dạng miếng vá gặp lỗi."
+msgstr "Dò tìm định dạng bản vá gặp lỗi."
 
 #, c-format
 msgid "failed to create directory '%s'"
 msgstr "tạo thư mục \"%s\" gặp lỗi"
 
 msgid "Failed to split patches."
-msgstr "Gặp lỗi khi chia nhỏ các miếng vá."
+msgstr "Gặp lỗi khi chia nhỏ các bản vá."
 
 #, c-format
-msgid "When you have resolved this problem, run \"%s --continue\"."
-msgstr "Khi bạn đã giải quyết xong trục trặc này, hãy chạy \"%s --continue\"."
-
-#, c-format
-msgid "If you prefer to skip this patch, run \"%s --skip\" instead."
+msgid "When you have resolved this problem, run \"%s --continue\".\n"
 msgstr ""
-"Nếu bạn muốn bỏ qua miếng vá này, hãy chạy lệnh \"%s --skip\" để thay thế."
+"Sau khi bạn đã giải quyết xong vấn đề, hãy chạy lệnh\"%s --continue\".\n"
 
 #, c-format
-msgid "To record the empty patch as an empty commit, run \"%s --allow-empty\"."
+msgid "If you prefer to skip this patch, run \"%s --skip\" instead.\n"
+msgstr "Nếu bạn muốn bỏ qua bản vá này, hãy chạy lệnh \"%s --skip\".\n"
+
+#, c-format
+msgid ""
+"To record the empty patch as an empty commit, run \"%s --allow-empty\".\n"
 msgstr ""
-"Để ghi một miếng vá trống rỗng như một lần chuyển giao rông, \"%s --allow-"
-"empty\"."
+"Để ghi lại lần chuyển giao rỗng ứng với một bản vá rỗng, hãy chạy \"%s --"
+"allow-empty\".\n"
 
 #, c-format
 msgid "To restore the original branch and stop patching, run \"%s --abort\"."
@@ -1956,7 +2007,7 @@
 
 msgid "Patch sent with format=flowed; space at the end of lines might be lost."
 msgstr ""
-"Miếng vá được gửi với format=flowed; khoảng trống ở cuối của các dòng có thể "
+"bản vá được gửi với format=flowed; khoảng trống ở cuối của các dòng có thể "
 "bị mất."
 
 #, c-format
@@ -1969,24 +2020,24 @@
 
 #, c-format
 msgid "unable to parse commit %s"
-msgstr "không thể phân tích lần chuyển giao “%s”"
+msgstr "không thể đọc lần chuyển giao '%s'"
 
 msgid "Repository lacks necessary blobs to fall back on 3-way merge."
-msgstr "Kho thiếu đối tượng blob cần thiết để thực hiện “3-way merge”."
+msgstr "Kho thiếu đối tượng blob cần thiết để thực hiện '3-way merge'."
 
 msgid "Using index info to reconstruct a base tree..."
 msgstr ""
-"Sử dụng thông tin trong bảng mục lục để cấu trúc lại một cây (tree) cơ sở…"
+"Sử dụng thông tin trong chỉ mục để cấu trúc lại một cây (tree) cơ sở..."
 
 msgid ""
 "Did you hand edit your patch?\n"
 "It does not apply to blobs recorded in its index."
 msgstr ""
-"Bạn đã sửa miếng vá của mình bằng cách thủ công à?\n"
-"Nó không thể áp dụng các blob đã được ghi lại trong bảng mục lục của nó."
+"Bạn đã sửa bản vá của mình bằng cách thủ công à?\n"
+"Nó không thể áp dụng các blob đã được ghi lại trong chỉ mục của nó."
 
 msgid "Falling back to patching base and 3-way merge..."
-msgstr "Đang dùng phương án dự phòng: vá bản cơ sở và “hòa trộn 3-đường”…"
+msgstr "Đang dùng phương án dự phòng: vá bản cơ sở và 'hòa trộn 3-đường'..."
 
 msgid "Failed to merge in the changes."
 msgstr "Gặp lỗi khi trộn vào các thay đổi."
@@ -2018,11 +2069,12 @@
 "cả [a]: "
 
 msgid "unable to write index file"
-msgstr "không thể ghi tập tin lưu mục lục"
+msgstr "không thể ghi tập tin chỉ mục"
 
 #, c-format
 msgid "Dirty index: cannot apply patches (dirty: %s)"
-msgstr "Bảng mục lục bẩn: không thể áp dụng các miếng vá (bẩn: %s)"
+msgstr ""
+"chỉ mục không sạch sẽ: không thể áp dụng các bản vá (còn không sạch: %s)"
 
 #, c-format
 msgid "Skipping: %.*s"
@@ -2033,21 +2085,21 @@
 msgstr "Đang tạo một lần chuyển giao trống rỗng: %.*s"
 
 msgid "Patch is empty."
-msgstr "Miếng vá trống rỗng."
+msgstr "bản vá trống rỗng."
 
 #, c-format
 msgid "Applying: %.*s"
 msgstr "Áp dụng: %.*s"
 
 msgid "No changes -- Patch already applied."
-msgstr "Không thay đổi gì cả -- Miếng vá đã được áp dụng rồi."
+msgstr "Không thay đổi gì cả -- bản vá đã được áp dụng rồi."
 
 #, c-format
 msgid "Patch failed at %s %.*s"
 msgstr "Gặp lỗi khi vá tại %s %.*s"
 
 msgid "Use 'git am --show-current-patch=diff' to see the failed patch"
-msgstr "Dùng “git am --show-current-patch=diff” để xem miếng vá bị lỗi"
+msgstr "Dùng 'git am --show-current-patch=diff' để xem bản vá bị lỗi"
 
 msgid "No changes - recorded it as an empty commit."
 msgstr "Không có thay đổi nào - được ghi thành một lần chuyển giao rỗng."
@@ -2057,7 +2109,7 @@
 "If there is nothing left to stage, chances are that something else\n"
 "already introduced the same changes; you might want to skip this patch."
 msgstr ""
-"Không có thay đổi nào - bạn đã quên sử dụng lệnh “git add” à?\n"
+"Không có thay đổi nào - bạn đã quên sử dụng lệnh 'git add' à?\n"
 "Nếu ở đây không có gì còn lại stage, tình cờ là có một số thứ khác\n"
 "đã sẵn được đưa vào với cùng nội dung thay đổi; bạn có lẽ muốn bỏ qua miếng "
 "vá này."
@@ -2069,38 +2121,31 @@
 "You might run `git rm` on a file to accept \"deleted by them\" for it."
 msgstr ""
 "Bạn vẫn có những đường dẫn chưa hòa trộn trong chỉ mục của bạn.\n"
-"Bạn nên “git add” từng tập tin với các xung đột đã được giải quyết để đánh "
+"Bạn nên 'git add' từng tập tin với các xung đột đã được giải quyết để đánh "
 "dấu chúng là thế.\n"
-"Bạn có lẽ muốn chạy “git rm“ trên một tập tin để chấp nhận \"được xóa bởi họ"
-"\" cho nó."
-
-msgid "unable to write new index file"
-msgstr "không thể ghi tập tin lưu bảng mục lục mới"
+"Bạn có lẽ muốn chạy 'git rm' trên một tập tin để chấp nhận \"được xóa bởi "
+"họ\" cho nó."
 
 #, c-format
 msgid "Could not parse object '%s'."
-msgstr "Không thể phân tích đối tượng “%s”."
+msgstr "Không thể đọc đối tượng '%s'."
 
 msgid "failed to clean index"
-msgstr "gặp lỗi khi dọn bảng mục lục"
+msgstr "gặp lỗi khi dọn chỉ mục"
 
 msgid ""
 "You seem to have moved HEAD since the last 'am' failure.\n"
 "Not rewinding to ORIG_HEAD"
 msgstr ""
-"Bạn có lẽ đã có HEAD đã bị di chuyển đi kể từ lần “am” thất bại cuối cùng.\n"
+"Bạn có lẽ đã có HEAD đã bị di chuyển đi kể từ lần 'am' thất bại cuối cùng.\n"
 "Không thể chuyển tới ORIG_HEAD"
 
 #, c-format
 msgid "failed to read '%s'"
-msgstr "gặp lỗi khi đọc “%s”"
-
-#, c-format
-msgid "options '%s=%s' and '%s=%s' cannot be used together"
-msgstr "tùy chọn '%s=%s' và '%s=%s' không thể dùng cùng nhau"
+msgstr "gặp lỗi khi đọc '%s'"
 
 msgid "git am [<options>] [(<mbox> | <Maildir>)...]"
-msgstr "git am [<các tùy chọn>] [(<mbox>|<Maildir>)…]"
+msgstr "git am [<các tùy chọn>] [(<mbox>|<Maildir>)...]"
 
 msgid "git am [<options>] (--continue | --skip | --abort)"
 msgstr "git am [<các tùy chọn>] (--continue | --skip | --abort)"
@@ -2108,11 +2153,14 @@
 msgid "run interactively"
 msgstr "chạy kiểu tương tác"
 
+msgid "bypass pre-applypatch and applypatch-msg hooks"
+msgstr "bỏ qua hook pre-applypatch và applypatch-msg"
+
 msgid "historical option -- no-op"
-msgstr "tùy chọn lịch sử -- không-toán-tử"
+msgstr "tùy chọn cũ -- không làm gì cả"
 
 msgid "allow fall back on 3way merging if needed"
-msgstr "cho phép quay trở lại để hòa trộn kiểu “3way” nếu cần"
+msgstr "cho phép quay trở lại để hòa trộn kiểu 3way nếu cần"
 
 msgid "be quiet"
 msgstr "im lặng"
@@ -2135,10 +2183,6 @@
 msgid "pass --keep-cr flag to git-mailsplit for mbox format"
 msgstr "chuyển cờ --keep-cr cho git-mailsplit với định dạng mbox"
 
-msgid "do not pass --keep-cr flag to git-mailsplit independent of am.keepcr"
-msgstr ""
-"đừng chuyển cờ --keep-cr cho git-mailsplit không phụ thuộc vào am.keepcr"
-
 msgid "strip everything before a scissors line"
 msgstr "cắt mọi thứ trước dòng scissors"
 
@@ -2155,31 +2199,31 @@
 msgstr "định dạng"
 
 msgid "format the patch(es) are in"
-msgstr "định dạng (các) miếng vá theo"
+msgstr "định dạng (các) bản vá theo"
 
 msgid "override error message when patch failure occurs"
 msgstr "đè lên các lời nhắn lỗi khi xảy ra lỗi vá nghiêm trọng"
 
 msgid "continue applying patches after resolving a conflict"
-msgstr "tiếp tục áp dụng các miếng vá sau khi giải quyết xung đột"
+msgstr "tiếp tục áp dụng các bản vá sau khi giải quyết xung đột"
 
 msgid "synonyms for --continue"
 msgstr "đồng nghĩa với --continue"
 
 msgid "skip the current patch"
-msgstr "bỏ qua miếng vá hiện hành"
+msgstr "bỏ qua bản vá hiện hành"
 
 msgid "restore the original branch and abort the patching operation"
-msgstr "phục hồi lại nhánh gốc và loại bỏ thao tác vá"
+msgstr "phục hồi lại nhánh gốc và huỷ thao tác vá"
 
 msgid "abort the patching operation but keep HEAD where it is"
-msgstr "bỏ qua thao tác vá nhưng vẫn giữ HEAD nơi nó chỉ đến"
+msgstr "huỷ thao tác vá nhưng vẫn giữ HEAD nơi nó chỉ đến"
 
 msgid "show the patch being applied"
-msgstr "hiển thị miếng vá đã được áp dụng rồi"
+msgstr "hiển thị bản vá đã được áp dụng rồi"
 
 msgid "record the empty patch as an empty commit"
-msgstr "ghi lại miếng vá trống rỗng như là một lần chuyển giao trống"
+msgstr "ghi lại bản vá trống rỗng như là một lần chuyển giao trống"
 
 msgid "lie about committer date"
 msgstr "nói dối về ngày chuyển giao"
@@ -2194,7 +2238,7 @@
 msgstr "Các lần chuyển giao ký-GPG"
 
 msgid "how to handle empty patches"
-msgstr "xử lý các miếng vá trống rỗng như thế nào"
+msgstr "xử lý các bản vá trống rỗng như thế nào"
 
 msgid "(internal use for git-rebase)"
 msgstr "(dùng nội bộ cho git-rebase)"
@@ -2204,10 +2248,10 @@
 "it will be removed. Please do not use it anymore."
 msgstr ""
 "Tùy chọn -b/--binary đã không dùng từ lâu rồi, và\n"
-"nó sẽ được bỏ đi. Xin đừng sử dụng nó thêm nữa."
+"nó sẽ được bỏ đi. Xin đừng sử dụng nó nữa."
 
 msgid "failed to read the index"
-msgstr "gặp lỗi đọc bảng mục lục"
+msgstr "gặp lỗi đọc chỉ mục"
 
 #, c-format
 msgid "previous rebase directory %s still exists but mbox given."
@@ -2222,16 +2266,16 @@
 "Dùng \"git am --abort\" để loại bỏ nó đi."
 
 msgid "Resolve operation not in progress, we are not resuming."
-msgstr "Thao tác phân giải không được tiến hành, chúng ta không phục hồi lại."
+msgstr "Thao tác phân giải không được tiến hành, sẽ không phục hồi lại."
 
 msgid "interactive mode requires patches on the command line"
-msgstr "chế độ tương tác yêu cầu có các miếng vá trên dòng lệnh"
+msgstr "chế độ tương tác yêu cầu có các bản vá trên dòng lệnh"
 
 msgid "git apply [<options>] [<patch>...]"
-msgstr "git apply [<các tùy chọn>] [<miếng-vá>…]"
+msgstr "git apply [<các tùy chọn>] [<miếng-vá>...]"
 
 msgid "could not redirect output"
-msgstr "không thể chuyển hướng kết xuất"
+msgstr "không thể chuyển hướng đầu ra"
 
 msgid "git archive: Remote with no URL"
 msgstr "git archive: Máy chủ không có địa chỉ URL"
@@ -2247,58 +2291,53 @@
 msgstr "git archive: lỗi giao thức"
 
 msgid "git archive: expected a flush"
-msgstr "git archive: cần một flush (đẩy dữ liệu lên đĩa)"
-
-msgid "git bisect--helper --bisect-reset [<commit>]"
-msgstr "git bisect--helper --bisect-reset [<lần_chuyển_giao>]"
+msgstr "git archive: cần flush dữ liệu"
 
 msgid ""
-"git bisect--helper --bisect-start [--term-{new,bad}=<term> --term-{old,good}"
-"=<term>] [--no-checkout] [--first-parent] [<bad> [<good>...]] [--] "
-"[<paths>...]"
+"git bisect start [--term-(new|bad)=<term> --term-(old|good)=<term>]    [--no-"
+"checkout] [--first-parent] [<bad> [<good>...]] [--]    [<pathspec>...]"
 msgstr ""
-"git bisect--helper --bisect-start [--term-{new,bad}=<term> --term-{old,good}"
-"=<term>] [--no-checkout] [--first-parent] [<bad> [<good>…]] [--] [</các/"
-"đường/dẫn>…]"
+"git bisect start [--term-(new|bad)=<term> --term-(old|good)=<term>]    [--no-"
+"checkout] [--first-parent] [<bad> [<good>...]] [--]    [<đường/dẫn>...]"
 
-msgid "git bisect--helper --bisect-state (bad|new) [<rev>]"
-msgstr "git bisect--helper --bisect-state (bad|new) [<lần_chuyển_giao>]"
+msgid "git bisect (good|bad) [<rev>...]"
+msgstr "git bisect (good|bad) [<rev>...]"
 
-msgid "git bisect--helper --bisect-state (good|old) [<rev>...]"
-msgstr "git bisect--helper --bisect-state (good|old) [<lần_chuyển_giao>…]"
+msgid "git bisect skip [(<rev>|<range>)...]"
+msgstr "git bisect skip [(<rev>|<vùng>)...]"
 
-msgid "git bisect--helper --bisect-replay <filename>"
-msgstr "git bisect--helper --bisect-replay <tên_tập_tin>"
+msgid "git bisect reset [<commit>]"
+msgstr "git bisect reset [<lần_chuyển_giao>]"
 
-msgid "git bisect--helper --bisect-skip [(<rev>|<range>)...]"
-msgstr "git bisect--helper --bisect-skip [(<rev>|<vùng>)…]"
+msgid "git bisect replay <logfile>"
+msgstr "git bisect replay <tên_tập tin>"
 
-msgid "git bisect--helper --bisect-run <cmd>..."
-msgstr "git bisect--helper --bisect-run <lệnh>…"
+msgid "git bisect run <cmd> [<arg>...]"
+msgstr "git bisect run <lệnh> [<đối_số>]..."
 
 #, c-format
 msgid "cannot open file '%s' in mode '%s'"
-msgstr "không thể mở tập tin “%s” ở chế độ “%s”"
+msgstr "không thể mở tập tin '%s' ở chế độ '%s'"
 
 #, c-format
 msgid "could not write to file '%s'"
-msgstr "không thể ghi vào tập tin “%s”"
+msgstr "không thể ghi vào tập tin '%s'"
 
 #, c-format
 msgid "cannot open file '%s' for reading"
-msgstr "không thể mở tập tin “%s” để đọc"
+msgstr "không thể mở tập tin '%s' để đọc"
 
 #, c-format
 msgid "'%s' is not a valid term"
-msgstr "“%s” không phải một thời hạn hợp lệ"
+msgstr "'%s' không phải một thời hạn hợp lệ"
 
 #, c-format
 msgid "can't use the builtin command '%s' as a term"
-msgstr "không thể dùng lệnh tích hợp “%s” như là một thời kỳ"
+msgstr "không thể dùng lệnh tích hợp '%s' như là một thời kỳ"
 
 #, c-format
 msgid "can't change the meaning of the term '%s'"
-msgstr "không thể thay đổi nghĩa của thời kỳ “%s”"
+msgstr "không thể thay đổi nghĩa của thời kỳ '%s'"
 
 msgid "please use two different terms"
 msgstr "vui lòng dùng hai thời kỳ khác nhau"
@@ -2309,14 +2348,14 @@
 
 #, c-format
 msgid "'%s' is not a valid commit"
-msgstr "“%s” không phải một lần chuyển giao hợp lệ"
+msgstr "'%s' không phải một lần chuyển giao hợp lệ"
 
 #, c-format
 msgid ""
 "could not check out original HEAD '%s'. Try 'git bisect reset <commit>'."
 msgstr ""
-"không thể lấy ra HEAD nguyên thủy của “%s”. Hãy thử “git bisect reset <lần-"
-"chuyển-giao>”."
+"không thể checkout HEAD nguyên thủy của '%s'. Hãy thử 'git bisect reset <lần-"
+"chuyển-giao>'."
 
 #, c-format
 msgid "Bad bisect_write argument: %s"
@@ -2324,11 +2363,11 @@
 
 #, c-format
 msgid "couldn't get the oid of the rev '%s'"
-msgstr "không thể lấy oid của điểm xét duyệt “%s”"
+msgstr "không thể lấy oid của điểm xét duyệt '%s'"
 
 #, c-format
 msgid "couldn't open the file '%s'"
-msgstr "không thể mở tập tin “%s”"
+msgstr "không thể mở tập tin '%s'"
 
 #, c-format
 msgid "Invalid command: you're currently in a %s/%s bisect"
@@ -2393,7 +2432,7 @@
 "invalid argument %s for 'git bisect terms'.\n"
 "Supported options are: --term-good|--term-old and --term-bad|--term-new."
 msgstr ""
-"tham số không hợp lệ %s cho “git bisect terms”.\n"
+"tham số không hợp lệ %s cho 'git bisect terms'.\n"
 "Các tùy chọn hỗ trợ là: --term-good|--term-old và --term-bad|--term-new."
 
 msgid "revision walk setup failed\n"
@@ -2401,35 +2440,32 @@
 
 #, c-format
 msgid "could not open '%s' for appending"
-msgstr "không thể mở “%s” để nối thêm"
+msgstr "không thể mở '%s' để nối thêm"
 
 msgid "'' is not a valid term"
-msgstr "” không phải một thời hạn hợp lệ"
+msgstr "'' không phải term hợp lệ"
 
 #, c-format
 msgid "unrecognized option: '%s'"
-msgstr "tùy chọn không được thừa nhận: “%s”"
+msgstr "không nhận ra tuỳ chọn: '%s'"
 
 #, c-format
 msgid "'%s' does not appear to be a valid revision"
-msgstr "“%s” không có vẻ như là một điểm xét duyệt hợp lệ"
+msgstr "'%s' không có vẻ như là một điểm xét duyệt hợp lệ"
 
 msgid "bad HEAD - I need a HEAD"
 msgstr "sai HEAD - Tôi cần một HEAD"
 
 #, c-format
 msgid "checking out '%s' failed. Try 'git bisect start <valid-branch>'."
-msgstr "lấy ra “%s” ra gặp lỗi. Hãy thử \"git bisect reset <nhánh_hợp_lệ>\"."
-
-msgid "won't bisect on cg-seek'ed tree"
-msgstr "sẽ không di chuyển nửa bước trên cây được cg-seek"
+msgstr "checkout '%s' ra gặp lỗi. Hãy thử \"git bisect reset <nhánh_hợp_lệ>\"."
 
 msgid "bad HEAD - strange symbolic ref"
 msgstr "sai HEAD - tham chiếu mềm kỳ lạ"
 
 #, c-format
 msgid "invalid ref: '%s'"
-msgstr "refspec không hợp lệ: “%s”"
+msgstr "refspec không hợp lệ: '%s'"
 
 msgid "You need to start by \"git bisect start\"\n"
 msgstr "Bạn cần khởi đầu bằng \"git bisect start\"\n"
@@ -2442,11 +2478,11 @@
 msgstr "Bạn có muốn tôi thực hiện điều này cho bạn không [Y/n]? "
 
 msgid "Please call `--bisect-state` with at least one argument"
-msgstr "Hãy gọi “--bisect-state” với ít nhất một đối số"
+msgstr "Hãy gọi '--bisect-state' với ít nhất một đối số"
 
 #, c-format
 msgid "'git bisect %s' can take only one argument."
-msgstr "“git bisect %s” có thể lấy chỉ một đối số."
+msgstr "'git bisect %s' có thể lấy chỉ một đối số."
 
 #, c-format
 msgid "Bad rev input: %s"
@@ -2461,11 +2497,11 @@
 
 #, c-format
 msgid "'%s'?? what are you talking about?"
-msgstr "“%s”?? bạn đang nói gì thế?"
+msgstr "'%s'?? bạn đang nói gì thế?"
 
 #, c-format
 msgid "cannot read file '%s' for replaying"
-msgstr "không thể đọc tập tin “%s” để thao diễn lại"
+msgstr "không thể đọc tập tin '%s' để thao diễn lại"
 
 #, c-format
 msgid "running %s\n"
@@ -2475,97 +2511,68 @@
 msgstr "bisect chạy gặp lỗi: không đưa ra lệnh."
 
 #, c-format
-msgid "unable to verify '%s' on good revision"
-msgstr "không thể xác nhận “%s” trên điểm xét duyệt tốt"
+msgid "unable to verify %s on good revision"
+msgstr "không thể xác nhận '%s' trên điểm xét duyệt tốt"
 
 #, c-format
 msgid "bogus exit code %d for good revision"
-msgstr "mã thoát giả %d cho điểm xét duyệt tốt"
+msgstr "mã trả về %d bất thường cho điểm xét duyệt tốt"
 
 #, c-format
-msgid "bisect run failed: exit code %d from '%s' is < 0 or >= 128"
-msgstr "chạy bisect gặp lỗi: mã trả về %d từ lệnh “%s” là < 0 hoặc >= 128"
+msgid "bisect run failed: exit code %d from %s is < 0 or >= 128"
+msgstr "bisect gặp lỗi: mã trả về %d từ lệnh '%s' < 0 hoặc >= 128"
 
 #, c-format
 msgid "cannot open file '%s' for writing"
-msgstr "không thể mở “%s” để ghi"
+msgstr "không thể mở '%s' để ghi"
 
 msgid "bisect run cannot continue any more"
-msgstr "bisect không thể tiếp tục thêm được nữa"
+msgstr "không thể tiếp tục bisect thêm được nữa"
 
-#, c-format
 msgid "bisect run success"
-msgstr "bisect chạy thành công"
+msgstr "bisect thành công"
 
-#, c-format
 msgid "bisect found first bad commit"
 msgstr "bisect tìm thấy lần chuyển giao sai đầu tiên"
 
 #, c-format
-msgid ""
-"bisect run failed: 'git bisect--helper --bisect-state %s' exited with error "
-"code %d"
-msgstr ""
-"chạy bisect gặp lỗi: “git bisect--helper --bisect-state %s” đã thoát ra với "
-"mã lỗi %d"
+msgid "bisect run failed: 'git bisect %s' exited with error code %d"
+msgstr "bisect gặp lỗi: 'git bisect %s' đã thoát với mã lỗi %d"
 
-msgid "reset the bisection state"
-msgstr "đặt lại trạng di chuyển nửa bước"
+#, c-format
+msgid "'%s' requires either no argument or a commit"
+msgstr "'%s' không nhận đối số hay lần chuyển giao"
 
-msgid "check whether bad or good terms exist"
-msgstr "kiểm tra xem các thời điểm xấu/tốt có tồn tại không"
+#, c-format
+msgid "'%s' requires 0 or 1 argument"
+msgstr "%s cần 0 hoặc 1 tham số"
 
-msgid "print out the bisect terms"
-msgstr "in ra các thời điểm di chuyển nửa bước"
-
-msgid "start the bisect session"
-msgstr "bắt đầu phiên di chuyển nửa bước"
-
-msgid "find the next bisection commit"
-msgstr "tìm lần chuyển giao không di chuyển phân đôi"
-
-msgid "mark the state of ref (or refs)"
-msgstr "đánh dấu trạng thái ref (hoặc refs)"
-
-msgid "list the bisection steps so far"
-msgstr "liệt kê các bước bisection đi quá xa"
-
-msgid "replay the bisection process from the given file"
-msgstr "phát lại quá trình bisection từ tệp đã cho"
-
-msgid "skip some commits for checkout"
-msgstr "bỏ qua một số lần chuyển giao để lấy ra"
-
-msgid "visualize the bisection"
-msgstr "trực quan việc di chuyển nửa bước"
-
-msgid "use <cmd>... to automatically bisect"
-msgstr "dùng <cmd>… để bisect một cách tự động"
-
-msgid "no log for BISECT_WRITE"
-msgstr "không có nhật ký cho BISECT_WRITE"
-
-msgid "--bisect-reset requires either no argument or a commit"
-msgstr ""
-"--bisect-reset requires không nhận đối số cũng không nhận lần chuyển giao"
-
-msgid "--bisect-terms requires 0 or 1 argument"
-msgstr "--bisect-terms cần 0 hoặc 1 tham số"
-
-msgid "--bisect-next requires 0 arguments"
-msgstr "--bisect-next cần 0 tham số"
-
-msgid "--bisect-log requires 0 arguments"
-msgstr "--bisect-log cần 0 tham số"
+#, c-format
+msgid "'%s' requires 0 arguments"
+msgstr "%s không cần tham số"
 
 msgid "no logfile given"
 msgstr "chưa chỉ ra tập tin ghi nhật ký"
 
+#, c-format
+msgid "'%s' failed: no command provided."
+msgstr "'%s' gặp lỗi: không chỉ ra lệnh."
+
+msgid "need a command"
+msgstr "cần chỉ ra lệnh"
+
+#, c-format
+msgid "unknown command: '%s'"
+msgstr "không hiểu câu lệnh: '%s'"
+
 msgid "git blame [<options>] [<rev-opts>] [<rev>] [--] <file>"
 msgstr "git blame [<các tùy chọn>] [<rev-opts>] [<rev>] [--] <tập-tin>"
 
+msgid "git annotate [<options>] [<rev-opts>] [<rev>] [--] <file>"
+msgstr "git annotate [<các tùy chọn>] [<rev-opts>] [<rev>] [--] <tập-tin>"
+
 msgid "<rev-opts> are documented in git-rev-list(1)"
-msgstr "<rev-opts> được mô tả trong tài liệu git-rev-list(1)"
+msgstr "<rev-opts> được mô tả trong git-rev-list(1)"
 
 #, c-format
 msgid "expecting a color: %s"
@@ -2576,10 +2583,10 @@
 
 #, c-format
 msgid "cannot find revision %s to ignore"
-msgstr "không thể tìm thấy điểm xét duyệt %s để mà bỏ qua"
+msgstr "không thể tìm thấy điểm xét duyệt %s để bỏ qua"
 
 msgid "show blame entries as we find them, incrementally"
-msgstr "hiển thị các mục “blame” như là chúng ta thấy chúng, tăng dần"
+msgstr "hiển thị các mục 'blame' theo thời gian, tăng dần"
 
 msgid "do not show object names of boundary commits (Default: off)"
 msgstr ""
@@ -2593,10 +2600,10 @@
 msgstr "hiển thị thống kê công sức làm việc"
 
 msgid "force progress reporting"
-msgstr "ép buộc báo cáo tiến triển công việc"
+msgstr "ép buộc báo cáo tiến độ công việc"
 
 msgid "show output score for blame entries"
-msgstr "hiển thị kết xuất điểm số cho các mục tin “blame”"
+msgstr "hiển thị kết xuất điểm số cho các mục tin 'blame'"
 
 msgid "show original filename (Default: auto)"
 msgstr "hiển thị tên tập tin gốc (Mặc định: auto)"
@@ -2608,7 +2615,7 @@
 msgstr "hiển thị ở định dạng đã thiết kế cho dùng bằng máy"
 
 msgid "show porcelain format with per-line commit information"
-msgstr "hiển thị định dạng “porcelain” với thông tin chuyển giao mỗi dòng"
+msgstr "hiển thị định dạng 'porcelain' với thông tin chuyển giao mỗi dòng"
 
 msgid "use the same output mode as git-annotate (Default: off)"
 msgstr "dùng cùng chế độ xuất ra với git-annotate (Mặc định: off)"
@@ -2648,7 +2655,7 @@
 
 msgid "use revisions from <file> instead of calling git-rev-list"
 msgstr ""
-"sử dụng các điểm xét duyệt (revision) từ <tập tin> thay vì gọi “git-rev-list”"
+"sử dụng các điểm xét duyệt (revision) từ <tập tin> thay vì gọi 'git-rev-list'"
 
 msgid "use <file>'s contents as the final image"
 msgstr "sử dụng nội dung của <tập tin> như là ảnh cuối cùng"
@@ -2681,7 +2688,7 @@
 #. columns.
 #.
 msgid "4 years, 11 months ago"
-msgstr "4 năm, 11 tháng trước"
+msgstr "11 tháng, 28 ngày trước"
 
 #, c-format
 msgid "file %s has only %lu line"
@@ -2705,7 +2712,7 @@
 msgstr "git branch [<các tùy chọn>] [-l] [<mẫu>...]"
 
 msgid "git branch [<options>] [-r] (-d | -D) <branch-name>..."
-msgstr "git branch [<các tùy chọn>] [-r] (-d | -D) <tên-nhánh> …"
+msgstr "git branch [<các tùy chọn>] [-r] (-d | -D) <tên-nhánh> ..."
 
 msgid "git branch [<options>] (-m | -M) [<old-branch>] <new-branch>"
 msgstr "git branch [<các tùy chọn>] (-m | -M) [<nhánh-cũ>] <nhánh-mới>"
@@ -2722,51 +2729,56 @@
 #, c-format
 msgid ""
 "deleting branch '%s' that has been merged to\n"
-"         '%s', but not yet merged to HEAD."
+"         '%s', but not yet merged to HEAD"
 msgstr ""
-"đang xóa nhánh “%s” mà nó lại đã được hòa trộn vào\n"
-"         “%s”, nhưng vẫn chưa được hòa trộn vào HEAD."
+"đang xóa nhánh '%s' đã được hòa trộn vào\n"
+"         '%s', nhưng vẫn chưa được hòa trộn vào HEAD."
 
 #, c-format
 msgid ""
 "not deleting branch '%s' that is not yet merged to\n"
-"         '%s', even though it is merged to HEAD."
+"         '%s', even though it is merged to HEAD"
 msgstr ""
-"không xóa nhánh “%s” cái mà chưa được hòa trộn vào\n"
-"         “%s”, cho dù là nó đã được hòa trộn vào HEAD."
+"không xóa nhánh '%s' chưa được hòa trộn vào\n"
+"         '%s', dù đã được hòa trộn vào HEAD."
 
 #, c-format
-msgid "Couldn't look up commit object for '%s'"
-msgstr "Không thể tìm kiếm đối tượng chuyển giao cho “%s”"
+msgid "couldn't look up commit object for '%s'"
+msgstr "Không thể tìm kiếm đối tượng chuyển giao cho '%s'"
 
 #, c-format
-msgid ""
-"The branch '%s' is not fully merged.\n"
-"If you are sure you want to delete it, run 'git branch -D %s'."
-msgstr ""
-"Nhánh “%s” không được trộn một cách đầy đủ.\n"
-"Nếu bạn thực sự muốn xóa nó, thì chạy lệnh “git branch -D %s”."
+msgid "the branch '%s' is not fully merged"
+msgstr "nhánh '%s' chưa được hoà trộn."
 
-msgid "Update of config-file failed"
-msgstr "Cập nhật tập tin cấu hình gặp lỗi"
+#, c-format
+msgid "If you are sure you want to delete it, run 'git branch -D %s'"
+msgstr "Nếu bạn thực sự muốn xóa nó, hãy chạy lệnh 'git branch -D %s'."
+
+msgid "update of config-file failed"
+msgstr "cập nhật tập tin cấu hình gặp lỗi"
 
 msgid "cannot use -a with -d"
 msgstr "không thể dùng tùy chọn -a với -d"
 
-msgid "Couldn't look up commit object for HEAD"
-msgstr "Không thể tìm kiếm đối tượng chuyển giao cho HEAD"
+#, c-format
+msgid "cannot delete branch '%s' used by worktree at '%s'"
+msgstr "chông thể xóa nhánh '%s' đang được sử dụng tại cây làm việc '%s'"
 
 #, c-format
-msgid "Cannot delete branch '%s' checked out at '%s'"
-msgstr "Không thể xóa nhánh “%s” đã được lấy ra tại “%s”"
+msgid "remote-tracking branch '%s' not found"
+msgstr "không tìm thấy nhánh theo dõi máy chủ '%s'."
 
 #, c-format
-msgid "remote-tracking branch '%s' not found."
-msgstr "không tìm thấy nhánh theo dõi máy chủ “%s”."
+msgid ""
+"branch '%s' not found.\n"
+"Did you forget --remote?"
+msgstr ""
+"không tìm thấy nhánh '%s'.\n"
+"Bạn có quên dùng --remote không?"
 
 #, c-format
-msgid "branch '%s' not found."
-msgstr "không tìm thấy nhánh “%s”."
+msgid "branch '%s' not found"
+msgstr "không tìm thấy nhánh '%s'."
 
 #, c-format
 msgid "Deleted remote-tracking branch %s (was %s).\n"
@@ -2774,10 +2786,10 @@
 
 #, c-format
 msgid "Deleted branch %s (was %s).\n"
-msgstr "Nhánh “%s” đã bị xóa (từng là %s)\n"
+msgstr "Nhánh '%s' đã bị xóa (từng là %s)\n"
 
 msgid "unable to parse format string"
-msgstr "không thể phân tích chuỗi định dạng"
+msgstr "không thể đọc chuỗi định dạng"
 
 msgid "could not resolve HEAD"
 msgstr "không thể phân giải HEAD"
@@ -2787,56 +2799,62 @@
 msgstr "HEAD (%s) chỉ bên ngoài của refs/heads/"
 
 #, c-format
-msgid "Branch %s is being rebased at %s"
-msgstr "Nhánh %s đang được cải tổ lại tại %s"
+msgid "branch %s is being rebased at %s"
+msgstr "Nhánh %s đang được cải tổ tại %s"
 
 #, c-format
-msgid "Branch %s is being bisected at %s"
-msgstr "Nhánh %s đang được di chuyển phân đôi (bisect) tại %s"
-
-msgid "cannot copy the current branch while not on any."
-msgstr "không thể sao chép nhánh hiện hành trong khi nó chẳng ở đâu cả."
-
-msgid "cannot rename the current branch while not on any."
-msgstr "không thể đổi tên nhánh hiện hành trong khi nó chẳng ở đâu cả."
+msgid "branch %s is being bisected at %s"
+msgstr "Nhánh %s đang được bisect tại %s"
 
 #, c-format
-msgid "Invalid branch name: '%s'"
-msgstr "Tên nhánh không hợp lệ: “%s”"
-
-msgid "Branch rename failed"
-msgstr "Gặp lỗi khi đổi tên nhánh"
-
-msgid "Branch copy failed"
-msgstr "Gặp lỗi khi sao chép nhánh"
+msgid "HEAD of working tree %s is not updated"
+msgstr "HEAD của cây làm việc %s chưa được cập nhật"
 
 #, c-format
-msgid "Created a copy of a misnamed branch '%s'"
-msgstr "Đã tạo một bản sao của nhánh khuyết danh “%s”"
+msgid "invalid branch name: '%s'"
+msgstr "tên nhánh không hợp lệ: '%s'"
 
 #, c-format
-msgid "Renamed a misnamed branch '%s' away"
-msgstr "Đã đổi tên nhánh khuyết danh “%s” đi"
+msgid "no commit on branch '%s' yet"
+msgstr "vẫn chưa chuyển giao trên nhánh '%s'."
 
 #, c-format
-msgid "Branch renamed to %s, but HEAD is not updated!"
-msgstr "Nhánh bị đổi tên thành %s, nhưng HEAD lại không được cập nhật!"
+msgid "no branch named '%s'"
+msgstr "không có nhánh nào có tên '%s'."
 
-msgid "Branch is renamed, but update of config-file failed"
-msgstr "Nhánh bị đổi tên, nhưng cập nhật tập tin cấu hình gặp lỗi"
+msgid "branch rename failed"
+msgstr "gặp lỗi khi đổi tên nhánh"
 
-msgid "Branch is copied, but update of config-file failed"
-msgstr "Nhánh đã được sao chép, nhưng cập nhật tập tin cấu hình gặp lỗi"
+msgid "branch copy failed"
+msgstr "gặp lỗi khi sao chép nhánh"
+
+#, c-format
+msgid "created a copy of a misnamed branch '%s'"
+msgstr "đã tạo một bản sao của nhánh khuyết danh '%s'"
+
+#, c-format
+msgid "renamed a misnamed branch '%s' away"
+msgstr "đã đổi tên nhánh khuyết danh '%s'"
+
+#, c-format
+msgid "branch renamed to %s, but HEAD is not updated"
+msgstr "đã đổi tên nhánh thành %s, nhưng HEAD không được cập nhật"
+
+msgid "branch is renamed, but update of config-file failed"
+msgstr "đã đổi tên nhánh, nhưng cập nhật tập tin cấu hình gặp lỗi"
+
+msgid "branch is copied, but update of config-file failed"
+msgstr "đã sao chép nhánh, nhưng cập nhật tập tin cấu hình gặp lỗi"
 
 #, c-format
 msgid ""
 "Please edit the description for the branch\n"
 "  %s\n"
-"Lines starting with '%c' will be stripped.\n"
+"Lines starting with '%s' will be stripped.\n"
 msgstr ""
-"Viết các ghi chú cho nhánh:\n"
+"Viết các ghi chú cho nhánh\n"
 "  %s\n"
-"Những dòng được bắt đầu bằng “%c” sẽ được cắt bỏ.\n"
+"Những dòng được bắt đầu bằng '%s' sẽ được cắt bỏ.\n"
 
 msgid "Generic options"
 msgstr "Tùy chọn chung"
@@ -2866,7 +2884,7 @@
 msgstr "tô màu kết xuất"
 
 msgid "act on remote-tracking branches"
-msgstr "thao tác trên nhánh “remote-tracking”"
+msgstr "thao tác trên nhánh 'remote-tracking'"
 
 msgid "print only branches that contain the commit"
 msgstr "chỉ hiển thị những nhánh mà nó chứa lần chuyển giao"
@@ -2878,7 +2896,7 @@
 msgstr "Hành động git-branch:"
 
 msgid "list both remote-tracking and local branches"
-msgstr "liệt kê cả nhánh “remote-tracking” và nội bộ"
+msgstr "liệt kê cả nhánh 'remote-tracking' và nội bộ"
 
 msgid "delete fully merged branch"
 msgstr "xóa một toàn bộ nhánh đã hòa trộn"
@@ -2892,6 +2910,9 @@
 msgid "move/rename a branch, even if target exists"
 msgstr "di chuyển hoặc đổi tên một nhánh ngay cả khi đích đã có sẵn"
 
+msgid "do not output a newline after empty formatted refs"
+msgstr "không in ra ký tự xuống dòng sau tham chiếu rỗng"
+
 msgid "copy a branch and its reflog"
 msgstr "sao chép một nhánh và reflog của nó"
 
@@ -2937,8 +2958,8 @@
 msgid "format to use for the output"
 msgstr "định dạng sẽ dùng cho đầu ra"
 
-msgid "Failed to resolve HEAD as a valid ref."
-msgstr "Gặp lỗi khi phân giải HEAD như là một tham chiếu hợp lệ."
+msgid "failed to resolve HEAD as a valid ref"
+msgstr "gặp lỗi khi phân giải HEAD thành một tham chiếu hợp lệ."
 
 msgid "HEAD not found below refs/heads!"
 msgstr "Không tìm thấy HEAD ở dưới refs/heads!"
@@ -2956,22 +2977,20 @@
 msgid "branch name required"
 msgstr "cần chỉ ra tên nhánh"
 
-msgid "Cannot give description to detached HEAD"
-msgstr "Không thể đưa ra mô tả HEAD đã tách rời"
+msgid "cannot give description to detached HEAD"
+msgstr "không thể đưa ra mô tả cho HEAD đã tách rời"
 
 msgid "cannot edit description of more than one branch"
 msgstr "không thể sửa mô tả cho nhiều hơn một nhánh"
 
-#, c-format
-msgid "No commit on branch '%s' yet."
-msgstr "Vẫn chưa chuyển giao trên nhánh “%s”."
+msgid "cannot copy the current branch while not on any"
+msgstr "không thể sao chép nhánh hiện hành khi đang không ở trên nhánh nào."
 
-#, c-format
-msgid "No branch named '%s'."
-msgstr "Không có nhánh nào có tên “%s”."
+msgid "cannot rename the current branch while not on any"
+msgstr "không thể đổi tên nhánh hiện hành khi đang không ở trên nhánh nào."
 
 msgid "too many branches for a copy operation"
-msgstr "quá nhiều nhánh dành cho thao tác sao chép"
+msgstr "quá nhiều nhánh cho thao tác sao chép"
 
 msgid "too many arguments for a rename operation"
 msgstr "quá nhiều tham số cho thao tác đổi tên"
@@ -2981,50 +3000,48 @@
 
 #, c-format
 msgid ""
-"could not set upstream of HEAD to %s when it does not point to any branch."
+"could not set upstream of HEAD to %s when it does not point to any branch"
 msgstr ""
-"không thể đặt thượng nguồn của HEAD thành %s khi mà nó chẳng chỉ đến nhánh "
-"nào cả."
+"không thể đặt thượng nguồn của HEAD thành %s khi nó không chỉ đến nhánh nào."
 
 #, c-format
 msgid "no such branch '%s'"
-msgstr "không có nhánh nào như thế “%s”"
+msgstr "không có nhánh nào tên '%s'"
 
 #, c-format
 msgid "branch '%s' does not exist"
-msgstr "chưa có nhánh “%s”"
+msgstr "chưa có nhánh '%s'"
 
 msgid "too many arguments to unset upstream"
 msgstr "quá nhiều tham số để bỏ đặt thượng nguồn"
 
-msgid "could not unset upstream of HEAD when it does not point to any branch."
-msgstr "không thể bỏ đặt thượng nguồn của HEAD không chỉ đến một nhánh nào cả."
+msgid "could not unset upstream of HEAD when it does not point to any branch"
+msgstr "không thể bỏ đặt thượng nguồn của HEAD khi nó không chỉ đến nhánh nào."
 
 #, c-format
-msgid "Branch '%s' has no upstream information"
-msgstr "Nhánh “%s” không có thông tin thượng nguồn"
+msgid "branch '%s' has no upstream information"
+msgstr "nhánh '%s' không có thông tin thượng nguồn"
 
 msgid ""
-"The -a, and -r, options to 'git branch' do not take a branch name.\n"
+"the -a, and -r, options to 'git branch' do not take a branch name.\n"
 "Did you mean to use: -a|-r --list <pattern>?"
 msgstr ""
-"Hai tùy chọn -a và -r áp dụng cho lệnh “git branch” không nhận một tên "
-"nhánh.\n"
-"Có phải ý bạn là dùng: -a|-r --list <mẫu>?"
+"Hai tùy chọn -a, và -r, cho lệnh 'git branch' không nhận một tên nhánh.\n"
+"Có phải ý bạn là: -a|-r --list <mẫu>?"
 
 msgid ""
 "the '--set-upstream' option is no longer supported. Please use '--track' or "
-"'--set-upstream-to' instead."
+"'--set-upstream-to' instead"
 msgstr ""
-"tùy chọn --set-upstream đã không còn được hỗ trợ nữa. Vui lòng dùng “--"
-"track” hoặc “--set-upstream-to” để thay thế."
+"tùy chọn --set-upstream đã không còn được hỗ trợ nữa. Vui lòng dùng '--"
+"track' hoặc '--set-upstream-to'"
 
 msgid "git version:\n"
 msgstr "phiên bản git:\n"
 
 #, c-format
 msgid "uname() failed with error '%s' (%d)\n"
-msgstr "uname() gặp lỗi “%s” (%d)\n"
+msgstr "uname() gặp lỗi '%s' (%d)\n"
 
 msgid "compiler info: "
 msgstr "thông tin trình biên dịch: "
@@ -3033,11 +3050,16 @@
 msgstr "thông tin libc: "
 
 msgid "not run from a git repository - no hooks to show\n"
-msgstr "không chạy từ một kho git - nên chẳng có móc nào để mà hiển thị cả\n"
+msgstr "không chạy từ một kho git - nên chẳng có móc nào để hiển thị cả\n"
 
-msgid "git bugreport [-o|--output-directory <file>] [-s|--suffix <format>]"
+msgid ""
+"git bugreport [(-o | --output-directory) <path>]\n"
+"              [(-s | --suffix) <format> | --no-suffix]\n"
+"              [--diagnose[=<mode>]]"
 msgstr ""
-"git bugreport [-o|--output-directory <tập_tin>] [-s|--suffix <định_dạng>]"
+"git bugreport [(-o | --output-directory) <đường dẫn>]\n"
+"              [(-s | --suffix) <định dạng> | --no-suffix]\n"
+"              [--diagnose[=<chế độ>]]"
 
 msgid ""
 "Thank you for filling out a Git bug report!\n"
@@ -3059,29 +3081,45 @@
 "Cảm ơn bạn đã tạo một báo cáo lỗi Git!\n"
 "Vui lòng trả lời các câu hỏi sau để giúp chúng tôi hiểu vấn đề của bạn.\n"
 "\n"
-"Bạn đã làm gì trước khi lỗi xảy ra? (Các bước để tái tạo sự cố của bạn)\n"
+"Bạn đã làm gì trước khi lỗi xảy ra? (Các bước để tái hiện sự cố của bạn)\n"
 "\n"
 "Điều bạn mong muốn xảy ra? (Hành vi dự kiến)\n"
 "\n"
-"Điều gì đã xảy ra thay thế? (Hành vi thực tế)\n"
+"Điều gì đã xảy ra? (Hành vi thực tế)\n"
 "\n"
 "Có gì khác biệt giữa những gì bạn mong đợi và những gì thực sự xảy ra?\n"
 "\n"
-"Bất kỳ thứ gì khác bạn muốn thêm:\n"
+"Những thứ khác bạn muốn thêm:\n"
 "\n"
-"Vui lòng xen xét phần còn lại của báo cáo lỗi bên dưới.\n"
+"Vui lòng xem xét phần còn lại của báo cáo lỗi bên dưới.\n"
 "Bạn có thể xóa bất kỳ dòng nào bạn không muốn chia sẻ.\n"
 
-msgid "specify a destination for the bugreport file"
-msgstr "chỉ định thư mục định để tạo tập tin báo cáo lỗi"
+msgid "mode"
+msgstr "chế độ"
 
-msgid "specify a strftime format suffix for the filename"
+msgid ""
+"create an additional zip archive of detailed diagnostics (default 'stats')"
+msgstr ""
+"tạo thêm tập tin nén zip của bản báo cáo chi tiết hơn (mặc định 'stats')"
+
+msgid "specify a destination for the bugreport file(s)"
+msgstr "chỉ định thư mục đích để tạo tập tin báo cáo lỗi"
+
+msgid "specify a strftime format suffix for the filename(s)"
 msgstr ""
 "chỉ định chuỗi định dạng thời gian strftime dùng làm hậu tố cho tên tập tin"
 
 #, c-format
+msgid "unknown argument `%s'"
+msgstr "không hiểu đối số: '%s'"
+
+#, c-format
 msgid "could not create leading directories for '%s'"
-msgstr "không thể tạo các thư mục dẫn đầu cho “%s”"
+msgstr "không thể tạo các thư mục cha cho '%s'"
+
+#, c-format
+msgid "unable to create diagnostics archive %s"
+msgstr "không thể tạo bản báo cáo %s"
 
 msgid "System Info"
 msgstr "Thông tin hệ thống"
@@ -3095,34 +3133,41 @@
 
 #, c-format
 msgid "Created new report at '%s'.\n"
-msgstr "Đã tạo báo cáo mới tại “%s”\n"
+msgstr "Đã tạo báo cáo mới tại '%s'\n"
 
-msgid "git bundle create [<options>] <file> <git-rev-list args>"
-msgstr "git bundle create [<các tùy chọn>] <tập_tin> <git-rev-list args>"
+msgid ""
+"git bundle create [-q | --quiet | --progress]\n"
+"                  [--version=<version>] <file> <git-rev-list-args>"
+msgstr ""
+"git bundle create [-q | --quiet | --progress]\n"
+"                  [--version=<phiên_bản>] <tập tin> <đối-số-git-rev-list>"
 
-msgid "git bundle verify [<options>] <file>"
-msgstr "git bundle verify [<các tùy chọn>] <tập-tin>"
+msgid "git bundle verify [-q | --quiet] <file>"
+msgstr "git bundle verify [-q | --quiet] <tập-tin>"
 
 msgid "git bundle list-heads <file> [<refname>...]"
-msgstr "git bundle list-heads <tập tin> [<tên tham chiếu>…]"
+msgstr "git bundle list-heads <tập tin> [<tên tham chiếu>...]"
 
-msgid "git bundle unbundle <file> [<refname>...]"
-msgstr "git bundle unbundle <tập tin> [<tên tham chiếu>…]"
+msgid "git bundle unbundle [--progress] <file> [<refname>...]"
+msgstr "git bundle unbundle [--progress] <tập tin> [<tên tham chiếu>...]"
+
+msgid "need a <file> argument"
+msgstr "cần tham số <tập_tin>"
 
 msgid "do not show progress meter"
-msgstr "không hiển thị bộ đo tiến trình"
+msgstr "không hiển thị thanh đo tiến độ"
 
 msgid "show progress meter"
-msgstr "hiển thị bộ đo tiến trình"
+msgstr "hiển thị thanh đo tiến độ"
 
-msgid "show progress meter during object writing phase"
-msgstr "hiển thị bộ đo tiến triển trong suốt pha ghi đối tượng"
+msgid "historical; same as --progress"
+msgstr "tuỳ chọn cũ; giống như --progress"
 
-msgid "similar to --all-progress when progress meter is shown"
-msgstr "tương tự --all-progress khi bộ đo tiến trình được xuất hiện"
+msgid "historical; does nothing"
+msgstr "tuỳ chọn cũ; không làm gì cả"
 
 msgid "specify bundle format version"
-msgstr "chỉ điịnh định dạng cho bundle"
+msgstr "chỉ định phiên bản định dạng bundle"
 
 msgid "Need a repository to create a bundle."
 msgstr "Cần một kho chứa để có thể tạo một bundle."
@@ -3132,7 +3177,7 @@
 
 #, c-format
 msgid "%s is okay\n"
-msgstr "“%s” tốt\n"
+msgstr "%s tốt\n"
 
 msgid "Need a repository to unbundle."
 msgstr "Cần một kho chứa để có thể giải nén một bundle."
@@ -3141,12 +3186,8 @@
 msgstr "Tháo rời các đối tượng"
 
 #, c-format
-msgid "Unknown subcommand: %s"
-msgstr "Không hiểu câu lệnh con: %s"
-
-#, c-format
 msgid "cannot read object %s '%s'"
-msgstr "không thể đọc đối tượng %s “%s”"
+msgstr "không thể đọc đối tượng %s '%s'"
 
 msgid "flush is only for --buffer mode"
 msgstr "flush chỉ dành cho chế độ --buffer"
@@ -3166,10 +3207,6 @@
 msgid "%s takes no arguments"
 msgstr "%s không nhận tham số"
 
-#, c-format
-msgid "unknown command: '%s'"
-msgstr "không hiểu câu lệnh: '%s'"
-
 msgid "only one batch option may be specified"
 msgstr "chỉ một tùy chọn batch được chỉ ra"
 
@@ -3183,22 +3220,22 @@
 msgstr "git cat-file (-t | -s) [--allow-unknown-type] <đối_tượng>"
 
 msgid ""
-"git cat-file (--batch | --batch-check | --batch-command) [--batch-all-"
-"objects]\n"
-"             [--buffer] [--follow-symlinks] [--unordered]\n"
-"             [--textconv | --filters]"
+"git cat-file (--textconv | --filters)\n"
+"             [<rev>:<path|tree-ish> | --path=<path|tree-ish> <rev>]"
 msgstr ""
-"git cat-file (--batch | --batch-check | --batch-command) [--batch-all-"
-"objects]\n"
-"             [--buffer] [--follow-symlinks] [--unordered]\n"
-"             [--textconv | --filters]"
+"git cat-file (--textconv | --filters)\n"
+"             [<rev>:<path|tree-ish> | --path=<path|tree-ish> <rev>]"
 
 msgid ""
-"git cat-file (--textconv | --filters)\n"
-"             [<rev>:<path|tree-ish> | --path=<path|tree-ish> <rev>]"
+"git cat-file (--batch | --batch-check | --batch-command) [--batch-all-"
+"objects]\n"
+"             [--buffer] [--follow-symlinks] [--unordered]\n"
+"             [--textconv | --filters] [-Z]"
 msgstr ""
-"git cat-file (--textconv | --filters)\n"
-"             [<rev>:<path|tree-ish> | --path=<path|tree-ish> <rev>]"
+"git cat-file (--batch | --batch-check | --batch-command) [--batch-all-"
+"objects]\n"
+"             [--buffer] [--follow-symlinks] [--unordered]\n"
+"             [--textconv | --filters] [-Z]"
 
 msgid "Check object existence or emit object contents"
 msgstr "Kiểm tra đối tượng có sẵn hay không hoặc phát nội dung của đối tượng"
@@ -3223,10 +3260,11 @@
 msgid "allow -s and -t to work with broken/corrupt objects"
 msgstr "cho phép -s và -t để làm việc với các đối tượng sai/hỏng"
 
+msgid "use mail map file"
+msgstr "sử dụng tập tin ánh xạ thư"
+
 msgid "Batch objects requested on stdin (or --batch-all-objects)"
-msgstr ""
-"Đã yêu cầu các đối tượng batch trên đầu vào tiêu chuẩn stdin (hoặc --batch-"
-"all-objects)"
+msgstr "Đã yêu cầu các đối tượng batch trên stdin (hoặc --batch-all-objects)"
 
 msgid "show full <object> or <rev> contents"
 msgstr "hiển thị đầy đủ nội dung <object> hay <rev>"
@@ -3234,13 +3272,17 @@
 msgid "like --batch, but don't emit <contents>"
 msgstr "giống --batch, nhưng không phát ra <contents>"
 
+msgid "stdin is NUL-terminated"
+msgstr "stdin được kết thúc bởi NUL"
+
+msgid "stdin and stdout is NUL-terminated"
+msgstr "stdin và stdout được kết thúc bởi NUL"
+
 msgid "read commands from stdin"
-msgstr "đọc các lệnh từ đầu vào tiêu chuẩn"
+msgstr "đọc các lệnh từ stdin"
 
 msgid "with --batch[-check]: ignores stdin, batches all known objects"
-msgstr ""
-"với --batch[-check]: bỏ qua đầu vào tiêu chuẩn stdin, batch mọi đối tượng đã "
-"biết"
+msgstr "với --batch[-check]: bỏ qua stdin, batch mọi đối tượng đã biết"
 
 msgid "Change or optimize batch output"
 msgstr "Thay đổi hay tối ưu hóa đầu ra batch"
@@ -3283,11 +3325,11 @@
 
 #, c-format
 msgid "'%s' requires a batch mode"
-msgstr "“%s” cần một chế độ batch"
+msgstr "'%s' cần một chế độ batch"
 
 #, c-format
 msgid "'-%c' is incompatible with batch mode"
-msgstr "'-%c' là xung khắc với chế độ batch"
+msgstr "'-%c' không tương thích với chế độ batch"
 
 msgid "batch modes take no arguments"
 msgstr "chế độ batch không nhận các đối số"
@@ -3300,30 +3342,39 @@
 msgid "<object> required with '-%c'"
 msgstr "cần <object> với '-%c'"
 
-msgid "too many arguments"
-msgstr "có quá nhiều đối số"
-
 #, c-format
 msgid "only two arguments allowed in <type> <object> mode, not %d"
 msgstr "chỉ hai đối số được phép trong chế độ <type> <object>, không phải %d"
 
-msgid "git check-attr [-a | --all | <attr>...] [--] <pathname>..."
-msgstr "git check-attr [-a | --all | <attr>…] [--] tên-đường-dẫn…"
+msgid ""
+"git check-attr [--source <tree-ish>] [-a | --all | <attr>...] [--] "
+"<pathname>..."
+msgstr ""
+"git check-attr [--source <tree-ish>] [-a | --all | <attr>...] [--] <tên-"
+"đường-dẫn>..."
 
-msgid "git check-attr --stdin [-z] [-a | --all | <attr>...]"
-msgstr "git check-attr --stdin [-z] [-a | --all | <attr>…]"
+msgid ""
+"git check-attr --stdin [-z] [--source <tree-ish>] [-a | --all | <attr>...]"
+msgstr ""
+"git check-attr --stdin [-z] [--source <tree-ish>] [-a | --all | <attr>...]"
 
 msgid "report all attributes set on file"
-msgstr "báo cáo tất cả các thuộc tính đặt trên tập tin"
+msgstr "liệt kê tất cả các thuộc tính đặt trên tập tin"
 
 msgid "use .gitattributes only from the index"
-msgstr "chỉ dùng .gitattributes từ bảng mục lục"
+msgstr "chỉ dùng .gitattributes từ chỉ mục"
 
 msgid "read file names from stdin"
-msgstr "đọc tên tập tin từ đầu vào tiêu chuẩn"
+msgstr "đọc tên tập tin từ stdin"
 
 msgid "terminate input and output records by a NUL character"
-msgstr "chấm dứt các bản ghi vào và ra bằng ký tự NULL"
+msgstr "kết thúc các bản ghi vào và ra bằng ký tự NULL"
+
+msgid "<tree-ish>"
+msgstr "<tree-ish>"
+
+msgid "which tree-ish to check attributes at"
+msgstr "kiểm tra thuộc tính từ tree-ish nào"
 
 msgid "suppress progress reporting"
 msgstr "chặn các báo cáo tiến trình hoạt động"
@@ -3332,7 +3383,7 @@
 msgstr "hiển thị những đường dẫn đầu vào không khớp với mẫu"
 
 msgid "ignore index when checking"
-msgstr "bỏ qua mục lục khi kiểm tra"
+msgstr "bỏ qua chỉ mục khi kiểm tra"
 
 msgid "cannot specify pathnames with --stdin"
 msgstr "không thể chỉ định các tên đường dẫn với --stdin"
@@ -3353,14 +3404,14 @@
 msgstr "tùy-chọn --non-matching chỉ hợp lệ khi dùng với --verbose"
 
 msgid "git check-mailmap [<options>] <contact>..."
-msgstr "git check-mailmap [<các tùy chọn>] <danh-bạ>…"
+msgstr "git check-mailmap [<các tùy chọn>] <danh-bạ>..."
 
 msgid "also read contacts from stdin"
-msgstr "đồng thời đọc các danh bạ từ đầu vào tiêu chuẩn"
+msgstr "đồng thời đọc các danh bạ từ stdin"
 
 #, c-format
 msgid "unable to parse contact: %s"
-msgstr "không thể phân tích danh bạ: “%s”"
+msgstr "không thể đọc danh bạ: '%s'"
 
 msgid "no contacts specified"
 msgstr "chưa chỉ ra danh bạ"
@@ -3375,13 +3426,13 @@
 msgstr "khi tạo các tập tin, nối thêm <chuỗi>"
 
 msgid "git checkout-index [<options>] [--] [<file>...]"
-msgstr "git checkout-index [<các tùy chọn>] [--] [<tập-tin>…]"
+msgstr "git checkout-index [<các tùy chọn>] [--] [<tập-tin>...]"
 
 msgid "stage should be between 1 and 3 or all"
 msgstr "stage nên giữa 1 và 3 hay all"
 
 msgid "check out all files in the index"
-msgstr "lấy ra toàn bộ các tập tin trong bảng mục lục"
+msgstr "checkout toàn bộ các tập tin trong chỉ mục"
 
 msgid "do not skip files with skip-worktree set"
 msgstr "đừng bỏ qua các tập tin với skip-worktree được đặt"
@@ -3390,17 +3441,16 @@
 msgstr "ép buộc ghi đè lên tập tin đã sẵn có từ trước"
 
 msgid "no warning for existing files and files not in index"
-msgstr ""
-"không cảnh báo cho những tập tin tồn tại và không có trong bảng mục lục"
+msgstr "không cảnh báo cho những tập tin tồn tại và không có trong chỉ mục"
 
 msgid "don't checkout new files"
 msgstr "không checkout các tập tin mới"
 
 msgid "update stat information in the index file"
-msgstr "cập nhật thông tin thống kê trong tập tin lưu bảng mục lục mới"
+msgstr "cập nhật thông tin thống kê trong tập tin chỉ mục mới"
 
 msgid "read list of paths from the standard input"
-msgstr "đọc danh sách đường dẫn từ đầu vào tiêu chuẩn"
+msgstr "đọc danh sách đường dẫn từ stdin"
 
 msgid "write the content to temporary files"
 msgstr "ghi nội dung vào tập tin tạm"
@@ -3412,37 +3462,37 @@
 msgstr "git checkout [<các tùy chọn>] <nhánh>"
 
 msgid "git checkout [<options>] [<branch>] -- <file>..."
-msgstr "git checkout [<các tùy chọn>] [<nhánh>] -- <tập-tin>…"
+msgstr "git checkout [<các tùy chọn>] [<nhánh>] -- <tập-tin>..."
 
 msgid "git switch [<options>] [<branch>]"
 msgstr "git switch [<các tùy chọn>] [<nhánh>]"
 
 msgid "git restore [<options>] [--source=<branch>] <file>..."
-msgstr "git restore [<các tùy chọn>] [--source=<nhánh>] <tập tin>…"
+msgstr "git restore [<các tùy chọn>] [--source=<nhánh>] <tập tin>..."
 
 #, c-format
 msgid "path '%s' does not have our version"
-msgstr "đường dẫn “%s” không có các phiên bản của chúng ta"
+msgstr "đường dẫn '%s' không có các phiên bản của ta"
 
 #, c-format
 msgid "path '%s' does not have their version"
-msgstr "đường dẫn “%s” không có các phiên bản của chúng"
+msgstr "đường dẫn '%s' không có các phiên bản của họ"
 
 #, c-format
 msgid "path '%s' does not have all necessary versions"
-msgstr "đường dẫn “%s” không có tất cả các phiên bản cần thiết"
+msgstr "đường dẫn '%s' không có tất cả các phiên bản cần thiết"
 
 #, c-format
 msgid "path '%s' does not have necessary versions"
-msgstr "đường dẫn “%s” không có các phiên bản cần thiết"
+msgstr "đường dẫn '%s' không có các phiên bản cần thiết"
 
 #, c-format
 msgid "path '%s': cannot merge"
-msgstr "đường dẫn “%s”: không thể hòa trộn"
+msgstr "đường dẫn '%s': không thể hòa trộn"
 
 #, c-format
 msgid "Unable to add merge result for '%s'"
-msgstr "Không thể thêm kết quả hòa trộn cho “%s”"
+msgstr "Không thể thêm kết quả hòa trộn cho '%s'"
 
 #, c-format
 msgid "Recreated %d merge conflict"
@@ -3457,35 +3507,43 @@
 #, c-format
 msgid "Updated %d path from the index"
 msgid_plural "Updated %d paths from the index"
-msgstr[0] "Đã cập nhật đường dẫn %d từ mục lục"
+msgstr[0] "Đã cập nhật đường dẫn %d từ chỉ mục"
 
 #, c-format
 msgid "'%s' cannot be used with updating paths"
-msgstr "không được dùng “%s” với các đường dẫn cập nhật"
+msgstr "không được dùng '%s' với các đường dẫn cập nhật"
 
 #, c-format
 msgid "Cannot update paths and switch to branch '%s' at the same time."
 msgstr ""
-"Không thể cập nhật các đường dẫn và chuyển đến nhánh “%s” cùng một lúc."
+"Không thể cập nhật các đường dẫn và chuyển đến nhánh '%s' cùng một lúc."
 
 #, c-format
 msgid "neither '%s' or '%s' is specified"
-msgstr "không chỉ định “%s” cũng không “%s”"
+msgstr "không chỉ định '%s' cũng không '%s'"
 
 #, c-format
 msgid "'%s' must be used when '%s' is not specified"
-msgstr "phải có “%s” khi không chỉ định “%s”"
+msgstr "phải có '%s' khi không chỉ định '%s'"
 
 #, c-format
 msgid "'%s' or '%s' cannot be used with %s"
-msgstr "“%s” hay “%s” không thể được sử dụng với %s"
+msgstr "'%s' hay '%s' không thể được sử dụng với %s"
+
+#, c-format
+msgid "'%s', '%s', or '%s' cannot be used when checking out of a tree"
+msgstr "'%s', '%s', hay '%s' không thể được sử dụng khi checkout cây làm việc"
 
 #, c-format
 msgid "path '%s' is unmerged"
-msgstr "đường dẫn “%s” không được hòa trộn"
+msgstr "đường dẫn '%s' không được hòa trộn"
+
+#, c-format
+msgid "unable to read tree (%s)"
+msgstr "không thể đọc cây (%s)"
 
 msgid "you need to resolve your current index first"
-msgstr "bạn cần phải giải quyết bảng mục lục hiện tại của bạn trước đã"
+msgstr "bạn cần phải giải quyết chỉ mục hiện tại của bạn trước đã"
 
 #, c-format
 msgid ""
@@ -3498,7 +3556,7 @@
 
 #, c-format
 msgid "Can not do reflog for '%s': %s\n"
-msgstr "Không thể thực hiện reflog cho “%s”: %s\n"
+msgstr "Không thể thực hiện reflog cho '%s': %s\n"
 
 msgid "HEAD is now at"
 msgstr "HEAD hiện giờ tại"
@@ -3508,27 +3566,27 @@
 
 #, c-format
 msgid "Reset branch '%s'\n"
-msgstr "Đặt lại nhánh “%s”\n"
+msgstr "Đặt lại nhánh '%s'\n"
 
 #, c-format
 msgid "Already on '%s'\n"
-msgstr "Đã sẵn sàng trên “%s”\n"
+msgstr "Đã sẵn sàng trên '%s'\n"
 
 #, c-format
 msgid "Switched to and reset branch '%s'\n"
-msgstr "Đã chuyển tới và đặt lại nhánh “%s”\n"
+msgstr "Đã chuyển tới và đặt lại nhánh '%s'\n"
 
 #, c-format
 msgid "Switched to a new branch '%s'\n"
-msgstr "Đã chuyển đến nhánh mới “%s”\n"
+msgstr "Đã chuyển đến nhánh mới '%s'\n"
 
 #, c-format
 msgid "Switched to branch '%s'\n"
-msgstr "Đã chuyển đến nhánh “%s”\n"
+msgstr "Đã chuyển đến nhánh '%s'\n"
 
 #, c-format
 msgid " ... and %d more.\n"
-msgstr " … và nhiều hơn %d.\n"
+msgstr " ... và nhiều hơn %d.\n"
 
 #, c-format
 msgid ""
@@ -3582,7 +3640,7 @@
 "'%s' could be both a local file and a tracking branch.\n"
 "Please use -- (and optionally --no-guess) to disambiguate"
 msgstr ""
-"“%s” không thể là cả tập tin nội bộ và một nhánh theo dõi.\n"
+"'%s' không thể là cả tập tin nội bộ và một nhánh theo dõi.\n"
 "Vui long dùng -- (và tùy chọn thêm --no-guess) để tránh lẫn lộn"
 
 msgid ""
@@ -3595,18 +3653,18 @@
 "one remote, e.g. the 'origin' remote, consider setting\n"
 "checkout.defaultRemote=origin in your config."
 msgstr ""
-"Nếu ý bạn là lấy ra nhánh máy chủ được theo dõi, ví dụ “origin”,\n"
+"Nếu ý bạn là checkout nhánh máy chủ được theo dõi, ví dụ 'origin',\n"
 "bạn có thể làm như vậy bằng cách chỉ định đầy đủ tên với tùy chọn --track:\n"
 "\n"
 "    git checkout --track origin/<tên>\n"
 "\n"
-"Nếu bạn muốn luôn lấy ra từ một <tên> một máy chủ ưa thích\n"
-"chưa rõ ràng, ví dụ máy chủ “origin”, cân nhắc cài đặt\n"
+"Nếu bạn muốn luôn checkout từ một <tên> một máy chủ ưa thích\n"
+"chưa rõ ràng, ví dụ máy chủ 'origin', cân nhắc cài đặt\n"
 "checkout.defaultRemote=origin trong cấu hình của bạn."
 
 #, c-format
 msgid "'%s' matched multiple (%d) remote tracking branches"
-msgstr "“%s” khớp với nhiều (%d) nhánh máy chủ được theo dõi"
+msgstr "'%s' khớp với nhiều (%d) nhánh máy chủ được theo dõi"
 
 msgid "only one reference expected"
 msgstr "chỉ cần một tham chiếu"
@@ -3625,19 +3683,19 @@
 
 #, c-format
 msgid "a branch is expected, got tag '%s'"
-msgstr "cần một nhánh, nhưng lại nhận được thẻ “%s”"
+msgstr "cần một nhánh, nhưng lại có thẻ '%s'"
 
 #, c-format
 msgid "a branch is expected, got remote branch '%s'"
-msgstr "cần một nhánh, nhưng lại nhận được nhánh máy phục vụ “%s”"
+msgstr "cần một nhánh, nhưng lại có nhánh máy chủ '%s'"
 
 #, c-format
 msgid "a branch is expected, got '%s'"
-msgstr "cần một nhánh, nhưng lại nhận được “%s”"
+msgstr "cần một nhánh, nhưng lại có '%s'"
 
 #, c-format
 msgid "a branch is expected, got commit '%s'"
-msgstr "cần một nhánh, nhưng lại nhận được “%s”"
+msgstr "cần một nhánh, nhưng lại có '%s'"
 
 msgid ""
 "If you want to detach HEAD at the commit, try again with the --detach option."
@@ -3650,35 +3708,35 @@
 "Consider \"git merge --quit\" or \"git worktree add\"."
 msgstr ""
 "không thể chuyển nhánh trong khi đang hòa trộn\n"
-"Cân nhắc dung \"git merge --quit\" hoặc \"git worktree add\"."
+"Thử dung \"git merge --quit\" hoặc \"git worktree add\"."
 
 msgid ""
 "cannot switch branch in the middle of an am session\n"
 "Consider \"git am --quit\" or \"git worktree add\"."
 msgstr ""
 "không thể chuyển nhanh ở giữa một phiên am\n"
-"Cân nhắc dùng \"git am --quit\" hoặc \"git worktree add\"."
+"Thử dùng \"git am --quit\" hoặc \"git worktree add\"."
 
 msgid ""
 "cannot switch branch while rebasing\n"
 "Consider \"git rebase --quit\" or \"git worktree add\"."
 msgstr ""
 "không thể chuyển nhánh trong khi cải tổ\n"
-"Cân nhắc dùng \"git rebase --quit\" hay \"git worktree add\"."
+"Thử dùng \"git rebase --quit\" hay \"git worktree add\"."
 
 msgid ""
 "cannot switch branch while cherry-picking\n"
 "Consider \"git cherry-pick --quit\" or \"git worktree add\"."
 msgstr ""
-"không thể chuyển nhánh trong khi  cherry-picking\n"
-"Cân nhắc dùng \"git cherry-pick --quit\" hay \"git worktree add\"."
+"không thể chuyển nhánh trong khi cherry-pick\n"
+"Hãy dùng \"git cherry-pick --quit\" hay \"git worktree add\"."
 
 msgid ""
 "cannot switch branch while reverting\n"
 "Consider \"git revert --quit\" or \"git worktree add\"."
 msgstr ""
 "không thể chuyển nhánh trong khi hoàn nguyên\n"
-"Cân nhắc dùng \"git revert --quit\" hoặc \"git worktree add\"."
+"Thử dùng \"git revert --quit\" hoặc \"git worktree add\"."
 
 msgid "you are switching branch while bisecting"
 msgstr ""
@@ -3690,23 +3748,27 @@
 
 #, c-format
 msgid "'%s' cannot be used with switching branches"
-msgstr "“%s” không thể được sử dụng với các nhánh chuyển"
+msgstr "'%s' không thể được sử dụng với các nhánh chuyển"
 
 #, c-format
 msgid "'%s' cannot be used with '%s'"
-msgstr "“%s” không thể được dùng với “%s”"
+msgstr "'%s' không thể được dùng với '%s'"
 
 #, c-format
 msgid "'%s' cannot take <start-point>"
-msgstr "“%s” không thể nhận <điểm-đầu>"
+msgstr "'%s' không thể nhận <điểm-đầu>"
 
 #, c-format
 msgid "Cannot switch branch to a non-commit '%s'"
-msgstr "Không thể chuyển nhánh đến một thứ không phải là lần chuyển giao “%s”"
+msgstr "Không thể chuyển nhánh đến một thứ không phải là lần chuyển giao '%s'"
 
 msgid "missing branch or commit argument"
 msgstr "thiếu tham số là nhánh hoặc lần chuyển giao"
 
+#, c-format
+msgid "unknown conflict style '%s'"
+msgstr "không hiểu kiểu hiển thị xung đột '%s'"
+
 msgid "perform a 3-way merge with the new branch"
 msgstr "thực hiện hòa trộn kiểu 3-way với nhánh mới"
 
@@ -3720,13 +3782,13 @@
 msgstr "rời bỏ HEAD tại lần chuyển giao theo tên"
 
 msgid "force checkout (throw away local modifications)"
-msgstr "ép buộc lấy ra (bỏ đi những thay đổi nội bộ)"
+msgstr "ép buộc checkout (bỏ đi những thay đổi nội bộ)"
 
 msgid "new-branch"
 msgstr "nhánh-mới"
 
-msgid "new unparented branch"
-msgstr "nhánh không cha mới"
+msgid "new unborn branch"
+msgstr "nhánh chưa sinh mới"
 
 msgid "update ignored files (default)"
 msgstr "cập nhật các tập tin bị bỏ qua (mặc định)"
@@ -3735,15 +3797,13 @@
 msgstr "không kiểm tra nếu cây làm việc khác đang giữ tham chiếu đã cho"
 
 msgid "checkout our version for unmerged files"
-msgstr ""
-"lấy ra (checkout) phiên bản của chúng ta cho các tập tin chưa được hòa trộn"
+msgstr "checkout phiên bản của ta cho các tập tin chưa được hòa trộn"
 
 msgid "checkout their version for unmerged files"
-msgstr ""
-"lấy ra (checkout) phiên bản của chúng họ cho các tập tin chưa được hòa trộn"
+msgstr "checkout phiên bản của họ cho các tập tin chưa được hòa trộn"
 
 msgid "do not limit pathspecs to sparse entries only"
-msgstr "không giới hạn đặc tả đường dẫn thành chỉ các mục rải rác"
+msgstr "không giới hạn đặc tả đường dẫn chỉ trong các mục sparse (thưa)"
 
 #, c-format
 msgid "options '-%c', '-%c', and '%s' cannot be used together"
@@ -3758,7 +3818,7 @@
 
 #, c-format
 msgid "could not resolve %s"
-msgstr "không thể phân giải “%s”"
+msgstr "không thể phân giải '%s'"
 
 msgid "invalid path specification"
 msgstr "đường dẫn đã cho không hợp lệ"
@@ -3766,19 +3826,19 @@
 #, c-format
 msgid "'%s' is not a commit and a branch '%s' cannot be created from it"
 msgstr ""
-"“%s” không phải là một lần chuyển giao và một nhánh'%s” không thể được tạo "
+"'%s' không phải là một lần chuyển giao và một nhánh'%s' không thể được tạo "
 "từ đó"
 
 #, c-format
 msgid "git checkout: --detach does not take a path argument '%s'"
-msgstr "git checkout: --detach không nhận một đối số đường dẫn “%s”"
+msgstr "git checkout: --detach không nhận một đối số đường dẫn '%s'"
 
 msgid ""
 "git checkout: --ours/--theirs, --force and --merge are incompatible when\n"
 "checking out of the index."
 msgstr ""
 "git checkout: --ours/--theirs, --force và --merge là xung khắc với nhau khi\n"
-"checkout bảng mục lục (index)."
+"checkout chỉ mục (index)."
 
 msgid "you must specify path(s) to restore"
 msgstr "bạn phải chỉ định các thư mục muốn hồi phục"
@@ -3796,7 +3856,7 @@
 msgstr "tạo reflog cho nhánh mới"
 
 msgid "second guess 'git checkout <no-such-branch>' (default)"
-msgstr "gợi ý thứ hai “git checkout <không-nhánh-nào-như-vậy>” (mặc định)"
+msgstr "gợi ý thứ hai 'git checkout <không-nhánh-nào-như-vậy>' (mặc định)"
 
 msgid "use overlay mode (default)"
 msgstr "dùng chế độ che phủ (mặc định)"
@@ -3814,10 +3874,10 @@
 msgstr "vứt bỏ các sửa đổi địa phương"
 
 msgid "which tree-ish to checkout from"
-msgstr "lấy ra từ tree-ish nào"
+msgstr "checkout từ tree-ish nào"
 
 msgid "restore the index"
-msgstr "phục hồi bảng mục lục"
+msgstr "phục hồi chỉ mục"
 
 msgid "restore the working tree (default)"
 msgstr "phục hồi cây làm việc (mặc định)"
@@ -3829,18 +3889,18 @@
 msgstr "dùng chế độ che phủ"
 
 msgid ""
-"git clean [-d] [-f] [-i] [-n] [-q] [-e <pattern>] [-x | -X] [--] <paths>..."
+"git clean [-d] [-f] [-i] [-n] [-q] [-e <pattern>] [-x | -X] [--] "
+"[<pathspec>...]"
 msgstr ""
-"git clean [-d] [-f] [-i] [-n] [-q] [-e <mẫu>] [-x | -X] [--] </các/đường/"
-"dẫn>…"
+"git clean [-d] [-f] [-i] [-n] [-q] [-e <mẫu>] [-x | -X] [--][<đường/dẫn>...]"
 
 #, c-format
 msgid "Removing %s\n"
-msgstr "Đang gỡ bỏ %s\n"
+msgstr "Đang xoá %s\n"
 
 #, c-format
 msgid "Would remove %s\n"
-msgstr "Có thể gỡ bỏ %s\n"
+msgstr "Sẽ xoá %s\n"
 
 #, c-format
 msgid "Skipping repository %s\n"
@@ -3852,17 +3912,17 @@
 
 #, c-format
 msgid "failed to remove %s"
-msgstr "gặp lỗi khi gỡ bỏ %s"
+msgstr "gặp lỗi khi xoá %s"
 
 #, c-format
 msgid "could not lstat %s\n"
-msgstr "không thể lấy thông tin thống kê đầy đủ của %s\n"
+msgstr "không thể lstat %s\n"
 
 msgid "Refusing to remove current working directory\n"
-msgstr "Từ chối gỡ bỏ thư mục làm việc hiện tại\n"
+msgstr "Từ chối xoá thư mục làm việc hiện tại\n"
 
 msgid "Would refuse to remove current working directory\n"
-msgstr "Nên từ chối gỡ bỏ thư mục làm việc hiện tại\n"
+msgstr "Sẽ từ chối xoá bỏ thư mục làm việc hiện tại\n"
 
 #, c-format
 msgid ""
@@ -3892,17 +3952,17 @@
 "3-5        - chọn một vùng\n"
 "2-3,6-9    - chọn nhiều vùng\n"
 "foo        - chọn mục dựa trên tiền tố duy nhất\n"
-"-…         - không chọn các mục đã chỉ ra\n"
+"-...         - không chọn các mục đã chỉ ra\n"
 "*          - chọn tất\n"
 "           - (để trống) kết thúc việc chọn\n"
 
-#, c-format, perl-format
+#, c-format
 msgid "Huh (%s)?\n"
 msgstr "Hả (%s)?\n"
 
 #, c-format
 msgid "Input ignore patterns>> "
-msgstr "Mẫu để lọc các tập tin đầu vào cần lờ đi>> "
+msgstr "Mẫu để lọc các tập tin đầu vào cần bỏ qua>> "
 
 #, c-format
 msgid "WARNING: Cannot find items matched by: %s"
@@ -3914,7 +3974,7 @@
 #. TRANSLATORS: Make sure to keep [y/N] as is
 #, c-format
 msgid "Remove %s [y/N]? "
-msgstr "Xóa bỏ “%s” [y/N]? "
+msgstr "Xóa bỏ '%s' [y/N]? "
 
 msgid ""
 "clean               - start cleaning\n"
@@ -3935,7 +3995,7 @@
 
 msgid "Would remove the following item:"
 msgid_plural "Would remove the following items:"
-msgstr[0] "Có muốn gỡ bỏ (các) mục sau đây không:"
+msgstr[0] "Có muốn xoá (các) mục sau đây không:"
 
 msgid "No more files to clean, exiting."
 msgstr "Không còn tập-tin nào để dọn dẹp, đang thoát ra."
@@ -3950,13 +4010,13 @@
 msgstr "dọn bằng kiểu tương tác"
 
 msgid "remove whole directories"
-msgstr "gỡ bỏ toàn bộ thư mục"
+msgstr "xoá toàn bộ thư mục"
 
 msgid "pattern"
 msgstr "mẫu"
 
 msgid "add <pattern> to ignore rules"
-msgstr "thêm <mẫu> vào trong qui tắc bỏ qua"
+msgstr "thêm <mẫu> vào trong quy tắc bỏ qua"
 
 msgid "remove ignored files, too"
 msgstr "đồng thời gỡ bỏ cả các tập tin bị bỏ qua"
@@ -3964,22 +4024,10 @@
 msgid "remove only ignored files"
 msgstr "chỉ gỡ bỏ những tập tin bị bỏ qua"
 
-msgid ""
-"clean.requireForce set to true and neither -i, -n, nor -f given; refusing to "
-"clean"
+msgid "clean.requireForce is true and -f not given: refusing to clean"
 msgstr ""
-"clean.requireForce được đặt thành true và không đưa ra tùy chọn -i, -n mà "
-"cũng không -f; từ chối lệnh dọn dẹp (clean)"
-
-msgid ""
-"clean.requireForce defaults to true and neither -i, -n, nor -f given; "
-"refusing to clean"
-msgstr ""
-"clean.requireForce mặc định được đặt là true và không đưa ra tùy chọn -i, -n "
-"mà cũng không -f; từ chối lệnh dọn dẹp (clean)"
-
-msgid "-x and -X cannot be used together"
-msgstr "-x và -X không thể dùng cùng nhau"
+"clean.requireForce được đặt thành true và không có tuỳ chọn -f; từ chối dọn "
+"dẹp"
 
 msgid "git clone [<options>] [--] <repo> [<dir>]"
 msgstr "git clone [<các tùy chọn>] [--] <kho> [<t.mục>]"
@@ -3991,10 +4039,10 @@
 msgstr "không tạo một checkout"
 
 msgid "create a bare repository"
-msgstr "tạo kho thuần"
+msgstr "tạo kho bare"
 
-msgid "create a mirror repository (implies bare)"
-msgstr "tạo kho bản sao (ý là kho thuần)"
+msgid "create a mirror repository (implies --bare)"
+msgstr "tạo kho bản sao (ngụ ý --bare)"
 
 msgid "to clone from a local repository"
 msgstr "để nhân bản từ kho nội bộ"
@@ -4030,10 +4078,10 @@
 msgstr "tên"
 
 msgid "use <name> instead of 'origin' to track upstream"
-msgstr "dùng <tên> thay cho “origin” để theo dõi thượng nguồn"
+msgstr "dùng <tên> thay cho 'origin' để theo dõi thượng nguồn"
 
 msgid "checkout <branch> instead of the remote's HEAD"
-msgstr "lấy ra <nhánh> thay cho HEAD của máy chủ"
+msgstr "checkout <nhánh> thay cho HEAD của máy chủ"
 
 msgid "path to git-upload-pack on the remote"
 msgstr "đường dẫn đến git-upload-pack trên máy chủ"
@@ -4044,9 +4092,6 @@
 msgid "create a shallow clone of that depth"
 msgstr "tạo bản sao không đầy đủ cho mức sâu đã cho"
 
-msgid "time"
-msgstr "thời-gian"
-
 msgid "create a shallow clone since a specific time"
 msgstr "tạo bản sao không đầy đủ từ thời điểm đã cho"
 
@@ -4073,6 +4118,9 @@
 msgid "separate git dir from working tree"
 msgstr "không dùng chung thư mục dành riêng cho git và thư mục làm việc"
 
+msgid "specify the reference format to use"
+msgstr "dùng định dạng tham chiếu nào cho các lần chuyển giao"
+
 msgid "key=value"
 msgstr "khóa=giá_trị"
 
@@ -4085,40 +4133,48 @@
 msgid "option to transmit"
 msgstr "tùy chọn để chuyển giao"
 
-msgid "use IPv4 addresses only"
-msgstr "chỉ dùng địa chỉ IPv4"
-
-msgid "use IPv6 addresses only"
-msgstr "chỉ dùng địa chỉ IPv6"
-
 msgid "apply partial clone filters to submodules"
 msgstr "áp dụng các bộ lọc nhân bản một phần cho mô-đun-con"
 
 msgid "any cloned submodules will use their remote-tracking branch"
-msgstr "mọi mô-đun-con nhân bản sẽ dung nhánh theo dõi máy chủ của chúng"
+msgstr "mọi mô-đun-con được nhân bản sẽ dùng nhánh theo dõi máy chủ của chúng"
 
 msgid "initialize sparse-checkout file to include only files at root"
 msgstr "khởi tạo tập tin sparse-checkout để bao gồm chỉ các tập tin ở gốc"
 
+msgid "uri"
+msgstr "uri"
+
+msgid "a URI for downloading bundles before fetching from origin remote"
+msgstr "URI để tải xuống bundle trước khi lấy về từ máy chủ origin"
+
 #, c-format
 msgid "info: Could not add alternate for '%s': %s\n"
-msgstr "thông tin: không thể thêm thay thế cho “%s”: %s\n"
+msgstr "thông tin: không thể thêm thay thế cho '%s': %s\n"
 
 #, c-format
 msgid "failed to stat '%s'"
-msgstr "gặp lỗi khi lấy thống kê về “%s”"
+msgstr "gặp lỗi khi stat '%s'"
 
 #, c-format
 msgid "%s exists and is not a directory"
 msgstr "%s có tồn tại nhưng lại không phải là một thư mục"
 
 #, c-format
+msgid "'%s' is a symlink, refusing to clone with --local"
+msgstr "'%s' là liên kết mềm, từ chối sao chép với --local"
+
+#, c-format
 msgid "failed to start iterator over '%s'"
-msgstr "gặp lỗi khi bắt đầu lặp qua “%s”"
+msgstr "gặp lỗi khi bắt đầu lặp qua '%s'"
+
+#, c-format
+msgid "symlink '%s' exists, refusing to clone with --local"
+msgstr "liên kết mềm '%s' đã tồn tại, từ chối sao chép với --local"
 
 #, c-format
 msgid "failed to unlink '%s'"
-msgstr "gặp lỗi khi bỏ liên kết (unlink) “%s”"
+msgstr "gặp lỗi khi unlink '%s'"
 
 #, c-format
 msgid "failed to create link '%s'"
@@ -4126,11 +4182,11 @@
 
 #, c-format
 msgid "failed to copy file to '%s'"
-msgstr "gặp lỗi khi sao chép tập tin và “%s”"
+msgstr "gặp lỗi khi sao chép tập tin và '%s'"
 
 #, c-format
 msgid "failed to iterate over '%s'"
-msgstr "gặp lỗi khi lặp qua “%s”"
+msgstr "gặp lỗi khi lặp qua '%s'"
 
 #, c-format
 msgid "done.\n"
@@ -4142,8 +4198,8 @@
 "and retry with 'git restore --source=HEAD :/'\n"
 msgstr ""
 "Việc nhân bản thành công, nhưng checkout gặp lỗi.\n"
-"Bạn kiểm tra kỹ xem cái gì được lấy ra bằng lệnh “git status”\n"
-"và thử lấy ra với lệnh “git restore --source=HEAD :/”\n"
+"Kiểm tra xem cái gì đã được checkout bằng lệnh 'git status'\n"
+"và thử lại với lệnh 'git restore --source=HEAD :/'\n"
 
 #, c-format
 msgid "Could not find remote branch %s to clone."
@@ -4159,11 +4215,11 @@
 msgid "failed to initialize sparse-checkout"
 msgstr "gặp lỗi khi khởi tạo sparse-checkout"
 
-msgid "remote HEAD refers to nonexistent ref, unable to checkout.\n"
-msgstr "refers HEAD máy chủ  chỉ đến ref không tồn tại, không thể lấy ra.\n"
+msgid "remote HEAD refers to nonexistent ref, unable to checkout"
+msgstr "HEAD ở máy chủ chỉ đến ref không tồn tại, không thể checkout"
 
 msgid "unable to checkout working tree"
-msgstr "không thể lấy ra (checkout) cây làm việc"
+msgstr "không thể checkout cây làm việc"
 
 msgid "unable to write parameters to config file"
 msgstr "không thể ghi các tham số vào tập tin cấu hình"
@@ -4175,18 +4231,18 @@
 msgstr "không thể bỏ liên kết tập tin thay thế tạm thời"
 
 msgid "Too many arguments."
-msgstr "Có quá nhiều đối số."
+msgstr "Quá nhiều đối số."
 
 msgid "You must specify a repository to clone."
-msgstr "Bạn phải chỉ định một kho để mà nhân bản (clone)."
+msgstr "Bạn phải chỉ định một kho để nhân bản."
 
 #, c-format
-msgid "options '%s' and '%s %s' cannot be used together"
-msgstr "tùy chọn '%s', và '%s %s' không thể dùng cùng nhau"
+msgid "unknown ref storage format '%s'"
+msgstr "Không hiểu định dạng lưu tham chiếu '%s'"
 
 #, c-format
 msgid "repository '%s' does not exist"
-msgstr "kho chứa “%s” chưa tồn tại"
+msgstr "kho chứa '%s' chưa tồn tại"
 
 #, c-format
 msgid "depth %s is not a positive number"
@@ -4194,32 +4250,32 @@
 
 #, c-format
 msgid "destination path '%s' already exists and is not an empty directory."
-msgstr "đường dẫn đích “%s” đã có từ trước và không phải là một thư mục rỗng."
+msgstr "đường dẫn đích '%s' đã có từ trước và không phải là một thư mục rỗng."
 
 #, c-format
 msgid "repository path '%s' already exists and is not an empty directory."
 msgstr ""
-"đường dẫn kho chứa “%s” đã có từ trước và không phải là một thư mục rỗng."
+"đường dẫn kho chứa '%s' đã có từ trước và không phải là một thư mục rỗng."
 
 #, c-format
 msgid "working tree '%s' already exists."
-msgstr "cây làm việc “%s” đã sẵn tồn tại rồi."
+msgstr "cây làm việc '%s' đã sẵn tồn tại rồi."
 
 #, c-format
 msgid "could not create leading directories of '%s'"
-msgstr "không thể tạo các thư mục dẫn đầu của “%s”"
+msgstr "không thể tạo các thư mục dẫn đầu của '%s'"
 
 #, c-format
 msgid "could not create work tree dir '%s'"
-msgstr "không thể tạo cây thư mục làm việc dir “%s”"
+msgstr "không thể tạo cây làm việc dir '%s'"
 
 #, c-format
 msgid "Cloning into bare repository '%s'...\n"
-msgstr "Đang nhân bản thành kho chứa bare “%s”…\n"
+msgstr "Đang nhân bản thành kho chứa bare '%s'...\n"
 
 #, c-format
 msgid "Cloning into '%s'...\n"
-msgstr "Đang nhân bản thành “%s”…\n"
+msgstr "Đang nhân bản thành '%s'...\n"
 
 msgid ""
 "clone --recursive is not compatible with both --reference and --reference-if-"
@@ -4230,24 +4286,25 @@
 
 #, c-format
 msgid "'%s' is not a valid remote name"
-msgstr "“%s” không phải tên máy chủ hợp lệ"
+msgstr "'%s' không phải tên máy chủ hợp lệ"
 
 msgid "--depth is ignored in local clones; use file:// instead."
-msgstr "--depth bị lờ đi khi nhân bản nội bộ; hãy sử dụng file:// để thay thế."
+msgstr ""
+"--depth bị bỏ qua khi nhân bản nội bộ; hãy sử dụng file:// để thay thế."
 
 msgid "--shallow-since is ignored in local clones; use file:// instead."
 msgstr ""
-"--shallow-since bị lờ đi khi nhân bản nội bộ; hãy sử dụng file:// để thay "
+"--shallow-since bị bỏ qua khi nhân bản nội bộ; hãy sử dụng file:// để thay "
 "thế."
 
 msgid "--shallow-exclude is ignored in local clones; use file:// instead."
 msgstr ""
-"--shallow-exclude bị lờ đi khi nhân bản nội bộ; hãy sử dụng file:// để thay "
+"--shallow-exclude bị bỏ qua khi nhân bản nội bộ; hãy sử dụng file:// để thay "
 "thế."
 
 msgid "--filter is ignored in local clones; use file:// instead."
 msgstr ""
-"--filter bị lờ đi khi nhân bản nội bộ; hãy sử dụng file:// để thay thế."
+"--filter bị bỏ qua khi nhân bản nội bộ; hãy sử dụng file:// để thay thế."
 
 msgid "source repository is shallow, reject to clone."
 msgstr "kho nguồn là nông, nên bỏ từ chối nhân bản."
@@ -4256,13 +4313,23 @@
 msgstr "kho nguồn là nông, nên bỏ qua --local"
 
 msgid "--local is ignored"
-msgstr "--local bị lờ đi"
+msgstr "--local bị bỏ qua"
 
 msgid "cannot clone from filtered bundle"
 msgstr "không thể nhân bản từ bundle được lọc ra"
 
+msgid "failed to initialize the repo, skipping bundle URI"
+msgstr "khởi tạo kho chứa thất bại, đang bỏ qua URI bundle"
+
+#, c-format
+msgid "failed to fetch objects from bundle URI '%s'"
+msgstr "lấy về đối tượng từ URI bundle '%s' thất bại"
+
+msgid "failed to fetch advertised bundles"
+msgstr "lấy về bundle thất bại"
+
 msgid "remote transport reported error"
-msgstr "vận chuyển máy mạng đã báo cáo lỗi"
+msgstr "trình vận chuyển đã báo lỗi"
 
 #, c-format
 msgid "Remote branch %s not found in upstream %s"
@@ -4292,38 +4359,50 @@
 msgid "padding space between columns"
 msgstr "chèn thêm khoảng trắng giữa các cột"
 
+#, c-format
+msgid "%s must be non-negative"
+msgstr "%s phải không âm"
+
 msgid "--command must be the first argument"
 msgstr "--command phải là đối số đầu tiên"
 
 msgid ""
-"git commit-graph verify [--object-dir <objdir>] [--shallow] [--[no-]progress]"
+"git commit-graph verify [--object-dir <dir>] [--shallow] [--[no-]progress]"
 msgstr ""
 "git commit-graph verify [--object-dir </thư/mục/đối/tượng>] [--shallow] [--"
 "[no-]progress]"
 
 msgid ""
-"git commit-graph write [--object-dir <objdir>] [--append] [--"
-"split[=<strategy>]] [--reachable|--stdin-packs|--stdin-commits] [--changed-"
-"paths] [--[no-]max-new-filters <n>] [--[no-]progress] <split options>"
+"git commit-graph write [--object-dir <dir>] [--append]\n"
+"                       [--split[=<strategy>]] [--reachable | --stdin-packs | "
+"--stdin-commits]\n"
+"                       [--changed-paths] [--[no-]max-new-filters <n>] [--"
+"[no-]progress]\n"
+"                       <split-options>"
 msgstr ""
-"git commit-graph write [--object-dir </thư/mục/đối/tượng>] [--append][--"
-"split[=<chiến lược>]] [--reachable|--stdin-packs|--stdin-commits][--changed-"
-"paths] [--[no-]max-new-filters <n>] [--[no-]progress] <các tùy chọn chia "
-"tách>"
+"git commit-graph write [--object-dir </thư/mục/đối/tượng>] [--append]\n"
+"                       [--split[=<chiến lược>]] [--reachable | --stdin-packs "
+"| --stdin-commits]\n"
+"                       [--changed-paths] [--[no-]max-new-filters <n>] [--"
+"[no-]progress]\n"
+"                       <các tùy chọn chia tách>"
 
 msgid "dir"
-msgstr "tmục"
+msgstr "thư mục"
 
 msgid "the object directory to store the graph"
 msgstr "thư mục đối tượng để lưu đồ thị"
 
 msgid "if the commit-graph is split, only verify the tip file"
-msgstr ""
-"nếu đồ-thị-các-lần-chuyển-giao bị chia cắt, thì chỉ thẩm tra tập tin đỉnh"
+msgstr "nếu đồ-thị-chuyển-giao bị chia cắt, thì chỉ thẩm tra tập tin đỉnh"
 
 #, c-format
 msgid "Could not open commit-graph '%s'"
-msgstr "Không thể mở đồ thị chuyển giao “%s”"
+msgstr "Không thể mở đồ thị chuyển giao '%s'"
+
+#, c-format
+msgid "could not open commit-graph chain '%s'"
+msgstr "Không thể mở dãy đồ thị chuyển giao '%s'"
 
 #, c-format
 msgid "unrecognized --split argument, %s"
@@ -4331,7 +4410,7 @@
 
 #, c-format
 msgid "unexpected non-hex object ID: %s"
-msgstr "nhận được ID đối tượng không phải dạng hex không cần: %s"
+msgstr "nhận được ID đối tượng không phải dạng hex bất thường %s"
 
 #, c-format
 msgid "invalid object: %s"
@@ -4339,24 +4418,19 @@
 
 #, c-format
 msgid "option `%s' expects a numerical value"
-msgstr "tùy chọn “%s” cần một giá trị bằng số"
+msgstr "tùy chọn '%s' cần một giá trị bằng số"
 
 msgid "start walk at all refs"
 msgstr "bắt đầu di chuyển tại mọi tham chiếu"
 
 msgid "scan pack-indexes listed by stdin for commits"
-msgstr ""
-"quét dó các mục lục gói được liệt kê bởi đầu vào tiêu chuẩn cho các lần "
-"chuyển giao"
+msgstr "quét dó các chỉ mục gói được liệt kê bởi stdin cho các lần chuyển giao"
 
 msgid "start walk at commits listed by stdin"
-msgstr ""
-"bắt đầu di chuyển tại các lần chuyển giao được liệt kê bởi đầu vào tiêu chuẩn"
+msgstr "bắt đầu di chuyển tại các lần chuyển giao được liệt kê bởi stdin"
 
 msgid "include all commits already in the commit-graph file"
-msgstr ""
-"bao gồm mọi lần chuyển giao đã sẵn có trongười tập tin đồ-thị-các-lần-chuyển-"
-"giao"
+msgstr "bao gồm mọi lần chuyển giao đã sẵn có trong tập tin đồ-thị-chuyển-giao"
 
 msgid "enable computation for changed paths"
 msgstr "cho phép tính toán các đường dẫn đã bị thay đổi"
@@ -4366,11 +4440,11 @@
 
 msgid "maximum number of commits in a non-base split commit-graph"
 msgstr ""
-"số lượng tối đa của các lần chuyển giao trong một đồ-thị-các-lần-chuyển-giao "
-"chia cắt không-cơ-sở"
+"số lượng tối đa của các lần chuyển giao trong một đồ-thị-chuyển-giao chia "
+"cắt không-cơ-sở"
 
 msgid "maximum ratio between two levels of a split commit-graph"
-msgstr "tỷ lệ tối đa giữa hai mức của một đồ-thị-các-lần-chuyển-giao chia cắt"
+msgstr "tỉ lệ tối đa giữa hai mức của một đồ-thị-chuyển-giao chia cắt"
 
 msgid "only expire files older than a given date-time"
 msgstr "chỉ làm hết hạn các tập tin khi nó cũ hơn khoảng <thời gian> đưa ra"
@@ -4385,16 +4459,15 @@
 msgid "Collecting commits from input"
 msgstr "Sưu tập các lần chuyển giao từ đầu vào"
 
-#, c-format
-msgid "unrecognized subcommand: %s"
-msgstr "không hiểu câu lệnh con: %s"
+msgid "git commit-tree <tree> [(-p <parent>)...]"
+msgstr "git commit-tree <cây> [(-p <cha>)...]"
 
 msgid ""
-"git commit-tree [(-p <parent>)...] [-S[<keyid>]] [(-m <message>)...] [(-F "
-"<file>)...] <tree>"
+"git commit-tree [(-p <parent>)...] [-S[<keyid>]] [(-m <message>)...]\n"
+"                [(-F <file>)...] <tree>"
 msgstr ""
-"git commit-tree [(-p <cha>)…] [-S[<keyid>]] [(-m <ghi chú>)…] [(-F <tập tin>)"
-"…] <cây>"
+"git commit-tree [(-p <cha>)...] [-S[<keyid>]] [(-m <ghi chú>)...]\n"
+"                [(-F <tập tin>)...] <cây>"
 
 #, c-format
 msgid "duplicate parent %s ignored"
@@ -4402,15 +4475,15 @@
 
 #, c-format
 msgid "not a valid object name %s"
-msgstr "không phải là tên đối tượng hợp lệ “%s”"
+msgstr "không phải là tên đối tượng hợp lệ '%s'"
 
 #, c-format
 msgid "git commit-tree: failed to read '%s'"
-msgstr "git commit-tree: gặp lỗi khi đọc “%s”"
+msgstr "git commit-tree: gặp lỗi khi đọc '%s'"
 
 #, c-format
 msgid "git commit-tree: failed to close '%s'"
-msgstr "git commit-tree: gặp lỗi khi đóng “%s”"
+msgstr "git commit-tree: gặp lỗi khi đóng '%s'"
 
 msgid "parent"
 msgstr "cha-mẹ"
@@ -4436,22 +4509,38 @@
 msgid "git commit-tree: failed to read"
 msgstr "git commit-tree: gặp lỗi khi đọc"
 
-msgid "git commit [<options>] [--] <pathspec>..."
-msgstr "git commit [<các tùy chọn>] [--] <pathspec>…"
+msgid ""
+"git commit [-a | --interactive | --patch] [-s] [-v] [-u<mode>] [--amend]\n"
+"           [--dry-run] [(-c | -C | --squash) <commit> | --fixup [(amend|"
+"reword):]<commit>)]\n"
+"           [-F <file> | -m <msg>] [--reset-author] [--allow-empty]\n"
+"           [--allow-empty-message] [--no-verify] [-e] [--author=<author>]\n"
+"           [--date=<date>] [--cleanup=<mode>] [--[no-]status]\n"
+"           [-i | -o] [--pathspec-from-file=<file> [--pathspec-file-nul]]\n"
+"           [(--trailer <token>[(=|:)<value>])...] [-S[<keyid>]]\n"
+"           [--] [<pathspec>...]"
+msgstr ""
+"git commit [-a | --interactive | --patch] [-s] [-v] [-u<chế-độ>] [--amend]\n"
+"           [--dry-run] [(-c | -C | --squash) <lần chuyển giao> | --fixup "
+"[(amend|reword):]<lần chuyển giao>)]\n"
+"           [-F <tập tin> | -m <ghi chú>] [--reset-author] [--allow-empty]\n"
+"           [--allow-empty-message] [--no-verify] [-e] [--author=<tác giả>]\n"
+"           [--date=<ngày tháng>] [--cleanup=<chế-độ>] [--[no-]status]\n"
+"           [-i | -o] [--pathspec-from-file=<tập-tin> [--pathspec-file-nul]]\n"
+"           [(--trailer <thẻ>[(=|:)<giá-trị>])...] [-S[<keyid>]]\n"
+"           [--] [<pathspec>...]"
 
-msgid "git status [<options>] [--] <pathspec>..."
-msgstr "git status [<các tùy chọn>] [--] <pathspec>…"
+msgid "git status [<options>] [--] [<pathspec>...]"
+msgstr "git status [<các tùy chọn>] [--] <pathspec>..."
 
 msgid ""
 "You asked to amend the most recent commit, but doing so would make\n"
 "it empty. You can repeat your command with --allow-empty, or you can\n"
 "remove the commit entirely with \"git reset HEAD^\".\n"
 msgstr ""
-"Bạn đã yêu cầu amend (“tu bổ”) phần lớn các lần chuyển giao gần đây, nhưng "
-"làm như thế\n"
-"có thể làm cho nó trở nên trống rỗng. Bạn có thể lặp lại lệnh của mình bằng "
-"--allow-empty,\n"
-"hoặc là bạn gỡ bỏ các lần chuyển giao một cách hoàn toàn bằng lệnh:\n"
+"Bạn đã yêu cầu amend ('tu bổ') lần chuyển giao gần nhất, nhưng làm vậy\n"
+"sẽ làm cho nó trở nên rỗng. Bạn có thể lặp lại lệnh với --allow-empty,\n"
+"hoặc là bạn gỡ bỏ lần chuyển giao một cách hoàn toàn bằng lệnh:\n"
 "\"git reset HEAD^\".\n"
 
 msgid ""
@@ -4461,18 +4550,17 @@
 "    git commit --allow-empty\n"
 "\n"
 msgstr ""
-"Lần cherry-pick trước hiện nay trống rỗng, có lẽ là bởi vì sự phân giải xung "
-"đột.\n"
+"Lần cherry-pick trước hiện nay trống rỗng, có lẽ là do giải quyết xung đột.\n"
 "Nếu bạn vẫn muốn chuyển giao nó cho dù thế nào đi nữa, hãy dùng:\n"
 "\n"
 "    git commit --allow-empty\n"
 "\n"
 
 msgid "Otherwise, please use 'git rebase --skip'\n"
-msgstr "Nếu không được thì dùng lệnh \"git rebase --skip\"\n"
+msgstr "Nếu không thì dùng lệnh \"git rebase --skip\"\n"
 
 msgid "Otherwise, please use 'git cherry-pick --skip'\n"
-msgstr "Nếu không được thì dùng lệnh \"git cherry-pick --skip\"\n"
+msgstr "Nếu không thì dùng lệnh \"git cherry-pick --skip\"\n"
 
 msgid ""
 "and then use:\n"
@@ -4489,12 +4577,15 @@
 "\n"
 "    git cherry-pick --continue\n"
 "\n"
-"để lại tiếp tục cherry-picking các lần chuyển giao còn lại.\n"
+"để lại tiếp tục cherry-pick các lần chuyển giao còn lại.\n"
 "Nếu bạn muốn bỏ qua lần chuyển giao này thì dùng:\n"
 "\n"
 "    git cherry-pick --skip\n"
 "\n"
 
+msgid "updating files failed"
+msgstr "cập nhật tập tin gặp lỗi"
+
 msgid "failed to unpack HEAD tree object"
 msgstr "gặp lỗi khi tháo dỡ HEAD đối tượng cây"
 
@@ -4502,20 +4593,17 @@
 msgstr "Không đường dẫn với các tùy chọn --include/--only không hợp lý."
 
 msgid "unable to create temporary index"
-msgstr "không thể tạo bảng mục lục tạm thời"
+msgstr "không thể tạo chỉ mục tạm thời"
 
 msgid "interactive add failed"
 msgstr "gặp lỗi khi thêm bằng cách tương"
 
 msgid "unable to update temporary index"
-msgstr "không thể cập nhật bảng mục lục tạm thời"
+msgstr "không thể cập nhật chỉ mục tạm thời"
 
 msgid "Failed to update main cache tree"
 msgstr "Gặp lỗi khi cập nhật cây bộ nhớ đệm"
 
-msgid "unable to write new_index file"
-msgstr "không thể ghi tập tin lưu bảng mục lục mới (new_index)"
-
 msgid "cannot do a partial commit during a merge."
 msgstr ""
 "không thể thực hiện việc chuyển giao cục bộ trong khi đang được hòa trộn."
@@ -4529,21 +4617,21 @@
 "không thể thực hiện việc chuyển giao cục bộ trong khi đang thực hiện cải tổ."
 
 msgid "cannot read the index"
-msgstr "không đọc được bảng mục lục"
+msgstr "không đọc được chỉ mục"
 
 msgid "unable to write temporary index file"
-msgstr "không thể ghi tập tin lưu bảng mục lục tạm thời"
+msgstr "không thể ghi tập tin chỉ mục tạm thời"
 
 #, c-format
 msgid "commit '%s' lacks author header"
-msgstr "lần chuyển giao “%s” thiếu phần tác giả ở đầu"
+msgstr "lần chuyển giao '%s' thiếu phần tác giả ở đầu"
 
 #, c-format
 msgid "commit '%s' has malformed author line"
-msgstr "lần chuyển giao “%s” có phần tác giả ở đầu dị dạng"
+msgstr "lần chuyển giao '%s' có phần tác giả ở đầu dị dạng"
 
 msgid "malformed --author parameter"
-msgstr "đối số cho --author bị dị hình"
+msgstr "đối số cho --author bị sai quy cách"
 
 #, c-format
 msgid "invalid date format: %s"
@@ -4557,19 +4645,19 @@
 "trong phần ghi chú hiện tại"
 
 #, c-format
-msgid "could not lookup commit %s"
-msgstr "không thể tìm kiếm commit (lần chuyển giao) %s"
+msgid "could not lookup commit '%s'"
+msgstr "không thể tìm kiếm lần chuyển giao '%s'"
 
 #, c-format
 msgid "(reading log message from standard input)\n"
-msgstr "(đang đọc thông điệp nhật ký từ đầu vào tiêu chuẩn)\n"
+msgstr "(đang đọc thông điệp nhật ký từ stdin)\n"
 
 msgid "could not read log from standard input"
-msgstr "không thể đọc nhật ký từ đầu vào tiêu chuẩn"
+msgstr "không thể đọc nhật ký từ stdin"
 
 #, c-format
 msgid "could not read log file '%s'"
-msgstr "không đọc được tệp nhật ký “%s”"
+msgstr "không đọc được tập nhật ký '%s'"
 
 #, c-format
 msgid "options '%s' and '%s:%s' cannot be used together"
@@ -4583,7 +4671,7 @@
 
 #, c-format
 msgid "could not open '%s'"
-msgstr "không thể mở “%s”"
+msgstr "không thể mở '%s'"
 
 msgid "could not write commit template"
 msgstr "không thể ghi mẫu chuyển giao"
@@ -4591,39 +4679,39 @@
 #, c-format
 msgid ""
 "Please enter the commit message for your changes. Lines starting\n"
-"with '%c' will be ignored.\n"
+"with '%s' will be ignored.\n"
 msgstr ""
 "Hãy nhập vào các thông tin để giải thích các thay đổi của bạn. Những\n"
-"dòng được bắt đầu bằng “%c” sẽ được bỏ qua.\n"
+"dòng được bắt đầu bằng '%s' sẽ được bỏ qua.\n"
 
 #, 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"
+"with '%s' will be ignored, and an empty message aborts the commit.\n"
 msgstr ""
 "Hãy nhập vào các thông tin để giải thích các thay đổi của bạn. Những dòng "
 "được\n"
-"bắt đầu bằng “%c” sẽ được bỏ qua, nếu phần chú thích rỗng sẽ hủy bỏ lần "
+"bắt đầu bằng '%s' sẽ được bỏ qua, nếu phần chú thích rỗng sẽ hủy bỏ lần "
 "chuyển giao.\n"
 
 #, 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"
+"with '%s' will be kept; you may remove them yourself if you want to.\n"
 msgstr ""
 "Hãy nhập vào các thông tin để giải thích các thay đổi của bạn. Những dòng "
 "được\n"
-"bắt đầu bằng “%c” sẽ được bỏ qua; bạn có thể xóa chúng đi nếu muốn thế.\n"
+"bắt đầu bằng '%s' sẽ được bỏ qua; bạn có thể xóa chúng đi nếu muốn thế.\n"
 
 #, 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"
+"with '%s' will be kept; you may remove them yourself if you want to.\n"
 "An empty message aborts the commit.\n"
 msgstr ""
 "Hãy nhập vào các thông tin để giải thích các thay đổi của bạn. Những dòng "
 "được\n"
-"bắt đầu bằng “%c” sẽ được bỏ qua; bạn có thể xóa chúng đi nếu muốn thế.\n"
+"bắt đầu bằng '%s' sẽ được bỏ qua; bạn có thể xóa chúng đi nếu muốn thế.\n"
 "Phần chú thích này nếu trống rỗng sẽ hủy bỏ lần chuyển giao.\n"
 
 msgid ""
@@ -4665,10 +4753,10 @@
 msgstr "%sNgười chuyển giao: %.*s <%.*s>"
 
 msgid "Cannot read index"
-msgstr "Không đọc được bảng mục lục"
+msgstr "Không đọc được chỉ mục"
 
 msgid "unable to pass trailers to --trailers"
-msgstr "không thể chuyển phần đuôi cho “--trailers”"
+msgstr "không thể chuyển phần đuôi cho '--trailers'"
 
 msgid "Error building trees"
 msgstr "Gặp lỗi khi xây dựng cây"
@@ -4680,25 +4768,25 @@
 #, c-format
 msgid "--author '%s' is not 'Name <email>' and matches no existing author"
 msgstr ""
-"--author “%s” không phải là “Họ và tên <thư điện tửl>” và không khớp bất kỳ "
-"tác giả nào sẵn có"
+"--author '%s' không phải là 'Họ-và-tên <email>' và không khớp bất kỳ tác giả "
+"nào sẵn có"
 
 #, c-format
 msgid "Invalid ignored mode '%s'"
-msgstr "Chế độ bỏ qua không hợp lệ “%s”"
+msgstr "Chế độ bỏ qua không hợp lệ '%s'"
 
 #, c-format
 msgid "Invalid untracked files mode '%s'"
-msgstr "Chế độ cho các tập tin chưa được theo dõi không hợp lệ “%s”"
+msgstr "Chế độ cho các tập tin chưa được theo dõi không hợp lệ '%s'"
 
 msgid "You are in the middle of a merge -- cannot reword."
 msgstr ""
-"Bạn đang ở giữa của quá trình hòa trộn -- không thể thực hiện việc “reword”."
+"Bạn đang ở giữa của quá trình hòa trộn -- không thể thực hiện việc 'reword'."
 
 msgid "You are in the middle of a cherry-pick -- cannot reword."
 msgstr ""
 "Bạn đang ở giữa của quá trình cherry-pick -- không thể thực hiện việc "
-"“reword”."
+"'reword'."
 
 #, c-format
 msgid "reword option of '%s' and path '%s' cannot be used together"
@@ -4710,20 +4798,20 @@
 msgstr "không thể tổ hợp tùy chọn \"reword\" của '%s' với '%s' cùng nhau"
 
 msgid "You have nothing to amend."
-msgstr "Không có gì để mà “tu bổ” cả."
+msgstr "Không có gì để 'tu bổ' cả."
 
 msgid "You are in the middle of a merge -- cannot amend."
 msgstr ""
-"Bạn đang ở giữa của quá trình hòa trộn -- không thể thực hiện việc “tu bổ”."
+"Bạn đang ở giữa của quá trình hòa trộn -- không thể thực hiện việc 'tu bổ'."
 
 msgid "You are in the middle of a cherry-pick -- cannot amend."
 msgstr ""
-"Bạn đang ở giữa của quá trình cherry-pick -- không thể thực hiện việc “tu "
-"bổ”."
+"Bạn đang ở giữa của quá trình cherry-pick -- không thể thực hiện việc 'tu "
+"bổ'."
 
 msgid "You are in the middle of a rebase -- cannot amend."
 msgstr ""
-"Bạn đang ở giữa của quá trình cải tổ -- nên không thể thực hiện việc “tu bổ”."
+"Bạn đang ở giữa của quá trình cải tổ -- nên không thể thực hiện việc 'tu bổ'."
 
 msgid "--reset-author can be used only with -C, -c or --amend."
 msgstr ""
@@ -4735,7 +4823,7 @@
 
 #, c-format
 msgid "paths '%s ...' with -a does not make sense"
-msgstr "các đường dẫn “%s …” với tùy chọn -a không hợp lý"
+msgstr "các đường dẫn '%s ...' với tùy chọn -a không hợp lý"
 
 msgid "show status concisely"
 msgstr "hiển thị trạng thái ở dạng súc tích"
@@ -4747,7 +4835,7 @@
 msgstr "hiển thị thông tin về tạm cất"
 
 msgid "compute full ahead/behind values"
-msgstr "tính đầy đủ giá trị trước/sau"
+msgstr "tính đầy đủ giá trị dẫn trước/sau"
 
 msgid "version"
 msgstr "phiên bản"
@@ -4759,10 +4847,7 @@
 msgstr "hiển thị trạng thái ở định dạng dài (mặc định)"
 
 msgid "terminate entries with NUL"
-msgstr "chấm dứt các mục bằng NUL"
-
-msgid "mode"
-msgstr "chế độ"
+msgstr "kết thúc các mục bằng NUL"
 
 msgid "show untracked files, optional modes: all, normal, no. (Default: all)"
 msgstr ""
@@ -4790,20 +4875,19 @@
 msgstr "hiển thị danh sách các tập-tin chưa được theo dõi trong các cột"
 
 msgid "do not detect renames"
-msgstr "không dò tìm các tên thay đổi"
+msgstr "không dò tìm các lần đổi tên"
 
 msgid "detect renames, optionally set similarity index"
-msgstr "dò các tên thay đổi, tùy ý đặt mục lục tương tự"
+msgstr "tìm và phát hiện các lần đổi tên, có thể đánh chỉ số tương tự"
 
 msgid "Unsupported combination of ignored and untracked-files arguments"
-msgstr ""
-"Không hỗ trỡ tổ hợp các tham số các tập tin bị bỏ qua và không được theo dõi"
+msgstr "Không hỗ trợ cùng lúc tham số tập tin bị bỏ qua và không được theo dõi"
 
 msgid "suppress summary after successful commit"
 msgstr "không hiển thị tổng kết sau khi chuyển giao thành công"
 
 msgid "show diff in commit message template"
-msgstr "hiển thị sự khác biệt trong mẫu tin nhắn chuyển giao"
+msgstr "hiển thị diff trong mẫu tin nhắn chuyển giao"
 
 msgid "Commit message options"
 msgstr "Các tùy chọn ghi chú commit"
@@ -4878,7 +4962,7 @@
 msgstr "chuyển giao tất cả các tập tin có thay đổi"
 
 msgid "add specified files to index for commit"
-msgstr "thêm các tập tin đã chỉ ra vào bảng mục lục để chuyển giao"
+msgstr "thêm các tập tin đã chỉ ra vào chỉ mục để chuyển giao"
 
 msgid "interactively add files"
 msgstr "thêm các tập-tin bằng tương tác"
@@ -4896,7 +4980,7 @@
 msgstr "hiển thị xem cái gì có thể được chuyển giao"
 
 msgid "amend previous commit"
-msgstr "“tu bổ” (amend) lần commit trước"
+msgstr "'tu bổ' (amend) lần commit trước"
 
 msgid "bypass post-rewrite hook"
 msgstr "vòng qua móc (hook) post-rewrite"
@@ -4908,7 +4992,7 @@
 msgstr "ok để ghi các thay đổi với lời nhắn trống rỗng"
 
 msgid "could not parse HEAD commit"
-msgstr "không thể phân tích commit (lần chuyển giao) HEAD"
+msgstr "không thể đọc commit (lần chuyển giao) HEAD"
 
 #, c-format
 msgid "Corrupt MERGE_HEAD file (%s)"
@@ -4923,27 +5007,26 @@
 
 #, c-format
 msgid "Aborting commit due to empty commit message.\n"
-msgstr "Bãi bỏ việc chuyển giao bởi vì phần chú thích của nó trống rỗng.\n"
+msgstr "Huỷ bỏ lệnh chuyển giao bởi vì phần chú thích của nó trống rỗng.\n"
 
 #, c-format
 msgid "Aborting commit; you did not edit the message.\n"
 msgstr ""
-"Đang bỏ qua việc chuyển giao; bạn đã không biên soạn phần chú thích "
-"(message).\n"
+"Huỷ bỏ lệnh chuyển giao; bạn đã không biên soạn phần chú thích (message).\n"
 
 #, c-format
 msgid "Aborting commit due to empty commit message body.\n"
 msgstr ""
-"Bãi bỏ việc chuyển giao bởi vì phần thân chú thích của nó trống rỗng.\n"
+"Huỷ bỏ lệnh chuyển giao bởi vì phần thân chú thích của nó trống rỗng.\n"
 
 msgid ""
 "repository has been updated, but unable to write\n"
-"new_index file. Check that disk is not full and quota is\n"
+"new index file. Check that disk is not full and quota is\n"
 "not exceeded, and then \"git restore --staged :/\" to recover."
 msgstr ""
 "kho chứa đã được cập nhật, nhưng không thể ghi vào\n"
-"tập tin new_index (bảng mục lục mới). Hãy kiểm tra xem đĩa\n"
-"có bị đầy quá hay quota (hạn nghạch đĩa cứng) bị vượt quá,\n"
+"tập tin chỉ mục mới. Hãy kiểm tra xem đĩa\n"
+"có bị đầy quá hay hạn nghạch đĩa (quota) bị vượt quá hay không,\n"
 "và sau đó \"git restore --staged :/\" để khắc phục."
 
 msgid "git config [<options>]"
@@ -5017,7 +5100,7 @@
 msgstr "liệt kê tất"
 
 msgid "use string equality when comparing values to 'value-pattern'"
-msgstr "sử dụng so sánh bằng chuỗi khi so sánh các giá trị với “value-pattern”"
+msgstr "sử dụng so sánh bằng chuỗi khi so sánh các giá trị với 'value-pattern'"
 
 msgid "open an editor"
 msgstr "mở một trình biên soạn"
@@ -5059,7 +5142,7 @@
 msgstr "Khác"
 
 msgid "terminate values with NUL byte"
-msgstr "chấm dứt giá trị với byte NUL"
+msgstr "kết thúc giá trị với byte NUL"
 
 msgid "show variable names only"
 msgstr "chỉ hiển thị các tên biến"
@@ -5068,9 +5151,7 @@
 msgstr "tôn trọng kể cà các hướng trong tìm kiếm"
 
 msgid "show origin of config (file, standard input, blob, command line)"
-msgstr ""
-"hiển thị nguyên gốc của cấu hình (tập tin, đầu vào tiêu chuẩn, blob, dòng "
-"lệnh)"
+msgstr "hiển thị nguồn gốc của cấu hình (tập tin, stdin, blob, dòng lệnh)"
 
 msgid "show scope of config (worktree, local, global, system, command)"
 msgstr ""
@@ -5083,6 +5164,9 @@
 msgid "with --get, use default value when missing entry"
 msgstr "với --get, dùng giá trị mặc định khi thiếu mục tin"
 
+msgid "human-readable comment string (# will be prepended as needed)"
+msgstr "ghi chú cho người đọc được (tự động thêm # vào trước nếu cần)"
+
 #, c-format
 msgid "wrong number of arguments, should be %d"
 msgstr "sai số lượng tham số, phải là %d"
@@ -5105,16 +5189,16 @@
 
 #, c-format
 msgid "cannot parse color '%s'"
-msgstr "không thể phân tích màu “%s”"
+msgstr "không thể đọc màu '%s'"
 
 msgid "unable to parse default color value"
-msgstr "không thể phân tích giá trị màu mặc định"
+msgstr "không thể đọc giá trị màu mặc định"
 
 msgid "not in a git directory"
 msgstr "không trong thư mục git"
 
 msgid "writing to stdin is not supported"
-msgstr "việc ghi ra đầu ra tiêu chuẩn là không được hỗ trợ"
+msgstr "việc ghi ra stdin là không được hỗ trợ"
 
 msgid "writing config blobs is not supported"
 msgstr "không hỗ trợ ghi cấu hình các blob"
@@ -5176,25 +5260,28 @@
 msgid "--default is only applicable to --get"
 msgstr "--default chỉ được áp dụng cho --get"
 
+msgid "--comment is only applicable to add/set/replace operations"
+msgstr "--comment chỉ được áp dụng cho thao tác add/set/replace"
+
 msgid "--fixed-value only applies with 'value-pattern'"
-msgstr "--fixed-value chỉ áp dụng với “value-pattern”"
+msgstr "--fixed-value chỉ áp dụng với 'value-pattern'"
 
 #, c-format
 msgid "unable to read config file '%s'"
-msgstr "không thể đọc tập tin cấu hình “%s”"
+msgstr "không thể đọc tập tin cấu hình '%s'"
 
 msgid "error processing config file(s)"
 msgstr "gặp lỗi khi xử lý các tập tin cấu hình"
 
 msgid "editing stdin is not supported"
-msgstr "sửa chữa đầu ra tiêu chuẩn là không được hỗ trợ"
+msgstr "sửa chữa stdin là không được hỗ trợ"
 
 msgid "editing blobs is not supported"
 msgstr "việc sửa chữa các blob là không được hỗ trợ"
 
 #, c-format
 msgid "cannot create configuration file %s"
-msgstr "không thể tạo tập tin cấu hình “%s”"
+msgstr "không thể tạo tập tin cấu hình '%s'"
 
 #, c-format
 msgid ""
@@ -5219,12 +5306,12 @@
 "\tchmod 0700 %s"
 msgstr ""
 "Quyền hạn trên thư mục gói mạng của bạn không chính xác; người dùng\n"
-"khác có lẽ có thể đọc được chứng thư được lưu đệm của bạn. Cân nhắc chạy:\n"
+"khác có lẽ có thể đọc được chứng thư được lưu đệm của bạn. Thử chạy:\n"
 "\n"
 "\tchmod 0700 %s"
 
 msgid "print debugging messages to stderr"
-msgstr "in thông tin gỡ lỗi ra đầu ra lỗi tiêu chuẩn"
+msgstr "in thông tin gỡ lỗi ra stderr"
 
 msgid "credential-cache--daemon unavailable; no unix socket support"
 msgstr "credential-cache--daemon không sẵn có; không hỗ trợ unix socket"
@@ -5236,17 +5323,24 @@
 msgid "unable to get credential storage lock in %d ms"
 msgstr "không thể lấy khóa lưu trữ ủy nhiệm %d ms"
 
-msgid "git describe [<options>] [<commit-ish>...]"
-msgstr "git describe [<các tùy chọn>] <commit-ish>*"
+msgid ""
+"git describe [--all] [--tags] [--contains] [--abbrev=<n>] [<commit-ish>...]"
+msgstr ""
+"git describe [--all] [--tags] [--contains] [--abbrev=<n>] [<commit-ish>...]"
 
-msgid "git describe [<options>] --dirty"
-msgstr "git describe [<các tùy chọn>] --dirty"
+msgid ""
+"git describe [--all] [--tags] [--contains] [--abbrev=<n>] --dirty[=<mark>]"
+msgstr ""
+"git describe [--all] [--tags] [--contains] [--abbrev=<n>] --dirty[=<mark>]"
+
+msgid "git describe <blob>"
+msgstr "git describe <blob>"
 
 msgid "head"
-msgstr "phía trước"
+msgstr "head"
 
 msgid "lightweight"
-msgstr "hạng nhẹ"
+msgstr "nhẹ"
 
 msgid "annotated"
 msgstr "có diễn giải"
@@ -5257,11 +5351,11 @@
 
 #, c-format
 msgid "tag '%s' is externally known as '%s'"
-msgstr "ở bên ngoài, thẻ “%s” đã được biết đến là “%s”"
+msgstr "ở bên ngoài, thẻ '%s' đã được biết đến là '%s'"
 
 #, c-format
 msgid "no tag exactly matches '%s'"
-msgstr "không có thẻ nào khớp chính xác với “%s”"
+msgstr "không có thẻ nào khớp chính xác với '%s'"
 
 #, c-format
 msgid "No exact match on refs or tags, searching to describe\n"
@@ -5276,7 +5370,7 @@
 "No annotated tags can describe '%s'.\n"
 "However, there were unannotated tags: try --tags."
 msgstr ""
-"Không có thẻ được chú giải nào được mô tả là “%s”.\n"
+"Không có thẻ được chú giải nào được mô tả là '%s'.\n"
 "Tuy nhiên, ở đây có những thẻ không được chú giải: hãy thử --tags."
 
 #, c-format
@@ -5284,7 +5378,7 @@
 "No tags can describe '%s'.\n"
 "Try --always, or create some tags."
 msgstr ""
-"Không có thẻ có thể mô tả “%s”.\n"
+"Không có thẻ có thể mô tả '%s'.\n"
 "Hãy thử --always, hoặc tạo một số thẻ."
 
 #, c-format
@@ -5315,13 +5409,13 @@
 msgstr "tìm các thẻ mà nó đến trước lần chuyển giao"
 
 msgid "debug search strategy on stderr"
-msgstr "chiến lược tìm kiếm gỡ lỗi trên đầu ra lỗi chuẩn stderr"
+msgstr "gỡ lỗi chiến lược tìm kiếm ra stderr"
 
 msgid "use any ref"
 msgstr "dùng ref bất kỳ"
 
 msgid "use any tag, even unannotated"
-msgstr "dùng thẻ bất kỳ, cả khi “unannotated”"
+msgstr "dùng thẻ bất kỳ, cả khi 'unannotated'"
 
 msgid "always use long format"
 msgstr "luôn dùng định dạng dài"
@@ -5333,39 +5427,60 @@
 msgstr "chỉ xuất những gì khớp chính xác"
 
 msgid "consider <n> most recent tags (default: 10)"
-msgstr "coi như <n> thẻ gần đây nhất (mặc định: 10)"
+msgstr "chọn trong <n> thẻ gần đây nhất (mặc định: 10)"
 
 msgid "only consider tags matching <pattern>"
-msgstr "chỉ cân nhắc đến những thẻ khớp với <mẫu>"
+msgstr "chỉ chọn những thẻ khớp với <mẫu>"
 
 msgid "do not consider tags matching <pattern>"
-msgstr "không coi rằng các thẻ khớp với <mẫu>"
+msgstr "không chọn những thẻ khớp với <mẫu>"
 
 msgid "show abbreviated commit object as fallback"
-msgstr "hiển thị đối tượng chuyển giao vắn tắt như là fallback"
+msgstr "hiển thị vắn tắt đối tượng chuyển giao để thay thế"
 
 msgid "mark"
 msgstr "dấu"
 
 msgid "append <mark> on dirty working tree (default: \"-dirty\")"
-msgstr "thêm <dấu> trên cây thư mục làm việc bẩn (mặc định \"-dirty\")"
+msgstr "thêm <dấu> trên cây làm việc không sạch (mặc định \"-dirty\")"
 
 msgid "append <mark> on broken working tree (default: \"-broken\")"
-msgstr "thêm <dấu> trên cây thư mục làm việc bị hỏng (mặc định \"-broken\")"
+msgstr "thêm <dấu> trên cây làm việc bị hỏng (mặc định \"-broken\")"
 
 msgid "No names found, cannot describe anything."
-msgstr "Không tìm thấy các tên, không thể mô tả gì cả."
+msgstr "Không tìm thấy tên, không thể mô tả gì cả."
 
 #, c-format
 msgid "option '%s' and commit-ishes cannot be used together"
 msgstr "tùy chọn '%s' và commit-ishes không thể dùng cùng nhau"
 
+msgid ""
+"git diagnose [(-o | --output-directory) <path>] [(-s | --suffix) <format>]\n"
+"             [--mode=<mode>]"
+msgstr ""
+"git diagnose [(-o | --output-directory) <tập tin>] [(-s | --suffix) <định "
+"dạng>]\n"
+"             [--mode=<chế độ>]"
+
+msgid "specify a destination for the diagnostics archive"
+msgstr "chỉ định thư mục đích để tạo bản báo cáo"
+
+msgid "specify a strftime format suffix for the filename"
+msgstr ""
+"chỉ định chuỗi định dạng thời gian strftime dùng làm hậu tố cho tên tập tin"
+
+msgid "specify the content of the diagnostic archive"
+msgstr "chỉ định nội dung bản báo cáo"
+
 msgid "--merge-base only works with two commits"
 msgstr "--merge-base chỉ hoạt động với hai lần chuyển giao"
 
 #, c-format
 msgid "'%s': not a regular file or symlink"
-msgstr "“%s”: không phải tập tin bình thường hay liên kết mềm"
+msgstr "'%s': không phải tập tin bình thường hay liên kết mềm"
+
+msgid "no merge given, only parents."
+msgstr "không có lần hoà trộn, chỉ có các lần chuyển giao cha"
 
 #, c-format
 msgid "invalid option: %s"
@@ -5373,31 +5488,31 @@
 
 #, c-format
 msgid "%s...%s: no merge base"
-msgstr "%s…%s: không có cơ sở hòa trộn"
+msgstr "%s...%s: không có gốc hòa trộn"
 
 msgid "Not a git repository"
 msgstr "Không phải là kho git"
 
 #, c-format
 msgid "invalid object '%s' given."
-msgstr "đối tượng đã cho “%s” không hợp lệ."
+msgstr "đối tượng đã cho '%s' không hợp lệ."
 
 #, c-format
 msgid "more than two blobs given: '%s'"
-msgstr "đã cho nhiều hơn hai đối tượng blob: “%s”"
+msgstr "đã cho nhiều hơn hai đối tượng blob: '%s'"
 
 #, c-format
 msgid "unhandled object '%s' given."
-msgstr "đã cho đối tượng không thể nắm giữ “%s”."
+msgstr "đã cho đối tượng không thể xử lý '%s'."
 
 #, c-format
 msgid "%s...%s: multiple merge bases, using %s"
-msgstr "%s…%s: có nhiều cơ sở để hòa trộn, nên dùng %s"
+msgstr "%s...%s: có nhiều gốc hòa trộn, sẽ dùng %s"
 
 msgid "git difftool [<options>] [<commit> [<commit>]] [--] [<path>...]"
 msgstr ""
 "git difftool [<các tùy chọn>] [<lần_chuyển_giao> [<lần_chuyển_giao>]] [--] </"
-"đường/dẫn>…]"
+"đường/dẫn>...]"
 
 #, c-format
 msgid "could not read symlink %s"
@@ -5415,23 +5530,23 @@
 "combined diff formats ('-c' and '--cc') are not supported in\n"
 "directory diff mode ('-d' and '--dir-diff')."
 msgstr ""
-"các định dạng diff tổ hợp(“-c” và “--cc”) chưa được hỗ trợ trong\n"
-"chế độ diff thư mục(“-d” và “--dir-diff”)."
+"các định dạng diff tổ hợp('-c' và '--cc') chưa được hỗ trợ trong\n"
+"chế độ diff thư mục('-d' và '--dir-diff')."
 
 #, c-format
 msgid "both files modified: '%s' and '%s'."
-msgstr "cả hai tập tin đã bị sửa: “%s” và “%s”."
+msgstr "cả hai tập tin đã bị sửa: '%s' và '%s'."
 
 msgid "working tree file has been left."
 msgstr "cây làm việc ở bên trái."
 
 #, c-format
 msgid "could not copy '%s' to '%s'"
-msgstr "không thể chép “%s” sang “%s”"
+msgstr "không thể chép '%s' sang '%s'"
 
 #, c-format
 msgid "temporary files exist in '%s'."
-msgstr "các tập tin tạm đã sẵn có trong “%s”."
+msgstr "các tập tin tạm đã sẵn có trong '%s'."
 
 msgid "you may want to cleanup or recover these."
 msgstr "bạn có lẽ muốn dọn dẹp hay phục hồi ở đây."
@@ -5441,7 +5556,7 @@
 msgstr "gặp lỗi: %d"
 
 msgid "use `diff.guitool` instead of `diff.tool`"
-msgstr "dùng “diff.guitool“ thay vì dùng “diff.tool“"
+msgstr "dùng 'diff.guitool' thay vì dùng 'diff.tool'"
 
 msgid "perform a full-directory diff"
 msgstr "thực hiện một diff toàn thư mục"
@@ -5459,18 +5574,18 @@
 msgstr "dùng công cụ diff đã cho"
 
 msgid "print a list of diff tools that may be used with `--tool`"
-msgstr "in ra danh sách các công cụ dif cái mà có thẻ dùng với “--tool“"
+msgstr "in ra danh sách các công cụ dif cái mà có thẻ dùng với '--tool'"
 
 msgid ""
 "make 'git-difftool' exit when an invoked diff tool returns a non-zero exit "
 "code"
-msgstr "làm cho “git-difftool” thoát khi gọi công cụ diff trả về mã khác không"
+msgstr "làm cho 'git-difftool' thoát khi gọi công cụ diff trả về mã khác không"
 
 msgid "specify a custom command for viewing diffs"
 msgstr "chỉ định một lệnh tùy ý để xem diff"
 
 msgid "passed to `diff`"
-msgstr "chuyển cho “diff”"
+msgstr "chuyển cho 'diff'"
 
 msgid "difftool requires worktree or --no-index"
 msgstr "difftool cần cây làm việc hoặc --no-index"
@@ -5481,28 +5596,6 @@
 msgid "no <cmd> given for --extcmd=<cmd>"
 msgstr "chưa đưa ra <lệnh> cho --extcmd=<lệnh>"
 
-msgid "git env--helper --type=[bool|ulong] <options> <env-var>"
-msgstr "git env--helper --type=[bool|ulong] <các tùy chọn> <env-var>"
-
-msgid "default for git_env_*(...) to fall back on"
-msgstr "mặc định cho git_env_*(…) để quay về"
-
-msgid "be quiet only use git_env_*() value as exit code"
-msgstr "im lặng chỉ khi dung giá trị git_env_*() làm mã thoát"
-
-#, c-format
-msgid "option `--default' expects a boolean value with `--type=bool`, not `%s`"
-msgstr ""
-"tùy chọn “--default” cần một giá trị logic với “--type=bool“, không phải “%s“"
-
-#, c-format
-msgid ""
-"option `--default' expects an unsigned long value with `--type=ulong`, not `"
-"%s`"
-msgstr ""
-"tùy chọn “--default” cần một giá trị số nguyên dài không dấu với “--"
-"type=ulong“, không phải “%s“"
-
 msgid "git fast-export [<rev-list-opts>]"
 msgstr "git fast-export [<rev-list-opts>]"
 
@@ -5541,7 +5634,7 @@
 msgstr "xuất ra toàn bộ cây cho mỗi lần chuyển giao"
 
 msgid "use the done feature to terminate the stream"
-msgstr "sử dụng tính năng done để chấm dứt luồng dữ liệu"
+msgstr "sử dụng tính năng done để kết thúc luồng dữ liệu"
 
 msgid "skip output of blob data"
 msgstr "bỏ qua kết xuất của dữ liệu blob"
@@ -5574,40 +5667,40 @@
 
 #, c-format
 msgid "Missing from marks for submodule '%s'"
-msgstr "Thiếu các đánh dấu cho mô-đun-con “%s”"
+msgstr "Thiếu các đánh dấu cho mô-đun-con '%s'"
 
 #, c-format
 msgid "Missing to marks for submodule '%s'"
-msgstr "Thiếu đánh dấu cho mô-đun-con “%s”"
+msgstr "Thiếu đánh dấu cho mô-đun-con '%s'"
 
 #, c-format
 msgid "Expected 'mark' command, got %s"
-msgstr "Cần lệnh “mark”, nhưng lại nhận được %s"
+msgstr "Cần lệnh 'mark', nhưng lại có %s"
 
 #, c-format
 msgid "Expected 'to' command, got %s"
-msgstr "Cần lệnh “to”, nhưng lại nhận được %s"
+msgstr "Cần lệnh 'to', nhưng lại có %s"
 
 msgid "Expected format name:filename for submodule rewrite option"
-msgstr "Cần định dạng tên:tên_tập_tin cho tùy chọn ghi lại mô-đun-con"
+msgstr "Cần định dạng tên:tên_tập tin cho tùy chọn ghi lại mô-đun-con"
 
 #, c-format
 msgid "feature '%s' forbidden in input without --allow-unsafe-features"
 msgstr ""
-"tính năng “%s” bị cấm chỉ trong đầu vào mà không có --allow-unsafe-features"
+"tính năng '%s' bị cấm chỉ trong đầu vào mà không có --allow-unsafe-features"
 
 #, c-format
 msgid "Lockfile created but not reported: %s"
 msgstr "Tập tin khóa đã được tạo nhưng chưa được báo cáo: %s"
 
 msgid "git fetch [<options>] [<repository> [<refspec>...]]"
-msgstr "git fetch [<các tùy chọn>] [<kho-chứa> [<refspec>…]]"
+msgstr "git fetch [<các tùy chọn>] [<kho-chứa> [<refspec>...]]"
 
 msgid "git fetch [<options>] <group>"
 msgstr "git fetch [<các tùy chọn>] [<nhóm>"
 
 msgid "git fetch --multiple [<options>] [(<repository> | <group>)...]"
-msgstr "git fetch --multiple [<các tùy chọn>] [(<kho> | <nhóm>)…]"
+msgstr "git fetch --multiple [<các tùy chọn>] [(<kho> | <nhóm>)...]"
 
 msgid "git fetch --all [<options>]"
 msgstr "git fetch --all [<các tùy chọn>]"
@@ -5615,6 +5708,174 @@
 msgid "fetch.parallel cannot be negative"
 msgstr "fetch.parallel không thể âm"
 
+msgid "couldn't find remote ref HEAD"
+msgstr "không thể tìm thấy HEAD tham chiếu máy chủ"
+
+#, c-format
+msgid "From %.*s\n"
+msgstr "Từ %.*s\n"
+
+#, c-format
+msgid "object %s not found"
+msgstr "không tìm thấy đối tượng %s"
+
+msgid "[up to date]"
+msgstr "[đã cập nhật]"
+
+msgid "[rejected]"
+msgstr "[Bị từ chối]"
+
+msgid "can't fetch into checked-out branch"
+msgstr "không thể fetch về nhánh đã checkout"
+
+msgid "[tag update]"
+msgstr "[cập nhật thẻ]"
+
+msgid "unable to update local ref"
+msgstr "không thể cập nhật tham chiếu nội bộ"
+
+msgid "would clobber existing tag"
+msgstr "nên xóa chồng các thẻ có sẵn"
+
+msgid "[new tag]"
+msgstr "[thẻ mới]"
+
+msgid "[new branch]"
+msgstr "[nhánh mới]"
+
+msgid "[new ref]"
+msgstr "[ref (tham chiếu) mới]"
+
+msgid "forced update"
+msgstr "cưỡng bức cập nhật"
+
+msgid "non-fast-forward"
+msgstr "không-phải-chuyển-tiếp-nhanh"
+
+#, c-format
+msgid "cannot open '%s'"
+msgstr "không mở được '%s'"
+
+msgid ""
+"fetch normally indicates which branches had a forced update,\n"
+"but that check has been disabled; to re-enable, use '--show-forced-updates'\n"
+"flag or run 'git config fetch.showForcedUpdates true'"
+msgstr ""
+"việc lấy về thường chỉ ra các nhánh buộc phải cập nhật,\n"
+"nhưng lựa chọn bị tắt; để kích hoạt lại, sử dụng cờ\n"
+"'--show-forced-updates' hoặc chạy 'git config fetch.showForcedUpdates true'."
+
+#, c-format
+msgid ""
+"it took %.2f seconds to check forced updates; you can use\n"
+"'--no-show-forced-updates' or run 'git config fetch.showForcedUpdates "
+"false'\n"
+"to avoid this check\n"
+msgstr ""
+"việc này cần %.2f giây để kiểm tra các cập nhật ép buộc; bạn có thể dùng\n"
+"'--no-show-forced-updates' hoặc chạy 'git config fetch.showForcedUpdates "
+"false'\n"
+"để tránh kiểm tra này\n"
+
+#, c-format
+msgid "%s did not send all necessary objects\n"
+msgstr "%s đã không gửi tất cả các đối tượng cần thiết\n"
+
+#, c-format
+msgid "rejected %s because shallow roots are not allowed to be updated"
+msgstr "từ chối %s bởi vì các gốc nông thì không được phép cập nhật"
+
+#, c-format
+msgid ""
+"some local refs could not be updated; try running\n"
+" 'git remote prune %s' to remove any old, conflicting branches"
+msgstr ""
+"một số tham chiếu nội bộ không thể được cập nhật; hãy thử chạy\n"
+" 'git remote prune %s' để bỏ đi những nhánh cũ, hay bị xung đột"
+
+#, c-format
+msgid "   (%s will become dangling)"
+msgstr "   (%s sẽ trở thành không đầu (không được quản lý))"
+
+#, c-format
+msgid "   (%s has become dangling)"
+msgstr "   (%s đã trở thành không đầu (không được quản lý))"
+
+msgid "[deleted]"
+msgstr "[đã xóa]"
+
+msgid "(none)"
+msgstr "(không)"
+
+#, c-format
+msgid "refusing to fetch into branch '%s' checked out at '%s'"
+msgstr "từ chối lấy về vào nhánh '%s' đã được checkout tại '%s'"
+
+#, c-format
+msgid "option \"%s\" value \"%s\" is not valid for %s"
+msgstr "tùy chọn \"%s\" có giá trị \"%s\" là không hợp lệ cho %s"
+
+#, c-format
+msgid "option \"%s\" is ignored for %s\n"
+msgstr "tùy chọn \"%s\" bị bỏ qua với %s\n"
+
+#, c-format
+msgid "%s is not a valid object"
+msgstr "%s không phải là một đối tượng hợp lệ"
+
+#, c-format
+msgid "the object %s does not exist"
+msgstr "đối tượng '%s' không tồn tại"
+
+msgid "multiple branches detected, incompatible with --set-upstream"
+msgstr "phát hiện nhiều nhánh, không tương thích với --set-upstream"
+
+#, c-format
+msgid ""
+"could not set upstream of HEAD to '%s' from '%s' when it does not point to "
+"any branch."
+msgstr ""
+"không thể đặt thượng nguồn của HEAD thành '%s' từ '%s' khi mà nó chẳng chỉ "
+"đến nhánh nào cả."
+
+msgid "not setting upstream for a remote remote-tracking branch"
+msgstr "không cài đặt thượng nguồn cho một nhánh được theo dõi trên máy chủ"
+
+msgid "not setting upstream for a remote tag"
+msgstr "không cài đặt thượng nguồn cho một thẻ nhánh trên máy chủ"
+
+msgid "unknown branch type"
+msgstr "không hiểu kiểu nhánh"
+
+msgid ""
+"no source branch found;\n"
+"you need to specify exactly one branch with the --set-upstream option"
+msgstr ""
+"không tìm thấy nhánh nguồn.\n"
+"bạn cần phải chỉ định chính xác một nhánh với tùy chọn --set-upstream"
+
+#, c-format
+msgid "Fetching %s\n"
+msgstr "Đang lấy '%s' về\n"
+
+#, c-format
+msgid "could not fetch %s"
+msgstr "không thể lấy '%s' về"
+
+#, c-format
+msgid "could not fetch '%s' (exit code: %d)\n"
+msgstr "không thể lấy '%s' (mã thoát: %d)\n"
+
+msgid ""
+"no remote repository specified; please specify either a URL or a\n"
+"remote name from which new revisions should be fetched"
+msgstr ""
+"chưa chỉ ra kho chứa máy chủ; xin hãy chỉ định hoặc là URL hoặc\n"
+"tên máy chủ từ cái mà những điểm xét duyệt mới có thể được fetch (lấy về)"
+
+msgid "you need to specify a tag name"
+msgstr "bạn cần chỉ định một tên thẻ"
+
 msgid "fetch from all remotes"
 msgstr "lấy về từ tất cả các máy chủ"
 
@@ -5651,11 +5912,11 @@
 
 msgid "prune remote-tracking branches no longer on remote"
 msgstr ""
-"cắt cụt (prune) các nhánh “remote-tracking” không còn tồn tại trên máy chủ "
-"nữa"
+"cắt (prune) các nhánh 'remote-tracking' không còn tồn tại trên máy chủ nữa"
 
 msgid "prune local tags no longer on remote and clobber changed tags"
-msgstr "cắt xém các thẻ nội bộ không còn ở máy chủ và xóa các thẻ đã thay đổi"
+msgstr ""
+"xoá (prune) các thẻ nội bộ không còn ở máy chủ và xóa các thẻ đã thay đổi"
 
 msgid "on-demand"
 msgstr "khi-cần"
@@ -5704,15 +5965,14 @@
 msgstr "chỉ ra refmap cần lấy về"
 
 msgid "report that we have only objects reachable from this object"
-msgstr ""
-"báo cáo rằng chúng ta chỉ có các đối tượng tiếp cận được từ đối tượng này"
+msgstr "báo rằng ta chỉ có các đối tượng tiếp cận được từ đối tượng này"
 
 msgid "do not fetch a packfile; instead, print ancestors of negotiation tips"
 msgstr ""
 "không lấy về một packfile; thay vào đó, hãy in tổ tiên của đỉnh đàm phán"
 
 msgid "run 'maintenance --auto' after fetching"
-msgstr "chạy “maintenance --auto” sau khi lấy về"
+msgstr "chạy 'maintenance --auto' sau khi lấy về"
 
 msgid "check for forced-updates on all updated branches"
 msgstr "kiểm cho các-cập-nhật-bắt-buộc trên mọi nhánh đã cập nhật"
@@ -5721,178 +5981,7 @@
 msgstr "ghi ra đồ thị các lần chuyển giao sau khi lấy về"
 
 msgid "accept refspecs from stdin"
-msgstr "chấp nhận tham chiếu từ đầu vào tiêu chuẩn"
-
-msgid "couldn't find remote ref HEAD"
-msgstr "không thể tìm thấy HEAD tham chiếu máy chủ"
-
-#, c-format
-msgid "object %s not found"
-msgstr "không tìm thấy đối tượng %s"
-
-msgid "[up to date]"
-msgstr "[đã cập nhật]"
-
-msgid "[rejected]"
-msgstr "[Bị từ chối]"
-
-msgid "can't fetch in current branch"
-msgstr "không thể fetch (lấy) về nhánh hiện hành"
-
-msgid "checked out in another worktree"
-msgstr "lấy ra trong cây làm việc khác"
-
-msgid "[tag update]"
-msgstr "[cập nhật thẻ]"
-
-msgid "unable to update local ref"
-msgstr "không thể cập nhật tham chiếu nội bộ"
-
-msgid "would clobber existing tag"
-msgstr "nên xóa chồng các thẻ có sẵn"
-
-msgid "[new tag]"
-msgstr "[thẻ mới]"
-
-msgid "[new branch]"
-msgstr "[nhánh mới]"
-
-msgid "[new ref]"
-msgstr "[ref (tham chiếu) mới]"
-
-msgid "forced update"
-msgstr "cưỡng bức cập nhật"
-
-msgid "non-fast-forward"
-msgstr "không-phải-chuyển-tiếp-nhanh"
-
-#, c-format
-msgid "cannot open '%s'"
-msgstr "không mở được “%s”"
-
-msgid ""
-"fetch normally indicates which branches had a forced update,\n"
-"but that check has been disabled; to re-enable, use '--show-forced-updates'\n"
-"flag or run 'git config fetch.showForcedUpdates true'"
-msgstr ""
-"việc lấy về thường chỉ ra các nhánh buộc phải cập nhật,\n"
-"nhưng lựa chọn bị tắt; để kích hoạt lại, sử dụng cờ\n"
-"“--show-forced-updates” hoặc chạy “git config fetch.showForcedUpdates true”."
-
-#, c-format
-msgid ""
-"it took %.2f seconds to check forced updates; you can use\n"
-"'--no-show-forced-updates' or run 'git config fetch.showForcedUpdates "
-"false'\n"
-"to avoid this check\n"
-msgstr ""
-"việc này cần %.2f giây để kiểm tra các cập nhật ép buộc; bạn có thể dùng\n"
-"“--no-show-forced-updates” hoặc chạy “git config fetch.showForcedUpdates "
-"false”\n"
-"để tránh kiểm tra này\n"
-
-#, c-format
-msgid "%s did not send all necessary objects\n"
-msgstr "%s đã không gửi tất cả các đối tượng cần thiết\n"
-
-#, c-format
-msgid "rejected %s because shallow roots are not allowed to be updated"
-msgstr "từ chối %s bởi vì các gốc nông thì không được phép cập nhật"
-
-#, c-format
-msgid "From %.*s\n"
-msgstr "Từ %.*s\n"
-
-#, c-format
-msgid ""
-"some local refs could not be updated; try running\n"
-" 'git remote prune %s' to remove any old, conflicting branches"
-msgstr ""
-"một số tham chiếu nội bộ không thể được cập nhật; hãy thử chạy\n"
-" “git remote prune %s” để bỏ đi những nhánh cũ, hay bị xung đột"
-
-#, c-format
-msgid "   (%s will become dangling)"
-msgstr "   (%s sẽ trở thành không đầu (không được quản lý))"
-
-#, c-format
-msgid "   (%s has become dangling)"
-msgstr "   (%s đã trở thành không đầu (không được quản lý))"
-
-msgid "[deleted]"
-msgstr "[đã xóa]"
-
-msgid "(none)"
-msgstr "(không)"
-
-#, c-format
-msgid "refusing to fetch into branch '%s' checked out at '%s'"
-msgstr "từ chối lấy về vào nhánh “%s” đã được lấy ra tại “%s”"
-
-#, c-format
-msgid "option \"%s\" value \"%s\" is not valid for %s"
-msgstr "tùy chọn \"%s\" có giá trị \"%s\" là không hợp lệ cho %s"
-
-#, c-format
-msgid "option \"%s\" is ignored for %s\n"
-msgstr "tùy chọn \"%s\" bị bỏ qua với %s\n"
-
-#, c-format
-msgid "%s is not a valid object"
-msgstr "%s không phải là một đối tượng hợp lệ"
-
-#, c-format
-msgid "the object %s does not exist"
-msgstr "đối tượng “%s” không tồn tại"
-
-msgid "multiple branches detected, incompatible with --set-upstream"
-msgstr "phát hiện nhiều nhánh, không tương thích với --set-upstream"
-
-#, c-format
-msgid ""
-"could not set upstream of HEAD to '%s' from '%s' when it does not point to "
-"any branch."
-msgstr ""
-"không thể đặt thượng nguồn của HEAD thành '%s' từ '%s' khi mà nó chẳng chỉ "
-"đến nhánh nào cả."
-
-msgid "not setting upstream for a remote remote-tracking branch"
-msgstr "không cài đặt thượng nguồn cho một nhánh được theo dõi trên máy chủ"
-
-msgid "not setting upstream for a remote tag"
-msgstr "không cài đặt thượng nguồn cho một thẻ nhánh trên máy chủ"
-
-msgid "unknown branch type"
-msgstr "không hiểu kiểu nhánh"
-
-msgid ""
-"no source branch found;\n"
-"you need to specify exactly one branch with the --set-upstream option"
-msgstr ""
-"không tìm thấy nhánh nguồn.\n"
-"bạn cần phải chỉ định chính xác một nhánh với tùy chọn --set-upstream"
-
-#, c-format
-msgid "Fetching %s\n"
-msgstr "Đang lấy “%s” về\n"
-
-#, c-format
-msgid "could not fetch %s"
-msgstr "không thể lấy “%s” về"
-
-#, c-format
-msgid "could not fetch '%s' (exit code: %d)\n"
-msgstr "không thể lấy “%s” (mã thoát: %d)\n"
-
-msgid ""
-"no remote repository specified; please specify either a URL or a\n"
-"remote name from which new revisions should be fetched"
-msgstr ""
-"chưa chỉ ra kho chứa máy chủ; xin hãy chỉ định hoặc là URL hoặc\n"
-"tên máy chủ từ cái mà những điểm xét duyệt mới có thể được fetch (lấy về)"
-
-msgid "you need to specify a tag name"
-msgstr "bạn cần chỉ định một tên thẻ"
+msgstr "chấp nhận tham chiếu từ stdin"
 
 msgid "--negotiate-only needs one or more --negotiation-tip=*"
 msgstr "--negotiate-only cần một hay nhiều --negotiation-tip=* hơn"
@@ -5903,6 +5992,10 @@
 msgid "--unshallow on a complete repository does not make sense"
 msgstr "--unshallow trên kho hoàn chỉnh là không hợp lý"
 
+#, c-format
+msgid "failed to fetch bundles from '%s'"
+msgstr "gặp lỗi khi lấy về bundle từ '%s'"
+
 msgid "fetch --all does not take a repository argument"
 msgstr "lệnh lấy về \"fetch --all\" không lấy đối số kho chứa"
 
@@ -5942,16 +6035,16 @@
 "tin>]"
 
 msgid "populate log with at most <n> entries from shortlog"
-msgstr "gắn nhật ký với ít nhất <n> mục từ lệnh “shortlog”"
+msgstr "gắn nhật ký với ít nhất <n> mục từ lệnh 'shortlog'"
 
 msgid "alias for --log (deprecated)"
-msgstr "bí danh cho --log (không được dùng)"
+msgstr "bí danh cho --log (đã lạc hậu)"
 
 msgid "text"
 msgstr "văn bản"
 
 msgid "use <text> as start of message"
-msgstr "dùng <văn bản thường> để bắt đầu ghi chú"
+msgstr "dùng <văn bản> để bắt đầu ghi chú"
 
 msgid "use <name> instead of the real target branch"
 msgstr "dùng <tên> thay cho nhánh đích thật"
@@ -5976,16 +6069,16 @@
 "chuyển-giao>]]"
 
 msgid "quote placeholders suitably for shells"
-msgstr "trích dẫn để phù hợp cho hệ vỏ (shell)"
+msgstr "trích dẫn dạng phù hợp cho shell"
 
 msgid "quote placeholders suitably for perl"
-msgstr "trích dẫn để phù hợp cho perl"
+msgstr "trích dẫn dạng phù hợp cho perl"
 
 msgid "quote placeholders suitably for python"
-msgstr "trích dẫn để phù hợp cho python"
+msgstr "trích dẫn dạng phù hợp cho python"
 
 msgid "quote placeholders suitably for Tcl"
-msgstr "trích dẫn để phù hợp cho Tcl"
+msgstr "trích dẫn dạng phù hợp cho Tcl"
 
 msgid "show only <n> matched refs"
 msgstr "hiển thị chỉ <n> tham chiếu khớp"
@@ -6008,8 +6101,17 @@
 msgid "print only refs which don't contain the commit"
 msgstr "chỉ hiển thị những tham chiếu mà nó không chứa lần chuyển giao"
 
-msgid "git for-each-repo --config=<config> <command-args>"
-msgstr "git for-each-repo --config=<config> <command-args>"
+msgid "read reference patterns from stdin"
+msgstr "đọc các mẫu tham chiếu từ stdin"
+
+msgid "also include HEAD ref and pseudorefs"
+msgstr "bao gồm tham chiếu HEAD và giả tham chiếu"
+
+msgid "unknown arguments supplied with --stdin"
+msgstr "đối số không rõ được chỉ định cùng với --stdin"
+
+msgid "git for-each-repo --config=<config> [--] <arguments>"
+msgstr "git for-each-repo --config=<tùy chọn> [--] <đối số>"
 
 msgid "config"
 msgstr "config"
@@ -6020,6 +6122,10 @@
 msgid "missing --config=<config>"
 msgstr "thiếu --config=<config>"
 
+#, c-format
+msgid "got bad config --config=%s"
+msgstr "cấu hình sai --config=%s"
+
 msgid "unknown"
 msgstr "không hiểu"
 
@@ -6068,11 +6174,11 @@
 
 #, c-format
 msgid "could not write '%s'"
-msgstr "không thể ghi “%s”"
+msgstr "không thể ghi '%s'"
 
 #, c-format
 msgid "could not finish '%s'"
-msgstr "không thể hoàn thành “%s”"
+msgstr "không thể hoàn thành '%s'"
 
 #, c-format
 msgid "Checking %s"
@@ -6087,7 +6193,7 @@
 msgstr "Đang kiểm tra %s %s"
 
 msgid "broken links"
-msgstr "các liên kết bị gẫy"
+msgstr "liên kết hỏng"
 
 #, c-format
 msgid "root %s"
@@ -6107,7 +6213,7 @@
 
 #, c-format
 msgid "Checking reflog %s->%s"
-msgstr "Đang kiểm tra việc đổi tên của “%s” thành “%s”"
+msgstr "Đang kiểm tra việc đổi tên của '%s' thành '%s'"
 
 #, c-format
 msgid "%s: invalid sha1 pointer %s"
@@ -6130,11 +6236,11 @@
 
 #, c-format
 msgid "%s: object is of unknown type '%s': %s"
-msgstr "%s: đối tượng có kiểu chưa biết “%s”: %s"
+msgstr "%s: đối tượng có kiểu chưa biết '%s': %s"
 
 #, c-format
 msgid "%s: object could not be parsed: %s"
-msgstr "%s: không thể phân tích cú đối tượng: %s"
+msgstr "%s: không thể đọc cú đối tượng: %s"
 
 #, c-format
 msgid "bad sha1 file: %s"
@@ -6166,36 +6272,57 @@
 msgid "notice: %s points to an unborn branch (%s)"
 msgstr "chú ý: %s chỉ đến một nhánh chưa sinh (%s)"
 
-msgid "Checking cache tree"
-msgstr "Đang kiểm tra cây nhớ tạm"
+#, c-format
+msgid "Checking cache tree of %s"
+msgstr "Đang kiểm tra cây nhớ tạm của %s"
 
 #, c-format
-msgid "%s: invalid sha1 pointer in cache-tree"
-msgstr "%s: con trỏ sha1 không hợp lệ trong cache-tree"
+msgid "%s: invalid sha1 pointer in cache-tree of %s"
+msgstr "%s: con trỏ sha1 không hợp lệ trong cây nhớ tạm của %s"
 
 msgid "non-tree in cache-tree"
 msgstr "non-tree trong cache-tree"
 
-msgid "git fsck [<options>] [<object>...]"
-msgstr "git fsck [<các tùy chọn>] [<đối-tượng>…]"
+#, c-format
+msgid "%s: invalid sha1 pointer in resolve-undo of %s"
+msgstr "%s: con trỏ sha1 không hợp lệ trong resolve-undo của %s"
+
+#, c-format
+msgid "unable to load rev-index for pack '%s'"
+msgstr "không thể tải pack-index cho gói '%s'"
+
+#, c-format
+msgid "invalid rev-index for pack '%s'"
+msgstr "giá trị rev-index cho gói '%s' không hợp lệ"
+
+msgid ""
+"git fsck [--tags] [--root] [--unreachable] [--cache] [--no-reflogs]\n"
+"         [--[no-]full] [--strict] [--verbose] [--lost-found]\n"
+"         [--[no-]dangling] [--[no-]progress] [--connectivity-only]\n"
+"         [--[no-]name-objects] [<object>...]"
+msgstr ""
+"git fsck [--tags] [--root] [--unreachable] [--cache] [--no-reflogs]\n"
+"         [--[no-]full] [--strict] [--verbose] [--lost-found]\n"
+"         [--[no-]dangling] [--[no-]progress] [--connectivity-only]\n"
+"         [--[no-]name-objects] [<đối tượng>...]"
 
 msgid "show unreachable objects"
-msgstr "hiển thị các đối tượng không thể đọc được"
+msgstr "hiển thị các đối tượng không thể tới được"
 
 msgid "show dangling objects"
 msgstr "hiển thị các đối tượng không được quản lý"
 
 msgid "report tags"
-msgstr "báo cáo các thẻ"
+msgstr "liệt kê các thẻ"
 
 msgid "report root nodes"
-msgstr "báo cáo node gốc"
+msgstr "liệt kê node gốc"
 
 msgid "make index objects head nodes"
-msgstr "tạo “index objects head nodes”"
+msgstr "tạo 'index objects head nodes'"
 
 msgid "make reflogs head nodes (default)"
-msgstr "tạo “reflogs head nodes” (mặc định)"
+msgstr "tạo 'reflogs head nodes' (mặc định)"
 
 msgid "also consider packs and alternate objects"
 msgstr "cũng cân nhắc đến các đối tượng gói và thay thế"
@@ -6224,7 +6351,7 @@
 
 #, c-format
 msgid "invalid parameter: expected sha1, got '%s'"
-msgstr "tham số không hợp lệ: cần sha1, nhưng lại nhận được “%s”"
+msgstr "tham số không hợp lệ: cần sha1, nhưng lại có '%s'"
 
 msgid "git fsmonitor--daemon start [<options>]"
 msgstr "git fsmonitor--daemon start [<các tùy chọn>]"
@@ -6232,15 +6359,9 @@
 msgid "git fsmonitor--daemon run [<options>]"
 msgstr "git fsmonitor--daemon run [<các tùy chọn>]"
 
-msgid "git fsmonitor--daemon stop"
-msgstr "git fsmonitor--daemon stop"
-
-msgid "git fsmonitor--daemon status"
-msgstr "git fsmonitor--daemon status"
-
 #, c-format
 msgid "value of '%s' out of range: %d"
-msgstr "siá trị '%s' ngoài phạm vi cho phép: %d"
+msgstr "giá trị '%s' ngoài phạm vi cho phép: %d"
 
 #, c-format
 msgid "value of '%s' not bool or int: %d"
@@ -6256,7 +6377,7 @@
 
 #, c-format
 msgid "could not create fsmonitor cookie '%s'"
-msgstr "không thể tạo fsmonitor cookie “%s”"
+msgstr "không thể tạo fsmonitor cookie '%s'"
 
 #, c-format
 msgid "fsmonitor: cookie_result '%d' != SEEN"
@@ -6264,24 +6385,23 @@
 
 #, c-format
 msgid "could not start IPC thread pool on '%s'"
-msgstr "không thể khởi chạy bể tiến trình IPC trêm “%s”"
+msgstr "không thể khởi chạy pool tiến trình IPC trên '%s'"
 
 msgid "could not start fsmonitor listener thread"
-msgstr "không thể lấy thông tin thống kê về tuyến trình lắng nghe fsmonitor"
+msgstr "không thể khởi chạy fsmonitor listener thread"
 
 msgid "could not start fsmonitor health thread"
-msgstr ""
-"không thể lấy thông tin thống kê về tuyến trình theo dõi sức khỏe fsmonitor"
+msgstr "không thể khởi chạy fsmonitor health thread"
 
 msgid "could not initialize listener thread"
-msgstr "không thể khởi tạo tuyến trình lắng nghe"
+msgstr "không thể khởi tạo listener thread"
 
 msgid "could not initialize health thread"
-msgstr "không thể khởi tạo tuyến trình sức "
+msgstr "không thể khởi tạo health thread"
 
 #, c-format
 msgid "could not cd home '%s'"
-msgstr "không thể chuyển đến thư mục cá nhân “%s”"
+msgstr "không thể cd home '%s'"
 
 #, c-format
 msgid "fsmonitor--daemon is already running '%s'"
@@ -6293,7 +6413,7 @@
 
 #, c-format
 msgid "starting fsmonitor-daemon in '%s'\n"
-msgstr "đang khởi chạy fsmonitor-daemon trong “%s”\n"
+msgstr "đang khởi chạy fsmonitor-daemon trong '%s'\n"
 
 msgid "daemon failed to start"
 msgstr "gặp lỗi khi khởi chạy dịch vụ chạy ngầm"
@@ -6329,15 +6449,15 @@
 
 #, c-format
 msgid "Failed to fstat %s: %s"
-msgstr "Gặp lỗi khi lấy thông tin thống kê về tập tin %s: %s"
+msgstr "Gặp lỗi khi fstat %s: %s"
 
 #, c-format
 msgid "failed to parse '%s' value '%s'"
-msgstr "gặp lỗi khi phân tích “%s” giá trị “%s”"
+msgstr "gặp lỗi khi đọc '%s' giá trị '%s'"
 
 #, c-format
 msgid "cannot stat '%s'"
-msgstr "không thể lấy thông tin thống kê về “%s”"
+msgstr "không thể stat '%s'"
 
 #, c-format
 msgid ""
@@ -6359,6 +6479,9 @@
 msgid "pack unreferenced objects separately"
 msgstr "đóng gói riêng các đối tượng không được tham chiếu"
 
+msgid "with --cruft, limit the size of new cruft packs"
+msgstr "với tuỳ chọn --cruft, giới hạn kích thước pack cruft mới"
+
 msgid "be more thorough (increased runtime)"
 msgstr "cẩn thận hơn nữa (tăng thời gian chạy)"
 
@@ -6373,11 +6496,11 @@
 
 #, c-format
 msgid "failed to parse gc.logExpiry value %s"
-msgstr "gặp lỗi khi phân tích giá trị gc.logExpiry %s"
+msgstr "gặp lỗi khi đọc giá trị gc.logExpiry %s"
 
 #, c-format
 msgid "failed to parse prune expiry value %s"
-msgstr "gặp lỗi khi phân tích giá trị prune %s"
+msgstr "gặp lỗi khi đọc giá trị prune %s"
 
 #, c-format
 msgid "Auto packing the repository in background for optimum performance.\n"
@@ -6397,13 +6520,13 @@
 msgid ""
 "gc is already running on machine '%s' pid %<PRIuMAX> (use --force if not)"
 msgstr ""
-"gc đang được thực hiện trên máy “%s” pid %<PRIuMAX> (dùng --force nếu không "
+"gc đang được thực hiện trên máy '%s' pid %<PRIuMAX> (dùng --force nếu không "
 "phải thế)"
 
 msgid ""
 "There are too many unreachable loose objects; run 'git prune' to remove them."
 msgstr ""
-"Có quá nhiều đối tượng tự do không được dùng đến; hãy chạy lệnh “git prune” "
+"Có quá nhiều đối tượng tự do không được dùng đến; hãy chạy lệnh 'git prune' "
 "để xóa bỏ chúng đi."
 
 msgid ""
@@ -6425,19 +6548,19 @@
 msgstr "gặp lỗi khi tải trước các máy chủ"
 
 msgid "failed to start 'git pack-objects' process"
-msgstr "gặp lỗi khi lấy thông tin thống kê về tiến trình “git pack-objects”"
+msgstr "gặp lỗi khi khởi chạy tiến trình 'git pack-objects'"
 
 msgid "failed to finish 'git pack-objects' process"
-msgstr "gặp lỗi khi hoàn tất tiến trình “git pack-objects”"
+msgstr "gặp lỗi khi hoàn tất tiến trình 'git pack-objects'"
 
 msgid "failed to write multi-pack-index"
 msgstr "gặp lỗi khi ghi multi-pack-index"
 
 msgid "'git multi-pack-index expire' failed"
-msgstr "gặp lỗi khi chạy “git multi-pack-index expire”"
+msgstr "gặp lỗi khi chạy 'git multi-pack-index expire'"
 
 msgid "'git multi-pack-index repack' failed"
-msgstr "gặp lỗi khi chạy “git multi-pack-index repack”"
+msgstr "gặp lỗi khi chạy 'git multi-pack-index repack'"
 
 msgid ""
 "skipping incremental-repack task because core.multiPackIndex is disabled"
@@ -6445,19 +6568,19 @@
 
 #, c-format
 msgid "lock file '%s' exists, skipping maintenance"
-msgstr "đã có khóa của tập tin “%s”, bỏ qua bảo trì"
+msgstr "đã có khóa của tập tin '%s', bỏ qua bảo trì"
 
 #, c-format
 msgid "task '%s' failed"
-msgstr "gặp lỗi khi thực hiện nhiệm vụ “%s”"
+msgstr "gặp lỗi khi thực hiện nhiệm vụ '%s'"
 
 #, c-format
 msgid "'%s' is not a valid task"
-msgstr "“%s” không phải một nhiệm vụ hợp lệ"
+msgstr "'%s' không phải một nhiệm vụ hợp lệ"
 
 #, c-format
 msgid "task '%s' cannot be selected multiple times"
-msgstr "nhiệm vụ “%s” không được chọn nhiều lần"
+msgstr "nhiệm vụ '%s' không được chọn nhiều lần"
 
 msgid "run tasks based on the state of the repository"
 msgstr "chạy nhiệm vụ dựa trên trạng thái của kho chứa"
@@ -6469,7 +6592,7 @@
 msgstr "chạy nhiệm vụ dựa trên tần suất"
 
 msgid "do not report progress or other information over stderr"
-msgstr "đừng báo cáo diễn tiến hay các thông tin khác ra đầu lỗi tiêu chuẩn"
+msgstr "đừng báo cáo tiến độ hay các thông tin khác ra stderr"
 
 msgid "task"
 msgstr "tác vụ"
@@ -6480,12 +6603,24 @@
 msgid "use at most one of --auto and --schedule=<frequency>"
 msgstr "dùng nhiều nhất là một trong --auto và --schedule=<frequency>"
 
-msgid "failed to run 'git config'"
-msgstr "gặp lỗi khi chạy “git config”"
+#, c-format
+msgid "unable to add '%s' value of '%s'"
+msgstr "không thể thêm giá trị '%s' của '%s'"
+
+msgid "return success even if repository was not registered"
+msgstr "trả về thành công kể cả khi kho chứa chưa được ghi nhận"
+
+#, c-format
+msgid "unable to unset '%s' value of '%s'"
+msgstr "không thể bỏ đặt giá trị '%s' của '%s'"
+
+#, c-format
+msgid "repository '%s' is not registered"
+msgstr "kho chứa '%s' chưa tồn tại"
 
 #, c-format
 msgid "failed to expand path '%s'"
-msgstr "gặp lỗi khi khai triển đường dẫn “%s”"
+msgstr "gặp lỗi khi khai triển đường dẫn '%s'"
 
 msgid "failed to start launchctl"
 msgstr "gặp lỗi khi khởi chạy launchctl"
@@ -6502,20 +6637,31 @@
 msgstr "gặp lỗi khi tạo tập tin xml tạm thời"
 
 msgid "failed to start schtasks"
-msgstr "gặp lỗi khi lấy thông tin thống kê về schtasks"
+msgstr "gặp lỗi khi khởi chạy schtasks"
 
 msgid "failed to run 'crontab -l'; your system might not support 'cron'"
 msgstr ""
-"gặp lỗi khi chạy “crontab -l”; hệ thống của bạn có thể không hỗ trợ “cron”"
+"gặp lỗi khi chạy 'crontab -l'; hệ thống của bạn có thể không hỗ trợ 'cron'"
+
+msgid "failed to create crontab temporary file"
+msgstr "không thể tạo tập tin tạm thời crontab"
+
+msgid "failed to open temporary file"
+msgstr "không thể mở tập tin tạm thời"
 
 msgid "failed to run 'crontab'; your system might not support 'cron'"
-msgstr "gặp lỗi khi chạy “crontab”; hiển thị của bạn có lẽ không hỗ trợ “cron”"
-
-msgid "failed to open stdin of 'crontab'"
-msgstr "gặp lỗi khi mở đầu vào tiêu chuẩn của “crontab”"
+msgstr "gặp lỗi khi chạy 'crontab'; hệ thống của bạn có lẽ không hỗ trợ 'cron'"
 
 msgid "'crontab' died"
-msgstr "“crontab” đã chết"
+msgstr "'crontab' đã chết"
+
+#, c-format
+msgid "failed to delete '%s'"
+msgstr "gặp lỗi khi xóa '%s'"
+
+#, c-format
+msgid "failed to flush '%s'"
+msgstr "gặp lỗi khi đẩy dữ liệu '%s' lên đĩa"
 
 msgid "failed to start systemctl"
 msgstr "gặp lỗi khi khởi chạy systemctl"
@@ -6524,16 +6670,8 @@
 msgstr "gặp lỗi khi chạy systemctl"
 
 #, c-format
-msgid "failed to delete '%s'"
-msgstr "gặp lỗi khi xóa “%s”"
-
-#, c-format
-msgid "failed to flush '%s'"
-msgstr "gặp lỗi khi đẩy dữ liệu “%s” lên đĩa"
-
-#, c-format
 msgid "unrecognized --scheduler argument '%s'"
-msgstr "đối số --scheduler không được thừa nhận “%s”"
+msgstr "đối số --scheduler không được thừa nhận '%s'"
 
 msgid "neither systemd timers nor crontab are available"
 msgstr "hoặc là bộ lập lịch systemd hoặc là crontab không sẵn có"
@@ -6554,18 +6692,17 @@
 msgid "scheduler to trigger git maintenance run"
 msgstr "bộ lên lịch để kích hoạt chạy chương trình bảo trì git"
 
+msgid "failed to set up maintenance schedule"
+msgstr "gặp lỗi khi lên lịch bảo trì"
+
 msgid "failed to add repo to global config"
 msgstr "gặp lỗi khi thêm cấu hình toàn cục"
 
 msgid "git maintenance <subcommand> [<options>]"
 msgstr "git maintenance run <lệnh_con> [<các tùy chọn>]"
 
-#, c-format
-msgid "invalid subcommand: %s"
-msgstr "lện con không hợp lệ: %s"
-
 msgid "git grep [<options>] [-e] <pattern> [<rev>...] [[--] <path>...]"
-msgstr "git grep [<các tùy chọn>] [-e] <mẫu> [<rev>…] [[--] </đường/dẫn>…]"
+msgstr "git grep [<các tùy chọn>] [-e] <mẫu> [<rev>...] [[--] </đường/dẫn>...]"
 
 #, c-format
 msgid "grep: failed to create thread: %s"
@@ -6585,8 +6722,8 @@
 msgstr "không hỗ trợ đa tuyến, bỏ qua %s"
 
 #, c-format
-msgid "unable to read tree (%s)"
-msgstr "không thể đọc cây (%s)"
+msgid "unable to read tree %s"
+msgstr "không thể đọc cây %s"
 
 #, c-format
 msgid "unable to grep from object of type %s"
@@ -6594,10 +6731,10 @@
 
 #, c-format
 msgid "switch `%c' expects a numerical value"
-msgstr "chuyển đến “%c” cần một giá trị bằng số"
+msgstr "chuyển đến '%c' cần một giá trị bằng số"
 
 msgid "search in index instead of in the work tree"
-msgstr "tìm trong bảng mục lục thay vì trong cây làm việc"
+msgstr "tìm trong chỉ mục thay vì trong cây làm việc"
 
 msgid "find in contents not managed by git"
 msgstr "tìm trong nội dung không được quản lý bởi git"
@@ -6606,7 +6743,7 @@
 msgstr "tìm kiếm các tập tin được và chưa được theo dõi dấu vết"
 
 msgid "ignore files specified via '.gitignore'"
-msgstr "các tập tin bị bỏ qua được chỉ định thông qua “.gitignore”"
+msgstr "các tập tin bị bỏ qua được chỉ định thông qua '.gitignore'"
 
 msgid "recursively search in each submodule"
 msgstr "tìm kiếm đệ quy trong từng mô-đun-con"
@@ -6627,16 +6764,16 @@
 msgstr "không khớp mẫu trong các tập tin nhị phân"
 
 msgid "process binary files with textconv filters"
-msgstr "xử lý tập tin nhị phân với các bộ lọc “textconv”"
+msgstr "xử lý tập tin nhị phân với các bộ lọc 'textconv'"
 
 msgid "search in subdirectories (default)"
 msgstr "tìm kiếm trong thư mục con (mặc định)"
 
-msgid "descend at most <depth> levels"
-msgstr "hạ xuống ít nhất là mức <sâu>"
+msgid "descend at most <n> levels"
+msgstr "hạ xuống tối đa <n> mức"
 
 msgid "use extended POSIX regular expressions"
-msgstr "dùng biểu thức chính qui POSIX có mở rộng"
+msgstr "dùng biểu thức chính quy POSIX có mở rộng"
 
 msgid "use basic POSIX regular expressions (default)"
 msgstr "sử dụng biểu thức chính quy kiểu POSIX (mặc định)"
@@ -6684,7 +6821,7 @@
 msgstr "tô sáng phần khớp mẫu"
 
 msgid "print empty line between matches from different files"
-msgstr "hiển thị dòng trống giữa các lần khớp từ các tập tin khác biệt"
+msgstr "hiển thị dòng trống giữa các lần khớp từ các tập tin khác nhau"
 
 msgid "show filename only once above matches from same file"
 msgstr ""
@@ -6735,6 +6872,9 @@
 msgid "allow calling of grep(1) (ignored by this build)"
 msgstr "cho phép gọi grep(1) (bị bỏ qua bởi lần dịch này)"
 
+msgid "maximum number of results per file"
+msgstr "số lượng kết quả tối đa trên mỗi tập tin"
+
 msgid "no pattern given"
 msgstr "chưa chỉ ra mẫu"
 
@@ -6768,11 +6908,14 @@
 msgstr "cả hai --cached và các cây phải được chỉ ra"
 
 msgid ""
-"git hash-object [-t <type>] [-w] [--path=<file> | --no-filters] [--stdin] "
-"[--] <file>..."
+"git hash-object [-t <type>] [-w] [--path=<file> | --no-filters]\n"
+"                [--stdin [--literally]] [--] <file>..."
 msgstr ""
-"git hash-object [-t <kiểu>] [-w] [--path=<tập-tin> | --no-filters] [--stdin] "
-"[--] <tập-tin>…"
+"git hash-object [-t <kiểu>] [-w] [--path=<tập-tin> | --no-filters]\n"
+"                [--stdin [--literally]] [--] <tập-tin>..."
+
+msgid "git hash-object [-t <type>] [-w] --stdin-paths [--no-filters]"
+msgstr "git hash-object [-t <kiểu>] [-w] --stdin-paths [--no-filters] "
 
 msgid "object type"
 msgstr "kiểu đối tượng"
@@ -6781,14 +6924,14 @@
 msgstr "ghi đối tượng vào dữ liệu đối tượng"
 
 msgid "read the object from stdin"
-msgstr "đọc đối tượng từ đầu vào tiêu chuẩn stdin"
+msgstr "đọc đối tượng từ stdin"
 
 msgid "store file as is without filters"
 msgstr "lưu các tập tin mà nó không có các bộ lọc"
 
 msgid ""
 "just hash any random garbage to create corrupt objects for debugging Git"
-msgstr "chỉ cần băm rác ngẫu nhiên để tạo một đối tượng hỏng để mà gỡ lỗi Git"
+msgstr "chỉ cần băm rác ngẫu nhiên để tạo một đối tượng hỏng để gỡ lỗi Git"
 
 msgid "process file as it were from this path"
 msgstr "xử lý tập tin như là nó đang ở thư mục này"
@@ -6820,49 +6963,55 @@
 msgid "print list of useful guides"
 msgstr "hiển thị danh sách các hướng dẫn hữu dụng"
 
+msgid "print list of user-facing repository, command and file interfaces"
+msgstr "hiển thị các giao diện cho người dùng"
+
+msgid "print list of file formats, protocols and other developer interfaces"
+msgstr "hiển thị các giao diện cho lập trình viên"
+
 msgid "print all configuration variable names"
 msgstr "in ra tất cả các tên biến cấu hình"
 
-msgid "git help [[-i|--info] [-m|--man] [-w|--web]] [<command>]"
-msgstr "git help [[-i|--info] [-m|--man] [-w|--web]] [<lệnh>]"
+msgid "git help [[-i|--info] [-m|--man] [-w|--web]] [<command>|<doc>]"
+msgstr "git help [[-i|--info] [-m|--man] [-w|--web]] [<lệnh>|<tài liệu>]"
 
 #, c-format
 msgid "unrecognized help format '%s'"
-msgstr "không nhận ra định dạng trợ giúp “%s”"
+msgstr "không nhận ra định dạng trợ giúp '%s'"
 
 msgid "Failed to start emacsclient."
 msgstr "Gặp lỗi khi khởi chạy emacsclient."
 
 msgid "Failed to parse emacsclient version."
-msgstr "Gặp lỗi khi phân tích phiên bản emacsclient."
+msgstr "Gặp lỗi khi đọc phiên bản emacsclient."
 
 #, c-format
 msgid "emacsclient version '%d' too old (< 22)."
-msgstr "phiên bản của emacsclient “%d” quá cũ (< 22)."
+msgstr "phiên bản của emacsclient '%d' quá cũ (< 22)."
 
 #, c-format
 msgid "failed to exec '%s'"
-msgstr "gặp lỗi khi thực thi “%s”"
+msgstr "gặp lỗi khi thực thi '%s'"
 
 #, c-format
 msgid ""
 "'%s': path for unsupported man viewer.\n"
 "Please consider using 'man.<tool>.cmd' instead."
 msgstr ""
-"“%s”: đường dẫn không hỗ trợ bộ trình chiếu man.\n"
-"Hãy cân nhắc đến việc sử dụng “man.<tool>.cmd” để thay thế."
+"'%s': đường dẫn không hỗ trợ bộ trình chiếu man.\n"
+"Hãy cân nhắc đến việc sử dụng 'man.<tool>.cmd' để thay thế."
 
 #, c-format
 msgid ""
 "'%s': cmd for supported man viewer.\n"
 "Please consider using 'man.<tool>.path' instead."
 msgstr ""
-"“%s”: cmd (lệnh) hỗ trợ bộ trình chiếu man.\n"
-"Hãy cân nhắc đến việc sử dụng “man.<tool>.path” để thay thế."
+"'%s': cmd (lệnh) hỗ trợ bộ trình chiếu man.\n"
+"Hãy cân nhắc đến việc sử dụng 'man.<tool>.path' để thay thế."
 
 #, c-format
 msgid "'%s': unknown man viewer."
-msgstr "“%s”: không rõ chương trình xem man."
+msgstr "'%s': không rõ chương trình xem man."
 
 msgid "no man viewer handled the request"
 msgstr "không có trình xem trợ giúp dạng manpage tiếp hợp với yêu cầu"
@@ -6872,7 +7021,7 @@
 
 #, c-format
 msgid "'%s' is aliased to '%s'"
-msgstr "“%s” được đặt bí danh thành “%s”"
+msgstr "'%s' được đặt bí danh thành '%s'"
 
 #, c-format
 msgid "bad alias.%s string: %s"
@@ -6893,13 +7042,20 @@
 msgstr "cách dùng: %s%s"
 
 msgid "'git help config' for more information"
-msgstr "Chạy lệnh “git help config” để có thêm thông tin"
+msgstr "Chạy lệnh 'git help config' để có thêm thông tin"
 
-msgid "git hook run [--ignore-missing] <hook-name> [-- <hook-args>]"
-msgstr "git hook run [--ignore-missing] <tên-móc> [-- <các tham số cho móc>]"
+msgid ""
+"git hook run [--ignore-missing] [--to-stdin=<path>] <hook-name> [-- <hook-"
+"args>]"
+msgstr ""
+"git hook run [--ignore-missing] [--to-stdin=</đường/dẫn/>] <tên-móc> [-- "
+"<các tham số cho móc>]"
 
 msgid "silently ignore missing requested <hook-name>"
-msgstr "bỏ qua âm thầm các <hook-name> đã yêu cầu còn thiếu"
+msgstr "âm thầm bỏ qua các <hook-name> đã yêu cầu còn thiếu"
+
+msgid "file to read into hooks' stdin"
+msgstr "tập tin để đưa vào stdin của hook"
 
 #, c-format
 msgid "object type mismatch at %s"
@@ -6911,7 +7067,7 @@
 
 #, c-format
 msgid "object %s: expected type %s, found %s"
-msgstr "đối tượng %s: cần kiểu %s nhưng lại nhận được %s"
+msgstr "đối tượng %s: cần kiểu %s nhưng lại có %s"
 
 #, c-format
 msgid "cannot fill %d byte"
@@ -6947,13 +7103,13 @@
 
 #, c-format
 msgid "inflate returned %d"
-msgstr "xả nén trả về %d"
+msgstr "giải nén trả về %d"
 
 msgid "offset value overflow for delta base object"
 msgstr "tràn giá trị khoảng bù cho đối tượng delta cơ sở"
 
 msgid "delta base offset is out of bound"
-msgstr "khoảng bù cơ sở cho delta nằm ngoài phạm vi"
+msgstr "khoảng bù cơ sở cho delta nằm ngoài biên"
 
 #, c-format
 msgid "unknown object type %d"
@@ -6968,17 +7124,13 @@
 msgstr[0] "tập tin gói bị kết thúc sớm, thiếu %<PRIuMAX> byte"
 
 msgid "serious inflate inconsistency"
-msgstr "sự mâu thuẫn xả nén nghiêm trọng"
+msgstr "sự mâu thuẫn giải nén nghiêm trọng"
 
 #, c-format
 msgid "SHA1 COLLISION FOUND WITH %s !"
 msgstr "SỰ VA CHẠM SHA1 ĐÃ XẢY RA VỚI %s!"
 
 #, c-format
-msgid "unable to read %s"
-msgstr "không thể đọc %s"
-
-#, c-format
 msgid "cannot read existing object info %s"
 msgstr "không thể đọc thông tin đối tượng sẵn có %s"
 
@@ -7004,13 +7156,13 @@
 msgstr "Đang nhận về các đối tượng"
 
 msgid "Indexing objects"
-msgstr "Các đối tượng bảng mục lục"
+msgstr "Các đối tượng chỉ mục"
 
 msgid "pack is corrupted (SHA1 mismatch)"
 msgstr "gói bị sai hỏng (SHA1 không khớp)"
 
 msgid "cannot fstat packfile"
-msgstr "không thể lấy thông tin thống kê packfile"
+msgstr "không thể fstat packfile"
 
 msgid "pack has junk at the end"
 msgstr "pack có phần thừa ở cuối"
@@ -7035,7 +7187,7 @@
 
 #, c-format
 msgid "Unexpected tail checksum for %s (disk corruption?)"
-msgstr "Gặp tổng kiểm tra tail không cần cho %s (đĩa hỏng?)"
+msgstr "Gặp tổng kiểm tra tail bất thường cho %s (đĩa hỏng?)"
 
 #, c-format
 msgid "pack has %d unresolved delta"
@@ -7044,7 +7196,7 @@
 
 #, c-format
 msgid "unable to deflate appended object (%d)"
-msgstr "không thể xả nén đối tượng nối thêm (%d)"
+msgstr "không thể giải nén đối tượng nối thêm (%d)"
 
 #, c-format
 msgid "local object %s is corrupt"
@@ -7052,19 +7204,19 @@
 
 #, c-format
 msgid "packfile name '%s' does not end with '.%s'"
-msgstr "tên tập tin tập tin gói “%s” không được kết thúc “.%s”"
+msgstr "tên tập tin tập tin gói '%s' không được kết thúc '.%s'"
 
 #, c-format
 msgid "cannot write %s file '%s'"
-msgstr "không thể ghi %s tập tin “%s”"
+msgstr "không thể ghi %s tập tin '%s'"
 
 #, c-format
 msgid "cannot close written %s file '%s'"
-msgstr "không thể đóng tập tin được ghi %s “%s”"
+msgstr "không thể đóng tập tin được ghi %s '%s'"
 
 #, c-format
 msgid "unable to rename temporary '*.%s' file to '%s'"
-msgstr "không thể đổi tên tập tin tạm thời “*.%s” thành “%s”"
+msgstr "không thể đổi tên tập tin tạm thời '*.%s' thành '%s'"
 
 msgid "error while closing pack file"
 msgstr "gặp lỗi trong khi đóng tập tin gói"
@@ -7075,11 +7227,11 @@
 
 #, c-format
 msgid "Cannot open existing pack file '%s'"
-msgstr "Không thể mở tập tin gói đã sẵn có “%s”"
+msgstr "Không thể mở tập tin gói đã sẵn có '%s'"
 
 #, c-format
 msgid "Cannot open existing pack idx file for '%s'"
-msgstr "Không thể mở tập tin idx của gói cho “%s”"
+msgstr "Không thể mở tập tin idx của gói cho '%s'"
 
 #, c-format
 msgid "non delta: %d object"
@@ -7089,10 +7241,10 @@
 #, c-format
 msgid "chain length = %d: %lu object"
 msgid_plural "chain length = %d: %lu objects"
-msgstr[0] "chiều dài xích = %d: %lu đối tượng"
+msgstr[0] "chiều dài chuỗi = %d: %lu đối tượng"
 
 msgid "Cannot come back to cwd"
-msgstr "Không thể quay lại cwd"
+msgstr "Không thể quay lại thư mục hiện hành"
 
 #, c-format
 msgid "bad %s"
@@ -7100,7 +7252,7 @@
 
 #, c-format
 msgid "unknown hash algorithm '%s'"
-msgstr "không hiểu thuật toán băm dữ liệu “%s”"
+msgstr "không hiểu thuật toán băm dữ liệu '%s'"
 
 msgid "--stdin requires a git repository"
 msgstr "--stdin cần một kho git"
@@ -7111,83 +7263,18 @@
 msgid "fsck error in pack objects"
 msgstr "lỗi fsck trong các đối tượng gói"
 
-#, c-format
-msgid "cannot stat template '%s'"
-msgstr "không thể lấy thông tin thống kê về mẫu “%s”"
-
-#, c-format
-msgid "cannot opendir '%s'"
-msgstr "không thể opendir() “%s”"
-
-#, c-format
-msgid "cannot readlink '%s'"
-msgstr "không thể readlink “%s”"
-
-#, c-format
-msgid "cannot symlink '%s' '%s'"
-msgstr "không thể tạo liên kết mềm (symlink) “%s” “%s”"
-
-#, c-format
-msgid "cannot copy '%s' to '%s'"
-msgstr "không thể sao chép “%s” sang “%s”"
-
-#, c-format
-msgid "ignoring template %s"
-msgstr "đang lờ đi mẫu “%s”"
-
-#, c-format
-msgid "templates not found in %s"
-msgstr "các mẫu không được tìm thấy trong %s"
-
-#, c-format
-msgid "not copying templates from '%s': %s"
-msgstr "không sao chép các mẫu từ “%s”: %s"
-
-#, c-format
-msgid "invalid initial branch name: '%s'"
-msgstr "tên nhánh khởi tạo không hợp lệ: “%s”"
-
-#, c-format
-msgid "unable to handle file type %d"
-msgstr "không thể xử lý (handle) tập tin kiểu %d"
-
-#, c-format
-msgid "unable to move %s to %s"
-msgstr "không di chuyển được %s vào %s"
-
-msgid "attempt to reinitialize repository with different hash"
-msgstr "cố để khởi tạo lại một kho với kiểu băm dữ liệu khác"
-
-#, c-format
-msgid "%s already exists"
-msgstr "%s đã có từ trước rồi"
-
-#, c-format
-msgid "re-init: ignored --initial-branch=%s"
-msgstr "re-init: --initial-branch=%s bị bỏ qua"
-
-#, c-format
-msgid "Reinitialized existing shared Git repository in %s%s\n"
-msgstr "Đã khởi tạo lại kho Git chia sẻ sẵn có trong %s%s\n"
-
-#, c-format
-msgid "Reinitialized existing Git repository in %s%s\n"
-msgstr "Đã khởi tạo lại kho Git sẵn có trong %s%s\n"
-
-#, c-format
-msgid "Initialized empty shared Git repository in %s%s\n"
-msgstr "Đã khởi tạo lại kho Git chia sẻ trống rỗng sẵn có trong %s%s\n"
-
-#, c-format
-msgid "Initialized empty Git repository in %s%s\n"
-msgstr "Đã khởi tạo lại kho Git trống rỗng sẵn có trong %s%s\n"
-
 msgid ""
-"git init [-q | --quiet] [--bare] [--template=<template-directory>] [--"
-"shared[=<permissions>]] [<directory>]"
+"git init [-q | --quiet] [--bare] [--template=<template-directory>]\n"
+"         [--separate-git-dir <git-dir>] [--object-format=<format>]\n"
+"         [--ref-format=<format>]\n"
+"         [-b <branch-name> | --initial-branch=<branch-name>]\n"
+"         [--shared[=<permissions>]] [<directory>]"
 msgstr ""
-"git init [-q | --quiet] [--bare] [--template=<thư-mục-tạm>] [--shared[=<các-"
-"quyền>]] [thư-mục]"
+"git init [-q | --quiet] [--bare] [--template=<thư mục mẫu>]\n"
+"         [--separate-git-dir <thư mục git>] [--object-format=<định dạng>]\n"
+"         [--ref-format=<định dạng>]\n"
+"         [-b <tên nhánh> | --initial-branch=<tên nhánh>]\n"
+"         [--shared[=<quyền hạn>]] [<thư mục>]"
 
 msgid "permissions"
 msgstr "các quyền"
@@ -7222,23 +7309,54 @@
 
 #, c-format
 msgid "Cannot access work tree '%s'"
-msgstr "Không thể truy cập cây (tree) làm việc “%s”"
+msgstr "Không thể truy cập cây làm việc '%s'"
 
 msgid "--separate-git-dir incompatible with bare repository"
-msgstr "--separate-git-dir xung khắc với kho thuần"
+msgstr "--separate-git-dir không tương thích với kho bare"
 
 msgid ""
-"git interpret-trailers [--in-place] [--trim-empty] [(--trailer "
-"<token>[(=|:)<value>])...] [<file>...]"
+"git interpret-trailers [--in-place] [--trim-empty]\n"
+"                       [(--trailer (<key>|<key-alias>)[(=|:)<value>])...]\n"
+"                       [--parse] [<file>...]"
 msgstr ""
-"git interpret-trailers [--in-place] [--trim-empty] [(--trailer "
-"<thẻ>[(=|:)<giá-trị>])…] [<tập-tin>…]"
+"git interpret-trailers [--in-place] [--trim-empty]\n"
+"                       [(--trailer (<key>|<key-alias>)[(=|:)<giá-trị>])...]\n"
+"                       [--parse] [<tập-tin>...]"
+
+#, c-format
+msgid "could not stat %s"
+msgstr "không thể stat %s"
+
+#, c-format
+msgid "file %s is not a regular file"
+msgstr "\"%s\" không phải là tập tin bình thường"
+
+#, c-format
+msgid "file %s is not writable by user"
+msgstr "tập tin %s người dùng không thể ghi được"
+
+msgid "could not open temporary file"
+msgstr "không thể tạo tập tin tạm thời"
+
+#, c-format
+msgid "could not read input file '%s'"
+msgstr "không đọc được tập tin đầu vào '%s'"
+
+msgid "could not read from stdin"
+msgstr "không thể đọc từ stdin"
+
+#, c-format
+msgid "could not rename temporary file to %s"
+msgstr "không thể đổi tên tập tin tạm thời thành %s"
 
 msgid "edit files in place"
 msgstr "sửa các tập tin tại chỗ"
 
 msgid "trim empty trailers"
-msgstr "bộ dò vết cắt bỏ phần trống rỗng"
+msgstr "cắt bỏ phần trống thừa ở đuôi"
+
+msgid "placement"
+msgstr "vị trí"
 
 msgid "where to place the new trailer"
 msgstr "đặt phần đuôi mới ở đâu"
@@ -7252,20 +7370,20 @@
 msgid "output only the trailers"
 msgstr "chỉ xuất phần đuôi"
 
-msgid "do not apply config rules"
-msgstr "đừng áp dụng các quy tắc cấu hình"
+msgid "do not apply trailer.* configuration variables"
+msgstr "không áp dụng các biến cấu hình trailer.*"
 
-msgid "join whitespace-continued values"
-msgstr "nối các giá trị khoảng-trắng-liên-tiếp"
+msgid "reformat multiline trailer values as single-line values"
+msgstr "định dạng lại giá trị đuôi thành giá trị trên một dòng"
 
-msgid "set parsing options"
-msgstr "đặt các tùy chọn phân tích cú pháp"
+msgid "alias for --only-trailers --only-input --unfold"
+msgstr "viết tắt cho --only-trailers --only-input --unfold"
 
-msgid "do not treat --- specially"
-msgstr "không coi --- là đặc biệt"
+msgid "do not treat \"---\" as the end of input"
+msgstr "không coi \"---\" là kết thúc đầu vào"
 
 msgid "trailer(s) to add"
-msgstr "bộ dò vết cần thêm"
+msgstr "phần đuôi cần thêm"
 
 msgid "--trailer with --only-input does not make sense"
 msgstr "--trailer cùng với --only-input không hợp lý"
@@ -7274,10 +7392,10 @@
 msgstr "không đưa ra tập tin đầu vào để sửa tại-chỗ"
 
 msgid "git log [<options>] [<revision-range>] [[--] <path>...]"
-msgstr "git log [<các tùy chọn>] [<vùng-xem-xét>] [[--] </đường/dẫn>…]"
+msgstr "git log [<các tùy chọn>] [<vùng-xem-xét>] [[--] </đường/dẫn>...]"
 
 msgid "git show [<options>] <object>..."
-msgstr "git show [<các tùy chọn>] <đối-tượng>…"
+msgstr "git show [<các tùy chọn>] <đối-tượng>..."
 
 #, c-format
 msgid "invalid --decorate option: %s"
@@ -7289,8 +7407,8 @@
 msgid "show source"
 msgstr "hiển thị mã nguồn"
 
-msgid "use mail map file"
-msgstr "sử dụng tập tin ánh xạ thư"
+msgid "clear all previously-defined decoration filters"
+msgstr "xoá các bộ lọc decorate đã định nghĩa từ trước"
 
 msgid "only decorate refs that match <pattern>"
 msgstr "chỉ tô sáng các tham chiếu khớp với <mẫu>"
@@ -7299,21 +7417,21 @@
 msgstr "không tô sáng các tham chiếu khớp với <mẫu>"
 
 msgid "decorate options"
-msgstr "các tùy chọn trang trí"
+msgstr "các tùy chọn decorate"
 
 msgid ""
 "trace the evolution of line range <start>,<end> or function :<funcname> in "
 "<file>"
 msgstr ""
-"theo dõi sự tiến hóa của phạm vi <start><end> dòng, hoặc chức năng:"
-"<funcname> trong <file>"
+"theo vết sự tiến hóa của phạm vi dòng <start>,<end>, hoặc hàm :<tên hàm> "
+"trong <tập tin>"
 
 #, c-format
 msgid "unrecognized argument: %s"
 msgstr "đối số không được thừa nhận: %s"
 
 msgid "-L<range>:<file> cannot be used with pathspec"
-msgstr "-L<vùng>:<tập_tin> không thể được sử dụng với đặc tả đường dẫn"
+msgstr "-L<vùng>:<tập tin> không thể được sử dụng với đặc tả đường dẫn"
 
 #, c-format
 msgid "Final output: %d %s\n"
@@ -7343,7 +7461,7 @@
 
 #, c-format
 msgid "cannot open patch file %s"
-msgstr "không thể mở tập tin miếng vá: %s"
+msgstr "không thể mở tập tin bản vá: %s"
 
 msgid "need exactly one range"
 msgstr "cần chính xác một vùng"
@@ -7351,8 +7469,12 @@
 msgid "not a range"
 msgstr "không phải là một vùng"
 
+#, c-format
+msgid "unable to read branch description file '%s'"
+msgstr "không thể đọc tập tin cấu hình nhánh '%s'"
+
 msgid "cover letter needs email format"
-msgstr "“cover letter” cần cho định dạng thư"
+msgstr "cover letter cần định dạng thư"
 
 msgid "failed to create cover-letter file"
 msgstr "gặp lỗi khi tạo các tập tin cover-letter"
@@ -7373,10 +7495,10 @@
 
 #, c-format
 msgid "failed to resolve '%s' as a valid ref"
-msgstr "gặp lỗi khi phân giải “%s” như là một tham chiếu hợp lệ"
+msgstr "gặp lỗi khi phân giải '%s' thành một tham chiếu hợp lệ"
 
 msgid "could not find exact merge base"
-msgstr "không tìm thấy nền hòa trộn chính xác"
+msgstr "không tìm thấy gốc hòa trộn chính xác"
 
 msgid ""
 "failed to get upstream, if you want to record base commit automatically,\n"
@@ -7389,7 +7511,7 @@
 "\"--base=<base-commit-id>\" một cách thủ công"
 
 msgid "failed to find exact merge base"
-msgstr "gặp lỗi khi tìm nền hòa trộn chính xác"
+msgstr "gặp lỗi khi tìm gốc hòa trộn chính xác"
 
 msgid "base commit should be the ancestor of revision list"
 msgstr "lần chuyển giao nền không là tổ tiên của danh sách điểm xét duyệt"
@@ -7398,7 +7520,7 @@
 msgstr "lần chuyển giao nền không được trong danh sách điểm xét duyệt"
 
 msgid "cannot get patch id"
-msgstr "không thể lấy mã miếng vá"
+msgstr "không thể lấy mã bản vá"
 
 msgid "failed to infer range-diff origin of current series"
 msgstr ""
@@ -7406,70 +7528,73 @@
 
 #, c-format
 msgid "using '%s' as range-diff origin of current series"
-msgstr "dùng “%s” như là gốc range-diff của sê-ri hiện tại"
+msgstr "dùng '%s' làm gốc range-diff của sê-ri hiện tại"
 
 msgid "use [PATCH n/m] even with a single patch"
-msgstr "dùng [PATCH n/m] ngay cả với miếng vá đơn"
+msgstr "dùng [PATCH n/m] ngay cả với bản vá đơn"
 
 msgid "use [PATCH] even with multiple patches"
-msgstr "dùng [VÁ] ngay cả với các miếng vá phức tạp"
+msgstr "dùng [PATCH] ngay cả với các bản vá nhiều phần"
 
 msgid "print patches to standard out"
-msgstr "hiển thị miếng vá ra đầu ra chuẩn"
+msgstr "hiển thị bản vá ra stdout"
 
 msgid "generate a cover letter"
 msgstr "tạo bì thư"
 
 msgid "use simple number sequence for output file names"
-msgstr "sử dụng chỗi dãy số dạng đơn giản cho tên tập-tin xuất ra"
+msgstr "sử dụng chuỗi dãy số dạng đơn giản cho tên tập-tin xuất ra"
 
 msgid "sfx"
-msgstr "sfx"
+msgstr "hậu-tố"
 
 msgid "use <sfx> instead of '.patch'"
-msgstr "sử dụng <sfx> thay cho “.patch”"
+msgstr "sử dụng <hậu-tố> thay cho '.patch'"
 
 msgid "start numbering patches at <n> instead of 1"
-msgstr "bắt đầu đánh số miếng vá từ <n> thay vì 1"
+msgstr "bắt đầu đánh số bản vá từ <n> thay vì 1"
 
 msgid "reroll-count"
-msgstr "đếm reroll"
+msgstr "số-lần-chạy-lại"
 
 msgid "mark the series as Nth re-roll"
-msgstr "đánh dấu chuỗi nối tiếp dạng thứ-N re-roll"
+msgstr "đánh dấu chuỗi là lần chạy lại thứ N"
 
 msgid "max length of output filename"
 msgstr "chiều dài tên tập tin đầu ra tối đa"
 
 msgid "use [RFC PATCH] instead of [PATCH]"
-msgstr "dùng [VÁ RFC] thay cho [VÁ]"
+msgstr "dùng [RFC PATCH] thay cho [PATCH]"
 
 msgid "cover-from-description-mode"
 msgstr "cover-from-description-mode"
 
 msgid "generate parts of a cover letter based on a branch's description"
-msgstr "tạo ra các phần của một lá thư bao gồm dựa trên mô tả của nhánh"
+msgstr "tạo ra phần bìa thư dựa trên mô tả của nhánh"
+
+msgid "use branch description from file"
+msgstr "dùng mô tả nhánh từ tập tin"
 
 msgid "use [<prefix>] instead of [PATCH]"
-msgstr "dùng [<tiền-tố>] thay cho [VÁ]"
+msgstr "dùng [<tiền-tố>] thay cho [PATCH]"
 
 msgid "store resulting files in <dir>"
-msgstr "lưu các tập tin kết quả trong <t.mục>"
+msgstr "lưu các tập tin kết quả trong <thư mục>"
 
 msgid "don't strip/add [PATCH]"
-msgstr "không strip/add [VÁ]"
+msgstr "không loại bỏ/thêm [PATCH]"
 
 msgid "don't output binary diffs"
-msgstr "không kết xuất diff (những khác biệt) nhị phân"
+msgstr "không kết xuất diff nhị phân"
 
 msgid "output all-zero hash in From header"
 msgstr "xuất mọi mã băm all-zero trong phần đầu From"
 
 msgid "don't include a patch matching a commit upstream"
-msgstr "không bao gồm miếng vá khớp với một lần chuyển giao thượng nguồn"
+msgstr "không bao gồm bản vá khớp với một lần chuyển giao thượng nguồn"
 
 msgid "show patch format instead of default (patch + stat)"
-msgstr "hiển thị định dạng miếng vá thay vì mặc định (miếng vá + thống kê)"
+msgstr "hiển thị định dạng bản vá thay vì mặc định (bản vá + thống kê)"
 
 msgid "Messaging"
 msgstr "Lời nhắn"
@@ -7490,11 +7615,10 @@
 msgstr "thêm Cc: đầu đề thư"
 
 msgid "ident"
-msgstr "thụt lề"
+msgstr "ident"
 
 msgid "set From address to <ident> (or committer ident if absent)"
-msgstr ""
-"đặt “Địa chỉ gửi” thành <thụ lề> (hoặc thụt lề người commit nếu bỏ quên)"
+msgstr "đặt 'Địa chỉ gửi' thành <ident> (hoặc người commit nếu bỏ quên)"
 
 msgid "message-id"
 msgstr "message-id"
@@ -7506,13 +7630,13 @@
 msgstr "ranh giới"
 
 msgid "attach the patch"
-msgstr "đính kèm miếng vá"
+msgstr "đính kèm bản vá"
 
 msgid "inline the patch"
-msgstr "dùng miếng vá làm nội dung"
+msgstr "dùng bản vá làm nội dung"
 
 msgid "enable message threading, styles: shallow, deep"
-msgstr "cho phép luồng lời nhắn, kiểu: “shallow”, “deep”"
+msgstr "cho phép luồng lời nhắn, kiểu: 'shallow', 'deep'"
 
 msgid "signature"
 msgstr "chữ ký"
@@ -7524,28 +7648,31 @@
 msgstr "lần_chuyển_giao_nền"
 
 msgid "add prerequisite tree info to the patch series"
-msgstr "add trước hết đòi hỏi thông tin cây tới sê-ri miếng vá"
+msgstr "add trước hết đòi hỏi thông tin cây tới sê-ri bản vá"
 
 msgid "add a signature from a file"
 msgstr "thêm chữ ký từ một tập tin"
 
 msgid "don't print the patch filenames"
-msgstr "không hiển thị các tên tập tin của miếng vá"
+msgstr "không hiển thị các tên tập tin của bản vá"
 
 msgid "show progress while generating patches"
-msgstr "hiển thị bộ đo tiến triển trong khi tạo các miếng vá"
+msgstr "hiển thị bộ đo tiến triển trong khi tạo các bản vá"
 
 msgid "show changes against <rev> in cover letter or single patch"
 msgstr ""
-"hiển thị các thay đổi dựa trên <rev> trong các chữ bao bọc hoặc miếng vá đơn"
+"hiển thị các thay đổi dựa trên <rev> trong các chữ bao bọc hoặc bản vá đơn"
 
 msgid "show changes against <refspec> in cover letter or single patch"
 msgstr ""
-"hiển thị các thay đổi dựa trên <refspec> trong các chữ bao bọc hoặc miếng vá "
+"hiển thị các thay đổi dựa trên <refspec> trong các chữ bao bọc hoặc bản vá "
 "đơn"
 
 msgid "percentage by which creation is weighted"
-msgstr "tỷ lệ phần trăm theo cái tạo là weighted"
+msgstr "tỉ lệ phần trăm theo cái tạo là weighted"
+
+msgid "show in-body From: even if identical to the e-mail header"
+msgstr "hiện mục From: trong phần thân kể cả khi giống với phần tiêu đề e-mail"
 
 #, c-format
 msgid "invalid ident line: %s"
@@ -7565,7 +7692,7 @@
 
 #, c-format
 msgid "could not create directory '%s'"
-msgstr "không thể tạo thư mục “%s”"
+msgstr "không thể tạo thư mục '%s'"
 
 msgid "--interdiff requires --cover-letter or single patch"
 msgstr "--interdiff cần --cover-letter hoặc vá đơn"
@@ -7578,7 +7705,7 @@
 msgstr "Interdiff dựa trên v%d:"
 
 msgid "--range-diff requires --cover-letter or single patch"
-msgstr "--range-diff yêu cầu --cover-letter hoặc miếng vá đơn"
+msgstr "--range-diff yêu cầu --cover-letter hoặc bản vá đơn"
 
 msgid "Range-diff:"
 msgstr "Range-diff:"
@@ -7589,10 +7716,10 @@
 
 #, c-format
 msgid "unable to read signature file '%s'"
-msgstr "không thể đọc tập tin chữ ký “%s”"
+msgstr "không thể đọc tập tin chữ ký '%s'"
 
 msgid "Generating patches"
-msgstr "Đang tạo các miếng vá"
+msgstr "Đang tạo các bản vá"
 
 msgid "failed to create output files"
 msgstr "gặp lỗi khi tạo các tập tin kết xuất"
@@ -7607,8 +7734,12 @@
 "Không tìm thấy nhánh mạng được theo dõi, hãy chỉ định <thượng-nguồn> một "
 "cách thủ công.\n"
 
+#, c-format
+msgid "could not get object info about '%s'"
+msgstr "không thể lấy thông tin đối tượng về '%s'"
+
 msgid "git ls-files [<options>] [<file>...]"
-msgstr "git ls-files [<các tùy chọn>] [<tập-tin>…]"
+msgstr "git ls-files [<các tùy chọn>] [<tập-tin>...]"
 
 msgid "separate paths with the NUL character"
 msgstr "các đường dẫn được ngăn cách bởi ký tự NULL"
@@ -7618,11 +7749,11 @@
 
 msgid "use lowercase letters for 'assume unchanged' files"
 msgstr ""
-"dùng chữ cái viết thường cho các tập tin “assume unchanged” (giả định không "
+"dùng chữ cái viết thường cho các tập tin 'assume unchanged' (giả định không "
 "thay đổi)"
 
 msgid "use lowercase letters for 'fsmonitor clean' files"
-msgstr "dùng chữ cái viết thường cho các tập tin “fsmonitor clean”"
+msgstr "dùng chữ cái viết thường cho các tập tin 'fsmonitor clean'"
 
 msgid "show cached files in the output (default)"
 msgstr "hiển thị các tập tin được nhớ tạm vào đầu ra (mặc định)"
@@ -7646,7 +7777,7 @@
 msgstr "hiển thị các tập tin trên hệ thống tập tin mà nó cần được gỡ bỏ"
 
 msgid "show 'other' directories' names only"
-msgstr "chỉ hiển thị tên của các thư mục “khác”"
+msgstr "chỉ hiển thị tên của các thư mục 'khác'"
 
 msgid "show line endings of files"
 msgstr "hiển thị kết thúc dòng của các tập tin"
@@ -7676,7 +7807,7 @@
 msgstr "làm cho kết xuất liên quan đến thư mục ở mức cao nhất (gốc) của dự án"
 
 msgid "if any <file> is not in the index, treat this as an error"
-msgstr "nếu <tập tin> bất kỳ không ở trong bảng mục lục, xử lý nó như một lỗi"
+msgstr "nếu <tập tin> bất kỳ không ở trong chỉ mục, xử lý nó như một lỗi"
 
 msgid "tree-ish"
 msgstr "tree-ish"
@@ -7692,16 +7823,23 @@
 msgstr "chặn các mục tin trùng lặp"
 
 msgid "show sparse directories in the presence of a sparse index"
-msgstr "hiển thị thư mục \"sparse\" trong sự có mặt của mục lục \"sparse\""
+msgstr "hiển thị thư mục thưa trong sự có mặt của chỉ mục thưa"
+
+msgid ""
+"--format cannot be used with -s, -o, -k, -t, --resolve-undo, --deduplicate, "
+"--eol"
+msgstr ""
+"--format không thể được dùng với -s, -o, -k, -t, --resolve-undo,--"
+"deduplicate, --eol"
 
 msgid ""
 "git ls-remote [--heads] [--tags] [--refs] [--upload-pack=<exec>]\n"
-"              [-q | --quiet] [--exit-code] [--get-url]\n"
-"              [--symref] [<repository> [<refs>...]]"
+"              [-q | --quiet] [--exit-code] [--get-url] [--sort=<key>]\n"
+"              [--symref] [<repository> [<patterns>...]]"
 msgstr ""
 "git ls-remote [--heads] [--tags] [--refs] [--upload-pack=<exec>]\n"
-"              [-q | --quiet] [--exit-code] [--get-url]\n"
-"              [--symref] [<kho> [<các tham chiếu>…]]"
+"              [-q | --quiet] [--exit-code] [--get-url] [--sort=<key>]\n"
+"              [--symref] [<kho> [<mẫu>...]]"
 
 msgid "do not print remote URL"
 msgstr "không hiển thị URL máy chủ"
@@ -7731,23 +7869,7 @@
 msgstr "hiển thị tham chiếu nằm dưới để thêm vào đối tượng được chỉ bởi nó"
 
 msgid "git ls-tree [<options>] <tree-ish> [<path>...]"
-msgstr "git ls-tree [<các tùy chọn>] <tree-ish> [</đường/dẫn>…]"
-
-#, c-format
-msgid "could not get object info about '%s'"
-msgstr "không thể lấy thông tin đối tượng về “%s”"
-
-#, c-format
-msgid "bad ls-tree format: element '%s' does not start with '('"
-msgstr "định dạng ls-tree sai: phần tử “%s” không bắt đầu bằng “(”"
-
-#, c-format
-msgid "bad ls-tree format: element '%s' does not end in ')'"
-msgstr "định dạng ls-tree sai: phần tử “%s” không bắt kết thúc bằng “)”"
-
-#, c-format
-msgid "bad ls-tree format: %%%.*s"
-msgstr "định dạng ls-tree sai: %%%.*s"
+msgstr "git ls-tree [<các tùy chọn>] <tree-ish> [</đường/dẫn>...]"
 
 msgid "only show trees"
 msgstr "chỉ hiển thị các tree"
@@ -7759,7 +7881,7 @@
 msgstr "hiển thị cây khi đệ quy"
 
 msgid "terminate entries with NUL byte"
-msgstr "chấm dứt mục tin với byte NUL"
+msgstr "kết thúc mục tin với byte NUL"
 
 msgid "include object size"
 msgstr "gồm cả kích thước đối tượng"
@@ -7818,38 +7940,38 @@
 msgstr "sử dụng phần đầu trong nội dung thư"
 
 msgid "reading patches from stdin/tty..."
-msgstr "đọc các miếng vá từ đầu vào tiêu chuẩn stdin/tty..."
+msgstr "đọc các bản vá từ stdin/tty..."
 
 #, c-format
 msgid "empty mbox: '%s'"
-msgstr "mbox trống rỗng: “%s”"
+msgstr "mbox trống rỗng: '%s'"
 
 msgid "git merge-base [-a | --all] <commit> <commit>..."
-msgstr "git merge-base [-a | --all] <lần_chuyển_giao> <lần_chuyển_giao>…"
+msgstr "git merge-base [-a | --all] <lần_chuyển_giao> <lần_chuyển_giao>..."
 
 msgid "git merge-base [-a | --all] --octopus <commit>..."
-msgstr "git merge-base [-a | --all] --octopus <lần_chuyển_giao>…"
-
-msgid "git merge-base --independent <commit>..."
-msgstr "git merge-base --independent <lần_chuyển_giao>…"
+msgstr "git merge-base [-a | --all] --octopus <lần_chuyển_giao>..."
 
 msgid "git merge-base --is-ancestor <commit> <commit>"
 msgstr "git merge-base --is-ancestor <commit> <lần_chuyển_giao>"
 
+msgid "git merge-base --independent <commit>..."
+msgstr "git merge-base --independent <lần_chuyển_giao>..."
+
 msgid "git merge-base --fork-point <ref> [<commit>]"
 msgstr "git merge-base --fork-point <tham-chiếu> [<lần_chuyển_giao>]"
 
 msgid "output all common ancestors"
-msgstr "xuất ra tất cả các ông bà, tổ tiên chung"
+msgstr "xuất ra tất cả các ông bà tổ tiên chung"
 
 msgid "find ancestors for a single n-way merge"
 msgstr "tìm tổ tiên của hòa trộn n-way đơn"
 
 msgid "list revs not reachable from others"
-msgstr "liệt kê các “rev” mà nó không thể đọc được từ cái khác"
+msgstr "liệt kê các 'rev' không thể tới được từ cái còn lại"
 
 msgid "is the first one ancestor of the other?"
-msgstr "là cha mẹ đầu tiên của cái khác?"
+msgstr "có phải cái trước là tổ tiên của cái sau?"
 
 msgid "find where <commit> forked from reflog of <ref>"
 msgstr "tìm xem <commit> được rẽ nhánh ở đâu từ reflog của <th.chiếu>"
@@ -7861,8 +7983,18 @@
 "git merge-file [<các tùy chọn>] [-L <tên1> [-L <gốc> [-L <tên2>]]] <tập-"
 "tin1> <tập-tin-gốc> <tập-tin2>"
 
+msgid ""
+"option diff-algorithm accepts \"myers\", \"minimal\", \"patience\" and "
+"\"histogram\""
+msgstr ""
+"tùy chọn diff-algorithm chấp nhận \"myers\", \"minimal\", \"patience\" và "
+"\"histogram\""
+
 msgid "send results to standard output"
-msgstr "gửi kết quả vào đầu ra tiêu chuẩn"
+msgstr "gửi kết quả ra stdout"
+
+msgid "use object IDs instead of filenames"
+msgstr "dùng ID đối tượng thay vì tên tập tin"
 
 msgid "use a diff3 based merge"
 msgstr "dùng kiểu hòa dựa trên diff3"
@@ -7871,16 +8003,22 @@
 msgstr "dùng kiểu hòa trộn dựa trên 'zealous diff3'"
 
 msgid "for conflicts, use our version"
-msgstr "để tránh xung đột, sử dụng phiên bản của chúng ta"
+msgstr "nếu xung đột, sử dụng phiên bản của ta"
 
 msgid "for conflicts, use their version"
-msgstr "để tránh xung đột, sử dụng phiên bản của họ"
+msgstr "nếu xung đột, sử dụng phiên bản của họ"
 
 msgid "for conflicts, use a union version"
-msgstr "để tránh xung đột, sử dụng phiên bản kết hợp"
+msgstr "nếu xung đột, sử dụng phiên bản kết hợp"
+
+msgid "<algorithm>"
+msgstr "<thuật toán>"
+
+msgid "choose a diff algorithm"
+msgstr "chọn thuật toán diff"
 
 msgid "for conflicts, use this marker size"
-msgstr "để tránh xung đột, hãy sử dụng kích thước bộ tạo này"
+msgstr "nếu xung đột, hãy sử dụng kích thước bộ tạo này"
 
 msgid "do not warn about conflicts"
 msgstr "không cảnh báo về các xung đột xảy ra"
@@ -7889,12 +8027,19 @@
 msgstr "đặt nhãn cho tập-tin-1/tập-tin-gốc/tập-tin-2"
 
 #, c-format
+msgid "object '%s' does not exist"
+msgstr "đối tượng '%s' không tồn tại"
+
+msgid "Could not write object file"
+msgstr "Không thể ghi vào tập tin"
+
+#, c-format
 msgid "unknown option %s"
 msgstr "không hiểu tùy chọn %s"
 
 #, c-format
 msgid "could not parse object '%s'"
-msgstr "không thể phân tích đối tượng “%s”"
+msgstr "không thể đọc đối tượng '%s'"
 
 #, c-format
 msgid "cannot handle more than %d base. Ignoring %s."
@@ -7912,33 +8057,94 @@
 msgid "Merging %s with %s\n"
 msgstr "Đang hòa trộn %s với %s\n"
 
+#, c-format
+msgid "could not parse as tree '%s'"
+msgstr "không hiểu cú pháp cây '%s'"
+
+msgid "not something we can merge"
+msgstr "không phải là thứ gì đó mà chúng tôi có thể hòa trộn"
+
+msgid "refusing to merge unrelated histories"
+msgstr "từ chối hòa trộn lịch sử không liên quan"
+
+msgid "failure to merge"
+msgstr "gặp lỗi khi hoà trộn"
+
+msgid "git merge-tree [--write-tree] [<options>] <branch1> <branch2>"
+msgstr "git merge-tree [--write-tree] [<tuỳ chọn>] <nhánh 1> <nhánh 2>"
+
+msgid "git merge-tree [--trivial-merge] <base-tree> <branch1> <branch2>"
+msgstr "git merge-tree [--trivial-merge] <cây gốc> <nhánh 1> <nhánh 2>"
+
+msgid "do a real merge instead of a trivial merge"
+msgstr "hoà trộn đúng chuẩn thay vì đơn giản"
+
+msgid "do a trivial merge only"
+msgstr "chỉ hoà trộn đơn giản"
+
+msgid "also show informational/conflict messages"
+msgstr "hiển thị thông báo chú thích/xung đột"
+
+msgid "list filenames without modes/oids/stages"
+msgstr "liệt kê tên tập tin không kèm chế độ/oid/stage"
+
+msgid "allow merging unrelated histories"
+msgstr "cho phép hòa trộn lịch sử không liên quan"
+
+msgid "perform multiple merges, one per line of input"
+msgstr "thực hiện hoà trộn nhiều lần, với từng dòng đầu vào"
+
+msgid "specify a merge-base for the merge"
+msgstr "chỉ định gốc hoà trộn để hòa trộn"
+
+msgid "option=value"
+msgstr "tùy_chọn=giá_trị"
+
+msgid "option for selected merge strategy"
+msgstr "tùy chọn cho chiến lược hòa trộn đã chọn"
+
+msgid "--trivial-merge is incompatible with all other options"
+msgstr "--trivial-merge không tương thích với các tùy chọn khác"
+
+#, c-format
+msgid "unknown strategy option: -X%s"
+msgstr "không hiểu chiến lược: -X%s"
+
+#, c-format
+msgid "malformed input line: '%s'."
+msgstr "dòng đầu vào sai quy cách: '%s'."
+
+#, c-format
+msgid "merging cannot continue; got unclean result of %d"
+msgstr "không thể tiếp tục hoà trộn; kết quả không hoàn toàn %d"
+
 msgid "git merge [<options>] [<commit>...]"
-msgstr "git merge [<các tùy chọn>] [<commit>…]"
+msgstr "git merge [<các tùy chọn>] [<commit>...]"
 
 msgid "switch `m' requires a value"
-msgstr "switch “m” yêu cầu một giá trị"
+msgstr "tuỳ chọn 'm' yêu cầu một giá trị"
 
 #, c-format
 msgid "option `%s' requires a value"
-msgstr "tùy chọn “%s” yêu cầu một giá trị"
+msgstr "tùy chọn '%s' yêu cầu một giá trị"
 
 #, c-format
 msgid "Could not find merge strategy '%s'.\n"
-msgstr "Không tìm thấy chiến lược hòa trộn “%s”.\n"
+msgstr "Không tìm thấy chiến lược hòa trộn '%s'.\n"
 
 #, c-format
 msgid "Available strategies are:"
-msgstr "Các chiến lược sẵn sàng là:"
+msgstr "Các chiến lược khả dụng là:"
 
 #, c-format
 msgid "Available custom strategies are:"
-msgstr "Các chiến lược tùy chỉnh sẵn sàng là:"
+msgstr "Các chiến lược tùy chỉnh khả dụng là:"
 
 msgid "do not show a diffstat at the end of the merge"
-msgstr "không hiển thị thống kê khác biệt tại cuối của lần hòa trộn"
+msgstr "không hiển thị diffstat (thống kê khác biệt) phía dưới hòa trộn"
 
 msgid "show a diffstat at the end of the merge"
-msgstr "hiển thị thống kê khác biệt tại cuối của hòa trộn"
+msgstr "hiển thị diffstat (thống kê khác biệt) phía dưới hòa trộn"
 
 msgid "(synonym to --stat)"
 msgstr "(đồng nghĩa với --stat)"
@@ -7947,7 +8153,7 @@
 msgstr "thêm (ít nhất <n>) mục từ shortlog cho ghi chú chuyển giao hòa trộn"
 
 msgid "create a single commit instead of doing a merge"
-msgstr "tạo một lần chuyển giao đưon thay vì thực hiện việc hòa trộn"
+msgstr "tạo một lần chuyển giao đơn thay vì thực hiện việc hòa trộn"
 
 msgid "perform a commit if the merge succeeds (default)"
 msgstr "thực hiện chuyển giao nếu hòa trộn thành công (mặc định)"
@@ -7959,7 +8165,7 @@
 msgstr "cho phép chuyển-tiếp-nhanh (mặc định)"
 
 msgid "abort if fast-forward is not possible"
-msgstr "bỏ qua nếu chuyển-tiếp-nhanh không thể được"
+msgstr "huỷ lệnh nếu không thể chuyển-tiếp-nhanh"
 
 msgid "verify that the named commit has a valid GPG signature"
 msgstr "thẩm tra xem lần chuyển giao có tên đó có chữ ký GPG hợp lệ hay không"
@@ -7970,12 +8176,6 @@
 msgid "merge strategy to use"
 msgstr "chiến lược hòa trộn sẽ dùng"
 
-msgid "option=value"
-msgstr "tùy_chọn=giá_trị"
-
-msgid "option for selected merge strategy"
-msgstr "tùy chọn cho chiến lược hòa trộn đã chọn"
-
 msgid "merge commit message (for a non-fast-forward merge)"
 msgstr ""
 "hòa trộn ghi chú của lần chuyển giao (dành cho hòa trộn không-chuyển-tiếp-"
@@ -7985,17 +8185,14 @@
 msgstr "dùng <tên> thay cho đích thật"
 
 msgid "abort the current in-progress merge"
-msgstr "bãi bỏ quá trình hòa trộn hiện tại đang thực hiện"
+msgstr "huỷ bỏ quá trình hòa trộn hiện đang thực hiện"
 
 msgid "--abort but leave index and working tree alone"
-msgstr "--abort nhưng để lại bảng mục lục và cây làm việc"
+msgstr "--abort nhưng để lại chỉ mục và cây làm việc"
 
 msgid "continue the current in-progress merge"
 msgstr "tiếp tục quá trình hòa trộn hiện tại đang thực hiện"
 
-msgid "allow merging unrelated histories"
-msgstr "cho phép hòa trộn lịch sử không liên quan"
-
 msgid "bypass pre-merge-commit and commit-msg hooks"
 msgstr "vòng qua móc (hook) pre-merge-commit và commit-msg"
 
@@ -8028,34 +8225,30 @@
 
 #, c-format
 msgid "'%s' does not point to a commit"
-msgstr "“%s” không chỉ đến một lần chuyển giao nào cả"
+msgstr "'%s' không chỉ đến một lần chuyển giao nào cả"
 
 #, c-format
 msgid "Bad branch.%s.mergeoptions string: %s"
 msgstr "Chuỗi branch.%s.mergeoptions sai: %s"
 
 msgid "Unable to write index."
-msgstr "Không thể ghi bảng mục lục."
+msgstr "Không thể ghi chỉ mục."
 
 msgid "Not handling anything other than two heads merge."
 msgstr "Không cầm nắm gì ngoài hai head hòa trộn."
 
 #, c-format
-msgid "unknown strategy option: -X%s"
-msgstr "không hiểu chiến lược: -X%s"
-
-#, c-format
 msgid "unable to write %s"
 msgstr "không thể ghi %s"
 
 #, c-format
 msgid "Could not read from '%s'"
-msgstr "Không thể đọc từ “%s”"
+msgstr "Không thể đọc từ '%s'"
 
 #, c-format
 msgid "Not committing merge; use 'git commit' to complete the merge.\n"
 msgstr ""
-"Vẫn chưa hòa trộn các lần chuyển giao; sử dụng lệnh “git commit” để hoàn tất "
+"Vẫn chưa hòa trộn các lần chuyển giao; sử dụng lệnh 'git commit' để hoàn tất "
 "việc hòa trộn.\n"
 
 msgid ""
@@ -8074,10 +8267,10 @@
 
 #, c-format
 msgid ""
-"Lines starting with '%c' will be ignored, and an empty message aborts\n"
+"Lines starting with '%s' will be ignored, and an empty message aborts\n"
 "the commit.\n"
 msgstr ""
-"Những dòng được bắt đầu bằng “%c” sẽ được bỏ qua, và nếu phần chú\n"
+"Những dòng được bắt đầu bằng '%s' sẽ được bỏ qua, và nếu phần chú\n"
 "thích rỗng sẽ hủy bỏ lần chuyển giao.\n"
 
 msgid "Empty commit message."
@@ -8108,19 +8301,16 @@
 
 #, c-format
 msgid "Bad value '%s' in environment '%s'"
-msgstr "Giá trị sai “%s” trong biến môi trường “%s”"
+msgstr "Giá trị sai '%s' trong biến môi trường '%s'"
 
 #, c-format
 msgid "could not close '%s'"
-msgstr "không thể đóng “%s”"
+msgstr "không thể đóng '%s'"
 
 #, c-format
 msgid "not something we can merge in %s: %s"
 msgstr "không phải là một thứ gì đó mà chúng tôi có thể hòa trộn trong %s: %s"
 
-msgid "not something we can merge"
-msgstr "không phải là thứ gì đó mà chúng tôi có thể hòa trộn"
-
 msgid "--abort expects no arguments"
 msgstr "--abort không nhận các đối số"
 
@@ -8172,16 +8362,22 @@
 msgstr ""
 "Không thể hòa trộn một cách đúng đắn một lần chuyển giao vào một head rỗng"
 
-msgid "refusing to merge unrelated histories"
-msgstr "từ chối hòa trộn lịch sử không liên quan"
-
 #, c-format
 msgid "Updating %s..%s\n"
 msgstr "Đang cập nhật %s..%s\n"
 
 #, c-format
+msgid ""
+"Your local changes to the following files would be overwritten by merge:\n"
+"  %s"
+msgstr ""
+"Các thay đổi nội bộ của bạn với các tập tin sau đây sẽ bị ghi đè bởi lệnh "
+"hòa trộn:\n"
+"  %s"
+
+#, c-format
 msgid "Trying really trivial in-index merge...\n"
-msgstr "Đang thử hòa trộn kiểu “trivial in-index”…\n"
+msgstr "Đang thử hòa trộn kiểu 'trivial in-index'...\n"
 
 #, c-format
 msgid "Nope.\n"
@@ -8189,15 +8385,15 @@
 
 #, c-format
 msgid "Rewinding the tree to pristine...\n"
-msgstr "Đang tua lại cây thành thời xa xưa…\n"
+msgstr "Đang tua lại cây thành thời xa xưa...\n"
 
 #, c-format
 msgid "Trying merge strategy %s...\n"
-msgstr "Đang thử chiến lược hòa trộn %s…\n"
+msgstr "Đang thử chiến lược hòa trộn %s...\n"
 
 #, c-format
 msgid "No merge strategy handled the merge.\n"
-msgstr "Không có chiến lược hòa trộn nào được nắm giữ (handle) sự hòa trộn.\n"
+msgstr "Không có chiến lược hòa trộn nào có thể xử lý việc hòa trộn.\n"
 
 #, c-format
 msgid "Merge with strategy %s failed.\n"
@@ -8209,9 +8405,12 @@
 
 #, c-format
 msgid "Automatic merge went well; stopped before committing as requested\n"
+msgstr "Hòa trộn tự động đã xong; dừng trước khi chuyển giao như đã yêu cầu\n"
+
+#, c-format
+msgid "When finished, apply stashed changes with `git stash pop`\n"
 msgstr ""
-"Hòa trộn tự động đã trở nên tốt; bị dừng trước khi việc chuyển giao được yêu "
-"cầu\n"
+"Sau khi hoàn thành, áp dụng các thay đổi trong stash với `git stash pop` \n"
 
 #, c-format
 msgid "warning: tag input does not pass fsck: %s"
@@ -8219,11 +8418,11 @@
 
 #, c-format
 msgid "error: tag input does not pass fsck: %s"
-msgstr "lỗi: đầu vào thẻ không vượt qua fsck: %s"
+msgstr "lỗi: đầu vào thẻ không qua kiểm tra fsck: %s"
 
 #, c-format
 msgid "%d (FSCK_IGNORE?) should never trigger this callback"
-msgstr "%d (FSCK_IGNORE?) không bao giờ nên kích hoạt cuộc gọi ngược này"
+msgstr "%d (FSCK_IGNORE?) không bao giờ nên kích hoạt callback này"
 
 #, c-format
 msgid "could not read tagged object '%s'"
@@ -8231,24 +8430,20 @@
 
 #, c-format
 msgid "object '%s' tagged as '%s', but is a '%s' type"
-msgstr "đối tượng %s được đánh thẻ là %s, không phải là kiểu %s"
-
-msgid "could not read from stdin"
-msgstr "không thể đọc từ đầu vào tiêu chuẩn"
+msgstr "đối tượng '%s' được đánh thẻ là '%s', nhưng là kiểu '%s'"
 
 msgid "tag on stdin did not pass our strict fsck check"
 msgstr ""
 "thẻ trên stdin đã không vượt qua kiểm tra fsck nghiêm ngặt của chúng tôi"
 
 msgid "tag on stdin did not refer to a valid object"
-msgstr ""
-"thẻ trên đầu vào tiêu chuẩn không chỉ đến một lần chuyển giao hợp lệ nào cả"
+msgstr "thẻ trên stdin không chỉ đến một đối tượng hợp lệ"
 
 msgid "unable to write tag file"
-msgstr "không thể ghi vào tập tin lưu thẻ"
+msgstr "không thể ghi vào tập tin thẻ"
 
 msgid "input is NUL terminated"
-msgstr "đầu vào được chấm dứt bởi NUL"
+msgstr "đầu vào được kết thúc bởi NUL"
 
 msgid "allow missing objects"
 msgstr "cho phép thiếu đối tượng"
@@ -8288,7 +8483,7 @@
 msgstr "ghi multi-pack bitmap"
 
 msgid "write multi-pack index containing only given indexes"
-msgstr "ghi mục lục multi-pack chỉ chứa các mục lục đã cho"
+msgstr "ghi chỉ mục multi-pack chỉ chứa các chỉ mục đã cho"
 
 msgid "refs snapshot for selecting bitmap commits"
 msgstr "ảnh chụp nhanh refs để chọn các lần chuyển giao ánh xạ"
@@ -8301,11 +8496,11 @@
 "vào một bó cái mà lớn hơn kích thước này"
 
 msgid "git mv [<options>] <source>... <destination>"
-msgstr "git mv [<các tùy chọn>] <nguồn>… <đích>"
+msgstr "git mv [<các tùy chọn>] <nguồn>... <đích>"
 
 #, c-format
 msgid "Directory %s is in index and no submodule?"
-msgstr "Thư mục “%s” có ở trong chỉ mục mà không có mô-đun con?"
+msgstr "Thư mục '%s' có ở trong chỉ mục mà không có mô-đun con?"
 
 msgid "Please stage your changes to .gitmodules or stash them to proceed"
 msgstr ""
@@ -8313,7 +8508,7 @@
 
 #, c-format
 msgid "%.*s is in index"
-msgstr "%.*s trong bảng mục lục"
+msgstr "%.*s trong chỉ mục"
 
 msgid "force move/rename even if target exists"
 msgstr "ép buộc di chuyển hay đổi tên thậm chí cả khi đích đã tồn tại"
@@ -8323,20 +8518,23 @@
 
 #, c-format
 msgid "destination '%s' is not a directory"
-msgstr "có đích “%s” nhưng đây không phải là một thư mục"
+msgstr "có đích '%s' nhưng đây không phải là một thư mục"
 
 #, c-format
 msgid "Checking rename of '%s' to '%s'\n"
-msgstr "Đang kiểm tra việc đổi tên của “%s” thành “%s”\n"
+msgstr "Đang kiểm tra việc đổi tên của '%s' thành '%s'\n"
 
 msgid "bad source"
 msgstr "nguồn sai"
 
+msgid "destination exists"
+msgstr "đích đã tồn tại sẵn rồi"
+
 msgid "can not move directory into itself"
 msgstr "không thể di chuyển một thư mục vào trong chính nó được"
 
-msgid "cannot move directory over file"
-msgstr "không di chuyển được thư mục thông qua tập tin"
+msgid "destination already exists"
+msgstr "đích đã tồn tại sẵn rồi"
 
 msgid "source directory is empty"
 msgstr "thư mục nguồn là trống rỗng"
@@ -8347,12 +8545,9 @@
 msgid "conflicted"
 msgstr "bị xung đột"
 
-msgid "destination exists"
-msgstr "đích đã tồn tại sẵn rồi"
-
 #, c-format
 msgid "overwriting '%s'"
-msgstr "đang ghi đè lên “%s”"
+msgstr "đang ghi đè lên '%s'"
 
 msgid "Cannot overwrite"
 msgstr "Không thể ghi đè"
@@ -8363,6 +8558,9 @@
 msgid "destination directory does not exist"
 msgstr "thư mục đích không tồn tại"
 
+msgid "destination exists in the index"
+msgstr "đích đã tồn tại sẵn trong chỉ mục"
+
 #, c-format
 msgid "%s, source=%s, destination=%s"
 msgstr "%s, nguồn=%s, đích=%s"
@@ -8373,10 +8571,10 @@
 
 #, c-format
 msgid "renaming '%s' failed"
-msgstr "gặp lỗi khi đổi tên “%s”"
+msgstr "gặp lỗi khi đổi tên '%s'"
 
 msgid "git name-rev [<options>] <commit>..."
-msgstr "git name-rev [<các tùy chọn>] <commit>…"
+msgstr "git name-rev [<các tùy chọn>] <commit>..."
 
 msgid "git name-rev [<options>] --all"
 msgstr "git name-rev [<các tùy chọn>] --all"
@@ -8404,33 +8602,37 @@
 msgstr "đã lạc hậu: hãy dùng --annotate-stdin để thay thế"
 
 msgid "annotate text from stdin"
-msgstr "chú giải chữ từ đầu vào tiêu chuẩn stdin"
+msgstr "chú giải chữ từ stdin"
 
 msgid "allow to print `undefined` names (default)"
-msgstr "cho phép in các tên “chưa định nghĩa” (mặc định)"
+msgstr "cho phép in các tên `chưa định nghĩa` (mặc định)"
 
 msgid "dereference tags in the input (internal use)"
-msgstr "bãi bỏ tham chiếu các thẻ trong đầu vào (dùng nội bộ)"
+msgstr "giải tham chiếu các thẻ trong đầu vào (dùng nội bộ)"
 
 msgid "git notes [--ref <notes-ref>] [list [<object>]]"
 msgstr "git notes [--ref <notes-ref>] [list [<đối-tượng>]]"
 
 msgid ""
-"git notes [--ref <notes-ref>] add [-f] [--allow-empty] [-m <msg> | -F <file> "
-"| (-c | -C) <object>] [<object>]"
+"git notes [--ref <notes-ref>] add [-f] [--allow-empty] [--[no-]separator|--"
+"separator=<paragraph-break>] [--[no-]stripspace] [-m <msg> | -F <file> | (-c "
+"| -C) <object>] [<object>]"
 msgstr ""
-"git notes [--ref <notes-ref>] add [-f] [--allow-empty] [-m <lời-nhắn> | -F "
-"<tập-tin> | (-c | -C) <đối-tượng>] [<đối-tượng>]"
+"git notes [--ref <notes-ref>] add [-f] [--allow-empty] [--[no-]separator|--"
+"separator=<paragraph-break>] [--[no-]stripspace] [-m <lời-nhắn> | -F <tập-"
+"tin> | (-c | -C) <đối-tượng>] [<đối-tượng>]"
 
 msgid "git notes [--ref <notes-ref>] copy [-f] <from-object> <to-object>"
 msgstr "git notes [--ref <notes-ref>] copy [-f] <từ-đối-tượng> <đến-đối-tượng>"
 
 msgid ""
-"git notes [--ref <notes-ref>] append [--allow-empty] [-m <msg> | -F <file> | "
-"(-c | -C) <object>] [<object>]"
+"git notes [--ref <notes-ref>] append [--allow-empty] [--[no-]separator|--"
+"separator=<paragraph-break>] [--[no-]stripspace] [-m <msg> | -F <file> | (-c "
+"| -C) <object>] [<object>]"
 msgstr ""
-"git notes [--ref <notes-ref>] append [--allow-empty] [-m <lời-nhắn> | -F "
-"<tập-tin> | (-c | -C) <đối-tượng>] [<đối-tượng>]"
+"git notes [--ref <notes-ref>] append [--allow-empty] [--[no-]separator|--"
+"separator=<paragraph-break>] [--[no-]stripspace] [-m <lời-nhắn> | -F <tập-"
+"tin> | (-c | -C) <đối-tượng>] [<đối-tượng>]"
 
 msgid "git notes [--ref <notes-ref>] edit [--allow-empty] [<object>]"
 msgstr "git notes [--ref <notes-ref>] edit [--allow-empty] [<đối-tượng>]"
@@ -8444,7 +8646,7 @@
 "git notes [--ref <notes-ref>] merge [-v | -q] [-s <chiến-lược> ] <notes-ref>"
 
 msgid "git notes [--ref <notes-ref>] remove [<object>...]"
-msgstr "git notes [--ref <notes-ref>] remove [<đối-tượng>…]"
+msgstr "git notes [--ref <notes-ref>] remove [<đối-tượng>...]"
 
 msgid "git notes [--ref <notes-ref>] prune [-n] [-v]"
 msgstr "git notes [--ref <notes-ref>] prune [-n] [-v]"
@@ -8462,7 +8664,7 @@
 msgstr "git notes copy [<các tùy chọn>] <từ-đối-tượng> <đến-đối-tượng>"
 
 msgid "git notes copy --stdin [<from-object> <to-object>]..."
-msgstr "git notes copy --stdin [<từ-đối-tượng> <đến-đối-tượng>]…"
+msgstr "git notes copy --stdin [<từ-đối-tượng> <đến-đối-tượng>]..."
 
 msgid "git notes append [<options>] [<object>]"
 msgstr "git notes append [<các tùy chọn>] [<đối-tượng>]"
@@ -8491,16 +8693,12 @@
 msgid "Write/edit the notes for the following object:"
 msgstr "Ghi hay sửa ghi chú cho đối tượng sau đây:"
 
-#, c-format
-msgid "unable to start 'show' for object '%s'"
-msgstr "không thể khởi chạy “show” cho đối tượng “%s”"
-
 msgid "could not read 'show' output"
-msgstr "không thể đọc kết xuất “show”"
+msgstr "không thể đọc kết xuất 'show'"
 
 #, c-format
 msgid "failed to finish 'show' for object '%s'"
-msgstr "gặp lỗi khi hoàn thành “show” cho đối tượng “%s”"
+msgstr "gặp lỗi khi hoàn thành 'show' cho đối tượng '%s'"
 
 msgid "please supply the note contents using either -m or -F option"
 msgstr ""
@@ -8515,27 +8713,23 @@
 
 #, c-format
 msgid "could not open or read '%s'"
-msgstr "không thể mở hay đọc “%s”"
+msgstr "không thể mở hay đọc '%s'"
 
 #, c-format
 msgid "failed to resolve '%s' as a valid ref."
-msgstr "gặp lỗi khi phân giải “%s” như là một tham chiếu hợp lệ."
+msgstr "gặp lỗi khi phân giải '%s' thành một tham chiếu hợp lệ."
 
 #, c-format
 msgid "failed to read object '%s'."
-msgstr "gặp lỗi khi đọc đối tượng “%s”."
+msgstr "gặp lỗi khi đọc đối tượng '%s'."
 
 #, c-format
 msgid "cannot read note data from non-blob object '%s'."
-msgstr "không thể đọc dữ liệu ghi chú từ đối tượng không-blob “%s”."
-
-#, c-format
-msgid "malformed input line: '%s'."
-msgstr "dòng đầu vào dị hình: “%s”."
+msgstr "không thể đọc dữ liệu ghi chú từ đối tượng không-blob '%s'."
 
 #, c-format
 msgid "failed to copy notes from '%s' to '%s'"
-msgstr "gặp lỗi khi sao chép ghi chú (note) từ “%s” sang “%s”"
+msgstr "gặp lỗi khi sao chép ghi chú (note) từ '%s' sang '%s'"
 
 #. TRANSLATORS: the first %s will be replaced by a git
 #. notes command: 'add', 'merge', 'remove', etc.
@@ -8566,13 +8760,22 @@
 msgid "replace existing notes"
 msgstr "thay thế ghi chú trước"
 
+msgid "<paragraph-break>"
+msgstr "<dấu ngắt đoạn>"
+
+msgid "insert <paragraph-break> between paragraphs"
+msgstr "chèn <dấu ngắt đoạn> giữa các đoạn văn"
+
+msgid "remove unnecessary whitespace"
+msgstr "Xóa bỏ các khoảng trắng không cần thiết"
+
 #, c-format
 msgid ""
 "Cannot add notes. Found existing notes for object %s. Use '-f' to overwrite "
 "existing notes"
 msgstr ""
 "Không thể thêm các ghi chú. Đã tìm thấy các ghi chú đã có sẵn cho đối tượng "
-"%s. Sử dụng tùy chọn “-f” để ghi đè lên các ghi chú cũ"
+"%s. Sử dụng tùy chọn '-f' để ghi đè lên các ghi chú cũ"
 
 #, c-format
 msgid "Overwriting existing notes for object %s\n"
@@ -8583,10 +8786,10 @@
 msgstr "Đang gỡ bỏ ghi chú (note) cho đối tượng %s\n"
 
 msgid "read objects from stdin"
-msgstr "đọc các đối tượng từ đầu vào tiêu chuẩn"
+msgstr "đọc các đối tượng từ stdin"
 
 msgid "load rewriting config for <command> (implies --stdin)"
-msgstr "tải cấu hình chép lại cho <lệnh> (ngầm định là --stdin)"
+msgstr "tải cấu hình chép lại cho <lệnh> (ngụ ý --stdin)"
 
 msgid "too few arguments"
 msgstr "quá ít đối số"
@@ -8597,7 +8800,7 @@
 "existing notes"
 msgstr ""
 "Không thể sao chép các ghi chú. Đã tìm thấy các ghi chú đã có sẵn cho đối "
-"tượng %s. Sử dụng tùy chọn “-f” để ghi đè lên các ghi chú cũ"
+"tượng %s. Sử dụng tùy chọn '-f' để ghi đè lên các ghi chú cũ"
 
 #, c-format
 msgid "missing notes on source object %s. Cannot copy."
@@ -8608,8 +8811,8 @@
 "The -m/-F/-c/-C options have been deprecated for the 'edit' subcommand.\n"
 "Please use 'git notes add -f -m/-F/-c/-C' instead.\n"
 msgstr ""
-"Các tùy chọn -m/-F/-c/-C đã cổ không còn dùng nữa cho lệnh con “edit”.\n"
-"Xin hãy sử dụng lệnh sau để thay thế: “git notes add -f -m/-F/-c/-C”.\n"
+"Các tùy chọn -m/-F/-c/-C đã không còn dùng cho lệnh con 'edit'.\n"
+"Xin hãy sử dụng lệnh sau để thay thế: 'git notes add -f -m/-F/-c/-C'.\n"
 
 msgid "failed to delete ref NOTES_MERGE_PARTIAL"
 msgstr "gặp lỗi khi xóa tham chiếu NOTES_MERGE_PARTIAL"
@@ -8618,7 +8821,7 @@
 msgstr "gặp lỗi khi xóa tham chiếu NOTES_MERGE_REF"
 
 msgid "failed to remove 'git notes merge' worktree"
-msgstr "gặp lỗi khi gỡ bỏ cây làm việc “git notes merge”"
+msgstr "gặp lỗi khi gỡ bỏ cây làm việc 'git notes merge'"
 
 msgid "failed to read ref NOTES_MERGE_PARTIAL"
 msgstr "gặp lỗi khi đọc tham chiếu NOTES_MERGE_PARTIAL"
@@ -8627,7 +8830,7 @@
 msgstr "không thể tìm thấy lần chuyển giao từ NOTES_MERGE_PARTIAL."
 
 msgid "could not parse commit from NOTES_MERGE_PARTIAL."
-msgstr "không thể phân tích cú pháp lần chuyển giao từ NOTES_MERGE_PARTIAL."
+msgstr "không hiểu cú pháp lần chuyển giao từ NOTES_MERGE_PARTIAL."
 
 msgid "failed to resolve NOTES_MERGE_REF"
 msgstr "gặp lỗi khi phân giải NOTES_MERGE_REF"
@@ -8649,7 +8852,7 @@
 "resolve notes conflicts using the given strategy (manual/ours/theirs/union/"
 "cat_sort_uniq)"
 msgstr ""
-"phân giải các xung đột “notes” sử dụng chiến lược đã đưa ra (manual/ours/"
+"phân giải các xung đột 'notes' sử dụng chiến lược đã đưa ra (manual/ours/"
 "theirs/union/cat_sort_uniq)"
 
 msgid "Committing unmerged notes"
@@ -8691,49 +8894,48 @@
 "abort'.\n"
 msgstr ""
 "Gặp lỗi khi hòa trộn các ghi chú tự động. Sửa các xung đột này trong %s và "
-"chuyển giao kết quả bằng “git notes merge --commit”, hoặc bãi bỏ việc hòa "
-"trộn bằng “git notes merge --abort”.\n"
+"chuyển giao kết quả bằng 'git notes merge --commit', hoặc huỷ bỏ việc hòa "
+"trộn bằng 'git notes merge --abort'.\n"
 
 #, c-format
 msgid "Failed to resolve '%s' as a valid ref."
-msgstr "Gặp lỗi khi phân giải “%s” như là một tham chiếu hợp lệ."
+msgstr "Gặp lỗi khi phân giải '%s' thành một tham chiếu hợp lệ."
 
 #, c-format
 msgid "Object %s has no note\n"
 msgstr "Đối tượng %s không có ghi chú (note)\n"
 
 msgid "attempt to remove non-existent note is not an error"
-msgstr "cố gắng gỡ bỏ một note chưa từng tồn tại không phải là một lỗi"
+msgstr "việc gỡ bỏ một note không tồn tại không phải là lỗi"
 
 msgid "read object names from the standard input"
-msgstr "đọc tên đối tượng từ thiết bị nhập chuẩn"
+msgstr "đọc tên đối tượng từ stdin"
 
 msgid "do not remove, show only"
 msgstr "không gỡ bỏ, chỉ hiển thị"
 
 msgid "report pruned notes"
-msgstr "báo cáo các đối tượng đã prune"
+msgstr "liệt kê các đối tượng đã prune"
 
 msgid "notes-ref"
 msgstr "notes-ref"
 
 msgid "use notes from <notes-ref>"
-msgstr "dùng “notes” từ <notes-ref>"
+msgstr "dùng 'notes' từ <notes-ref>"
 
 #, c-format
-msgid "unknown subcommand: %s"
-msgstr "không hiểu câu lệnh con: %s"
+msgid "unknown subcommand: `%s'"
+msgstr "không hiểu câu lệnh con: `%s'"
 
-msgid ""
-"git pack-objects --stdout [<options>...] [< <ref-list> | < <object-list>]"
+msgid "git pack-objects --stdout [<options>] [< <ref-list> | < <object-list>]"
 msgstr ""
-"git pack-objects --stdout [các tùy chọn…] [< <danh-sách-tham-chiếu> | < "
+"git pack-objects --stdout [<các tùy chọn>] [< <danh-sách-tham-chiếu> | < "
 "<danh-sách-đối-tượng>]"
 
 msgid ""
-"git pack-objects [<options>...] <base-name> [< <ref-list> | < <object-list>]"
+"git pack-objects [<options>] <base-name> [< <ref-list> | < <object-list>]"
 msgstr ""
-"git pack-objects [các tùy chọn…] <base-name> [< <danh-sách-ref> | < <danh-"
+"git pack-objects [<các tùy chọn>] <base-name> [< <danh-sách-ref> | < <danh-"
 "sách-đối-tượng>]"
 
 #, c-format
@@ -8772,14 +8974,14 @@
 
 #, c-format
 msgid "failed to stat %s"
-msgstr "gặp lỗi khi lấy thông tin thống kê về %s"
+msgstr "gặp lỗi khi stat %s"
 
 #, c-format
 msgid "failed utime() on %s"
-msgstr "gặp lỗi utime() trên “%s”"
+msgstr "gặp lỗi utime() trên '%s'"
 
 msgid "failed to write bitmap index"
-msgstr "gặp lỗi khi ghi mục lục ánh xạ"
+msgstr "gặp lỗi khi ghi chỉ mục ánh xạ"
 
 #, c-format
 msgid "wrote %<PRIu32> objects while expecting %<PRIu32>"
@@ -8805,7 +9007,7 @@
 
 #, c-format
 msgid "unable to parse object header of %s"
-msgstr "không thể phân tích phần đầu đối tượng của “%s”"
+msgstr "không thể đọc phần đầu đối tượng của '%s'"
 
 #, c-format
 msgid "object %s cannot be read"
@@ -8826,11 +9028,11 @@
 
 #, c-format
 msgid "unable to pack objects reachable from tag %s"
-msgstr "không thể đóng gói các đối tượng tiếp cận được từ thẻ “%s”"
+msgstr "không thể đóng gói các đối tượng tiếp cận được từ thẻ '%s'"
 
 #, c-format
 msgid "unable to get type of object %s"
-msgstr "không thể lấy kiểu của đối tượng “%s”"
+msgstr "không thể lấy kiểu của đối tượng '%s'"
 
 msgid "Compressing objects"
 msgstr "Đang nén các đối tượng"
@@ -8839,27 +9041,31 @@
 msgstr "mâu thuẫn với số lượng delta"
 
 #, c-format
+msgid "invalid pack.allowPackReuse value: '%s'"
+msgstr "giá trị pack.allowPackReuse không hợp lệ: '%s'"
+
+#, c-format
 msgid ""
 "value of uploadpack.blobpackfileuri must be of the form '<object-hash> <pack-"
 "hash> <uri>' (got '%s')"
 msgstr ""
-"giá trị của uploadpack.blobpackfileuri phải có dạng “<object-hash> <pack-"
-"hash> <uri>” (nhận “%s”)"
+"giá trị của uploadpack.blobpackfileuri phải có dạng '<object-hash> <pack-"
+"hash> <uri>' (nhận '%s')"
 
 #, c-format
 msgid ""
 "object already configured in another uploadpack.blobpackfileuri (got '%s')"
 msgstr ""
 "đối tượng đã được cấu hình trong một uploadpack.blobpackfileuri khác (đã "
-"nhận “%s”)"
+"nhận '%s')"
 
 #, c-format
 msgid "could not get type of object %s in pack %s"
-msgstr "không thể lấy kiểu của đối tượng “%s” trong gói “%s”"
+msgstr "không thể lấy kiểu của đối tượng '%s' trong gói '%s'"
 
 #, c-format
 msgid "could not find pack '%s'"
-msgstr "không thể tìm thấy gói “%s”"
+msgstr "không thể tìm thấy gói '%s'"
 
 #, c-format
 msgid "packfile %s cannot be accessed"
@@ -8879,7 +9085,7 @@
 "expected edge object ID, got garbage:\n"
 " %s"
 msgstr ""
-"cần ID đối tượng cạnh, nhận được rác:\n"
+"cần ID đối tượng cạnh, có rác:\n"
 " %s"
 
 #, c-format
@@ -8887,14 +9093,14 @@
 "expected object ID, got garbage:\n"
 " %s"
 msgstr ""
-"cần ID đối tượng, nhận được rác:\n"
+"cần ID đối tượng, có rác:\n"
 " %s"
 
 msgid "could not load cruft pack .mtimes"
 msgstr "không thể tải cruft pack .mtimes"
 
 msgid "cannot open pack index"
-msgstr "không thể mở mục lục của gói"
+msgstr "không thể mở chỉ mục của gói"
 
 #, c-format
 msgid "loose object at %s could not be examined"
@@ -8905,31 +9111,37 @@
 
 #, c-format
 msgid "not a rev '%s'"
-msgstr "không phải một rev “%s”"
+msgstr "không phải một rev '%s'"
 
 #, c-format
 msgid "bad revision '%s'"
-msgstr "điểm xem xét sai “%s”"
+msgstr "điểm xem xét sai '%s'"
 
 msgid "unable to add recent objects"
 msgstr "không thể thêm các đối tượng mới dùng"
 
 #, c-format
 msgid "unsupported index version %s"
-msgstr "phiên bản mục lục không được hỗ trợ %s"
+msgstr "phiên bản chỉ mục không được hỗ trợ %s"
 
 #, c-format
 msgid "bad index version '%s'"
-msgstr "phiên bản mục lục sai “%s”"
+msgstr "phiên bản chỉ mục sai '%s'"
+
+msgid "show progress meter during object writing phase"
+msgstr "hiển thị bộ đo tiến triển trong suốt pha ghi đối tượng"
+
+msgid "similar to --all-progress when progress meter is shown"
+msgstr "tương tự --all-progress khi bộ đo tiến trình được xuất hiện"
 
 msgid "<version>[,<offset>]"
 msgstr "<phiên bản>[,offset]"
 
 msgid "write the pack index file in the specified idx format version"
-msgstr "ghi tập tin bảng mục lục gói (pack) ở phiên bản định dạng idx đã cho"
+msgstr "ghi tập tin chỉ mục gói (pack) ở phiên bản định dạng idx đã cho"
 
 msgid "maximum size of each output pack file"
-msgstr "kcíh thước tối đa cho tập tin gói được tạo"
+msgstr "kích thước tối đa cho tập tin gói được tạo"
 
 msgid "ignore borrowed objects from alternate object store"
 msgstr "bỏ qua các đối tượng vay mượn từ kho đối tượng thay thế"
@@ -8944,7 +9156,7 @@
 msgstr "giới hạn cửa sổ đóng gói theo bộ nhớ cộng thêm với giới hạn đối tượng"
 
 msgid "maximum length of delta chain allowed in the resulting pack"
-msgstr "độ dài tối đa của chuỗi móc xích “delta” được phép trong gói kết quả"
+msgstr "độ dài tối đa của chuỗi móc xích 'delta' được phép trong gói kết quả"
 
 msgid "reuse existing deltas"
 msgstr "dùng lại các delta sẵn có"
@@ -8962,7 +9174,7 @@
 msgstr "không thể tạo kết xuất gói trống rỗng"
 
 msgid "read revision arguments from standard input"
-msgstr "đọc tham số “revision” từ thiết bị nhập chuẩn"
+msgstr "đọc tham số 'revision' từ stdin"
 
 msgid "limit the objects to those that are not yet packed"
 msgstr "giới hạn các đối tượng thành những cái mà chúng vẫn chưa được đóng gói"
@@ -8974,13 +9186,13 @@
 msgstr "bao gồm các đối tượng được tham chiếu bởi các mục reflog"
 
 msgid "include objects referred to by the index"
-msgstr "bao gồm các đối tượng được tham chiếu bởi mục lục"
+msgstr "bao gồm các đối tượng được tham chiếu bởi chỉ mục"
 
 msgid "read packs from stdin"
-msgstr "đọc các gói từ đầu vào tiêu chuẩn"
+msgstr "đọc các gói từ stdin"
 
 msgid "output pack to stdout"
-msgstr "xuất gói ra đầu ra tiêu chuẩn"
+msgstr "xuất gói ra stdout"
 
 msgid "include tag objects that refer to objects to be packed"
 msgstr "bao gồm các đối tượng tham chiếu đến các đối tượng được đóng gói"
@@ -8993,16 +9205,16 @@
 
 msgid "unpack unreachable objects newer than <time>"
 msgstr ""
-"xả nén (gỡ khỏi gói) các đối tượng không thể đọc được mới hơn <thời-gian>"
+"giải nén (gỡ khỏi gói) các đối tượng không thể đọc được mới hơn <thời-gian>"
 
 msgid "create a cruft pack"
 msgstr "tạo gói cruft"
 
 msgid "expire cruft objects older than <time>"
-msgstr "các đối tượng cruft hết hạn cũ hơn khoảng <thời gian>"
+msgstr "các đối tượng cruft hết hạn cũ hơn <mốc thời gian>"
 
 msgid "use the sparse reachability algorithm"
-msgstr "sử dụng thuật toán “sparse reachability”"
+msgstr "sử dụng thuật toán 'sparse reachability'"
 
 msgid "create thin packs"
 msgstr "tạo gói nhẹ"
@@ -9020,25 +9232,25 @@
 msgstr "mức nén gói"
 
 msgid "do not hide commits by grafts"
-msgstr "không ẩn các lần chuyển giao bởi “grafts”"
+msgstr "không ẩn các lần chuyển giao bởi 'grafts'"
 
 msgid "use a bitmap index if available to speed up counting objects"
-msgstr "dùng mục lục ánh xạ nếu có thể được để nâng cao tốc độ đếm đối tượng"
+msgstr "dùng chỉ mục ánh xạ nếu có thể được để nâng cao tốc độ đếm đối tượng"
 
 msgid "write a bitmap index together with the pack index"
-msgstr "ghi một mục lục ánh xạ cùng với mục lục gói"
+msgstr "ghi một chỉ mục ánh xạ cùng với chỉ mục gói"
 
 msgid "write a bitmap index if possible"
-msgstr "ghi mục lục ánh xạ nếu được"
+msgstr "ghi chỉ mục ánh xạ nếu được"
 
 msgid "handling for missing objects"
 msgstr "xử lý cho thiếu đối tượng"
 
 msgid "do not pack objects in promisor packfiles"
-msgstr "không thể đóng gói các đối tượng trong các tập tin gói hứa hẹn"
+msgstr "không thể đóng gói các đối tượng trong các tập tin gói promisor"
 
 msgid "respect islands during delta compression"
-msgstr "tôn trọng island trong suốt quá trình nén “delta”"
+msgstr "tôn trọng island trong suốt quá trình nén 'delta'"
 
 msgid "protocol"
 msgstr "giao thức"
@@ -9048,7 +9260,7 @@
 
 #, c-format
 msgid "delta chain depth %d is too deep, forcing %d"
-msgstr "mức sau xích delta %d là quá sâu, buộc dùng %d"
+msgstr "mức delta chain %d là quá sâu, buộc dùng %d"
 
 #, c-format
 msgid "pack.deltaCacheLimit is too high, forcing %d"
@@ -9066,36 +9278,30 @@
 msgstr "giới hạn kích thước tối thiểu của gói là 1 MiB"
 
 msgid "--thin cannot be used to build an indexable pack"
-msgstr "--thin không thể được dùng để xây dựng gói đánh mục lục được"
-
-msgid "cannot use --filter without --stdout"
-msgstr "không thể dùng tùy chọn --filter mà không có --stdout"
+msgstr "không thể dùng --thin để xây dựng gói đánh chỉ mục được"
 
 msgid "cannot use --filter with --stdin-packs"
 msgstr "không thể dùng tùy chọn --filter với --stdin-packs"
 
 msgid "cannot use internal rev list with --stdin-packs"
-msgstr "không thể dùng danh sách rev bên trong với --stdin-packs"
+msgstr "không thể dùng danh sách rev nội bộ với --stdin-packs"
 
 msgid "cannot use internal rev list with --cruft"
-msgstr "không thể dùng danh sách rev bên trong với --cruft"
+msgstr "không thể dùng danh sách rev nội bộ với --cruft"
 
 msgid "cannot use --stdin-packs with --cruft"
-msgstr "không thể dùng tùy chọn --stdin-packs  với --cruft"
-
-msgid "cannot use --max-pack-size with --cruft"
-msgstr "không thể dùng tùy chọn --max-pack-size với --cruft"
+msgstr "không thể dùng tùy chọn --stdin-packs với --cruft"
 
 msgid "Enumerating objects"
-msgstr "Đánh số các đối tượng"
+msgstr "Duyệt các đối tượng"
 
 #, c-format
 msgid ""
 "Total %<PRIu32> (delta %<PRIu32>), reused %<PRIu32> (delta %<PRIu32>), pack-"
-"reused %<PRIu32>"
+"reused %<PRIu32> (from %<PRIuMAX>)"
 msgstr ""
-"Tổng %<PRIu32> (delta %<PRIu32>), dùng lại %<PRIu32> (delta %<PRIu32>), pack-"
-"reused %<PRIu32>"
+"Tổng %<PRIu32> (delta %<PRIu32>), dùng lại %<PRIu32> (delta %<PRIu32>),dùng "
+"lại pack %<PRIu32> (trong số %<PRIuMAX>)"
 
 msgid ""
 "'git pack-redundant' is nominated for removal.\n"
@@ -9104,14 +9310,21 @@
 "and let us know you still use it by sending an e-mail\n"
 "to <git@vger.kernel.org>.  Thanks.\n"
 msgstr ""
-"“git pack-redundant” được đề cử để loại bỏ.\n"
-"Nếu bạn vẫn sử dụng lệnh này, vui lòng bổ sung\n"
-"thêm một tùy chọn, “--i-still-use-this”, trên dòng lệnh\n"
+"'git pack-redundant' đã được đề cử để loại bỏ.\n"
+"Nếu bạn vẫn còn sử dụng lệnh này, vui lòng bổ sung\n"
+"thêm một tùy chọn, '--i-still-use-this', trên dòng lệnh\n"
 "và cho chúng tôi biết bạn vẫn sử dụng nó bằng cách gửi e-mail\n"
-"đến <git@vger.kernel.org>.  Cảm ơn.\n"
+"đến <git@vger.kernel.org>. Xin cảm ơn.\n"
 
-msgid "git pack-refs [<options>]"
-msgstr "git pack-refs [<các tùy chọn>]"
+msgid "refusing to run without --i-still-use-this"
+msgstr "từ chối chạy lệnh này mà không có --i-still-use-this"
+
+msgid ""
+"git pack-refs [--all] [--no-prune] [--auto] [--include <pattern>] [--exclude "
+"<pattern>]"
+msgstr ""
+"git pack-refs [--all] [--no-prune] [--auto] [--include <pattern>] [--exclude "
+"<pattern>]"
 
 msgid "pack everything"
 msgstr "đóng gói mọi thứ"
@@ -9119,23 +9332,45 @@
 msgid "prune loose refs (default)"
 msgstr "prune (cắt cụt) những tham chiếu bị mất (mặc định)"
 
+msgid "auto-pack refs as needed"
+msgstr "tự động pack tham chiếu nếu cần"
+
+msgid "references to include"
+msgstr "bao gồm các tham chiếu"
+
+msgid "references to exclude"
+msgstr "loại trừ các tham chiếu"
+
+msgid "git patch-id [--stable | --unstable | --verbatim]"
+msgstr "git patch-id [--stable | --unstable | --verbatim]"
+
+msgid "use the unstable patch-id algorithm"
+msgstr "sử dụng thuật toán patch-id unstable"
+
+msgid "use the stable patch-id algorithm"
+msgstr "sử dụng thuật toán patch-id stable"
+
+msgid "don't strip whitespace from the patch"
+msgstr "không lược bỏ khoảng trắng thừa từ bản vá"
+
 msgid "git prune [-n] [-v] [--progress] [--expire <time>] [--] [<head>...]"
-msgstr "git prune [-n] [-v] [--progress] [--expire <thời-gian>] [--] [<head>…]"
+msgstr ""
+"git prune [-n] [-v] [--progress] [--expire <thời-gian>] [--] [<head>...]"
 
 msgid "report pruned objects"
-msgstr "báo cáo các đối tượng đã prune"
+msgstr "liệt kê các đối tượng đã prune"
 
 msgid "expire objects older than <time>"
 msgstr "các đối tượng hết hạn cũ hơn khoảng <thời gian>"
 
 msgid "limit traversal to objects outside promisor packfiles"
-msgstr "giới hạn giao đến các đối tượng nằm ngoài các tập tin gói hứa hẹn"
+msgstr "giới hạn giao đến các đối tượng nằm ngoài các tập tin gói promisor"
 
 msgid "cannot prune in a precious-objects repo"
 msgstr "không thể tỉa bớt trong một kho đối_tượng_vĩ_đại"
 
 msgid "git pull [<options>] [<repository> [<refspec>...]]"
-msgstr "git pull [<các tùy chọn>] [<kho-chứa> [<refspec>…]]"
+msgstr "git pull [<các tùy chọn>] [<kho-chứa> [<refspec>...]]"
 
 msgid "control for recursive fetching of submodules"
 msgstr "điều khiển việc lấy về đệ quy của các mô-đun-con"
@@ -9164,6 +9399,12 @@
 msgid "number of submodules pulled in parallel"
 msgstr "số lượng mô-đun-con được đẩy lên đồng thời"
 
+msgid "use IPv4 addresses only"
+msgstr "chỉ dùng địa chỉ IPv4"
+
+msgid "use IPv6 addresses only"
+msgstr "chỉ dùng địa chỉ IPv6"
+
 msgid ""
 "There is no candidate for rebasing against among the refs that you just "
 "fetched."
@@ -9181,9 +9422,9 @@
 "Generally this means that you provided a wildcard refspec which had no\n"
 "matches on the remote end."
 msgstr ""
-"Đại thể điều này có nghĩa là bạn đã cung cấp đặc tả đường dẫn dạng dùng ký "
+"Đại khái điều này có nghĩa là bạn đã cung cấp đặc tả đường dẫn dạng dùng ký "
 "tự\n"
-"đại diện mà nó lại không khớp trên điểm cuối máy phục vụ."
+"đại diện mà nó lại không khớp trên điểm cuối máy chủ."
 
 #, c-format
 msgid ""
@@ -9191,16 +9432,16 @@
 "a branch. Because this is not the default configured remote\n"
 "for your current branch, you must specify a branch on the command line."
 msgstr ""
-"Bạn yêu cầu pull từ máy dịch vụ “%s”, nhưng lại chưa chỉ định\n"
-"nhánh nào. Bởi vì đây không phải là máy dịch vụ được cấu hình\n"
-"theo mặc định cho nhánh hiện tại của bạn, bạn phải chỉ định\n"
+"Bạn yêu cầu pull từ máy dịch vụ '%s', nhưng lại chưa chỉ định\n"
+"nhánh nào. Bởi vì đây không phải là máy chủ được cấu hình\n"
+"mặc định cho nhánh hiện tại của bạn, bạn phải chỉ định\n"
 "một nhánh trên dòng lệnh."
 
 msgid "You are not currently on a branch."
-msgstr "Hiện tại bạn chẳng ở nhánh nào cả."
+msgstr "Hiện tại bạn đang không ở trên nhánh nào."
 
 msgid "Please specify which branch you want to rebase against."
-msgstr "Vui lòng chỉ định nhánh nào bạn muốn cải tổ lại."
+msgstr "Vui lòng chỉ định nhánh bạn muốn cải tổ lại."
 
 msgid "Please specify which branch you want to merge with."
 msgstr "Vui lòng chỉ định nhánh nào bạn muốn hòa trộn vào."
@@ -9220,22 +9461,23 @@
 msgid ""
 "If you wish to set tracking information for this branch you can do so with:"
 msgstr ""
-"Nếu bạn muốn theo dõi thông tin cho nhánh này bạn có thể thực hiện bằng lệnh:"
+"Nếu bạn muốn thiết lập thông tin theo dõi cho nhánh này bạn có thể thực hiện "
+"bằng lệnh:"
 
 #, c-format
 msgid ""
 "Your configuration specifies to merge with the ref '%s'\n"
 "from the remote, but no such ref was fetched."
 msgstr ""
-"Các đặc tả cấu hình của bạn để hòa trộn với tham chiếu “%s”\n"
-"từ máy dịch vụ, nhưng không có nhánh nào như thế được lấy về."
+"Cấu hình của bạn nói cần hòa trộn với tham chiếu '%s'\n"
+"từ máy dịch vụ, nhưng không có tham chiếu nào như thế được lấy về."
 
 #, c-format
 msgid "unable to access commit %s"
-msgstr "không thể truy cập lần chuyển giao “%s”"
+msgstr "không thể truy cập lần chuyển giao '%s'"
 
 msgid "ignoring --verify-signatures for rebase"
-msgstr "bỏ qua --verify-signatures khi rebase"
+msgstr "bỏ qua --verify-signatures khi cải tổ"
 
 msgid ""
 "You have divergent branches and need to specify how to reconcile them.\n"
@@ -9252,31 +9494,30 @@
 "or --ff-only on the command line to override the configured default per\n"
 "invocation.\n"
 msgstr ""
-"Bạn có các nhánh phân kỳ và cần chỉ định cách hòa hợp chúng.\n"
-"Bạn có thể làm như vậy bằng cách chạy một trong những lệnh sau đây\n"
-"thỉnh thoảng trước khi thực hiện lệnh pull tiếp theo của bạn:\n"
+"Bạn có các nhánh phân kỳ và cần chỉ định cách hợp nhất chúng.\n"
+"Bạn có thể làm vậy bằng cách chạy một trong những lệnh sau đây\n"
+"trước khi thực hiện lệnh pull tiếp theo của bạn:\n"
 "\n"
-"  git config pull.rebase false  # merge\n"
-"  git config pull.rebase true   # rebase\n"
-"  git config pull.ff only       # chỉ fast-forward\n"
+"  git config pull.rebase false  # hợp nhất\n"
+"  git config pull.rebase true   # cải tổ\n"
+"  git config pull.ff only       # chỉ chuyển tiếp nhanh\n"
 "\n"
 "Bạn có thể thay thế \"git config\" với \"git config --global\" để thiết lập "
 "mặc định\n"
-"ưu tiên cho tất cả các kho. Bạn cũng có thể chuyển qua --rebase, --no-"
-"rebase,\n"
-"hoặc --ff-only trên dòng lệnh để ghi đè các mặc định đã cấu hình cho mỗi\n"
+"ưu tiên cho tất cả các kho. Bạn cũng có thể chỉ định --rebase, --no-rebase,\n"
+"hoặc --ff-only trên dòng lệnh để ghi đè cấu hình mặc định cho từng\n"
 "lần gọi.\n"
 
 msgid "Updating an unborn branch with changes added to the index."
 msgstr ""
-"Đang cập nhật một nhánh chưa được sinh ra với các thay đổi được thêm vào "
-"bảng mục lục."
+"Đang cập nhật một nhánh chưa được sinh ra từ các thay đổi được thêm vào mục "
+"lục."
 
 msgid "pull with rebase"
 msgstr "pull với rebase"
 
-msgid "please commit or stash them."
-msgstr "xin hãy chuyển giao hoặc tạm cất (stash) chúng."
+msgid "Please commit or stash them."
+msgstr "Xin hãy chuyển giao hoặc tạm cất chúng."
 
 #, c-format
 msgid ""
@@ -9286,7 +9527,7 @@
 msgstr ""
 "fetch đã cập nhật head nhánh hiện tại.\n"
 "đang chuyển-tiếp-nhanh cây làm việc của bạn từ\n"
-"lần chuyển giaot %s."
+"lần chuyển giao %s."
 
 #, c-format
 msgid ""
@@ -9299,30 +9540,29 @@
 msgstr ""
 "Không thể chuyển tiếp nhanh cây làm việc của bạn.\n"
 "Sau khi chắc chắn rằng mình đã ghi lại mọi thứ\n"
-"quý báu từ kết xuất của lệnh\n"
+"quan trọng từ đầu ra của lệnh\n"
 "$ git diff %s\n"
 "chạy\n"
 "$ git reset --hard\n"
-"để khôi phục lại."
+"để khôi phục."
 
 msgid "Cannot merge multiple branches into empty head."
-msgstr "Không thể hòa trộn nhiều nhánh vào trong một head trống rỗng."
+msgstr "Không thể hòa trộn nhiều nhánh vào một head trống rỗng."
 
 msgid "Cannot rebase onto multiple branches."
-msgstr "Không thể thực hiện lệnh rebase (cải tổ) trên nhiều nhánh."
+msgstr "Không thể thực hiện lệnh cải tổ trên nhiều nhánh."
 
 msgid "Cannot fast-forward to multiple branches."
 msgstr "Không thể thực hiện chuyển tiếp nhanh trên nhiều nhánh."
 
 msgid "Need to specify how to reconcile divergent branches."
-msgstr "Caanfchir định làm thế nào để giải quyết các nhánh phân kỳ."
+msgstr "Cần chỉ định làm thế nào để giải quyết các nhánh phân kỳ."
 
 msgid "cannot rebase with locally recorded submodule modifications"
-msgstr ""
-"không thể cải tổ với các thay đổi mô-đun-con được ghi lại một cách cục bộ"
+msgstr "không thể cải tổ với các thay đổi submodule cục bộ"
 
 msgid "git push [<options>] [<repository> [<refspec>...]]"
-msgstr "git push [<các tùy chọn>] [<kho-chứa> [<refspec>…]]"
+msgstr "git push [<các tùy chọn>] [<kho-chứa> [<refspec>...]]"
 
 msgid "tag shorthand without <tag>"
 msgstr "dùng tốc ký thẻ không có <thẻ>"
@@ -9335,14 +9575,13 @@
 "To choose either option permanently, see push.default in 'git help config'.\n"
 msgstr ""
 "\n"
-"Để chọn mỗi tùy chọn một cách cố định, xem push.default trong “git help "
-"config”.\n"
+"Để chọn mỗi tùy chọn một cách cố định, xem push.default trong 'git help "
+"config'.\n"
 
 msgid ""
 "\n"
-"To avoid automatically configuring upstream branches when their name\n"
-"doesn't match the local branch, see option 'simple' of branch."
-"autoSetupMerge\n"
+"To avoid automatically configuring an upstream branch when its name\n"
+"won't match the local branch, see option 'simple' of branch.autoSetupMerge\n"
 "in 'git help config'.\n"
 msgstr ""
 "\n"
@@ -9407,8 +9646,7 @@
 "%s"
 msgstr ""
 "Nhánh hiện tại %s không có nhánh thượng nguồn nào.\n"
-"Để push (đẩy lên) nhánh hiện tại và đặt máy chủ này làm thượng nguồn "
-"(upstream), sử dụng\n"
+"Để đẩy lên nhánh hiện tại và đặt máy chủ này làm thượng nguồn, sử dụng\n"
 "\n"
 "    git push --set-upstream %s %s\n"
 "%s"
@@ -9420,8 +9658,8 @@
 msgid ""
 "You didn't specify any refspecs to push, and push.default is \"nothing\"."
 msgstr ""
-"Bạn đã không chỉ ra một refspecs nào để đẩy lên, và push.default là \"không "
-"là gì cả\"."
+"Bạn đã không chỉ ra một refspecs nào để đẩy lên, và push.default "
+"là\"nothing\"."
 
 #, c-format
 msgid ""
@@ -9429,48 +9667,46 @@
 "your current branch '%s', without telling me what to push\n"
 "to update which remote branch."
 msgstr ""
-"Bạn đang push (đẩy lên) máy chủ “%s”, mà nó không phải là thượng nguồn "
-"(upstream) của\n"
-"nhánh hiện tại “%s” của bạn, mà không báo cho tôi biết là cái gì được push\n"
-"để cập nhật nhánh máy chủ nào."
+"Bạn đang đẩy lên máy chủ '%s', không phải là thượng nguồn của\n"
+"nhánh hiện tại '%s' của bạn, mà không báo cho tôi biết là cần đẩy lên\n"
+"nhánh nào để cập nhật nhánh nào."
 
 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"
+"its remote counterpart. If you want to integrate the remote changes,\n"
+"use 'git pull' before pushing again.\n"
 "See the 'Note about fast-forwards' in 'git push --help' for details."
 msgstr ""
-"Việc cập nhật bị từ chối bởi vì đầu mút của nhánh hiện tại của bạn nằm đằng\n"
-"sau bộ phận tương ứng của máy chủ. Hòa trộn với các thay đổi từ máy chủ\n"
-"(v.d. \"git pull …\") trước khi đẩy lên lần nữa.\n"
-"Xem “Note about fast-forwards” trong “git push --help” để có thông tin chi "
+"Việc cập nhật bị từ chối bởi vì đỉnh của nhánh hiện tại của bạn đứng sau\n"
+"nhánh tương ứng của máy chủ. Nếu bạn cần hòa trộn với các thay đổi từ\n"
+"máy chủ, hãy chạy 'git pull' trước khi đẩy lên.\n"
+"Xem 'Note about fast-forwards' trong 'git push --help' để biết thông tin chi "
 "tiết."
 
 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"
+"counterpart. If you want to integrate the remote changes, use 'git pull'\n"
+"before pushing again.\n"
 "See the 'Note about fast-forwards' in 'git push --help' for details."
 msgstr ""
-"Việc cập nhật bị từ chối bởi vì đầu mút của nhánh đã đẩy lên nằm đằng sau "
-"bộ\n"
-"phận tương ứng của máy chủ. Checkou nhánh này và hòa trộn với các thay đổi\n"
-"từ máy chủ (v.d. “git pull …”) trước khi lại push lần nữa.\n"
-"Xem “Note about fast-forwards” trong “git push --help” để có thông tin chi "
+"Việc cập nhật bị từ chối bởi vì đỉnh của nhánh đã đẩy lên đứng sau\n"
+"nhánh tương ứng của máy chủ. Nếu bạn cần hòa trộn với các thay đổi từ\n"
+"máy chủ, hãy chạy 'git pull' trước khi đẩy lên.\n"
+"Xem 'Note about fast-forwards' trong 'git push --help' để biết thông tin chi "
 "tiết."
 
 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"
-"to the same ref. You may want to first integrate the remote changes\n"
-"(e.g., 'git pull ...') before pushing again.\n"
+"Updates were rejected because the remote contains work that you do not\n"
+"have locally. This is usually caused by another repository pushing to\n"
+"the same ref. If you want to integrate the remote changes, use\n"
+"'git pull' before pushing again.\n"
 "See the 'Note about fast-forwards' in 'git push --help' for details."
 msgstr ""
-"Việc cập nhật bị từ chối bởi vì máy chủ có chứa công việc mà bạn không\n"
-"có ở máy nội bộ của mình. Lỗi này thường có nguyên nhân bởi kho khác đẩy\n"
-"dữ liệu lên cùng một tham chiếu. Bạn có lẽ muốn hòa trộn với các thay đổi\n"
-"từ máy chủ (v.d. “git pull…”) trước khi lại push lần nữa.\n"
-"Xem “Note about fast-forwards” trong “git push --help” để có thông tin chi "
+"Việc cập nhật bị từ chối bởi vì máy chủ có chứa thay đổi mà bạn không\n"
+"có ở nhánh của mình. Lỗi này thường xảy ra khi kho khác đẩy dữ liệu\n"
+"lên cùng một tham chiếu. Nếu bạn cần hòa trộn với các thay đổi từ\n"
+"máy chủ, hãy chạy 'git pull' trước khi đẩy lên.\n"
+"Xem 'Note about fast-forwards' trong 'git push --help' để biết thông tin chi "
 "tiết."
 
 msgid "Updates were rejected because the tag already exists in the remote."
@@ -9481,22 +9717,22 @@
 "or update a remote ref to make it point at a non-commit object,\n"
 "without using the '--force' option.\n"
 msgstr ""
-"Không thể cập nhật một tham chiếu trên máy chủ mà nó chỉ đến đối tượng "
-"không\n"
-"phải là lần chuyển giao, hoặc cập nhật một tham chiếu máy chủ để nó chỉ đến "
-"đối tượng\n"
-"không phải chuyển giao, mà không sử dụng tùy chọn “--force”.\n"
+"Không thể cập nhật tham chiếu trên máy chủ đang chỉ đến đối tượng không\n"
+"phải là lần chuyển giao, hoặc cập nhật tham chiếu trên máy chủ để nó\n"
+"chỉ đến đối tượng không phải lần chuyển giao, mà không sử dụng\n"
+"tùy chọn '--force'.\n"
 
 msgid ""
-"Updates were rejected because the tip of the remote-tracking\n"
-"branch has been updated since the last checkout. You may want\n"
-"to integrate those changes locally (e.g., 'git pull ...')\n"
-"before forcing an update.\n"
+"Updates were rejected because the tip of the remote-tracking branch has\n"
+"been updated since the last checkout. If you want to integrate the\n"
+"remote changes, use 'git pull' before pushing again.\n"
+"See the 'Note about fast-forwards' in 'git push --help' for details."
 msgstr ""
-"Việc cập nhật bị từ chối bởi vì đầu mút của nhánh theo dõi máy chủ\n"
-"đã được cập nhật kể từ sau lần lấy ra cuối cùng. Bạn có lẽ muốn\n"
-"tích hợp các thay đổi này một cách cục bộ (v.d. \"git pull …\")\n"
-"trước khi ép buộc một cập nhật.\n"
+"Việc cập nhật bị từ chối bởi vì đỉnh của nhánh theo dõi máy chủ đã được\n"
+"cập nhật sau lần checkout trước. Nếu bạn cần hòa trộn với các thay đổi từ\n"
+"máy chủ, hãy chạy 'git pull' trước khi đẩy lên.\n"
+"Xem 'Note about fast-forwards' trong 'git push --help' để biết thông tin chi "
+"tiết."
 
 #, c-format
 msgid "Pushing to %s\n"
@@ -9504,7 +9740,13 @@
 
 #, c-format
 msgid "failed to push some refs to '%s'"
-msgstr "gặp lỗi khi đẩy tới một số tham chiếu đến “%s”"
+msgstr "gặp lỗi khi đẩy tới một số tham chiếu đến '%s'"
+
+msgid ""
+"recursing into submodule with push.recurseSubmodules=only; using on-demand "
+"instead"
+msgstr ""
+"đệ quy vào mô-đun con với push.recurseSubmodules=only; thay bằng on-demand"
 
 #, c-format
 msgid "invalid value for '%s'"
@@ -9513,17 +9755,17 @@
 msgid "repository"
 msgstr "kho"
 
-msgid "push all refs"
-msgstr "đẩy tất cả các tham chiếu"
+msgid "push all branches"
+msgstr "đẩy tất cả các nhánh"
 
 msgid "mirror all refs"
-msgstr "mirror tất cả các tham chiếu"
+msgstr "sao tất cả các tham chiếu"
 
 msgid "delete refs"
 msgstr "xóa các tham chiếu"
 
-msgid "push tags (can't be used with --all or --mirror)"
-msgstr "đẩy các thẻ (không dùng cùng với --all hay --mirror)"
+msgid "push tags (can't be used with --all or --branches or --mirror)"
+msgstr "đẩy các thẻ (không dùng cùng với --all hay --branches hay --mirror)"
 
 msgid "force updates"
 msgstr "ép buộc cập nhật"
@@ -9538,7 +9780,7 @@
 msgstr "yêu cầu máy chủ cập nhật để thích hợp với máy cục bộ"
 
 msgid "control recursive pushing of submodules"
-msgstr "điều khiển việc đẩy lên (push) đệ qui của mô-đun-con"
+msgstr "điều khiển việc đẩy lên (push) đệ quy của mô-đun-con"
 
 msgid "use thin pack"
 msgstr "tạo gói nhẹ"
@@ -9569,7 +9811,7 @@
 
 #, c-format
 msgid "bad repository '%s'"
-msgstr "repository (kho) sai “%s”"
+msgstr "repository (kho) sai '%s'"
 
 msgid ""
 "No configured push destination.\n"
@@ -9605,7 +9847,7 @@
 "git range-diff [<các tùy chọn>] <old-base>..<old-tip> <new-base>..<new-tip>"
 
 msgid "git range-diff [<options>] <old-tip>...<new-tip>"
-msgstr "git range-diff [<các tùy chọn>] <old-tip>…<new-tip>"
+msgstr "git range-diff [<các tùy chọn>] <old-tip>...<new-tip>"
 
 msgid "git range-diff [<options>] <base> <old-tip> <new-tip>"
 msgstr "git range-diff [<các tùy chọn>] <base> <old-tip> <new-tip>"
@@ -9617,7 +9859,7 @@
 msgstr "ghi chú"
 
 msgid "passed to 'git log'"
-msgstr "chuyển cho “git log”"
+msgstr "chuyển cho 'git log'"
 
 msgid "only emit output related to the first range"
 msgstr "chỉ phát ra kết xuất liên quan đến vùng đầu tiên"
@@ -9626,29 +9868,36 @@
 msgstr "chỉ phát ra kết xuất liên quan đến vùng thứ hai"
 
 #, c-format
-msgid "not a commit range: '%s'"
-msgstr "không phải là vùng chuyển giao: “%s”"
+msgid "not a revision: '%s'"
+msgstr "không phải một revision '%s'"
 
-msgid "single arg format must be symmetric range"
-msgstr "định dạng đối số đơn phải là một vùng đối xứng"
+#, c-format
+msgid "not a commit range: '%s'"
+msgstr "không phải là vùng chuyển giao: '%s'"
+
+#, c-format
+msgid "not a symmetric range: '%s'"
+msgstr "không phải là vùng tương xứng: '%s'"
 
 msgid "need two commit ranges"
-msgstr "cần hai vùng lần chuyển giao"
+msgstr "cần hai vùng chuyển giao"
 
 msgid ""
-"git read-tree [(-m [--trivial] [--aggressive] | --reset | --prefix=<prefix>) "
-"[-u | -i]] [--no-sparse-checkout] [--index-output=<file>] (--empty | <tree-"
-"ish1> [<tree-ish2> [<tree-ish3>]])"
-msgstr ""
 "git read-tree [(-m [--trivial] [--aggressive] | --reset | --"
-"prefix=<tiền_tố>) [-u | -i]] [--no-sparse-checkout] [--index-"
-"output=<tập_tin>] (--empty | <tree-ish1> [<tree-ish2> [<tree-ish3>]])"
+"prefix=<prefix>)\n"
+"              [-u | -i]] [--index-output=<file>] [--no-sparse-checkout]\n"
+"              (--empty | <tree-ish1> [<tree-ish2> [<tree-ish3>]])"
+msgstr ""
+"git read-tree [(-m [--trivial] [--aggressive] | --reset | --prefix=<tiền "
+"tố>)\n"
+"              [-u | -i]] [--index-output=<tập tin>] [--no-sparse-checkout]\n"
+"              (--empty | <tree-ish1> [<tree-ish2> [<tree-ish3>]])"
 
 msgid "write resulting index to <file>"
-msgstr "ghi mục lục kết quả vào <tập-tin>"
+msgstr "ghi chỉ mục kết quả vào <tập-tin>"
 
 msgid "only empty the index"
-msgstr "chỉ với bảng mục lục trống rỗng"
+msgstr "chỉ với chỉ mục trống rỗng"
 
 msgid "Merging"
 msgstr "Hòa trộn"
@@ -9658,10 +9907,10 @@
 
 msgid "3-way merge if no file level merging required"
 msgstr ""
-"hòa trộn kiểu “3-way” nếu không có tập tin mức hòa trộn nào được yêu cầu"
+"hòa trộn kiểu '3-way' nếu không có tập tin mức hòa trộn nào được yêu cầu"
 
 msgid "3-way merge in presence of adds and removes"
-msgstr "hòa trộn 3-way trong sự hiện diện của “adds” và “removes”"
+msgstr "hòa trộn 3-way trong sự hiện diện của 'adds' và 'removes'"
 
 msgid "same as -m, but discard unmerged entries"
 msgstr "giống với -m, nhưng bỏ qua các mục chưa được hòa trộn"
@@ -9670,7 +9919,7 @@
 msgstr "<thư-mục-con>/"
 
 msgid "read the tree into the index under <subdirectory>/"
-msgstr "đọc cây vào trong bảng mục lục dưới <thư_mục_con>/"
+msgstr "đọc cây vào trong chỉ mục dưới <thư_mục_con>/"
 
 msgid "update working tree with merge result"
 msgstr "cập nhật cây làm việc với kết quả hòa trộn"
@@ -9679,25 +9928,25 @@
 msgstr "gitignore"
 
 msgid "allow explicitly ignored files to be overwritten"
-msgstr "cho phép các tập tin rõ ràng bị lờ đi được ghi đè"
+msgstr "cho phép các tập tin rõ ràng bị bỏ qua được ghi đè"
 
 msgid "don't check the working tree after merging"
 msgstr "không kiểm tra cây làm việc sau hòa trộn"
 
 msgid "don't update the index or the work tree"
-msgstr "không cập nhật bảng mục lục hay cây làm việc"
+msgstr "không cập nhật chỉ mục hay cây làm việc"
 
 msgid "skip applying sparse checkout filter"
-msgstr "bỏ qua áp dụng bộ lọc lấy ra (checkout) thưa thớt"
+msgstr "bỏ qua áp dụng bộ lọc sparse checkout (checkout thưa)"
 
 msgid "debug unpack-trees"
-msgstr "gỡ lỗi “unpack-trees”"
+msgstr "gỡ lỗi 'unpack-trees'"
 
 msgid "suppress feedback messages"
 msgstr "không xuất các thông tin phản hồi"
 
 msgid "You need to resolve your current index first"
-msgstr "Bạn cần phải giải quyết bảng mục lục hiện tại của bạn trước đã"
+msgstr "Bạn cần phải giải quyết chỉ mục hiện tại của bạn trước đã"
 
 msgid ""
 "git rebase [-i] [options] [--exec <cmd>] [--onto <newbase> | --keep-base] "
@@ -9714,7 +9963,7 @@
 
 #, c-format
 msgid "could not read '%s'."
-msgstr "không thể đọc “%s”."
+msgstr "không thể đọc '%s'."
 
 #, c-format
 msgid "could not create temporary %s"
@@ -9734,34 +9983,20 @@
 msgstr "%s cần một ứng dụng hòa trộn chạy phía sau"
 
 #, c-format
-msgid "could not get 'onto': '%s'"
-msgstr "không thể đặt lấy “onto”: “%s”"
+msgid "invalid onto: '%s'"
+msgstr "onto không hợp lệ: '%s'"
 
 #, c-format
 msgid "invalid orig-head: '%s'"
-msgstr "orig-head không hợp lệ: “%s”"
+msgstr "orig-head không hợp lệ: '%s'"
 
 #, c-format
 msgid "ignoring invalid allow_rerere_autoupdate: '%s'"
-msgstr "đang bỏ qua allow_rerere_autoupdate không hợp lệ: “%s”"
+msgstr "đang bỏ qua allow_rerere_autoupdate không hợp lệ: '%s'"
 
 #, c-format
 msgid "could not remove '%s'"
-msgstr "không thể gỡ bỏ “%s”"
-
-msgid ""
-"Resolve all conflicts manually, mark them as resolved with\n"
-"\"git add/rm <conflicted_files>\", then run \"git rebase --continue\".\n"
-"You can instead skip this commit: run \"git rebase --skip\".\n"
-"To abort and get back to the state before \"git rebase\", run \"git rebase --"
-"abort\"."
-msgstr ""
-"Giải quyết vấn đề này thủ công, hãy đanh dấu chúng đã được giải quyết bằng\n"
-"hãy chạy lệnh \"git add/rm <các_tập_tin_xung_đột>\", sau đó chạy \"git "
-"rebase --continue\".\n"
-"Bạn có thể bỏ qua miếng vá, chạy \"git rebase --skip\".\n"
-"Để bãi bỏ và quay trở lại trạng thái trước \"git rebase\", chạy \"git rebase "
-"--abort\"."
+msgstr "không thể gỡ bỏ '%s'"
 
 #, c-format
 msgid ""
@@ -9774,24 +10009,44 @@
 "As a result, git cannot rebase them."
 msgstr ""
 "\n"
-"git chạm trán một lỗi trong khi đang chuẩn bị các miếng vá để diễn lại\n"
+"git gặp phải một lỗi trong khi đang chuẩn bị các bản vá để diễn lại\n"
 "những điểm xét duyệt này:\n"
 "\n"
 "    %s\n"
 "\n"
-"Kết quả là git không thể cải tổ lại chúng."
+"Kết quả là, git không thể cải tổ lại chúng."
+
+#, c-format
+msgid "Unknown rebase-merges mode: %s"
+msgstr "Không hiểu chế độ cải tổ: %s"
 
 #, c-format
 msgid "could not switch to %s"
 msgstr "không thể chuyển đến %s"
 
+msgid "apply options and merge options cannot be used together"
+msgstr ""
+"không thể tổ hợp các tùy chọn áp dụng với các tùy chọn hòa trộn với nhau"
+
+msgid "--empty=ask is deprecated; use '--empty=stop' instead."
+msgstr "không cho dùng --empty=ask nữa; hãy thay thế bằng '--empty=stop'."
+
 #, c-format
 msgid ""
-"unrecognized empty type '%s'; valid values are \"drop\", \"keep\", and \"ask"
-"\"."
+"unrecognized empty type '%s'; valid values are \"drop\", \"keep\", and "
+"\"stop\"."
 msgstr ""
-"kiểu rỗng không được nhận dạng “%s”; giá trị hợp lệ là \"drop\", \"keep\", "
-"và \"ask\"."
+"kiểu rỗng không được nhận dạng '%s'; giá trị hợp lệ là \"drop\", \"keep\", "
+"và \"stop\"."
+
+msgid ""
+"--rebase-merges with an empty string argument is deprecated and will stop "
+"working in a future version of Git. Use --rebase-merges without an argument "
+"instead, which does the same thing."
+msgstr ""
+"--rebase-merges với tham số xâu rỗng được coi là lỗi thời và sẽ không còn "
+"hoạt động trong Git tương lai. Thay vào đó dùng --rebase-merges không có "
+"tham số, cho kết quả như nhau."
 
 #, c-format
 msgid ""
@@ -9803,10 +10058,10 @@
 "\n"
 msgstr ""
 "%s\n"
-"Vui lòng chỉ định nhánh nào bạn muốn cải tổ dựa vào.\n"
+"Vui lòng chỉ định nhánh nào bạn muốn cải tổ lên.\n"
 "Xem git-rebase(1) để biết thêm chi tiết.\n"
 "\n"
-"    git rebase “<nhánh>”\n"
+"    git rebase '<nhánh>'\n"
 "\n"
 
 #, c-format
@@ -9816,7 +10071,7 @@
 "    git branch --set-upstream-to=%s/<branch> %s\n"
 "\n"
 msgstr ""
-"Nếu bạn muốn theo dõi thông tin cho nhánh này bạn có thể thực hiện bằng "
+"Nếu bạn muốn đặt thông tin theo dõi cho nhánh này bạn có thể thực hiện bằng "
 "lệnh:\n"
 "\n"
 "    git branch --set-upstream-to=%s/<nhánh> %s\n"
@@ -9832,17 +10087,16 @@
 msgstr "cải tổ vào nhánh đã cho thay cho thượng nguồn"
 
 msgid "use the merge-base of upstream and branch as the current base"
-msgstr ""
-"sử dụng các cơ sở hòa trộn của thượng nguồn và nhánh như là cơ sở hiện tại"
+msgstr "sử dụng gốc hòa trộn của thượng nguồn và nhánh làm gốc hiện tại"
 
 msgid "allow pre-rebase hook to run"
 msgstr "cho phép móc (hook) pre-rebase được chạy"
 
 msgid "be quiet. implies --no-stat"
-msgstr "hãy im lặng. ý là --no-stat"
+msgstr "im lặng. ngụ ý --no-stat"
 
 msgid "display a diffstat of what changed upstream"
-msgstr "hiển thị một diffstat của những thay đổi thượng nguồn"
+msgstr "hiển thị diffstat của những thay đổi thượng nguồn"
 
 msgid "do not show diffstat of what changed upstream"
 msgstr "đừng hiển thị diffstat của những thay đổi thượng nguồn"
@@ -9860,10 +10114,10 @@
 msgstr "đồng nghĩa với --reset-author-date"
 
 msgid "passed to 'git apply'"
-msgstr "chuyển cho “git apply”"
+msgstr "chuyển cho 'git apply'"
 
 msgid "ignore changes in whitespace"
-msgstr "lờ đi sự thay đổi do khoảng trắng gây ra"
+msgstr "bỏ qua sự thay đổi do khoảng trắng gây ra"
 
 msgid "cherry-pick all commits, even if unchanged"
 msgstr ""
@@ -9873,19 +10127,19 @@
 msgstr "tiếp tục"
 
 msgid "skip current patch and continue"
-msgstr "bỏ qua miếng vá hiện hành và tiếp tục"
+msgstr "bỏ qua bản vá hiện hành và tiếp tục"
 
 msgid "abort and check out the original branch"
-msgstr "bãi bỏ và lấy ra nhánh nguyên thủy"
+msgstr "huỷ bỏ và checkout nhánh gốc"
 
 msgid "abort but keep HEAD where it is"
-msgstr "bãi bỏ nhưng vẫn vẫn giữ HEAD chỉ đến nó"
+msgstr "huỷ bỏ nhưng vẫn vẫn giữ nguyên HEAD"
 
 msgid "edit the todo list during an interactive rebase"
-msgstr "sửa danh sách cần làm trong quá trình “rebase” (cải tổ) tương tác"
+msgstr "sửa danh sách cần làm trong quá trình 'rebase' (cải tổ) tương tác"
 
 msgid "show the patch file being applied or merged"
-msgstr "hiển thị miếng vá đã được áp dụng hay hòa trộn"
+msgstr "hiển thị bản vá đã được áp dụng hay hòa trộn"
 
 msgid "use apply strategies to rebase"
 msgstr "dùng chiến lược áp dụng để cải tổ"
@@ -9908,6 +10162,9 @@
 msgid "move commits that begin with squash!/fixup! under -i"
 msgstr "di chuyển các lần chuyển giao mà bắt đầu bằng squash!/fixup! dưới -i"
 
+msgid "update branches that point to commits that are being rebased"
+msgstr "cập nhật các nhánh trỏ đến commit đang được cải tổ"
+
 msgid "add exec lines after each commit of the editable list"
 msgstr "thêm các dòng thực thi sau từng lần chuyển giao của danh sách sửa được"
 
@@ -9918,7 +10175,7 @@
 msgstr "cố thử cải tổ các hòa trộn thay vì bỏ qua chúng"
 
 msgid "use 'merge-base --fork-point' to refine upstream"
-msgstr "dùng “merge-base --fork-point” để định nghĩa lại thượng nguồn"
+msgstr "dùng 'merge-base --fork-point' để định nghĩa lại thượng nguồn"
 
 msgid "use the given merge strategy"
 msgstr "dùng chiến lược hòa trộn đã cho"
@@ -9933,7 +10190,7 @@
 msgstr "cải tổ tất các các lần chuyển giao cho đến root"
 
 msgid "automatically re-schedule any `exec` that fails"
-msgstr "lập lịch lại một cách tự động bất kỳ “exec“ bị lỗi"
+msgstr "lập lịch lại một cách tự động bất kỳ 'exec' bị lỗi"
 
 msgid "apply all changes, even those already present upstream"
 msgstr ""
@@ -9941,7 +10198,7 @@
 
 msgid "It looks like 'git am' is in progress. Cannot rebase."
 msgstr ""
-"Hình như đang trong quá trình thực hiện lệnh “git am”. Không thể rebase."
+"Hình như đang trong quá trình thực hiện lệnh 'git am'. Không thể rebase."
 
 msgid ""
 "`rebase --preserve-merges` (-p) is no longer supported.\n"
@@ -9949,7 +10206,7 @@
 "Or downgrade to v2.33, or earlier, to complete the rebase."
 msgstr ""
 "`rebase --preserve-merges` (-p) không còn được hỗ trợ nữa.\n"
-"Dùng `git rebase --abort` để chấm dứt việc cải tổ hiện tại.\n"
+"Dùng `git rebase --abort` để kết thúc việc cải tổ hiện tại.\n"
 "Hoặc là hạ phiên bản phần mềm xuống v2.33,\n"
 "hoặc trước nữa, để hoàn thành việc cải tổ."
 
@@ -9963,12 +10220,12 @@
 "'preserve',\n"
 "cái mà giờ không còn được hỗ trợ nữa; dùng 'merges' để thay thế"
 
-msgid "No rebase in progress?"
-msgstr "Không có tiến trình rebase nào phải không?"
+msgid "no rebase in progress"
+msgstr "không có cải tổ đang được thực hiện"
 
 msgid "The --edit-todo action can only be used during interactive rebase."
 msgstr ""
-"Hành động “--edit-todo” chỉ có thể dùng trong quá trình “rebase” (sửa lịch "
+"Hành động '--edit-todo' chỉ có thể dùng trong quá trình 'rebase' (sửa lịch "
 "sử) tương tác."
 
 msgid "Cannot read HEAD"
@@ -10000,67 +10257,67 @@
 "valuable there.\n"
 msgstr ""
 "Hình như là ở đây sẵn có một thư mục %s, và\n"
-"Tôi tự hỏi có phải bạn đang ở giữa một lệnh rebase khác. Nếu đúng là\n"
+"có lẽ bạn đang ở giữa một lệnh rebase khác. Nếu đúng là\n"
 "như vậy, xin hãy thử\n"
 "\t%s\n"
 "Nếu không phải thế, hãy thử\n"
 "\t%s\n"
-"và chạy TÔI lần nữa. TÔI dừng lại trong trường hợp bạn vẫn\n"
-"có một số thứ quý giá ở đây.\n"
+"và chạy TÔI lần nữa. TÔI sẽ dừng lại vì có khả năng bạn vẫn\n"
+"còn một số thứ quan trọng ở đây.\n"
 
 msgid "switch `C' expects a numerical value"
-msgstr "tùy chọn “%c” cần một giá trị bằng số"
+msgstr "tùy chọn '%c' cần một giá trị bằng số"
 
-#, c-format
-msgid "Unknown mode: %s"
-msgstr "Không hiểu chế độ: %s"
-
-msgid "--strategy requires --merge or --interactive"
-msgstr "--strategy cần --merge hay --interactive"
-
-msgid "apply options and merge options cannot be used together"
+msgid ""
+"apply options are incompatible with rebase.rebaseMerges.  Consider adding --"
+"no-rebase-merges"
 msgstr ""
-"không thể tổ hợp các tùy chọn áp dụng với các tùy chọn hòa trộn với nhau"
+"tuỳ chọn apply không tương thích với rebase.rebaseMerges. Cân nhắc dùng --no-"
+"rebase-merges"
+
+msgid ""
+"apply options are incompatible with rebase.updateRefs.  Consider adding --no-"
+"update-refs"
+msgstr ""
+"tuỳ chọn apply không tương thích với rebase.updateRefs. Cân nhắc dùng --no-"
+"update-refs"
 
 #, c-format
 msgid "Unknown rebase backend: %s"
-msgstr "Không hiểu ứng dụng chạy phía sau lệnh cải tổ: %s"
+msgstr "Không hiểu backend cải tổ: %s"
 
 msgid "--reschedule-failed-exec requires --exec or --interactive"
 msgstr "--reschedule-failed-exec cần --exec hay --interactive"
 
 #, c-format
 msgid "invalid upstream '%s'"
-msgstr "thượng nguồn không hợp lệ “%s”"
+msgstr "thượng nguồn không hợp lệ '%s'"
 
 msgid "Could not create new root commit"
 msgstr "Không thể tạo lần chuyển giao gốc mới"
 
 #, c-format
 msgid "no such branch/commit '%s'"
-msgstr "không có nhánh/lần chuyển giao “%s” như thế"
+msgstr "không có nhánh/lần chuyển giao '%s' như thế"
 
 #, c-format
 msgid "No such ref: %s"
 msgstr "Không có tham chiếu nào như thế: %s"
 
-msgid "Could not resolve HEAD to a revision"
-msgstr "Không thể phân giải lần chuyển giao HEAD đến một điểm xét duyệt"
+msgid "Could not resolve HEAD to a commit"
+msgstr "không thể phân giải HEAD thành tên lần chuyển giao"
 
 #, c-format
 msgid "'%s': need exactly one merge base with branch"
-msgstr "“%s”: cần chính xác một cơ sở hòa trộn với nhánh"
+msgstr "'%s': cần chính xác một gốc hòa trộn với nhánh"
 
 #, c-format
 msgid "'%s': need exactly one merge base"
-msgstr "“%s”: cần chính xác một cơ sở hòa trộn"
+msgstr "'%s': cần chính xác một gốc hòa trộn"
 
 #, c-format
 msgid "Does not point to a valid commit '%s'"
-msgstr "Không chỉ đến một lần chuyển giao không hợp lệ “%s”"
-
-msgid "Please commit or stash them."
-msgstr "Xin hãy chuyển giao hoặc tạm cất (stash) chúng."
+msgstr "Không chỉ đến một lần chuyển giao không hợp lệ '%s'"
 
 msgid "HEAD is up to date."
 msgstr "HEAD đã cập nhật."
@@ -10090,7 +10347,7 @@
 #, c-format
 msgid "First, rewinding head to replay your work on top of it...\n"
 msgstr ""
-"Trước tiên, di chuyển head để xem lại các công việc trên đỉnh của nó…\n"
+"Trước tiên, di chuyển head để xem lại các công việc trên đỉnh của nó...\n"
 
 msgid "Could not detach HEAD"
 msgstr "Không thể tách rời HEAD"
@@ -10117,19 +10374,19 @@
 "To squelch this message and still keep the default behaviour, set\n"
 "'receive.denyCurrentBranch' configuration variable to 'refuse'."
 msgstr ""
-"Theo mặc định, việc cập nhật nhánh hiện tại trong một kho không-thuần\n"
+"Theo mặc định, việc cập nhật nhánh hiện tại trong một kho không bare\n"
 "bị từ chối, bởi vì nó sẽ làm cho chỉ mục và cây làm việc mâu thuẫn với\n"
-"cái mà bạn đẩy lên, và sẽ yêu cầu lệnh “git reset --hard” để mà làm\n"
+"cái mà bạn đẩy lên, và sẽ yêu cầu lệnh 'git reset --hard' để làm\n"
 "cho cây làm việc khớp với HEAD.\n"
 "\n"
-"Bạn có thể đặt biến cấu hình “receive.denyCurrentBranch” thành\n"
-"“ignore” hay “warn” trong kho máy chủ để cho phép đẩy lên nhánh\n"
+"Bạn có thể đặt biến cấu hình 'receive.denyCurrentBranch' thành\n"
+"'ignore' hay 'warn' trong kho máy chủ để cho phép đẩy lên nhánh\n"
 "hiện tại của nó; tuy nhiên, không nên làm như thế trừ phi bạn\n"
 "sắp đặt để cập nhật cây làm việc của nó tương ứng với cái mà bạn đẩy\n"
 "lên theo cách nào đó.\n"
 "\n"
-"Để chấm dứt lời nhắn này và vẫn giữ cách ứng xử mặc định, hãy đặt\n"
-"biến cấu hình “receive.denyCurrentBranch” thành “refuse”."
+"Để tắt lời nhắn này và vẫn giữ hành vi mặc định, hãy đặt\n"
+"biến cấu hình 'receive.denyCurrentBranch' thành 'refuse'."
 
 msgid ""
 "By default, deleting the current branch is denied, because the next\n"
@@ -10142,14 +10399,14 @@
 "To squelch this message, you can set it to 'refuse'."
 msgstr ""
 "Theo mặc định, việc cập xóa nhánh hiện tại bị từ chối, bởi vì\n"
-"lệnh “git clone” tiếp theo sẽ không có tác dụng trong việc lấy\n"
+"lệnh 'git clone' tiếp theo sẽ không có tác dụng trong việc lấy\n"
 "ra bất kỳ tập tin nào, dẫn đến hỗn loạn\n"
 "\n"
-"Bạn có thể đặt biến cấu hình “receive.denyDeleteCurrent” thành\n"
-"“warn” hay “ignore” trong kho máy chủ để cho phép đẩy xóa nhánh\n"
+"Bạn có thể đặt biến cấu hình 'receive.denyDeleteCurrent' thành\n"
+"'warn' hay 'ignore' trong kho máy chủ để cho phép đẩy xóa nhánh\n"
 "hiện tại của nó có hoặc không cảnh báo.\n"
 "\n"
-"Để chấm dứt lời nhắn này, bạn hãy đặt nó thành “refuse”."
+"Để tắt lời nhắn này, bạn hãy đặt nó thành 'refuse'."
 
 msgid "quiet"
 msgstr "im lặng"
@@ -10160,6 +10417,9 @@
 msgid "git reflog [show] [<log-options>] [<ref>]"
 msgstr "git reflog [show] [<các tùy chọn>] [<tham chiếu>]"
 
+msgid "git reflog list"
+msgstr "git reflog list"
+
 msgid ""
 "git reflog expire [--expire=<time>] [--expire-unreachable=<time>]\n"
 "                  [--rewrite] [--updateref] [--stale-fix]\n"
@@ -10185,6 +10445,10 @@
 msgid "invalid timestamp '%s' given to '--%s'"
 msgstr "dấu vết thời gian không hợp lệ '%s' đưa cho '--%s'"
 
+#, c-format
+msgid "%s does not accept arguments: '%s'"
+msgstr "%s không nhận các đối số: '%s'"
+
 msgid "do not actually prune any entries"
 msgstr "thực tế không cắt ngắn bất kỳ mục tin nào"
 
@@ -10222,7 +10486,7 @@
 
 #, c-format
 msgid "Marking reachable objects..."
-msgstr "Đánh dấu các đối tượng tiếp cận được…"
+msgstr "Đánh dấu các đối tượng tiếp cận được..."
 
 #, c-format
 msgid "%s points nowhere!"
@@ -10260,10 +10524,10 @@
 msgid ""
 "git remote [-v | --verbose] update [-p | --prune] [(<group> | <remote>)...]"
 msgstr ""
-"git remote [-v | --verbose] update [-p | --prune] [(<nhóm> | <máy-chủ>)…]"
+"git remote [-v | --verbose] update [-p | --prune] [(<nhóm> | <máy-chủ>)...]"
 
 msgid "git remote set-branches [--add] <name> <branch>..."
-msgstr "git remote set-branches [--add] <tên> <nhánh>…"
+msgstr "git remote set-branches [--add] <tên> <nhánh>..."
 
 msgid "git remote get-url [--push] [--all] <name>"
 msgstr "git remote set-url [--push] [--all] <tên>"
@@ -10281,10 +10545,10 @@
 msgstr "git remote add [<các tùy chọn>] <tên> <url>"
 
 msgid "git remote set-branches <name> <branch>..."
-msgstr "git remote set-branches <tên> <nhánh>…"
+msgstr "git remote set-branches <tên> <nhánh>..."
 
 msgid "git remote set-branches --add <name> <branch>..."
-msgstr "git remote set-branches --add <tên> <nhánh>…"
+msgstr "git remote set-branches --add <tên> <nhánh>..."
 
 msgid "git remote show [<options>] <name>"
 msgstr "git remote show [<các tùy chọn>] <tên>"
@@ -10293,7 +10557,7 @@
 msgstr "git remote prune [<các tùy chọn>] <tên>"
 
 msgid "git remote update [<options>] [<group> | <remote>]..."
-msgstr "git remote update [<các tùy chọn>] [<nhóm> | <máy-chủ>]…"
+msgstr "git remote update [<các tùy chọn>] [<nhóm> | <máy-chủ>]..."
 
 #, c-format
 msgid "Updating %s"
@@ -10301,27 +10565,28 @@
 
 #, c-format
 msgid "Could not fetch %s"
-msgstr "Không thể lấy“%s” về"
+msgstr "Không thể lấy'%s' về"
 
 msgid ""
 "--mirror is dangerous and deprecated; please\n"
 "\t use --mirror=fetch or --mirror=push instead"
 msgstr ""
-"--mirror nguy hiểm và không dùng nữa; xin hãy\n"
+"--mirror nguy hiểm và không được dùng nữa; xin hãy\n"
 "\t sử dụng tùy chọn --mirror=fetch hoặc --mirror=push để thay thế"
 
 #, c-format
-msgid "unknown mirror argument: %s"
-msgstr "không hiểu tham số máy bản sao (mirror): %s"
+msgid "unknown --mirror argument: %s"
+msgstr "không hiểu tham số --mirror: %s"
 
 msgid "fetch the remote branches"
 msgstr "lấy về các nhánh từ máy chủ"
 
-msgid "import all tags and associated objects when fetching"
-msgstr "nhập vào tất cả các đối tượng thẻ và thành phần liên quan khi lấy về"
-
-msgid "or do not fetch any tag at all (--no-tags)"
-msgstr "hoặc không lấy về bất kỳ thẻ nào (--no-tags)"
+msgid ""
+"import all tags and associated objects when fetching\n"
+"or do not fetch any tag at all (--no-tags)"
+msgstr ""
+"nhập vào tất cả các thẻ và đối tượng liên quan khi lấy về\n"
+"hoặc không nhận về một thẻ nào cả (--no-tags)"
 
 msgid "branch(es) to track"
 msgstr "các nhánh để theo dõi"
@@ -10336,7 +10601,7 @@
 msgstr "đang chỉ định một nhánh master không hợp lý với tùy chọn --mirror"
 
 msgid "specifying branches to track makes sense only with fetch mirrors"
-msgstr "chỉ định những nhánh để theo dõi chỉ hợp lý với các “fetch mirror”"
+msgstr "chỉ định những nhánh để theo dõi chỉ hợp lý với các 'fetch mirror'"
 
 #, c-format
 msgid "remote %s already exists."
@@ -10344,7 +10609,7 @@
 
 #, c-format
 msgid "Could not setup master '%s'"
-msgstr "Không thể cài đặt nhánh master “%s”"
+msgstr "Không thể cài đặt nhánh master '%s'"
 
 #, c-format
 msgid "more than one %s"
@@ -10352,7 +10617,7 @@
 
 #, c-format
 msgid "unhandled branch.%s.rebase=%s; assuming 'true'"
-msgstr "nhánh chưa được quản lý.%s.rebase=%s; giả định là “true”"
+msgstr "nhánh chưa được quản lý.%s.rebase=%s; giả định là 'true'"
 
 #, c-format
 msgid "Could not get fetch map for refspec %s"
@@ -10366,11 +10631,11 @@
 
 #, c-format
 msgid "could not set '%s'"
-msgstr "không thể đặt “%s”"
+msgstr "không thể đặt '%s'"
 
 #, c-format
 msgid "could not unset '%s'"
-msgstr "không thể thôi đặt “%s”"
+msgstr "không thể thôi đặt '%s'"
 
 #, c-format
 msgid ""
@@ -10380,15 +10645,15 @@
 msgstr ""
 "Cấu hình %s remote.pushDefault trong:\n"
 "\t%s:%d\n"
-"bây giờ tên trên máy chủ không tồn tại “%s”"
+"bây giờ tên trên máy chủ không tồn tại '%s'"
 
 #, c-format
 msgid "No such remote: '%s'"
-msgstr "Không có máy chủ nào như vậy: “%s”"
+msgstr "Không có máy chủ nào như vậy: '%s'"
 
 #, c-format
 msgid "Could not rename config section '%s' to '%s'"
-msgstr "Không thể đổi tên phần của cấu hình từ “%s” thành “%s”"
+msgstr "Không thể đổi tên phần của cấu hình từ '%s' thành '%s'"
 
 #, c-format
 msgid ""
@@ -10396,20 +10661,20 @@
 "\t%s\n"
 "\tPlease update the configuration manually if necessary."
 msgstr ""
-"Không cập nhật “non-default fetch respec”\n"
+"Không cập nhật tham chiếu fetch không mặc định\n"
 "\t%s\n"
-"\tXin hãy cập nhật phần cấu hình một cách thủ công nếu thấy cần thiết."
+"\tXin hãy cập nhật phần cấu hình một cách thủ công nếu cần."
 
 msgid "Renaming remote references"
 msgstr "Đổi tên các tham chiếu máy chủ"
 
 #, c-format
 msgid "deleting '%s' failed"
-msgstr "gặp lỗi khi xóa “%s”"
+msgstr "gặp lỗi khi xóa '%s'"
 
 #, c-format
 msgid "creating '%s' failed"
-msgstr "gặp lỗi khi tạo “%s”"
+msgstr "gặp lỗi khi tạo '%s'"
 
 msgid ""
 "Note: A branch outside the refs/remotes/ hierarchy was not removed;\n"
@@ -10424,7 +10689,7 @@
 
 #, c-format
 msgid "Could not remove config section '%s'"
-msgstr "Không thể gỡ bỏ phần cấu hình “%s”"
+msgstr "Không thể gỡ bỏ phần cấu hình '%s'"
 
 #, c-format
 msgid " new (next fetch will store in remotes/%s)"
@@ -10433,8 +10698,11 @@
 msgid " tracked"
 msgstr " được theo dõi"
 
+msgid " skipped"
+msgstr " được bỏ qua"
+
 msgid " stale (use 'git remote prune' to remove)"
-msgstr " cũ rích (dùng “git remote prune” để gỡ bỏ)"
+msgstr " đã cũ (dùng 'git remote prune' để xoá bỏ)"
 
 msgid " ???"
 msgstr " ???"
@@ -10546,15 +10814,15 @@
 
 msgid "  Local branch configured for 'git pull':"
 msgid_plural "  Local branches configured for 'git pull':"
-msgstr[0] "  Những nhánh nội bộ đã được cấu hình cho lệnh “git pull”:"
+msgstr[0] "  Những nhánh nội bộ đã được cấu hình cho lệnh 'git pull':"
 
 msgid "  Local refs will be mirrored by 'git push'"
-msgstr "  refs nội bộ sẽ được phản chiếu bởi lệnh “git push”"
+msgstr "  refs nội bộ sẽ được phản chiếu bởi lệnh 'git push'"
 
 #, c-format
 msgid "  Local ref configured for 'git push'%s:"
 msgid_plural "  Local refs configured for 'git push'%s:"
-msgstr[0] "  Những tham chiếu nội bộ được cấu hình cho lệnh “git push”%s:"
+msgstr[0] "  Những tham chiếu nội bộ được cấu hình cho lệnh 'git push'%s:"
 
 msgid "set refs/remotes/<name>/HEAD according to remote"
 msgstr "đặt refs/remotes/<tên>/HEAD cho phù hợp với máy chủ"
@@ -10609,7 +10877,7 @@
 
 #, c-format
 msgid "No such remote '%s'"
-msgstr "Không có máy chủ nào có tên “%s”"
+msgstr "Không có máy chủ nào có tên '%s'"
 
 msgid "add branch"
 msgstr "thêm nhánh"
@@ -10625,10 +10893,10 @@
 
 #, c-format
 msgid "no URLs configured for remote '%s'"
-msgstr "không có URL nào được cấu hình cho nhánh “%s”"
+msgstr "không có URL nào được cấu hình cho nhánh '%s'"
 
 msgid "manipulate push URLs"
-msgstr "đẩy các “URL” bằng tay"
+msgstr "đẩy các 'URL' bằng tay"
 
 msgid "add URL"
 msgstr "thêm URL"
@@ -10665,35 +10933,45 @@
 
 msgid "could not start pack-objects to repack promisor objects"
 msgstr ""
-"không thể lấy thông tin thống kê pack-objects để mà đóng gói lại các đối "
-"tượng hứa hẹn"
+"không thể lấy thông tin thống kê pack-objects để đóng gói lại các đối tượng "
+"promisor"
+
+msgid "failed to feed promisor objects to pack-objects"
+msgstr "gặp lỗi khi đưa promisor object cho pack-objects"
 
 msgid "repack: Expecting full hex object ID lines only from pack-objects."
 msgstr ""
-"repack: Đang chỉ cần các dòng ID đối tượng dạng thập lục phân đầy dủ từ pack-"
-"objects."
+"repack: Đang chỉ cần các dòng ID đối tượng dạng hexa đầy đủ từ pack-objects."
 
 msgid "could not finish pack-objects to repack promisor objects"
-msgstr "không thể hoàn tất pack-objects để đóng gói các đối tượng hứa hẹn"
+msgstr "không thể hoàn tất pack-objects để đóng gói các đối tượng promisor"
 
 #, c-format
 msgid "cannot open index for %s"
-msgstr "không thể mở mục lục cho “%s”"
+msgstr "không thể mở chỉ mục cho %s"
 
 #, c-format
 msgid "pack %s too large to consider in geometric progression"
-msgstr "gói %s là quá lớn để được xem là trong tiến trình hình học"
+msgstr "gói %s quá lớn để xem xét cấp số nhân"
 
 #, c-format
 msgid "pack %s too large to roll up"
-msgstr "gói %s là quá lớn để được cuộn lại"
+msgstr "gói %s quá lớn để cuộn lại"
 
 #, c-format
 msgid "could not open tempfile %s for writing"
 msgstr "không thể mở tập tin tạm %s để ghi"
 
 msgid "could not close refs snapshot tempfile"
-msgstr "không thể đóng tập tin tạm thời chụp nhanh các tham chiếu"
+msgstr "không thể đóng tập tin snapshot các tham chiếu"
+
+#, c-format
+msgid "could not remove stale bitmap: %s"
+msgstr "không thể xoá bỏ bitmap đã cũ: %s"
+
+#, c-format
+msgid "pack prefix %s does not begin with objdir %s"
+msgstr "tiền tố gói '%s' không được bắt đầu với objdir '.%s'"
 
 msgid "pack everything in a single pack"
 msgstr "đóng gói mọi thứ trong một gói đơn"
@@ -10708,8 +10986,8 @@
 msgid "approxidate"
 msgstr "ngày ước tính"
 
-msgid "with -C, expire objects older than this"
-msgstr "với -C, các đối tượng hết hạn cũ hơn khoảng này"
+msgid "with --cruft, expire objects older than this"
+msgstr "với --cruft, đánh dấu hết hạn các đối tượng cũ hơn khoảng này"
 
 msgid "remove redundant packs, and run git-prune-packed"
 msgstr "xóa bỏ các gói dư thừa, và chạy git-prune-packed"
@@ -10727,7 +11005,7 @@
 msgstr "chuyển --local cho git-pack-objects"
 
 msgid "write bitmap index"
-msgstr "ghi mục lục ánh xạ"
+msgstr "ghi chỉ mục ánh xạ"
 
 msgid "pass --delta-islands to git-pack-objects"
 msgstr "chuyển --delta-islands cho git-pack-objects"
@@ -10739,7 +11017,7 @@
 msgstr "với -a, đóng gói lại các đối tượng không thể đọc được"
 
 msgid "size of the window used for delta compression"
-msgstr "kích thước cửa sổ được dùng cho nén “delta”"
+msgstr "kích thước cửa sổ được dùng cho nén 'delta'"
 
 msgid "bytes"
 msgstr "byte"
@@ -10748,7 +11026,7 @@
 msgstr "giống như trên, nhưng giới hạn kích thước bộ nhớ hay vì số lượng"
 
 msgid "limits the maximum delta depth"
-msgstr "giới hạn độ sâu tối đa của “delta”"
+msgstr "giới hạn độ sâu tối đa của 'delta'"
 
 msgid "limits the maximum number of threads"
 msgstr "giới hạn số lượng tối đa tuyến trình"
@@ -10766,25 +11044,35 @@
 msgstr "tìm một tiến trình hình học với hệ số <N>"
 
 msgid "write a multi-pack index of the resulting packs"
-msgstr "ghi mục lục “multi-pack” của các gói kết quả"
+msgstr "ghi chỉ mục 'multi-pack' của các gói kết quả"
+
+msgid "pack prefix to store a pack containing pruned objects"
+msgstr "tiền tố của gói để lưu gói gồm những đối tượng đã loại bỏ"
+
+msgid "pack prefix to store a pack containing filtered out objects"
+msgstr "tiền tố của gói để lưu gói gồm những đối tượng đã lọc bỏ"
 
 msgid "cannot delete packs in a precious-objects repo"
-msgstr "không thể xóa các gói trong một kho đối_tượng_vĩ_đại"
+msgstr "không thể xóa các gói trong một kho đối tượng cần thiết"
+
+#, c-format
+msgid "option '%s' can only be used along with '%s'"
+msgstr "tuỳ chọn '%s' chỉ có thể được dùng với '%s'"
 
 msgid "Nothing new to pack."
-msgstr "Không có gì mới để mà đóng gói."
+msgstr "Không có gì mới để đóng gói."
 
 #, c-format
-msgid "pack prefix %s does not begin with objdir %s"
-msgstr "tiền tố gói “%s” không được bắt đầu với objdir “.%s”"
+msgid "renaming pack to '%s' failed"
+msgstr "gặp lỗi khi đổi tên gói thành '%s'"
 
 #, c-format
-msgid "missing required file: %s"
-msgstr "thiếu tập tin cần thiết: %s"
+msgid "pack-objects did not write a '%s' file for pack %s-%s"
+msgstr "pack-objects không ghi tập tin '%s' cho gói %s-%s"
 
 #, c-format
 msgid "could not unlink: %s"
-msgstr "không thể bỏ liên kết: %s"
+msgstr "không thể unlink: %s"
 
 msgid "git replace [-f] <object> <replacement>"
 msgstr "git replace [-f] <đối-tượng> <thay-thế>"
@@ -10793,37 +11081,37 @@
 msgstr "git replace [-f] --edit <đối tượng>"
 
 msgid "git replace [-f] --graft <commit> [<parent>...]"
-msgstr "git replace [-f] --graft <lần_chuyển_giao> [<cha_mẹ>…]"
+msgstr "git replace [-f] --graft <lần_chuyển_giao> [<cha_mẹ>...]"
 
 msgid "git replace -d <object>..."
-msgstr "git replace -d <đối tượng>…"
+msgstr "git replace -d <đối tượng>..."
 
 msgid "git replace [--format=<format>] [-l [<pattern>]]"
-msgstr "git replace [--format=<định_dạng>] [-l [<mẫu>]]"
+msgstr "git replace [--format=<định dạng>] [-l [<mẫu>]]"
 
 #, c-format
 msgid ""
 "invalid replace format '%s'\n"
 "valid formats are 'short', 'medium' and 'long'"
 msgstr ""
-"định dạng thay thế không hợp lệ “%s”\n"
-"định dạng hợp lệ là “short”, “medium” và “long”"
+"định dạng thay thế không hợp lệ '%s'\n"
+"định dạng hợp lệ là 'short', 'medium' và 'long'"
 
 #, c-format
 msgid "replace ref '%s' not found"
-msgstr "không tìm thấy tham chiếu thay thế “%s”"
+msgstr "không tìm thấy tham chiếu thay thế '%s'"
 
 #, c-format
 msgid "Deleted replace ref '%s'"
-msgstr "Đã xóa tham chiếu thay thế “%s”"
+msgstr "Đã xóa tham chiếu thay thế '%s'"
 
 #, c-format
 msgid "'%s' is not a valid ref name"
-msgstr "“%s” không phải tên tham chiếu hợp lệ"
+msgstr "'%s' không phải tên tham chiếu hợp lệ"
 
 #, c-format
 msgid "replace ref '%s' already exists"
-msgstr "tham chiếu thay thế “%s” đã tồn tại rồi"
+msgstr "tham chiếu thay thế '%s' đã tồn tại rồi"
 
 #, c-format
 msgid ""
@@ -10832,19 +11120,19 @@
 "while '%s' points to a replacement object of type '%s'."
 msgstr ""
 "Các đối tượng phải cùng kiểu.\n"
-"“%s” chỉ đến đối tượng thay thế của kiểu “%s”\n"
-"trong khi “%s” chỉ đến đối tượng tham chiếu của kiểu “%s”."
+"'%s' chỉ đến đối tượng thay thế của kiểu '%s'\n"
+"trong khi '%s' chỉ đến đối tượng tham chiếu của kiểu '%s'."
 
 #, c-format
 msgid "unable to open %s for writing"
-msgstr "không thể mở “%s” để ghi"
+msgstr "không thể mở '%s' để ghi"
 
 msgid "cat-file reported failure"
-msgstr "cat-file đã báo cáo gặp lỗi nghiêm trọng"
+msgstr "cat-file đã báo nghiêm trọng"
 
 #, c-format
 msgid "unable to open %s for reading"
-msgstr "không thể mở “%s” để đọc"
+msgstr "không thể mở '%s' để đọc"
 
 msgid "unable to spawn mktree"
 msgstr "không thể sinh tiến trình con mktree"
@@ -10853,7 +11141,7 @@
 msgstr "không thể đọc từ mktree"
 
 msgid "mktree reported failure"
-msgstr "mktree đã báo cáo gặp lỗi nghiêm trọng"
+msgstr "mktree đã báo lỗi nghiêm trọng"
 
 msgid "mktree did not return an object name"
 msgstr "mktree đã không trả về một tên đối tượng"
@@ -10874,46 +11162,46 @@
 
 #, c-format
 msgid "new object is the same as the old one: '%s'"
-msgstr "đối tượng mới là giống với cái cũ: “%s”"
+msgstr "đối tượng mới là giống với cái cũ: '%s'"
 
 #, c-format
 msgid "could not parse %s as a commit"
-msgstr "không thể phân tích %s như là một lần chuyển giao"
+msgstr "không thể đọc %s như là một lần chuyển giao"
 
 #, c-format
 msgid "bad mergetag in commit '%s'"
-msgstr "thẻ hòa trộn sai trong lần chuyển giao “%s”"
+msgstr "thẻ hòa trộn sai trong lần chuyển giao '%s'"
 
 #, c-format
 msgid "malformed mergetag in commit '%s'"
-msgstr "thẻ hòa trộn không đúng dạng ở lần chuyển giao “%s”"
+msgstr "thẻ hòa trộn bất thường dạng ở lần chuyển giao '%s'"
 
 #, c-format
 msgid ""
 "original commit '%s' contains mergetag '%s' that is discarded; use --edit "
 "instead of --graft"
 msgstr ""
-"lần chuyển giao gốc “%s” có chứa thẻ hòa trộn “%s” cái mà bị loại bỏ; dùng "
-"tùy chọn --edit thay cho --graft"
+"lần chuyển giao gốc '%s' có chứa thẻ hòa trộn '%s' đã bị loại bỏ; dùng tùy "
+"chọn --edit thay cho --graft"
 
 #, c-format
 msgid "the original commit '%s' has a gpg signature"
-msgstr "lần chuyển giao gốc “%s” có chữ ký GPG"
+msgstr "lần chuyển giao gốc '%s' có chữ ký GPG"
 
 msgid "the signature will be removed in the replacement commit!"
 msgstr "chữ ký sẽ được bỏ đi trong lần chuyển giao thay thế!"
 
 #, c-format
 msgid "could not write replacement commit for: '%s'"
-msgstr "không thể ghi lần chuyển giao thay thế cho: “%s”"
+msgstr "không thể ghi lần chuyển giao thay thế cho: '%s'"
 
 #, c-format
 msgid "graft for '%s' unnecessary"
-msgstr "graft cho “%s” không cần thiết"
+msgstr "graft cho '%s' không cần thiết"
 
 #, c-format
 msgid "new commit is the same as the old one: '%s'"
-msgstr "lần chuyển giao mới là giống với cái cũ: “%s”"
+msgstr "lần chuyển giao mới là giống với cái cũ: '%s'"
 
 #, c-format
 msgid ""
@@ -10974,19 +11262,85 @@
 msgid "only one pattern can be given with -l"
 msgstr "chỉ một mẫu được chỉ ra với tùy chọn -l"
 
-msgid "git rerere [clear | forget <path>... | status | remaining | diff | gc]"
+msgid "need some commits to replay"
+msgstr "cần các chuyển giao để phát lại"
+
+msgid "--onto and --advance are incompatible"
+msgstr "--onto và --advance xung khắc"
+
+msgid "all positive revisions given must be references"
+msgstr "mọi điểm xét duyệt cộng thêm phải là tên tham chiếu"
+
+msgid "argument to --advance must be a reference"
+msgstr "tham số cho --advance phải là tham chiếu"
+
+msgid ""
+"cannot advance target with multiple sources because ordering would be ill-"
+"defined"
+msgstr "không thể đẩy nhánh với nhiều nguồn vì thứ tự không xác định"
+
+msgid ""
+"cannot implicitly determine whether this is an --advance or --onto operation"
+msgstr "không thể tự xác định là thực hiện --advance hay --onto"
+
+msgid ""
+"cannot advance target with multiple source branches because ordering would "
+"be ill-defined"
+msgstr "không thể đẩy nhánh với nhiều nhánh nguồn vì thứ tự không xác định"
+
+msgid "cannot implicitly determine correct base for --onto"
+msgstr "không thể tự xác định gốc thực hiện --onto"
+
+msgid ""
+"(EXPERIMENTAL!) git replay ([--contained] --onto <newbase> | --advance "
+"<branch>) <revision-range>..."
 msgstr ""
-"git rerere [clear | forget <đường dẫn>… | status | remaining | diff | gc]"
+"(TRONG QUÁ TRÌNH THỬ NGHIỆM!) git replay ([--contained] --onto <gốc mới>  | "
+"--advance <nhánh>) <khoảng-xét-duyệt>..."
+
+msgid "make replay advance given branch"
+msgstr "đẩy nhánh này trong khi phát lại"
+
+msgid "replay onto given commit"
+msgstr "phát lại vào commit này"
+
+msgid "advance all branches contained in revision-range"
+msgstr "đẩy tất cả các nhánh có trong khoảng-xét-duyệt "
+
+msgid "option --onto or --advance is mandatory"
+msgstr "tuỳ chọn --onto hoặc --advance là bắt buộc"
+
+#, c-format
+msgid ""
+"some rev walking options will be overridden as '%s' bit in 'struct rev_info' "
+"will be forced"
+msgstr ""
+"một số tuỳ chọn duyệt qua điểm xét duyệt sẽ bị bỏ qua do bit '%s' trong "
+"'struct rev_info' bị ép bật/tắt"
+
+msgid "error preparing revisions"
+msgstr "gặp lỗi khi chuẩn bị các điểm xét duyệt"
+
+msgid "replaying down to root commit is not supported yet!"
+msgstr "chưa hỗ trợ phát lại đến lần chuyển giao gốc!"
+
+msgid "replaying merge commits is not supported yet!"
+msgstr "chưa hỗ trợ phát lại các lần hoà trộn!"
+
+msgid ""
+"git rerere [clear | forget <pathspec>... | diff | status | remaining | gc]"
+msgstr ""
+"git rerere [clear | forget <đường dẫn>... | diff | status | remaining | gc]"
 
 msgid "register clean resolutions in index"
-msgstr "sổ ghi dọn sạch các phân giải trong bản mục lục"
+msgstr "ghi lại các lần giải quyết ổn thoả xung đột trong chỉ mục"
 
 msgid "'git rerere forget' without paths is deprecated"
-msgstr "“git rerere forget” mà không có các đường dẫn là đã lạc hậu"
+msgstr "không còn dùng 'git rerere forget' mà không có các đường dẫn"
 
 #, c-format
 msgid "unable to generate diff for '%s'"
-msgstr "không thể tạo khác biệt cho “%s”"
+msgstr "không thể tạo diff cho '%s'"
 
 msgid ""
 "git reset [--mixed | --soft | --hard | --merge | --keep] [-q] [<commit>]"
@@ -10994,7 +11348,7 @@
 "git reset [--mixed | --soft | --hard | --merge | --keep] [-q] [<commit>]"
 
 msgid "git reset [-q] [<tree-ish>] [--] <pathspec>..."
-msgstr "git reset [-q] [<tree-ish>] [--] <đặc/tả/đường/dẫn>…"
+msgstr "git reset [-q] [<tree-ish>] [--] <đặc/tả/đường/dẫn>..."
 
 msgid ""
 "git reset [-q] [--pathspec-from-file [--pathspec-file-nul]] [<tree-ish>]"
@@ -11002,7 +11356,7 @@
 "git reset [-q] [--pathspec-from-file [--pathspec-file-nul]] [<tree-ish>]"
 
 msgid "git reset --patch [<tree-ish>] [--] [<pathspec>...]"
-msgstr "git reset --patch [<tree-ish>] [--] [<đặc/tả/đường/dẫn>…]"
+msgstr "git reset --patch [<tree-ish>] [--] [<đặc/tả/đường/dẫn>...]"
 
 msgid "mixed"
 msgstr "pha trộn"
@@ -11041,16 +11395,16 @@
 msgstr "làm việc ở chế độ im lặng, chỉ hiển thị khi có lỗi"
 
 msgid "skip refreshing the index after reset"
-msgstr "bỏ qua làm tươi mục lục sau khi đặt lại"
+msgstr "bỏ qua làm mới chỉ mục sau khi reset"
 
 msgid "reset HEAD and index"
-msgstr "đặt lại (reset) HEAD và bảng mục lục"
+msgstr "đặt lại HEAD và chỉ mục"
 
 msgid "reset only HEAD"
-msgstr "chỉ đặt lại (reset) HEAD"
+msgstr "chỉ đặt lại HEAD"
 
 msgid "reset HEAD, index and working tree"
-msgstr "đặt lại HEAD, bảng mục lục và cây làm việc"
+msgstr "đặt lại HEAD, chỉ mục và cây làm việc"
 
 msgid "reset HEAD but keep local changes"
 msgstr "đặt lại HEAD nhưng giữ lại các thay đổi nội bộ"
@@ -11060,16 +11414,16 @@
 
 #, c-format
 msgid "Failed to resolve '%s' as a valid revision."
-msgstr "Gặp lỗi khi phân giải “%s” như là điểm xét duyệt hợp lệ."
+msgstr "Gặp lỗi khi phân giải '%s' thành điểm xét duyệt hợp lệ."
 
 #, c-format
 msgid "Failed to resolve '%s' as a valid tree."
-msgstr "Gặp lỗi khi phân giải “%s” như là một cây (tree) hợp lệ."
+msgstr "Gặp lỗi khi phân giải '%s' như là một cây (tree) hợp lệ."
 
 msgid "--mixed with paths is deprecated; use 'git reset -- <paths>' instead."
 msgstr ""
-"--mixed với các đường dẫn không còn dùng nữa; hãy thay thế bằng lệnh “git "
-"reset -- </các/đường/dẫn>”."
+"không cho dùng --mixed với các đường dẫn nữa; hãy thay thế bằng lệnh 'git "
+"reset -- </các/đường/dẫn>'."
 
 #, c-format
 msgid "Cannot do %s reset with paths."
@@ -11077,7 +11431,7 @@
 
 #, c-format
 msgid "%s reset is not allowed in a bare repository"
-msgstr "%s reset không được phép trên kho thuần"
+msgstr "%s reset không được phép trên kho chứa bare"
 
 msgid "Unstaged changes after reset:"
 msgstr "Những thay đổi được đưa ra khỏi bệ phóng sau khi reset:"
@@ -11087,21 +11441,25 @@
 "It took %.2f seconds to refresh the index after reset.  You can use\n"
 "'--no-refresh' to avoid this."
 msgstr ""
-"Việc này cần %.2f giây để làm tươi mới mục lục sau khi đặt lại. Bạn có thể "
+"Việc này cần %.2f giây để làm tươi mới chỉ mục sau khi đặt lại. Bạn có thể "
 "sử dụng\n"
-"“--no-refresh” tránh điều này."
+"'--no-refresh' tránh điều này."
 
 #, c-format
 msgid "Could not reset index file to revision '%s'."
-msgstr "Không thể đặt lại (reset) bảng mục lục thành điểm xét duyệt “%s”."
+msgstr "Không thể đặt lại (reset) chỉ mục thành điểm xét duyệt '%s'."
 
 msgid "Could not write new index file."
-msgstr "Không thể ghi tập tin lưu bảng mục lục mới."
+msgstr "Không thể ghi tập tin chỉ mục mới."
 
 #, c-format
 msgid "unable to get disk usage of %s"
 msgstr "không thể dung lượng đĩa đã dùng của %s"
 
+#, c-format
+msgid "invalid value for '%s': '%s', the only allowed format is '%s'"
+msgstr "giá trị không hợp lệ cho '%s': '%s', chỉ cho phép định dạng là '%s'"
+
 msgid "rev-list does not support display of notes"
 msgstr "rev-list không hỗ trợ hiển thị các ghi chú"
 
@@ -11110,22 +11468,25 @@
 msgstr "đánh dấu để đếm và '%s' không thể dùng cùng nhau"
 
 msgid "git rev-parse --parseopt [<options>] -- [<args>...]"
-msgstr "git rev-parse --parseopt [<các tùy chọn>] -- [<các tham số>…]"
+msgstr "git rev-parse --parseopt [<các tùy chọn>] -- [<các tham số>...]"
 
 msgid "keep the `--` passed as an arg"
-msgstr "giữ lại “--” chuyển sang làm tham số"
+msgstr "giữ lại '--' chuyển sang làm tham số"
 
 msgid "stop parsing after the first non-option argument"
-msgstr "dừng phân tích sau đối số đầu tiên không có tùy chọn"
+msgstr "dừng đọc sau đối số đầu tiên không có tùy chọn"
 
 msgid "output in stuck long form"
 msgstr "kết xuất trong định dạng gậy dài"
 
 msgid "premature end of input"
-msgstr "đầu vào chấm dứt bất thường"
+msgstr "đầu vào kết thúc bất thường"
 
 msgid "no usage string given before the `--' separator"
-msgstr "không có chuỗi cách dùng nào được đưa ra trước dấu phân cách “--”"
+msgstr "không có chuỗi cách dùng nào được đưa ra trước dấu phân cách '--'"
+
+msgid "missing opt-spec before option flags"
+msgstr "thiếu opt-spec trước các tuỳ chọn"
 
 msgid "Needed a single revision"
 msgstr "Cần một điểm xét duyệt đơn"
@@ -11137,9 +11498,9 @@
 "\n"
 "Run \"git rev-parse --parseopt -h\" for more information on the first usage."
 msgstr ""
-"git rev-parse --parseopt [<các tùy chọn>] -- [<các đối số>…]\n"
-"   hoặc: git rev-parse --sq-quote [<đ.số>…]\n"
-"   hoặc: git rev-parse [<các tùy chọn>] [<đ.số>…]\n"
+"git rev-parse --parseopt [<các tùy chọn>] -- [<các đối số>...]\n"
+"   hoặc: git rev-parse --sq-quote [<đ.số>...]\n"
+"   hoặc: git rev-parse [<các tùy chọn>] [<đ.số>...]\n"
 "\n"
 "Chạy lệnh \"git rev-parse --parseopt -h\" để có thêm thông tin về cách dùng."
 
@@ -11148,7 +11509,7 @@
 
 #, c-format
 msgid "not a gitdir '%s'"
-msgstr "không phải một thư mục git “%s”"
+msgstr "không phải một thư mục git '%s'"
 
 msgid "--git-path requires an argument"
 msgstr "--git-path cần một tham số"
@@ -11169,6 +11530,13 @@
 msgid "--prefix requires an argument"
 msgstr "--prefix cần một tham số"
 
+msgid "no object format specified"
+msgstr "không chỉ ra định dạng đối tượng"
+
+#, c-format
+msgid "unsupported object format: %s"
+msgstr "không hỗ trợ định dạng đối tượng: %s"
+
 #, c-format
 msgid "unknown mode for --abbrev-ref: %s"
 msgstr "không hiểu chế độ cho --abbrev-ref: %s"
@@ -11176,25 +11544,36 @@
 msgid "this operation must be run in a work tree"
 msgstr "thao tác này phải được thực hiện trong thư mục làm việc"
 
+msgid "Could not read the index"
+msgstr "Không thể đọc chỉ mục"
+
 #, c-format
 msgid "unknown mode for --show-object-format: %s"
 msgstr "không hiểu chế độ cho --show-object-format: %s"
 
-msgid "git revert [<options>] <commit-ish>..."
-msgstr "git revert [<các tùy chọn>] <commit-ish>…"
+msgid ""
+"git revert [--[no-]edit] [-n] [-m <parent-number>] [-s] [-S[<keyid>]] "
+"<commit>..."
+msgstr ""
+"git revert [--[no-]edit] [-n] [-m <parent-number>] [-s] [-S[<keyid>]] "
+"<commit>..."
 
-msgid "git revert <subcommand>"
-msgstr "git revert <lệnh-con>"
+msgid "git revert (--continue | --skip | --abort | --quit)"
+msgstr "git revert (--continue | --skip | --abort | --quit)"
 
-msgid "git cherry-pick [<options>] <commit-ish>..."
-msgstr "git cherry-pick [<các tùy chọn>] <commit-ish>…"
+msgid ""
+"git cherry-pick [--edit] [-n] [-m <parent-number>] [-s] [-x] [--ff]\n"
+"                [-S[<keyid>]] <commit>..."
+msgstr ""
+"git cherry-pick [--edit] [-n] [-m <parent-number>] [-s] [-x] [--ff]\n"
+"                [-S[<keyid>]] <commit>..."
 
-msgid "git cherry-pick <subcommand>"
-msgstr "git cherry-pick <lệnh-con>"
+msgid "git cherry-pick (--continue | --skip | --abort | --quit)"
+msgstr "git cherry-pick (--continue | --skip | --abort | --quit)"
 
 #, c-format
 msgid "option `%s' expects a number greater than zero"
-msgstr "tùy chọn “%s” cần một giá trị bằng số lớn hơn không"
+msgstr "tùy chọn '%s' cần một giá trị bằng số lớn hơn không"
 
 #, c-format
 msgid "%s: %s cannot be used with %s"
@@ -11239,8 +11618,8 @@
 msgid "allow commits with empty messages"
 msgstr "chấp nhận chuyển giao mà không ghi chú gì"
 
-msgid "keep redundant, empty commits"
-msgstr "giữ lại các lần chuyển giao dư thừa, rỗng"
+msgid "deprecated: use --empty=keep instead"
+msgstr "đã lạc hậu: hãy dùng --empty=keep"
 
 msgid "use the 'reference' format to refer to commits"
 msgstr "dùng định dạng 'tham chiếu' để quy cho các lần chuyển giao"
@@ -11251,8 +11630,14 @@
 msgid "cherry-pick failed"
 msgstr "cherry-pick gặp lỗi"
 
-msgid "git rm [<options>] [--] <file>..."
-msgstr "git rm [<các tùy chọn>] [--] <tập-tin>…"
+msgid ""
+"git rm [-f | --force] [-n] [-r] [--cached] [--ignore-unmatch]\n"
+"       [--quiet] [--pathspec-from-file=<file> [--pathspec-file-nul]]\n"
+"       [--] [<pathspec>...]"
+msgstr ""
+"git rm [-f | --force] [-n] [-r] [--cached] [--ignore-unmatch]\n"
+"       [--quiet] [--pathspec-from-file=<tập tin> [--pathspec-file-nul]]\n"
+"       [--] [<đặc/tả/đường/dẫn>...]]"
 
 msgid ""
 "the following file has staged content different from both the\n"
@@ -11273,7 +11658,7 @@
 
 msgid "the following file has changes staged in the index:"
 msgid_plural "the following files have changes staged in the index:"
-msgstr[0] "các tập tin sau đây có thay đổi trạng thái trong bảng mục lục:"
+msgstr[0] "các tập tin sau đây có thay đổi trạng thái trong chỉ mục:"
 
 msgid ""
 "\n"
@@ -11290,13 +11675,13 @@
 msgstr "không liệt kê các tập tin đã gỡ bỏ"
 
 msgid "only remove from the index"
-msgstr "chỉ gỡ bỏ từ mục lục"
+msgstr "chỉ gỡ bỏ từ chỉ mục"
 
 msgid "override the up-to-date check"
 msgstr "ghi đè lên kiểm tra cập nhật"
 
 msgid "allow recursive removal"
-msgstr "cho phép gỡ bỏ đệ qui"
+msgstr "cho phép gỡ bỏ đệ quy"
 
 msgid "exit with a zero status even if nothing matched"
 msgstr "thoát ra với trạng thái khác không thậm chí nếu không có gì khớp"
@@ -11310,7 +11695,7 @@
 
 #, c-format
 msgid "not removing '%s' recursively without -r"
-msgstr "không thể gỡ bỏ “%s” một cách đệ qui mà không có tùy chọn -r"
+msgstr "không thể gỡ bỏ '%s' một cách đệ quy mà không có tùy chọn -r"
 
 #, c-format
 msgid "git rm: unable to remove %s"
@@ -11320,37 +11705,43 @@
 "git send-pack [--mirror] [--dry-run] [--force]\n"
 "              [--receive-pack=<git-receive-pack>]\n"
 "              [--verbose] [--thin] [--atomic]\n"
+"              [--[no-]signed | --signed=(true|false|if-asked)]\n"
 "              [<host>:]<directory> (--all | <ref>...)"
 msgstr ""
 "git send-pack [--mirror] [--dry-run] [--force]\n"
 "              [--receive-pack=<git-receive-pack>]\n"
 "              [--verbose] [--thin] [--atomic]\n"
-"              [<host>:]<thư mục> (--all | <tham chiếu>…)"
+"              [--[no-]signed | --signed=(true|false|if-asked)]\n"
+"              [<host>:]<thư mục> (--all | <tham chiếu>...)"
 
 msgid "remote name"
 msgstr "tên máy dịch vụ"
 
+msgid "push all refs"
+msgstr "đẩy tất cả các tham chiếu"
+
 msgid "use stateless RPC protocol"
 msgstr "dùng giao thức RPC không ổn định"
 
 msgid "read refs from stdin"
-msgstr "đọc tham chiếu từ đầu vào tiêu chuẩn"
+msgstr "đọc tham chiếu từ stdin"
 
 msgid "print status from remote helper"
 msgstr "in các trạng thái từ phần hướng dẫn trên máy dịch vụ"
 
 msgid "git shortlog [<options>] [<revision-range>] [[--] <path>...]"
-msgstr "git shortlog [<các tùy chọn>] [<vùng-xét-duyệt>] [[--] [<đường/dẫn>…]]"
+msgstr ""
+"git shortlog [<các tùy chọn>] [<vùng-xét-duyệt>] [[--] [<đường/dẫn>...]]"
 
 msgid "git log --pretty=short | git shortlog [<options>]"
 msgstr "git log --pretty=short | git shortlog [<các tùy chọn>]"
 
 msgid "using multiple --group options with stdin is not supported"
-msgstr ""
-"việc dùng nhiều tùy chọn --group với đầu ra tiêu chuẩn là không được hỗ trợ"
+msgstr "việc dùng nhiều tùy chọn --group với stdin là không được hỗ trợ"
 
-msgid "using --group=trailer with stdin is not supported"
-msgstr "việc dùng --group=trailer với đầu ra tiêu chuẩn là không được hỗ trợ"
+#, c-format
+msgid "using %s with stdin is not supported"
+msgstr "không hỗ trợ dùng %s cùng stdin"
 
 #, c-format
 msgid "unknown group type: %s"
@@ -11387,15 +11778,17 @@
 "git show-branch [-a | --all] [-r | --remotes] [--topo-order | --date-order]\n"
 "                [--current] [--color[=<when>] | --no-color] [--sparse]\n"
 "                [--more=<n> | --list | --independent | --merge-base]\n"
-"                [--no-name | --sha1-name] [--topics] [(<rev> | <glob>)...]"
+"                [--no-name | --sha1-name] [--topics]\n"
+"                [(<rev> | <glob>)...]"
 msgstr ""
 "git show-branch [-a | --all] [-r | --remotes] [--topo-order | --date-order]\n"
 "                [--current] [--color[=<when>] | --no-color] [--sparse]\n"
 "                [--more=<n> | --list | --independent | --merge-base]\n"
-"                [--no-name | --sha1-name] [--topics] [(<rev> | <glob>)…]"
+"                [--no-name | --sha1-name] [--topics]\n"
+"                [(<rev> | <glob>)...]"
 
 msgid "git show-branch (-g | --reflog)[=<n>[,<base>]] [--list] [<ref>]"
-msgstr "git show-branch (-g | --reflog)[=<n>[,<nền>]] [--list] [<ref>]"
+msgstr "git show-branch (-g | --reflog)[=<n>[,<base>]] [--list] [<ref>]"
 
 #, c-format
 msgid "ignoring %s; cannot handle more than %d ref"
@@ -11413,7 +11806,7 @@
 msgstr "hiển thị các nhánh remote-tracking"
 
 msgid "color '*!+-' corresponding to the branch"
-msgstr "màu “*!+-” tương ứng với nhánh"
+msgstr "màu '*!+-' tương ứng với nhánh"
 
 msgid "show <n> more commits after the common ancestor"
 msgstr "hiển thị thêm <n> lần chuyển giao sau cha mẹ chung"
@@ -11431,7 +11824,7 @@
 msgstr "đặt tên các lần chuyển giao bằng các tên của đối tượng của chúng"
 
 msgid "show possible merge bases"
-msgstr "hiển thị mọi cơ sở có thể dùng để hòa trộn"
+msgstr "hiển thị mọi gốc hòa trộn khả dụng"
 
 msgid "show refs unreachable from any other ref"
 msgstr "hiển thị các tham chiếu không thể được đọc bởi bất kỳ tham chiếu khác"
@@ -11443,7 +11836,7 @@
 msgstr "chỉ hiển thị các lần chuyển giao không nằm trên nhánh đầu tiên"
 
 msgid "show merges reachable from only one tip"
-msgstr "hiển thị các lần hòa trộn có thể đọc được chỉ từ một đầu mút"
+msgstr "hiển thị các lần hòa trộn có thể đọc được chỉ từ một đỉnh"
 
 msgid "topologically sort, maintaining date order where possible"
 msgstr "sắp xếp hình thái học, bảo trì thứ tự ngày nếu có thể"
@@ -11452,7 +11845,7 @@
 msgstr "<n>[,<cơ_sở>]"
 
 msgid "show <n> most recent ref-log entries starting at base"
-msgstr "hiển thị <n> các mục “ref-log” gần nhất kể từ nền (base)"
+msgstr "hiển thị <n> các mục 'ref-log' gần nhất kể từ nền (base)"
 
 msgid "no branches given, and HEAD is not valid"
 msgstr "chưa đưa ra nhánh, và HEAD không hợp lệ"
@@ -11476,7 +11869,7 @@
 
 #, c-format
 msgid "'%s' is not a valid ref."
-msgstr "“%s” không phải tham chiếu hợp lệ."
+msgstr "'%s' không phải tham chiếu hợp lệ."
 
 #, c-format
 msgid "cannot find commit %s (%s)"
@@ -11489,61 +11882,83 @@
 msgstr "Không hiểu thuật toán băm dữ liệu"
 
 msgid ""
-"git show-ref [-q | --quiet] [--verify] [--head] [-d | --dereference] [-s | --"
-"hash[=<n>]] [--abbrev[=<n>]] [--tags] [--heads] [--] [<pattern>...]"
+"git show-ref [--head] [-d | --dereference]\n"
+"             [-s | --hash[=<n>]] [--abbrev[=<n>]] [--tags]\n"
+"             [--heads] [--] [<pattern>...]"
 msgstr ""
-"git show-ref [-q | --quiet] [--verify] [--head] [-d | --dereference] [-s | --"
-"hash[=<n>]] [--abbrev[=<n>]] [--tags] [--heads] [--] [<mẫu>…]"
+"git show-ref [--head] [-d | --dereference]\n"
+"             [-s | --hash[=<n>]] [--abbrev[=<n>]] [--tags]\n"
+"             [--heads] [--] [<mẫu>...]"
+
+msgid ""
+"git show-ref --verify [-q | --quiet] [-d | --dereference]\n"
+"             [-s | --hash[=<n>]] [--abbrev[=<n>]]\n"
+"             [--] [<ref>...]"
+msgstr ""
+"git show-ref --verify [-q | --quiet] [-d | --dereference]\n"
+"             [-s | --hash[=<n>]] [--abbrev[=<n>]]\n"
+"             [--] [<mẫu>...]"
 
 msgid "git show-ref --exclude-existing[=<pattern>]"
 msgstr "git show-ref --exclude-existing[=<mẫu>]"
 
+msgid "git show-ref --exists <ref>"
+msgstr "git show-ref --exists <tham_chiếu>"
+
+msgid "reference does not exist"
+msgstr "tham chiếu không tồn tại"
+
+msgid "failed to look up reference"
+msgstr "gặp lỗi khi tìm tham chiếu"
+
 msgid "only show tags (can be combined with heads)"
 msgstr "chỉ hiển thị thẻ (có thể tổ hợp cùng với đầu)"
 
 msgid "only show heads (can be combined with tags)"
 msgstr "chỉ hiển thị đầu (có thể tổ hợp cùng với thẻ)"
 
+msgid "check for reference existence without resolving"
+msgstr "kiểm tra tồn tại tham chiếu nhưng không phân giải"
+
 msgid "stricter reference checking, requires exact ref path"
-msgstr ""
-"việc kiểm tra tham chiếu chính xác, đòi hỏi chính xác đường dẫn tham chiếu"
+msgstr "kiểm tra tham chiếu chính xác, đòi hỏi chính xác đường dẫn tham chiếu"
 
 msgid "show the HEAD reference, even if it would be filtered out"
 msgstr "hiển thị tham chiếu HEAD, ngay cả khi nó đã được lọc ra"
 
 msgid "dereference tags into object IDs"
-msgstr "bãi bỏ tham chiếu các thẻ thành ra các ID đối tượng"
+msgstr "giải tham chiếu các thẻ thành các ID đối tượng"
 
 msgid "only show SHA1 hash using <n> digits"
 msgstr "chỉ hiển thị mã băm SHA1 sử dụng <n> chữ số"
 
 msgid "do not print results to stdout (useful with --verify)"
-msgstr ""
-"không hiển thị kết quả ra đầu ra chuẩn (stdout) (chỉ hữu dụng với --verify)"
+msgstr "không hiển thị kết quả ra stdout (hữu dụng khi dùng cùng --verify)"
 
 msgid "show refs from stdin that aren't in local repository"
-msgstr ""
-"hiển thị các tham chiếu từ đầu vào tiêu chuẩn (stdin) cái mà không ở kho nội "
-"bộ"
+msgstr "hiển thị các tham chiếu từ stdin mà không ở kho nội bộ"
 
-msgid "git sparse-checkout (init|list|set|add|reapply|disable) <options>"
-msgstr "git sparse-checkout (init|list|set|add|reapply|disable) <các-tùy-chọn>"
+msgid ""
+"git sparse-checkout (init | list | set | add | reapply | disable | check-"
+"rules) [<options>]"
+msgstr ""
+"git sparse-checkout (init | list | set | add | reapply | disable | check-"
+"rules) [<các-tùy-chọn>]"
 
 msgid "this worktree is not sparse"
-msgstr "cây làm việc này không phải là sparse"
+msgstr "cây làm việc này không thưa"
 
 msgid "this worktree is not sparse (sparse-checkout file may not exist)"
 msgstr ""
-"không thể phân tích cú pháp cây làm việc này (tập tin sparse-checkout có lẽ "
-"không tồn tại)"
+"cây làm việc này không thưa (tập tin sparse-checkout có lẽ không tồn tại)"
 
 #, c-format
 msgid ""
 "directory '%s' contains untracked files, but is not in the sparse-checkout "
 "cone"
 msgstr ""
-"thư mục “%s” có chứa các tập tin chưa được theo dõi, nhưng lại không trong "
-"“sparse-checkout cone”"
+"thư mục '%s' có chứa các tập tin chưa được theo dõi, nhưng không nằm trong "
+"'sparse-checkout cone' (vùng checkout thưa)"
 
 #, c-format
 msgid "failed to remove directory '%s'"
@@ -11556,35 +11971,35 @@
 msgstr "gặp lỗi khi khởi tạo cấu hình cây làm việc"
 
 msgid "failed to modify sparse-index config"
-msgstr "gặp lỗi khi sửa cấu hình \"sparse-index\""
+msgstr "gặp lỗi khi sửa cấu hình sparse-index"
 
 msgid "initialize the sparse-checkout in cone mode"
 msgstr "khởi tạo sparse-checkout trong chế độ nón"
 
 msgid "toggle the use of a sparse index"
-msgstr "bật tắt việc sử dụng một \"sparse index\""
+msgstr "bật tắt việc sử dụng sparse index"
 
 #, c-format
 msgid "unable to create leading directories of %s"
-msgstr "không thể tạo các thư mục dẫn đầu của “%s”"
+msgstr "không thể tạo các thư mục dẫn đầu của '%s'"
 
 #, c-format
 msgid "failed to open '%s'"
-msgstr "gặp lỗi khi mở “%s”"
+msgstr "gặp lỗi khi mở '%s'"
 
 #, c-format
 msgid "could not normalize path %s"
-msgstr "không thể thường hóa đường dẫn “%s”"
+msgstr "không thể thường hóa đường dẫn '%s'"
 
 #, c-format
 msgid "unable to unquote C-style string '%s'"
-msgstr "không thể bỏ trích dẫn chuỗi kiểu C “%s”"
+msgstr "không thể bỏ trích dẫn chuỗi kiểu C '%s'"
 
 msgid "unable to load existing sparse-checkout patterns"
 msgstr "không thể tải các mẫu sparse-checkout"
 
 msgid "existing sparse-checkout patterns do not use cone mode"
-msgstr "đặt các mẫu sparse-checkout sẵn có không sử dụng chế độ cone"
+msgstr "các mẫu sparse-checkout sẵn có không sử dụng chế độ cone"
 
 msgid "please run from the toplevel directory in non-cone mode"
 msgstr "vui lòng chạy từ thư mục mức cao nhất trong chế độ non-cone"
@@ -11619,8 +12034,8 @@
 "pass a leading slash before paths such as '%s' if you want a single file "
 "(see NON-CONE PROBLEMS in the git-sparse-checkout manual)."
 msgstr ""
-"chuyển một dấu xổ chéo dẫn đầu đường dẫn như là '%s' nếu bạn muốn một tập "
-"tin đơn (xem NON-CONE PROBLEMS trong hướng dẫn sử dụng git-sparse-checkout)."
+"dùng dấu gạch chéo dẫn đầu trước đường dẫn như '%s' nếu bạn muốn một tập tin "
+"đơn lẻ (xem NON-CONE PROBLEMS trong hướng dẫn sử dụng git-sparse-checkout)."
 
 msgid "git sparse-checkout add [--skip-checks] (--stdin | <patterns>)"
 msgstr "git sparse-checkout add [--skip-checks] (--stdin | <các mẫu>)"
@@ -11628,11 +12043,11 @@
 msgid ""
 "skip some sanity checks on the given paths that might give false positives"
 msgstr ""
-"bỏ qua một số kiểm tra đúng mục trên đường dẫn đã cho cái mà có thể đưa ra "
-"xác thực sai"
+"bỏ qua một số tiền kiểm tra có thể không cho kết quả đúng trên các đường dẫn "
+"đã cho"
 
 msgid "read patterns from standard in"
-msgstr "đọc các mẫu từ đầu vào tiêu chuẩn"
+msgstr "đọc các mẫu từ stdin"
 
 msgid "no sparse-checkout to add to"
 msgstr "không có sparse-checkout để thêm vào"
@@ -11645,76 +12060,82 @@
 "(--stdin | <các mẫu>)"
 
 msgid "must be in a sparse-checkout to reapply sparsity patterns"
-msgstr "phải trong một sparse-checkout để áp dụng lại các mẫu sparse"
+msgstr "phải trong sparse-checkout để áp dụng lại các mẫu sparse"
 
 msgid "error while refreshing working directory"
 msgstr "gặp lỗi khi đọc lại thư mục làm việc"
 
-msgid "git stash list [<options>]"
+msgid ""
+"git sparse-checkout check-rules [-z] [--skip-checks][--[no-]cone] [--rules-"
+"file <file>]"
+msgstr ""
+"git sparse-checkout check-rules [-z] [--skip-checks][--[no-]cone] [--rules-"
+"file <tập tin>]"
+
+msgid "terminate input and output files by a NUL character"
+msgstr "kết thúc các bản ghi vào và ra bằng ký tự NULL"
+
+msgid "when used with --rules-file interpret patterns as cone mode patterns"
+msgstr "khi dùng với --rules-file, dùng mẫu ở chế độ cone"
+
+msgid "use patterns in <file> instead of the current ones."
+msgstr "dùng mẫu từ <tập tin> thay vì các mẫu hiện tại"
+
+msgid "git stash list [<log-options>]"
 msgstr "git stash list [<các tùy chọn>]"
 
-msgid "git stash show [<options>] [<stash>]"
-msgstr "git stash show [<các tùy chọn>] <stash>"
+msgid ""
+"git stash show [-u | --include-untracked | --only-untracked] [<diff-"
+"options>] [<stash>]"
+msgstr ""
+"git stash show [-u | --include-untracked | --only-untracked] [<diff-"
+"options>] [<stash>]"
 
-msgid "git stash drop [-q|--quiet] [<stash>]"
-msgstr "git stash drop [-q|--quiet] [<stash>]"
+msgid "git stash drop [-q | --quiet] [<stash>]"
+msgstr "git stash drop [-q | --quiet] [<stash>]"
 
-msgid "git stash ( pop | apply ) [--index] [-q|--quiet] [<stash>]"
-msgstr "git stash ( pop | apply ) [--index] [-q|--quiet] [<stash>]"
+msgid "git stash pop [--index] [-q | --quiet] [<stash>]"
+msgstr "git stash pop [--index] [-q | --quiet] [<stash>]"
+
+msgid "git stash apply [--index] [-q | --quiet] [<stash>]"
+msgstr "git stash apply [--index] [-q | --quiet] [<stash>]"
 
 msgid "git stash branch <branchname> [<stash>]"
 msgstr "git stash branch <tên-nhánh> [<stash>]"
 
+msgid "git stash store [(-m | --message) <message>] [-q | --quiet] <commit>"
+msgstr "git stash store [(-m | --message) <ghi chú>] [-q | --quiet] <commit>"
+
 msgid ""
-"git stash [push [-p|--patch] [-S|--staged] [-k|--[no-]keep-index] [-q|--"
-"quiet]\n"
-"          [-u|--include-untracked] [-a|--all] [-m|--message <message>]\n"
+"git stash [push [-p | --patch] [-S | --staged] [-k | --[no-]keep-index] [-q "
+"| --quiet]\n"
+"          [-u | --include-untracked] [-a | --all] [(-m | --message) "
+"<message>]\n"
 "          [--pathspec-from-file=<file> [--pathspec-file-nul]]\n"
 "          [--] [<pathspec>...]]"
 msgstr ""
-"git stash [push [-p|--patch] [-S|--staged] [-k|--[no-]keep-index] [-q|--"
-"quiet]\n"
-"          [-u|--include-untracked] [-a|--all] [-m|--message <ghi chú>]\n"
-"          [--pathspec-from-file=<tập_tin> [--pathspec-file-nul]]\n"
-"          [--] [<đặc/tả/đường/dẫn>…]]"
+"git stash [push [-p | --patch] [-S | --staged] [-k | --[no-]keep-index] [-q "
+"| --quiet]\n"
+"          [-u | --include-untracked] [-a | --all] [(-m | --message) <ghi "
+"chú>]\n"
+"          [--pathspec-from-file=<tập tin> [--pathspec-file-nul]]\n"
+"          [--] [<đặc/tả/đường/dẫn>...]]"
 
 msgid ""
-"git stash save [-p|--patch] [-S|--staged] [-k|--[no-]keep-index] [-q|--"
-"quiet]\n"
-"          [-u|--include-untracked] [-a|--all] [<message>]"
+"git stash save [-p | --patch] [-S | --staged] [-k | --[no-]keep-index] [-q | "
+"--quiet]\n"
+"          [-u | --include-untracked] [-a | --all] [<message>]"
 msgstr ""
-"git stash save [-p|--patch] [-S|--staged] [-k|--[no-]keep-index] [-q|--"
-"quiet]\n"
-"          [-u|--include-untracked] [-a|--all] [<ghi chú>]"
+"git stash save [-p | --patch] [-S | --staged] [-k | --[no-]keep-index] [-q | "
+"--quiet]\n"
+"          [-u | --include-untracked] [-a | --all] [<ghi chú>]"
 
-msgid "git stash pop [--index] [-q|--quiet] [<stash>]"
-msgstr "git stash pop [--index] [-q|--quiet] [<stash>]"
-
-msgid "git stash apply [--index] [-q|--quiet] [<stash>]"
-msgstr "git stash apply [--index] [-q|--quiet] [<stash>]"
-
-msgid "git stash store [-m|--message <message>] [-q|--quiet] <commit>"
-msgstr "git stash store [-m|--message <ghi chú>] [-q|--quiet] <commit>"
-
-msgid ""
-"git stash [push [-p|--patch] [-k|--[no-]keep-index] [-q|--quiet]\n"
-"          [-u|--include-untracked] [-a|--all] [-m|--message <message>]\n"
-"          [--] [<pathspec>...]]"
-msgstr ""
-"git stash [push [-p|--patch] [-k|--[no-]keep-index] [-q|--quiet]\n"
-"          [-u|--include-untracked] [-a|--all] [-m|--message <lời nhắn>]\n"
-"          [--] [<đặc/tả/đường/dẫn>…]]"
-
-msgid ""
-"git stash save [-p|--patch] [-k|--[no-]keep-index] [-q|--quiet]\n"
-"               [-u|--include-untracked] [-a|--all] [<message>]"
-msgstr ""
-"git stash save [-p|--patch] [-k|--[no-]keep-index] [-q|--quiet]\n"
-"               [-u|--include-untracked] [-a|--all] [<ghi chú>]"
+msgid "git stash create [<message>]"
+msgstr "git stash create [<ghi chú>]"
 
 #, c-format
 msgid "'%s' is not a stash-like commit"
-msgstr "“%s” không phải là lần chuyển giao kiểu-stash (cất đi)"
+msgstr "'%s' không phải là lần chuyển giao kiểu-stash"
 
 #, c-format
 msgid "Too many revisions specified:%s"
@@ -11725,10 +12146,10 @@
 
 #, c-format
 msgid "%s is not a valid reference"
-msgstr "“%s” không phải một tham chiếu hợp lệ"
+msgstr "'%s' không phải một tham chiếu hợp lệ"
 
 msgid "git stash clear with arguments is unimplemented"
-msgstr "git stash clear với các tham số là chưa được thực hiện"
+msgstr "git stash clear với các tham số là chưa được hỗ trợ"
 
 #, c-format
 msgid ""
@@ -11736,7 +12157,8 @@
 "            %s -> %s\n"
 "         to make room.\n"
 msgstr ""
-"CẢNH BÁO: Tệp chưa được theo dõi theo cách của tệp được theo dõi!  Đổi tên\n"
+"CẢNH BÁO: tập tin chưa được theo dõi chắn đường tập tin được theo dõi! Đổi "
+"tên\n"
 "            %s -> %s\n"
 "         để nhường chỗ.\n"
 
@@ -11748,7 +12170,7 @@
 msgstr "không thể tạo diff %s^!."
 
 msgid "conflicts in index. Try without --index."
-msgstr "xung đột trong bảng mục lục. Hãy thử mà không dùng tùy chọn --index."
+msgstr "xung đột trong chỉ mục. Hãy thử mà không dùng tùy chọn --index."
 
 msgid "could not save index tree"
 msgstr "không thể ghi lại cây chỉ mục"
@@ -11758,13 +12180,13 @@
 msgstr "Đang hòa trộn %s với %s"
 
 msgid "Index was not unstashed."
-msgstr "Bảng mục lục đã không được bỏ stash."
+msgstr "chỉ mục đã không được bỏ stash."
 
 msgid "could not restore untracked files from stash"
 msgstr "không thể phục hồi các tập tin chưa theo dõi từ mục cất đi (stash)"
 
 msgid "attempt to recreate the index"
-msgstr "gặp lỗi đọc bảng mục lục"
+msgstr "gặp lỗi đọc chỉ mục"
 
 #, c-format
 msgid "Dropped %s (%s)"
@@ -11776,7 +12198,7 @@
 
 #, c-format
 msgid "'%s' is not a stash reference"
-msgstr "”%s” không phải tham chiếu đến stash"
+msgstr "'%s' không phải tham chiếu đến stash"
 
 msgid "The stash entry is kept in case you need it again."
 msgstr "Các mục tạm cất (stash) được giữ trong trường hợp bạn lại cần nó."
@@ -11785,7 +12207,7 @@
 msgstr "Chưa chỉ ra tên của nhánh"
 
 msgid "failed to parse tree"
-msgstr "gặp lỗi khi phân tích cây"
+msgstr "gặp lỗi khi đọc cây"
 
 msgid "failed to unpack trees"
 msgstr "gặp lỗi khi tháo dỡ cây"
@@ -11816,7 +12238,7 @@
 msgstr "Bạn chưa còn có lần chuyển giao khởi tạo"
 
 msgid "Cannot save the current index state"
-msgstr "Không thể ghi lại trạng thái bảng mục lục hiện hành"
+msgstr "Không thể ghi lại trạng thái chỉ mục hiện hành"
 
 msgid "Cannot save the untracked files"
 msgstr "Không thể ghi lại các tập tin chưa theo dõi"
@@ -11837,7 +12259,7 @@
 msgstr "Không thể dùng --staged và --include-untracked hay --all cùng một lúc"
 
 msgid "Did you forget to 'git add'?"
-msgstr "Có lẽ bạn đã quên “git add ” phải không?"
+msgstr "Có lẽ bạn đã quên 'git add'?"
 
 msgid "No local changes to save"
 msgstr "Không có thay đổi nội bộ nào được ghi lại"
@@ -11850,19 +12272,19 @@
 
 #, c-format
 msgid "Saved working directory and index state %s"
-msgstr "Đã ghi lại thư mục làm việc và trạng thái mục lục %s"
+msgstr "Đã ghi lại thư mục làm việc và trạng thái chỉ mục %s"
 
 msgid "Cannot remove worktree changes"
 msgstr "Không thể gỡ bỏ các thay đổi cây-làm-việc"
 
 msgid "keep index"
-msgstr "giữ nguyên bảng mục lục"
+msgstr "giữ nguyên chỉ mục"
 
 msgid "stash staged changes only"
 msgstr "chỉ tạm cất đi các thay đổi đã đưa lên bệ phóng"
 
 msgid "stash in patch mode"
-msgstr "cất đi ở chế độ miếng vá"
+msgstr "cất đi ở chế độ vá"
 
 msgid "quiet mode"
 msgstr "chế độ im lặng"
@@ -11881,29 +12303,27 @@
 
 #, c-format
 msgid "Expecting a full ref name, got %s"
-msgstr "Cần tên tham chiếu dạng đầy đủ, nhưng lại nhận được %s"
+msgstr "Cần tên tham chiếu dạng đầy đủ, nhưng lại có %s"
+
+#, c-format
+msgid "could not get a repository handle for submodule '%s'"
+msgstr "không thể lấy thẻ quản kho cho mô-đun-con '%s'"
 
 #, c-format
 msgid ""
 "could not look up configuration '%s'. Assuming this repository is its own "
 "authoritative upstream."
 msgstr ""
-"không thể tìm thấy cấu hình “%s”. Coi rằng đây là kho thượng nguồn có quyền "
+"không thể tìm thấy cấu hình '%s'. Coi rằng đây là kho thượng nguồn có quyền "
 "sở hữu chính nó."
 
-msgid "alternative anchor for relative paths"
-msgstr "điểm neo thay thế cho các đường dẫn tương đối"
-
-msgid "git submodule--helper list [--prefix=<path>] [<path>...]"
-msgstr "git submodule--helper list [--prefix=</đường/dẫn>] [</đường/dẫn>…]"
-
 #, c-format
 msgid "No url found for submodule path '%s' in .gitmodules"
-msgstr "Không tìm thấy url cho đường dẫn mô-đun-con “%s” trong .gitmodules"
+msgstr "Không tìm thấy url cho đường dẫn mô-đun-con '%s' trong .gitmodules"
 
 #, c-format
 msgid "Entering '%s'\n"
-msgstr "Đang vào “%s”\n"
+msgstr "Đang vào '%s'\n"
 
 #, c-format
 msgid ""
@@ -11929,44 +12349,44 @@
 msgid "recurse into nested submodules"
 msgstr "đệ quy vào trong mô-đun-con lồng nhau"
 
-msgid "git submodule--helper foreach [--quiet] [--recursive] [--] <command>"
-msgstr "git submodule--helper foreach [--quiet] [--recursive] [--]  <lệnh>"
+msgid "git submodule foreach [--quiet] [--recursive] [--] <command>"
+msgstr "git submodule foreach [--quiet] [--recursive] [--]  <lệnh>"
 
 #, c-format
 msgid "Failed to register url for submodule path '%s'"
-msgstr "Gặp lỗi khi đăng ký url cho đường dẫn mô-đun-con “%s”"
+msgstr "Gặp lỗi khi đăng ký url cho đường dẫn mô-đun-con '%s'"
 
 #, c-format
 msgid "Submodule '%s' (%s) registered for path '%s'\n"
-msgstr "Mô-đun-con “%s” (%s) được đăng ký cho đường dẫn “%s”\n"
+msgstr "Mô-đun-con '%s' (%s) được đăng ký cho đường dẫn '%s'\n"
 
 #, c-format
 msgid "warning: command update mode suggested for submodule '%s'\n"
-msgstr "cảnh báo: chế độ lệnh cập nhật được gợi ý cho mô-đun-con “%s”\n"
+msgstr "cảnh báo: chế độ lệnh cập nhật được gợi ý cho mô-đun-con '%s'\n"
 
 #, c-format
 msgid "Failed to register update mode for submodule path '%s'"
-msgstr "Gặp lỗi khi đăng ký chế độ cập nhật cho đường dẫn mô-đun-con “%s”"
+msgstr "Gặp lỗi khi đăng ký chế độ cập nhật cho đường dẫn mô-đun-con '%s'"
 
 msgid "suppress output for initializing a submodule"
 msgstr "chặn kết xuất của khởi tạo một mô-đun-con"
 
-msgid "git submodule--helper init [<options>] [<path>]"
-msgstr "git submodule--helper init [<các tùy chọn>] [</đường/dẫn>]"
+msgid "git submodule init [<options>] [<path>]"
+msgstr "git submodule init [<các tùy chọn>] [</đường/dẫn>]"
 
 #, c-format
 msgid "no submodule mapping found in .gitmodules for path '%s'"
 msgstr ""
 "không tìm thấy ánh xạ (mapping) mô-đun-con trong .gitmodules cho đường dẫn "
-"“%s”"
+"'%s'"
 
 #, c-format
 msgid "could not resolve HEAD ref inside the submodule '%s'"
-msgstr "không thể phân giải tham chiếu HEAD bên trong mô-đun-con “%s”"
+msgstr "không thể phân giải tham chiếu HEAD bên trong mô-đun-con '%s'"
 
 #, c-format
 msgid "failed to recurse into submodule '%s'"
-msgstr "gặp lỗi khi đệ quy vào trong mô-đun-con “%s”"
+msgstr "gặp lỗi khi đệ quy vào trong mô-đun-con '%s'"
 
 msgid "suppress submodule status output"
 msgstr "chặn kết xuất về tình trạng mô-đun-con"
@@ -11975,15 +12395,12 @@
 "use commit stored in the index instead of the one stored in the submodule "
 "HEAD"
 msgstr ""
-"dùng lần chuyển giao lưu trong mục lục thay cho cái được lưu trong HEAD mô-"
+"dùng lần chuyển giao lưu trong chỉ mục thay cho cái được lưu trong HEAD mô-"
 "đun-con"
 
 msgid "git submodule status [--quiet] [--cached] [--recursive] [<path>...]"
 msgstr ""
-"git submodule status [--quiet] [--cached] [--recursive] [</đường/dẫn>…]"
-
-msgid "git submodule--helper name <path>"
-msgstr "git submodule--helper name </đường/dẫn>"
+"git submodule status [--quiet] [--cached] [--recursive] [</đường/dẫn>...]"
 
 #, c-format
 msgid "* %s %s(blob)->%s(submodule)"
@@ -12001,61 +12418,57 @@
 
 #, c-format
 msgid "couldn't hash object from '%s'"
-msgstr "không thể băm đối tượng từ “%s”"
+msgstr "không thể băm đối tượng từ '%s'"
 
 #, c-format
 msgid "unexpected mode %o\n"
 msgstr "gặp chế độ không như mong chờ %o\n"
 
 msgid "use the commit stored in the index instead of the submodule HEAD"
-msgstr "hùng lần chuyển giao đã lưu trong mục lục thay cho HEAD mô-đun-con"
+msgstr "hùng lần chuyển giao đã lưu trong chỉ mục thay cho HEAD mô-đun-con"
 
 msgid "compare the commit in the index with that in the submodule HEAD"
-msgstr "để so sánh lần trong mục lục với cái trong HEAD mô-đun-con"
+msgstr "để so sánh lần trong chỉ mục với cái trong HEAD mô-đun-con"
 
 msgid "skip submodules with 'ignore_config' value set to 'all'"
 msgstr ""
-"bỏ qua các mô-đun-con với giá trị của “ignore_config” được đặt thành “all”"
+"bỏ qua các mô-đun-con với giá trị của 'ignore_config' được đặt thành 'all'"
 
 msgid "limit the summary size"
 msgstr "giới hạn kích cỡ tổng hợp"
 
-msgid "git submodule--helper summary [<options>] [<commit>] [--] [<path>]"
+msgid "git submodule summary [<options>] [<commit>] [--] [<path>]"
 msgstr ""
-"git submodule--helper summary [<các tùy chọn>] [<lần_chuyển_giao>] [--] [</"
-"đường/dẫn>]"
+"git submodule summary [<các tùy chọn>] [<lần_chuyển_giao>] [--] [</đường/"
+"dẫn>]"
 
 msgid "could not fetch a revision for HEAD"
 msgstr "không thể lấy về một điểm xem xét cho HEAD"
 
 #, c-format
 msgid "Synchronizing submodule url for '%s'\n"
-msgstr "Url mô-đun-con đồng bộ hóa cho “%s”\n"
+msgstr "Url mô-đun-con đồng bộ hóa cho '%s'\n"
 
 #, c-format
 msgid "failed to register url for submodule path '%s'"
-msgstr "gặp lỗi khi đăng ký url cho đường dẫn mô-đun-con “%s”"
-
-#, c-format
-msgid "failed to get the default remote for submodule '%s'"
-msgstr "gặp lỗi khi lấy máy chủ mặc định cho mô-đun-con “%s”"
+msgstr "gặp lỗi khi đăng ký url cho đường dẫn mô-đun-con '%s'"
 
 #, c-format
 msgid "failed to update remote for submodule '%s'"
-msgstr "gặp lỗi khi cập nhật cho mô-đun-con “%s”"
+msgstr "gặp lỗi khi cập nhật cho mô-đun-con '%s'"
 
 msgid "suppress output of synchronizing submodule url"
 msgstr "chặn kết xuất của url mô-đun-con đồng bộ"
 
-msgid "git submodule--helper sync [--quiet] [--recursive] [<path>]"
-msgstr "git submodule--helper sync [--quiet] [--recursive] [</đường/dẫn>]"
+msgid "git submodule sync [--quiet] [--recursive] [<path>]"
+msgstr "git submodule sync [--quiet] [--recursive] [</đường/dẫn>]"
 
 #, c-format
 msgid ""
 "Submodule work tree '%s' contains a .git directory. This will be replaced "
 "with a .git file by using absorbgitdirs."
 msgstr ""
-"Cây làm việc mô-đun-con “%s” có chứa thư mục .git. Việc này sẽ được thay thế "
+"Cây làm việc mô-đun-con '%s' có chứa thư mục .git. Việc này sẽ được thay thế "
 "với một tập tin .git bằng các sử dụng absorbgitdirs."
 
 #, c-format
@@ -12063,24 +12476,24 @@
 "Submodule work tree '%s' contains local modifications; use '-f' to discard "
 "them"
 msgstr ""
-"Cây làm việc mô-đun-con “%s” chứa các thay đổi nội bộ; hãy dùng “-f” để loại "
+"Cây làm việc mô-đun-con '%s' chứa các thay đổi nội bộ; hãy dùng '-f' để loại "
 "bỏ chúng đi"
 
 #, c-format
 msgid "Cleared directory '%s'\n"
-msgstr "Đã xóa thư mục “%s”\n"
+msgstr "Đã xóa thư mục '%s'\n"
 
 #, c-format
 msgid "Could not remove submodule work tree '%s'\n"
-msgstr "Không thể gỡ bỏ cây làm việc mô-đun-con “%s”\n"
+msgstr "Không thể gỡ bỏ cây làm việc mô-đun-con '%s'\n"
 
 #, c-format
 msgid "could not create empty submodule directory %s"
-msgstr "không thể tạo thư mục mô-đun-con rỗng “%s”"
+msgstr "không thể tạo thư mục mô-đun-con rỗng '%s'"
 
 #, c-format
 msgid "Submodule '%s' (%s) unregistered for path '%s'\n"
-msgstr "Mô-đun-con “%s” (%s) được đăng ký cho đường dẫn “%s”\n"
+msgstr "Mô-đun-con '%s' (%s) được đăng ký cho đường dẫn '%s'\n"
 
 msgid "remove submodule working trees even if they contain local changes"
 msgstr "gỡ bỏ cây làm việc của mô-đun-con ngay cả khi nó có thay đổi nội bộ"
@@ -12091,10 +12504,11 @@
 msgid ""
 "git submodule deinit [--quiet] [-f | --force] [--all | [--] [<path>...]]"
 msgstr ""
-"git submodule deinit [--quiet] [-f | --force] [--all | [--]  [</đường/dẫn>…]]"
+"git submodule deinit [--quiet] [-f | --force] [--all | [--]  [</đường/"
+"dẫn>...]]"
 
 msgid "Use '--all' if you really want to deinitialize all submodules"
-msgstr "Dùng “--all” nếu bạn thực sự muốn hủy khởi tạo mọi mô-đun-con"
+msgstr "Dùng '--all' nếu bạn thực sự muốn hủy khởi tạo mọi mô-đun-con"
 
 msgid ""
 "An alternate computed from a superproject's alternate is invalid.\n"
@@ -12102,41 +12516,48 @@
 "submodule.alternateErrorStrategy to 'info' or, equivalently, clone with\n"
 "'--reference-if-able' instead of '--reference'."
 msgstr ""
-"Một cái thay thế được tính toán từ một thay thế của siêu dự án là không hợp "
+"Một cái thay thế được tính toán từ một thay thế của project cha là không hợp "
 "lệ.\n"
 "Để cho Git thực hiện nhân bản mà không có cái thay thế như trong trường hợp "
 "này, đặt\n"
-"submodule.alternateErrorStrategy thành “info” hoặc, tương đương, nhân bản "
+"submodule.alternateErrorStrategy thành 'info' hoặc, tương đương, nhân bản "
 "bằng\n"
-"“--reference-if-able” thay vì dùng “--reference”."
+"'--reference-if-able' thay vì dùng '--reference'."
+
+#, c-format
+msgid "could not get a repository handle for gitdir '%s'"
+msgstr "không thể lấy thẻ quản kho cho gitdir '%s'"
 
 #, c-format
 msgid "submodule '%s' cannot add alternate: %s"
-msgstr "mô-đun-con “%s” không thể thêm thay thế: %s"
+msgstr "mô-đun-con '%s' không thể thêm thay thế: %s"
 
 #, c-format
 msgid "Value '%s' for submodule.alternateErrorStrategy is not recognized"
-msgstr "Giá trị “%s” cho submodule.alternateErrorStrategy không được thừa nhận"
+msgstr "Giá trị '%s' cho submodule.alternateErrorStrategy không được thừa nhận"
 
 #, c-format
 msgid "Value '%s' for submodule.alternateLocation is not recognized"
-msgstr "Giá trị “%s” cho submodule.alternateLocation không được thừa nhận"
+msgstr "Giá trị '%s' cho submodule.alternateLocation không được thừa nhận"
 
 #, c-format
 msgid "refusing to create/use '%s' in another submodule's git dir"
-msgstr "từ chối tạo/dùng “%s” trong một thư mục git của mô đun con"
+msgstr "từ chối tạo/dùng '%s' trong một thư mục git của mô đun con"
 
 #, c-format
 msgid "clone of '%s' into submodule path '%s' failed"
-msgstr "việc sao “%s” vào đường dẫn mô-đun-con “%s” gặp lỗi"
+msgstr "việc sao '%s' vào đường dẫn mô-đun-con '%s' gặp lỗi"
 
 #, c-format
 msgid "directory not empty: '%s'"
-msgstr "thư mục không trống: “%s”"
+msgstr "thư mục không trống: '%s'"
 
 #, c-format
 msgid "could not get submodule directory for '%s'"
-msgstr "không thể lấy thư mục mô-đun-con cho “%s”"
+msgstr "không thể lấy thư mục mô-đun-con cho '%s'"
+
+msgid "alternative anchor for relative paths"
+msgstr "điểm neo thay thế cho các đường dẫn tương đối"
 
 msgid "where the new submodule will be cloned to"
 msgstr "nhân bản mô-đun-con mới vào chỗ nào"
@@ -12166,20 +12587,16 @@
 "spec>] --url <url> --path </đường/dẫn>"
 
 #, c-format
-msgid "Invalid update mode '%s' for submodule path '%s'"
-msgstr "Chế độ cập nhật “%s” không hợp lệ cho đường dẫn mô-đun-con “%s”"
-
-#, c-format
 msgid "Invalid update mode '%s' configured for submodule path '%s'"
 msgstr ""
-"Chế độ cập nhật “%s” không hợp lệ được cấu hình cho đường dẫn mô-đun-con “%s”"
+"Chế độ cập nhật '%s' không hợp lệ được cấu hình cho đường dẫn mô-đun-con '%s'"
 
 #, c-format
 msgid "Submodule path '%s' not initialized"
-msgstr "Đường dẫn mô-đun-con “%s” chưa được khởi tạo"
+msgstr "Đường dẫn mô-đun-con '%s' chưa được khởi tạo"
 
 msgid "Maybe you want to use 'update --init'?"
-msgstr "Có lẽ bạn là bạn muốn dùng \"update --init\" phải không?"
+msgstr "Có lẽ bạn muốn dùng 'update --init'?"
 
 #, c-format
 msgid "Skipping unmerged submodule %s"
@@ -12187,93 +12604,97 @@
 
 #, c-format
 msgid "Skipping submodule '%s'"
-msgstr "Bỏ qua mô-đun-con “%s”"
+msgstr "Bỏ qua mô-đun-con '%s'"
+
+#, c-format
+msgid "cannot clone submodule '%s' without a URL"
+msgstr "không thể nhân bản mô-đun-con '%s' nếu không có URL"
 
 #, c-format
 msgid "Failed to clone '%s'. Retry scheduled"
-msgstr "Gặp lỗi khi nhân bản “%s”. Thử lại lịch trình"
+msgstr "Gặp lỗi khi nhân bản '%s'. Đã lên lịch thử lại"
 
 #, c-format
 msgid "Failed to clone '%s' a second time, aborting"
-msgstr "Gặp lỗi khi nhân bản “%s” lần thứ hai nên bãi bỏ"
+msgstr "Gặp lỗi khi nhân bản '%s' lần thứ hai, huỷ bỏ"
 
 #, c-format
 msgid "Unable to checkout '%s' in submodule path '%s'"
-msgstr "Không thể lấy ra “%s” trong đường dẫn mô-đun-con “%s”"
+msgstr "Không thể checkout '%s' trong đường dẫn mô-đun-con '%s'"
 
 #, c-format
 msgid "Unable to rebase '%s' in submodule path '%s'"
-msgstr "Không thể cải tổ “%s” trong đường dẫn mô-đun-con “%s”"
+msgstr "Không thể cải tổ '%s' trong đường dẫn mô-đun-con '%s'"
 
 #, c-format
 msgid "Unable to merge '%s' in submodule path '%s'"
-msgstr "Không thể hòa trộn (merge) “%s” trong đường dẫn mô-đun-con “%s”"
+msgstr "Không thể hòa trộn (merge) '%s' trong đường dẫn mô-đun-con '%s'"
 
 #, c-format
 msgid "Execution of '%s %s' failed in submodule path '%s'"
 msgstr ""
-"Thực hiện không thành công lệnh “%s %s” trong đường dẫn mô-đun-con “%s”"
+"Thực hiện không thành công lệnh '%s %s' trong đường dẫn mô-đun-con '%s'"
 
 #, c-format
 msgid "Submodule path '%s': checked out '%s'\n"
-msgstr "Đường dẫn mô-đun-con “%s”: đã checkout “%s”\n"
+msgstr "Đường dẫn mô-đun-con '%s': đã checkout '%s'\n"
 
 #, c-format
 msgid "Submodule path '%s': rebased into '%s'\n"
-msgstr "Đường dẫn mô-đun-con “%s”: được rebase vào trong “%s”\n"
+msgstr "Đường dẫn mô-đun-con '%s': được rebase vào trong '%s'\n"
 
 #, c-format
 msgid "Submodule path '%s': merged in '%s'\n"
-msgstr "Đường dẫn mô-đun-con “%s”: được hòa trộn vào “%s”\n"
+msgstr "Đường dẫn mô-đun-con '%s': được hòa trộn vào '%s'\n"
 
 #, c-format
 msgid "Submodule path '%s': '%s %s'\n"
-msgstr "Đường dẫn mô-đun-con “%s”: “%s %s”\n"
+msgstr "Đường dẫn mô-đun-con '%s': '%s %s'\n"
 
 #, c-format
 msgid "Unable to fetch in submodule path '%s'; trying to directly fetch %s:"
 msgstr ""
-"Không thể lấy về trong đường dẫn mô-đun-con “%s”; thử lấy về trực tiếp %s:"
+"Không thể lấy về trong đường dẫn mô-đun-con '%s'; thử lấy về trực tiếp %s:"
 
 #, c-format
 msgid ""
 "Fetched in submodule path '%s', but it did not contain %s. Direct fetching "
 "of that commit failed."
 msgstr ""
-"Đã lấy về từ đường dẫn mô-đun con “%s”, nhưng nó không chứa %s. Lấy về trực "
+"Đã lấy về từ đường dẫn mô-đun con '%s', nhưng nó không chứa %s. Lấy về trực "
 "tiếp lần chuyển giao gặp lỗi đó."
 
 #, c-format
+msgid "could not initialize submodule at path '%s'"
+msgstr "Không thể khởi tạo mô-đun-con tại đường dẫn '%s'"
+
+#, c-format
 msgid ""
 "Submodule (%s) branch configured to inherit branch from superproject, but "
 "the superproject is not on any branch"
 msgstr ""
-"Nhánh mô-đun-con (%s) được cấu hình kế thừa nhánh từ siêu dự án, nhưng siêu "
-"dự án lại không trên bất kỳ nhánh nào"
-
-#, c-format
-msgid "could not get a repository handle for submodule '%s'"
-msgstr "không thể lấy thẻ quản kho cho mô-đun-con “%s”"
+"Nhánh mô-đun-con (%s) được cấu hình kế thừa nhánh từ project cha, nhưng "
+"project cha lại không trên bất kỳ nhánh nào"
 
 #, c-format
 msgid "Unable to find current revision in submodule path '%s'"
 msgstr ""
-"Không tìm thấy điểm xét duyệt hiện hành trong đường dẫn mô-đun-con “%s”"
+"Không tìm thấy điểm xét duyệt hiện hành trong đường dẫn mô-đun-con '%s'"
 
 #, c-format
 msgid "Unable to fetch in submodule path '%s'"
-msgstr "Không thể lấy về trong đường dẫn mô-đun-con “%s”"
+msgstr "Không thể lấy về trong đường dẫn mô-đun-con '%s'"
 
 #, c-format
 msgid "Unable to find %s revision in submodule path '%s'"
-msgstr "Không tìm thấy điểm xét duyệt %s trong đường dẫn mô-đun-con “%s”"
+msgstr "Không tìm thấy điểm xét duyệt %s trong đường dẫn mô-đun-con '%s'"
 
 #, c-format
 msgid "Failed to recurse into submodule path '%s'"
-msgstr "Gặp lỗi khi đệ quy vào trong đường dẫn mô-đun-con “%s”"
+msgstr "Gặp lỗi khi đệ quy vào trong đường dẫn mô-đun-con '%s'"
 
 msgid "force checkout updates"
-msgstr "ép buộc lấy ra các cập nhật"
+msgstr "ép buộc checkout các cập nhật"
 
 msgid "initialize uninitialized submodules before update"
 msgstr "khởi tạo mô-đun-con chưa khởi tạo trước khi cập nhật"
@@ -12287,14 +12708,14 @@
 msgid "don't fetch new objects from the remote site"
 msgstr "đừng lấy các đối tượng mới từ địa chỉ trên mạng"
 
-msgid "path into the working tree"
-msgstr "đường dẫn đến cây làm việc"
+msgid "use the 'checkout' update strategy (default)"
+msgstr "dùng chiến lược hòa trộn 'checkout' (mặc định)"
 
-msgid "path into the working tree, across nested submodule boundaries"
-msgstr "đường dẫn đến cây làm việc, chéo biên giới mô-đun-con lồng nhau"
+msgid "use the 'merge' update strategy"
+msgstr "dùng chiến lược hòa trộn 'merge'"
 
-msgid "rebase, merge, checkout or none"
-msgstr "rebase, merge, checkout hoặc không làm gì cả"
+msgid "use the 'rebase' update strategy"
+msgstr "dùng chiến lược hòa trộn 'rebase'"
 
 msgid "create a shallow clone truncated to the specified number of revisions"
 msgstr ""
@@ -12309,6 +12730,9 @@
 msgid "don't print cloning progress"
 msgstr "đừng in tiến trình nhân bản"
 
+msgid "disallow cloning into non-empty directory, implies --init"
+msgstr "không cho phép nhân bản vào thư mục trống, ngụ ý --init"
+
 msgid ""
 "git submodule [--quiet] update [--init [--filter=<filter-spec>]] [--remote] "
 "[-N|--no-fetch] [-f|--force] [--checkout|--merge|--rebase] [--[no-]recommend-"
@@ -12320,35 +12744,17 @@
 "shallow] [--reference <kho>] [--recursive] [--[no-]single-branch] [--] [</"
 "đường/dẫn/>...]"
 
-msgid "bad value for update parameter"
-msgstr "giá trị cho  tham số cập nhật bị sai"
+msgid "Failed to resolve HEAD as a valid ref."
+msgstr "Gặp lỗi khi phân giải HEAD như là một tham chiếu hợp lệ."
 
-msgid "recurse into submodules"
-msgstr "đệ quy vào trong mô-đun-con"
-
-msgid "git submodule--helper absorb-git-dirs [<options>] [<path>...]"
-msgstr "git submodule--helper absorb-git-dirs [<các tùy chọn>] [</đường/dẫn>…]"
-
-msgid "check if it is safe to write to the .gitmodules file"
-msgstr "chọn nếu nó là an toàn để ghi vào tập tin .gitmodules"
-
-msgid "unset the config in the .gitmodules file"
-msgstr "bỏ đặt cấu hình trong tập tin .gitmodules"
-
-msgid "git submodule--helper config <name> [<value>]"
-msgstr "git submodule--helper config <tên> [<giá trị>]"
-
-msgid "git submodule--helper config --unset <name>"
-msgstr "git submodule--helper config --unset <tên>"
-
-msgid "please make sure that the .gitmodules file is in the working tree"
-msgstr "hãy đảm bảo rằng tập tin .gitmodules có trong cây làm việc"
+msgid "git submodule absorbgitdirs [<options>] [<path>...]"
+msgstr "git submodule absorbgitdirs [<các tùy chọn>] [</đường/dẫn>...]"
 
 msgid "suppress output for setting url of a submodule"
-msgstr "chặn kết xuất cho cài đặt url của một mô-đun-con"
+msgstr "chặn đầu ra cho việc đặt url của một mô-đun-con"
 
-msgid "git submodule--helper set-url [--quiet] <path> <newurl>"
-msgstr "git submodule--helper set-url [--quiet] </đường/dẫn> <url_mới>"
+msgid "git submodule set-url [--quiet] <path> <newurl>"
+msgstr "git submodule set-url [--quiet] </đường/dẫn> <url_mới>"
 
 msgid "set the default tracking branch to master"
 msgstr "đặt nhánh theo dõi mặc định thành master"
@@ -12356,15 +12762,12 @@
 msgid "set the default tracking branch"
 msgstr "đặt nhánh theo dõi mặc định"
 
-msgid "git submodule--helper set-branch [-q|--quiet] (-d|--default) <path>"
-msgstr ""
-"git submodule--helper set-branch [-q|--quiet](-d|--default)</đường/dẫn>"
+msgid "git submodule set-branch [-q|--quiet] (-d|--default) <path>"
+msgstr "git submodule set-branch [-q|--quiet](-d|--default)</đường/dẫn>"
 
-msgid ""
-"git submodule--helper set-branch [-q|--quiet] (-b|--branch) <branch> <path>"
+msgid "git submodule set-branch [-q|--quiet] (-b|--branch) <branch> <path>"
 msgstr ""
-"git submodule--helper set-branch [-q|--quiet] (-b|--branch) <nhánh> </đường/"
-"dẫn>"
+"git submodule set-branch [-q|--quiet] (-b|--branch) <nhánh> </đường/dẫn>"
 
 msgid "--branch or --default required"
 msgstr "cần --branch hoặc --default"
@@ -12387,19 +12790,19 @@
 
 #, c-format
 msgid "creating branch '%s'"
-msgstr "đang tạo nhánh “%s”"
+msgstr "đang tạo nhánh '%s'"
 
 #, c-format
 msgid "Adding existing repo at '%s' to the index\n"
-msgstr "Đang thêm repo có sẵn tại “%s” vào bảng mục lục\n"
+msgstr "Đang thêm repo có sẵn tại '%s' vào chỉ mục\n"
 
 #, c-format
 msgid "'%s' already exists and is not a valid git repo"
-msgstr "“%s” đã tồn tại từ trước và không phải là một kho git hợp lệ"
+msgstr "'%s' đã tồn tại từ trước và không phải là một kho git hợp lệ"
 
 #, c-format
 msgid "A git directory for '%s' is found locally with remote(s):\n"
-msgstr "Thư mục git cho “%s” được tìm thấy một cách cục bộ với các máy chủ:\n"
+msgstr "Thư mục git cho '%s' được tìm thấy một cách cục bộ với các máy chủ:\n"
 
 #, c-format
 msgid ""
@@ -12413,39 +12816,41 @@
 "Nếu bạn muốn sử dụng lại thư mục git nội bộ này thay vì nhân bản lại lần nữa "
 "từ\n"
 "  %s\n"
-"dùng tùy chọn “--force”. Nếu thư mục git nội bộ không phải là một kho đúng "
+"dùng tùy chọn '--force'. Nếu thư mục git nội bộ không phải là một kho đúng "
 "hoặc\n"
-"là bạn không chắc chắn điều đó nghĩa là gì thì chọn tên khác với tùy chọn “--"
-"name”."
+"là bạn không chắc chắn điều đó nghĩa là gì thì chọn tên khác với tùy chọn '--"
+"name'."
 
 #, c-format
 msgid "Reactivating local git directory for submodule '%s'\n"
-msgstr "Phục hồi sự hoạt động của thư mục git nội bộ cho mô-đun-con “%s”.\n"
+msgstr "Phục hồi sự hoạt động của thư mục git nội bộ cho mô-đun-con '%s'.\n"
 
 #, c-format
 msgid "unable to checkout submodule '%s'"
-msgstr "không thể lấy ra mô-đun-con “%s”"
+msgstr "không thể checkout mô-đun-con '%s'"
+
+msgid "please make sure that the .gitmodules file is in the working tree"
+msgstr "hãy đảm bảo rằng tập tin .gitmodules có trong cây làm việc"
 
 #, c-format
 msgid "Failed to add submodule '%s'"
-msgstr "Gặp lỗi khi thêm mô-đun-con “%s”"
+msgstr "Gặp lỗi khi thêm mô-đun-con '%s'"
 
 #, c-format
 msgid "Failed to register submodule '%s'"
-msgstr "Gặp lỗi khi đăng ký mô-đun-con “%s”"
+msgstr "Gặp lỗi khi đăng ký mô-đun-con '%s'"
 
 #, c-format
 msgid "'%s' already exists in the index"
-msgstr "”%s” thực sự đã tồn tại ở bảng mục lục rồi"
+msgstr "'%s' thực sự đã tồn tại ở chỉ mục rồi"
 
 #, c-format
 msgid "'%s' already exists in the index and is not a submodule"
-msgstr ""
-"”%s” thực sự đã tồn tại ở bảng mục lục rồi và không phải là một mô-đun-con"
+msgstr "'%s' thực sự đã tồn tại ở chỉ mục rồi và không phải là một mô-đun-con"
 
 #, c-format
 msgid "'%s' does not have a commit checked out"
-msgstr "“%s” không có một lần chuyển giao nào được lấy ra"
+msgstr "'%s' không có một lần chuyển giao nào được checkout"
 
 msgid "branch of repository to add as submodule"
 msgstr "nhánh của kho để thêm như là mô-đun-con"
@@ -12462,8 +12867,8 @@
 msgstr ""
 "đặt tên của mô-đun-con bằng chuỗi đã cho thay vì mặc định là đường dẫn của nó"
 
-msgid "git submodule--helper add [<options>] [--] <repository> [<path>]"
-msgstr "git submodule--helper add [<các tùy chọn>] [--] <kho> [</đường/dẫn>]"
+msgid "git submodule add [<options>] [--] <repository> [<path>]"
+msgstr "git submodule add [<các tùy chọn>] [--] <kho> [</đường/dẫn>]"
 
 msgid "Relative path can only be used from the toplevel of the working tree"
 msgstr ""
@@ -12472,28 +12877,26 @@
 
 #, c-format
 msgid "repo URL: '%s' must be absolute or begin with ./|../"
-msgstr "repo URL: “%s” phải là đường dẫn tuyệt đối hoặc là bắt đầu bằng ./|../"
+msgstr "repo URL: '%s' phải là đường dẫn tuyệt đối hoặc là bắt đầu bằng ./|../"
 
 #, c-format
 msgid "'%s' is not a valid submodule name"
-msgstr "“%s” không phải là một tên mô-đun-con hợp lệ"
+msgstr "'%s' không phải là một tên mô-đun-con hợp lệ"
 
-#, c-format
-msgid "%s doesn't support --super-prefix"
-msgstr "%s không hỗ trợ --super-prefix"
+msgid "git submodule--helper <command>"
+msgstr "git submodule--helper <lệnh>"
 
-#, c-format
-msgid "'%s' is not a valid submodule--helper subcommand"
-msgstr "“%s” không phải là lệnh con submodule--helper hợp lệ"
+msgid "git symbolic-ref [-m <reason>] <name> <ref>"
+msgstr "git symbolic-ref [-m <lý do>] <tên> <tham chiếu>"
 
-msgid "git symbolic-ref [<options>] <name> [<ref>]"
-msgstr "git symbolic-ref [<các tùy chọn>] <tên> [<t.chiếu>]"
+msgid "git symbolic-ref [-q] [--short] [--no-recurse] <name>"
+msgstr "git symbolic-ref [-q] [--short] [--no-recurse] <tên>"
 
-msgid "git symbolic-ref -d [-q] <name>"
-msgstr "git symbolic-ref -d [-q] <tên>"
+msgid "git symbolic-ref --delete [-q] <name>"
+msgstr "git symbolic-ref --delete [-q] <tên>"
 
 msgid "suppress error message for non-symbolic (detached) refs"
-msgstr "chặn các thông tin lỗi cho các tham chiếu “không-mềm” (bị tách ra)"
+msgstr "chặn các thông tin lỗi cho các tham chiếu 'không-mềm' (bị tách ra)"
 
 msgid "delete symbolic ref"
 msgstr "xóa tham chiếu mềm"
@@ -12501,6 +12904,9 @@
 msgid "shorten ref output"
 msgstr "làm ngắn kết xuất ref (tham chiếu)"
 
+msgid "recursively dereference (default)"
+msgstr "chế độ giải tham chiếu đệ quy (mặc định)"
+
 msgid "reason"
 msgstr "lý do"
 
@@ -12508,61 +12914,63 @@
 msgstr "lý do cập nhật"
 
 msgid ""
-"git tag [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <file>]\n"
-"        <tagname> [<head>]"
+"git tag [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <file>] [-e]\n"
+"        <tagname> [<commit> | <object>]"
 msgstr ""
-"git tag [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <tập-tin>]\n"
-"        <tên-thẻ> [<head>]"
+"git tag [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <tập-tin>] [-e]\n"
+"        <tên-thẻ> [<lần chuyển giao> | <đối tượng> ]"
 
 msgid "git tag -d <tagname>..."
-msgstr "git tag -d <tên-thẻ>…"
+msgstr "git tag -d <tên-thẻ>..."
 
 msgid ""
-"git tag -l [-n[<num>]] [--contains <commit>] [--no-contains <commit>] [--"
-"points-at <object>]\n"
-"        [--format=<format>] [--merged <commit>] [--no-merged <commit>] "
-"[<pattern>...]"
+"git tag [-n[<num>]] -l [--contains <commit>] [--no-contains <commit>]\n"
+"        [--points-at <object>] [--column[=<options>] | --no-column]\n"
+"        [--create-reflog] [--sort=<key>] [--format=<format>]\n"
+"        [--merged <commit>] [--no-merged <commit>] [<pattern>...]"
 msgstr ""
-"git tag -l [-n[<số>]] [--contains <lần_chuyển_giao>] [--no-contains "
-"<lần_chuyển_giao>] [--points-at <đối-tượng>]\n"
-"        [--format=<định_dạng>] [--merged <lần_chuyển_giao>] [--no-merged "
-"[<lần_chuyển_giao>]] [<mẫu>…]"
+"git tag [-n[<số>]] -l [--contains <lần_chuyển_giao>] [--no-contains "
+"<lần_chuyển_giao>]\n"
+"        [--points-at <đối-tượng>] [--column[=<options>] | --no-column]\n"
+"        [--create-reflog] [--sort=<key>] [--format=<định dạng>]\n"
+"        [--merged <lần_chuyển_giao>] [--no-merged <lần_chuyển_giao>] "
+"[<mẫu>...]"
 
 msgid "git tag -v [--format=<format>] <tagname>..."
-msgstr "git tag -v [--format=<định_dạng>]  <tên-thẻ>…"
+msgstr "git tag -v [--format=<định dạng>] <tên-thẻ>..."
 
 #, c-format
 msgid "tag '%s' not found."
-msgstr "không tìm thấy tìm thấy thẻ “%s”."
+msgstr "không tìm thấy thẻ '%s'."
 
 #, c-format
 msgid "Deleted tag '%s' (was %s)\n"
-msgstr "Thẻ đã bị xóa “%s” (từng là %s)\n"
+msgstr "Thẻ đã bị xóa '%s' (từng là %s)\n"
 
 #, c-format
 msgid ""
 "\n"
 "Write a message for tag:\n"
 "  %s\n"
-"Lines starting with '%c' will be ignored.\n"
+"Lines starting with '%s' will be ignored.\n"
 msgstr ""
 "\n"
 "Viết các ghi chú cho thẻ:\n"
 "  %s\n"
-"Những dòng được bắt đầu bằng “%c” sẽ được bỏ qua.\n"
+"Những dòng được bắt đầu bằng '%s' sẽ được bỏ qua.\n"
 
 #, c-format
 msgid ""
 "\n"
 "Write a message for tag:\n"
 "  %s\n"
-"Lines starting with '%c' will be kept; you may remove them yourself if you "
+"Lines starting with '%s' will be kept; you may remove them yourself if you "
 "want to.\n"
 msgstr ""
 "\n"
 "Viết các ghi chú cho thẻ:\n"
 "  %s\n"
-"Những dòng được bắt đầu bằng “%c” sẽ được giữ lại; bạn có thể xóa chúng đi "
+"Những dòng được bắt đầu bằng '%s' sẽ được giữ lại; bạn có thể xóa chúng đi "
 "nếu muốn.\n"
 
 msgid "unable to sign the tag"
@@ -12647,17 +13055,20 @@
 msgid "print only tags of the object"
 msgstr "chỉ hiển thị các thẻ của đối tượng"
 
+msgid "could not start 'git column'"
+msgstr "không thể chạy 'git column'"
+
 #, c-format
 msgid "the '%s' option is only allowed in list mode"
 msgstr "tùy chọn '%s' chỉ cho phép dùng trong chế độ liệt kê"
 
 #, c-format
 msgid "'%s' is not a valid tag name."
-msgstr "“%s” không phải thẻ hợp lệ."
+msgstr "'%s' không phải thẻ hợp lệ."
 
 #, c-format
 msgid "tag '%s' already exists"
-msgstr "thẻ “%s” đã tồn tại rồi"
+msgstr "thẻ '%s' đã tồn tại rồi"
 
 #, c-format
 msgid "Invalid cleanup mode %s"
@@ -12665,11 +13076,21 @@
 
 #, c-format
 msgid "Updated tag '%s' (was %s)\n"
-msgstr "Đã cập nhật thẻ “%s” (trước là %s)\n"
+msgstr "Đã cập nhật thẻ '%s' (trước là %s)\n"
 
 msgid "pack exceeds maximum allowed size"
 msgstr "gói đã vượt quá cỡ tối đa được phép"
 
+msgid "failed to write object in stream"
+msgstr "gặp lỗi khi đọc đối tượng trong stream"
+
+#, c-format
+msgid "inflate returned (%d)"
+msgstr "inflate trả về (%d)"
+
+msgid "invalid blob object from stream"
+msgstr "đối tượng blob không hợp lệ trong stream"
+
 msgid "Unpacking objects"
 msgstr "Đang giải nén các đối tượng"
 
@@ -12687,7 +13108,7 @@
 
 #, c-format
 msgid "Testing mtime in '%s' "
-msgstr "Đang kiểm thử mtime trong “%s” "
+msgstr "Đang kiểm thử mtime trong '%s' "
 
 msgid "directory stat info does not change after adding a new file"
 msgstr "thông tin thống kê thư mục không thay đổi sau khi thêm tập tin mới"
@@ -12713,38 +13134,37 @@
 msgstr " Đồng ý"
 
 msgid "git update-index [<options>] [--] [<file>...]"
-msgstr "git update-index [<các tùy chọn>] [--] [<tập-tin>…]"
+msgstr "git update-index [<các tùy chọn>] [--] [<tập-tin>...]"
 
 msgid "continue refresh even when index needs update"
-msgstr "tiếp tục làm mới ngay cả khi bảng mục lục cần được cập nhật"
+msgstr "tiếp tục làm mới ngay cả khi chỉ mục cần được cập nhật"
 
 msgid "refresh: ignore submodules"
-msgstr "refresh: lờ đi mô-đun-con"
+msgstr "refresh: bỏ qua mô-đun-con"
 
 msgid "do not ignore new files"
 msgstr "không bỏ qua các tập tin mới tạo"
 
 msgid "let files replace directories and vice-versa"
-msgstr "để các tập tin thay thế các thư mục và “vice-versa”"
+msgstr "để các tập tin thay thế các thư mục và 'vice-versa'"
 
 msgid "notice files missing from worktree"
 msgstr "thông báo các tập-tin thiếu trong thư-mục làm việc"
 
 msgid "refresh even if index contains unmerged entries"
-msgstr ""
-"làm tươi mới thậm chí khi bảng mục lục chứa các mục tin chưa được hòa trộn"
+msgstr "làm tươi mới thậm chí khi chỉ mục chứa các mục tin chưa được hòa trộn"
 
 msgid "refresh stat information"
 msgstr "lấy lại thông tin thống kê"
 
 msgid "like --refresh, but ignore assume-unchanged setting"
-msgstr "giống --refresh, nhưng bỏ qua các cài đặt “assume-unchanged”"
+msgstr "giống --refresh, nhưng bỏ qua các cài đặt 'assume-unchanged'"
 
 msgid "<mode>,<object>,<path>"
 msgstr "<chế_độ>,<đối_tượng>,<đường_dẫn>"
 
 msgid "add the specified entry to the index"
-msgstr "thêm các tập tin đã chỉ ra vào bảng mục lục"
+msgstr "thêm các tập tin đã chỉ ra vào chỉ mục"
 
 msgid "mark files as \"not changing\""
 msgstr "đánh dấu các tập tin là \"không thay đổi\""
@@ -12753,7 +13173,7 @@
 msgstr "xóa bít assumed-unchanged (giả định là không thay đổi)"
 
 msgid "mark files as \"index-only\""
-msgstr "đánh dấu các tập tin là “chỉ-đọc”"
+msgstr "đánh dấu các tập tin là 'chỉ-đọc'"
 
 msgid "clear skip-worktree bit"
 msgstr "xóa bít skip-worktree"
@@ -12762,8 +13182,7 @@
 msgstr "đừng động vào các mục index-only"
 
 msgid "add to index only; do not add content to object database"
-msgstr ""
-"chỉ thêm vào bảng mục lục; không thêm nội dung vào cơ sở dữ liệu đối tượng"
+msgstr "chỉ thêm vào chỉ mục; không thêm nội dung vào cơ sở dữ liệu đối tượng"
 
 msgid "remove named paths even if present in worktree"
 msgstr ""
@@ -12771,13 +13190,13 @@
 "làm việc"
 
 msgid "with --stdin: input lines are terminated by null bytes"
-msgstr "với tùy chọn --stdin: các dòng đầu vào được chấm dứt bởi ký tự null"
+msgstr "với tùy chọn --stdin: các dòng đầu vào được kết thúc bởi ký tự null"
 
 msgid "read list of paths to be updated from standard input"
-msgstr "đọc danh sách đường dẫn cần cập nhật từ đầu vào tiêu chuẩn"
+msgstr "đọc danh sách đường dẫn cần cập nhật từ stdin"
 
 msgid "add entries from standard input to the index"
-msgstr "không thể đọc các mục từ đầu vào tiêu chuẩn vào bảng mục lục"
+msgstr "không thể đọc các mục từ stdin vào chỉ mục"
 
 msgid "repopulate stages #2 and #3 for the listed paths"
 msgstr "phục hồi các trạng thái #2 và #3 cho các đường dẫn được liệt kê"
@@ -12789,16 +13208,19 @@
 msgstr "bỏ qua các tập-tin thiếu trong thư-mục làm việc"
 
 msgid "report actions to standard output"
-msgstr "báo cáo các thao tác ra thiết bị xuất chuẩn"
+msgstr "ghi các thao tác ra stdout"
 
 msgid "(for porcelains) forget saved unresolved conflicts"
-msgstr "(cho “porcelains”) quên các xung đột chưa được giải quyết đã ghi"
+msgstr "(cho 'porcelains') quên các xung đột chưa được giải quyết đã ghi"
 
 msgid "write index in this format"
-msgstr "ghi mục lục ở định dạng này"
+msgstr "ghi chỉ mục ở định dạng này"
+
+msgid "report on-disk index format version"
+msgstr "cho biết phiên bản định dạng chỉ mục trên đĩa"
 
 msgid "enable or disable split index"
-msgstr "bật/tắt chia cắt bảng mục lục"
+msgstr "bật/tắt chia cắt chỉ mục"
 
 msgid "enable/disable untracked cache"
 msgstr "bật/tắt bộ đệm không theo vết"
@@ -12810,7 +13232,7 @@
 msgstr "bật bộ đệm không theo vết mà không kiểm tra hệ thống tập tin"
 
 msgid "write out the index even if is not flagged as changed"
-msgstr "ghi ra mục lục ngay cả khi không được đánh cờ là có thay đổi"
+msgstr "ghi ra chỉ mục ngay cả khi không được đánh cờ là có thay đổi"
 
 msgid "enable or disable file system monitor"
 msgstr "bật/tắt theo dõi hệ thống tập tin"
@@ -12821,19 +13243,27 @@
 msgid "clear fsmonitor valid bit"
 msgstr "xóa bít hợp lệ fsmonitor"
 
+#, c-format
+msgid "%d\n"
+msgstr "%d\n"
+
+#, c-format
+msgid "index-version: was %d, set to %d"
+msgstr "index-version: đang là %d, đặt về %d"
+
 msgid ""
 "core.splitIndex is set to false; remove or change it, if you really want to "
 "enable split index"
 msgstr ""
 "core.splitIndex được đặt là sai; xóa bỏ hay thay đổi nó, nếu bạn thực sự "
-"muốn bật chia tách mục lục"
+"muốn bật chia tách chỉ mục"
 
 msgid ""
 "core.splitIndex is set to true; remove or change it, if you really want to "
 "disable split index"
 msgstr ""
 "core.splitIndex được đặt là đúng; xóa bỏ hay thay đổi nó, nếu bạn thực sự "
-"muốn tắt chia tách mục lục"
+"muốn tắt chia tách chỉ mục"
 
 msgid ""
 "core.untrackedCache is set to true; remove or change it, if you really want "
@@ -12854,7 +13284,7 @@
 
 #, c-format
 msgid "Untracked cache enabled for '%s'"
-msgstr "Nhớ đệm không theo vết được bật cho “%s”"
+msgstr "Nhớ đệm không theo vết được bật cho '%s'"
 
 msgid "core.fsmonitor is unset; set it if you really want to enable fsmonitor"
 msgstr ""
@@ -12873,11 +13303,11 @@
 msgid "fsmonitor disabled"
 msgstr "fsmonitor bị tắt"
 
-msgid "git update-ref [<options>] -d <refname> [<old-val>]"
-msgstr "git update-ref [<các tùy chọn>] -d <refname> [<biến-cũ>]"
+msgid "git update-ref [<options>] -d <refname> [<old-oid>]"
+msgstr "git update-ref [<các tùy chọn>] -d <refname> [<oid-cũ>]"
 
-msgid "git update-ref [<options>]    <refname> <new-val> [<old-val>]"
-msgstr "git update-ref [<các tùy chọn>]    <refname> <biến-mới> [<biến-cũ>]"
+msgid "git update-ref [<options>]    <refname> <new-oid> [<old-oid>]"
+msgstr "git update-ref [<các tùy chọn>]    <refname> <oid-mới> [<oid-cũ>]"
 
 msgid "git update-ref [<options>] --stdin [-z]"
 msgstr "git update-ref [<các tùy chọn>] --stdin [-z]"
@@ -12889,19 +13319,23 @@
 msgstr "cập nhật <tên-tham-chiếu> không phải cái nó chỉ tới"
 
 msgid "stdin has NUL-terminated arguments"
-msgstr "đầu vào tiêu chuẩn có các đối số được chấm dứt bởi NUL"
+msgstr "stdin có các đối số được kết thúc bởi NUL"
 
 msgid "read updates from stdin"
-msgstr "đọc cập nhật từ đầu vào tiêu chuẩn"
+msgstr "đọc cập nhật từ stdin"
 
 msgid "update the info files from scratch"
 msgstr "cập nhật các tập tin thông tin từ điểm xuất phát"
 
-msgid "git upload-pack [<options>] <dir>"
-msgstr "git upload-pack [<các tùy chọn>] </đường/dẫn>"
+msgid ""
+"git-upload-pack [--[no-]strict] [--timeout=<n>] [--stateless-rpc]\n"
+"                [--advertise-refs] <directory>"
+msgstr ""
+"git-upload-pack [--[no-]strict] [--timeout=<n>] [--stateless-rpc]\n"
+"                [--advertise-refs] <thư mục>"
 
 msgid "quit after a single request/response exchange"
-msgstr "thoát sau khi một trao đổi yêu cầu hay trả lời đơn"
+msgstr "thoát sau một trao đổi yêu cầu/trả lời"
 
 msgid "serve up the info/refs for git-http-backend"
 msgstr "phục vụ info/refs (thông tin/tham chiếu) cho git-http-backend"
@@ -12912,8 +13346,8 @@
 msgid "interrupt transfer after <n> seconds of inactivity"
 msgstr "ngắt truyền thông sau <n> giây không hoạt động"
 
-msgid "git verify-commit [-v | --verbose] <commit>..."
-msgstr "git verify-commit [-v | --verbose] <lần_chuyển_giao>…"
+msgid "git verify-commit [-v | --verbose] [--raw] <commit>..."
+msgstr "git verify-commit [-v | --verbose] [--raw] <lần_chuyển_giao>..."
 
 msgid "print commit contents"
 msgstr "hiển thị nội dung của lần chuyển giao"
@@ -12921,8 +13355,8 @@
 msgid "print raw gpg status output"
 msgstr "in kết xuất trạng thái gpg dạng thô"
 
-msgid "git verify-pack [-v | --verbose] [-s | --stat-only] <pack>..."
-msgstr "git verify-pack [-v | --verbose] [-s | --stat-only] <gói>…"
+msgid "git verify-pack [-v | --verbose] [-s | --stat-only] [--] <pack>.idx..."
+msgstr "git verify-pack [-v | --verbose] [-s | --stat-only] [--] <gói>.idx..."
 
 msgid "verbose"
 msgstr "chi tiết"
@@ -12930,69 +13364,106 @@
 msgid "show statistics only"
 msgstr "chỉ hiển thị thống kê"
 
-msgid "git verify-tag [-v | --verbose] [--format=<format>] <tag>..."
-msgstr "git verify-tag [-v | --verbose] [--format=<định_dạng>] <thẻ>…"
+msgid "git verify-tag [-v | --verbose] [--format=<format>] [--raw] <tag>..."
+msgstr ""
+"git verify-tag [-v | --verbose] [--format=<định dạng>] [--raw] <thẻ>..."
 
 msgid "print tag contents"
 msgstr "hiển thị nội dung của thẻ"
 
-msgid "git worktree add [<options>] <path> [<commit-ish>]"
-msgstr "git worktree add [<các tùy chọn>] </đường/dẫn> [<commit-ish>]"
+msgid ""
+"git worktree add [-f] [--detach] [--checkout] [--lock [--reason <string>]]\n"
+"                 [--orphan] [(-b | -B) <new-branch>] <path> [<commit-ish>]"
+msgstr ""
+"git worktree add [-f] [--detach] [--checkout] [--lock [--reason <lý do>]]\n"
+"                 [--orphan] [(-b | -B) <nhánh-mới>] <đường/dẫn> [<commit-"
+"ish>]"
 
-msgid "git worktree list [<options>]"
-msgstr "git worktree list [<các tùy chọn>]"
+msgid "git worktree list [-v | --porcelain [-z]]"
+msgstr "git worktree list [-v | --porcelain [-z]]"
 
-msgid "git worktree lock [<options>] <path>"
-msgstr "git worktree lock [<các tùy chọn>] </đường/dẫn>"
+msgid "git worktree lock [--reason <string>] <worktree>"
+msgstr "git worktree lock [--reason <lý do>] <cây làm việc>"
 
 msgid "git worktree move <worktree> <new-path>"
-msgstr "git worktree move <worktree> </đường/dẫn/mới>"
+msgstr "git worktree move <cây làm việc> </đường/dẫn/mới>"
 
-msgid "git worktree prune [<options>]"
-msgstr "git worktree prune [<các tùy chọn>]"
+msgid "git worktree prune [-n] [-v] [--expire <expire>]"
+msgstr "git worktree prune [-n] [-v] [--expire <khi nào hết hạn>]"
 
-msgid "git worktree remove [<options>] <worktree>"
-msgstr "git worktree remove [<các tùy chọn>] <worktree>"
+msgid "git worktree remove [-f] <worktree>"
+msgstr "git worktree remove [-f] <cây làm việc>"
 
 msgid "git worktree repair [<path>...]"
 msgstr "git worktree repair [</đường/dẫn/>...]"
 
-msgid "git worktree unlock <path>"
-msgstr "git worktree unlock </đường/dẫn>"
+msgid "git worktree unlock <worktree>"
+msgstr "git worktree unlock <cây làm việc>"
+
+msgid "No possible source branch, inferring '--orphan'"
+msgstr "Không có nhánh gốc, đoán là --orphan"
+
+#, c-format
+msgid ""
+"If you meant to create a worktree containing a new unborn branch\n"
+"(branch with no commits) for this repository, you can do so\n"
+"using the --orphan flag:\n"
+"\n"
+"    git worktree add --orphan -b %s %s\n"
+msgstr ""
+"Nếu bạn muốn tạo cây làm việc với nhánh chưa sinh\n"
+"(nhánh chưa có lần chuyển giao) cho kho chứa này, bạn có thể dùng\n"
+"tuỳ chọn --orphan:\n"
+"\n"
+"    git worktree add --orphan -b %s %s\n"
+
+#, c-format
+msgid ""
+"If you meant to create a worktree containing a new unborn branch\n"
+"(branch with no commits) for this repository, you can do so\n"
+"using the --orphan flag:\n"
+"\n"
+"    git worktree add --orphan %s\n"
+msgstr ""
+"Nếu bạn muốn tạo cây làm việc với nhánh chưa sinh\n"
+"(nhánh chưa có lần chuyển giao) cho kho chứa này, bạn có thể dùng\n"
+"tuỳ chọn --orphan:\n"
+"\n"
+"    git worktree add --orphan %s\n"
 
 #, c-format
 msgid "Removing %s/%s: %s"
 msgstr "Đang xóa %s/%s: %s"
 
 msgid "report pruned working trees"
-msgstr "báo cáo các cây làm việc đã prune"
+msgstr "liệt kê các cây làm việc đã prune"
 
 msgid "expire working trees older than <time>"
 msgstr "các cây làm việc hết hạn cũ hơn khoảng <thời gian>"
 
 #, c-format
 msgid "'%s' already exists"
-msgstr "“%s” đã có từ trước rồi"
+msgstr "'%s' đã có từ trước rồi"
 
 #, c-format
 msgid "unusable worktree destination '%s'"
-msgstr "đích cây làm việc không sử dụng được “%s”"
+msgstr "đích cây làm việc không sử dụng được '%s'"
 
 #, c-format
 msgid ""
 "'%s' is a missing but locked worktree;\n"
 "use '%s -f -f' to override, or 'unlock' and 'prune' or 'remove' to clear"
 msgstr ""
-"“%s” bị mất nhưng cây làm việc bị khóa;\n"
-"dùng “%s -f -f” để ghi đè, hoặc “unlock” và “prune” hay “remove” để xóa"
+"'%s' bị mất nhưng cây làm việc bị khóa;\n"
+"dùng '%s -f -f' để ghi đè, hoặc 'unlock' và 'prune' hay 'remove' để xóa"
 
 #, c-format
 msgid ""
 "'%s' is a missing but already registered worktree;\n"
 "use '%s -f' to override, or 'prune' or 'remove' to clear"
 msgstr ""
-"“%s” bị mất nhưng cây làm việc đã được đăng ký;\n"
-"dùng “%s -f” để ghi đè, hoặc “prune” hay “remove” để xóa"
+"'%s' bị mất nhưng cây làm việc đã được đăng ký;\n"
+"dùng '%s -f' để ghi đè, hoặc 'prune' hay 'remove' để xóa"
 
 #, c-format
 msgid "failed to copy '%s' to '%s'; sparse-checkout may not work correctly"
@@ -13000,37 +13471,62 @@
 
 #, c-format
 msgid "failed to copy worktree config from '%s' to '%s'"
-msgstr "gặp lỗi khi sao chép cấu hình cây làm việc từ “%s” sang “%s”"
+msgstr "gặp lỗi khi sao chép cấu hình cây làm việc từ '%s' sang '%s'"
 
 #, c-format
 msgid "failed to unset '%s' in '%s'"
-msgstr "gặp lỗi bỏ đặt “%s” trong “%s”"
+msgstr "gặp lỗi bỏ đặt '%s' trong '%s'"
 
 #, c-format
 msgid "could not create directory of '%s'"
-msgstr "không thể tạo thư mục của “%s”"
+msgstr "không thể tạo thư mục của '%s'"
 
 msgid "initializing"
 msgstr "khởi tạo"
 
 #, c-format
+msgid "could not find created worktree '%s'"
+msgstr "không tìm thấy cây làm việc '%s'"
+
+#, c-format
 msgid "Preparing worktree (new branch '%s')"
-msgstr "Đang chuẩn bị cây làm việc (nhánh mới “%s”)"
+msgstr "Đang chuẩn bị cây làm việc (nhánh mới '%s')"
 
 #, c-format
 msgid "Preparing worktree (resetting branch '%s'; was at %s)"
-msgstr "Đang chuẩn bị cây làm việc (đang cài đặt nhánh “%s”, trước đây tại %s)"
+msgstr "Đang chuẩn bị cây làm việc (đang tái đặt nhánh '%s'; trước đây tại %s)"
 
 #, c-format
 msgid "Preparing worktree (checking out '%s')"
-msgstr "Đang chuẩn bị cây làm việc (đang lấy ra “%s”)"
+msgstr "Đang chuẩn bị cây làm việc (đang checkout '%s')"
+
+#, c-format
+msgid "unreachable: invalid reference: %s"
+msgstr "không tham chiếu được: tham chiếu không hợp lệ: %s"
 
 #, c-format
 msgid "Preparing worktree (detached HEAD %s)"
-msgstr "Đang chuẩn bị cây làm việc (HEAD đã tách rời “%s”)"
+msgstr "Đang chuẩn bị cây làm việc (HEAD đã tách rời '%s')"
+
+#, c-format
+msgid ""
+"HEAD points to an invalid (or orphaned) reference.\n"
+"HEAD path: '%s'\n"
+"HEAD contents: '%s'"
+msgstr ""
+"HEAD trỏ đến tham chiếu sai (hoặc mồ côi).\n"
+"Đường dẫn HEAD: '%s'\n"
+"Nội dung HEAD: '%s'"
+
+msgid ""
+"No local or remote refs exist despite at least one remote\n"
+"present, stopping; use 'add -f' to override or fetch a remote first"
+msgstr ""
+"Không tồn tại tham chiếu cục bộ hay trên máy chủ mặc dù có cấu hình\n"
+"máy chủ, dừng lại; hãy dùng 'add -f' để ép buộc hoặc thực hiện kéo về trước"
 
 msgid "checkout <branch> even if already checked out in other worktree"
-msgstr "lấy ra <nhánh> ngay cả khi nó đã được lấy ra ở cây làm việc khác"
+msgstr "checkout <nhánh> ngay cả khi nó đã được checkout ở cây làm việc khác"
 
 msgid "create a new branch"
 msgstr "tạo nhánh mới"
@@ -13038,11 +13534,14 @@
 msgid "create or reset a branch"
 msgstr "tạo hay đặt lại một nhánh"
 
+msgid "create unborn branch"
+msgstr "tạo nhánh chưa sinh"
+
 msgid "populate the new working tree"
 msgstr "di chuyển cây làm việc mới"
 
 msgid "keep the new working tree locked"
-msgstr "giữ cây làm việc mới bị khóa"
+msgstr "tiếp tục khoá cây làm việc mới"
 
 msgid "reason for locking"
 msgstr "lý do khóa"
@@ -13057,6 +13556,10 @@
 msgid "options '%s', '%s', and '%s' cannot be used together"
 msgstr "tùy chọn '%s', '%s' và '%s' không thể dùng cùng nhau"
 
+#, c-format
+msgid "option '%s' and commit-ish cannot be used together"
+msgstr "tùy chọn '%s' và commit-ish không thể dùng cùng nhau"
+
 msgid "added with --lock"
 msgstr "được thêm với --lock"
 
@@ -13068,30 +13571,30 @@
 
 msgid "add 'prunable' annotation to worktrees older than <time>"
 msgstr ""
-"thêm chú thích kiểu “prunable” cho các cây làm việc hết hạn cũ hơn khoảng "
+"thêm chú thích kiểu 'prunable' cho các cây làm việc hết hạn cũ hơn khoảng "
 "<thời gian>"
 
 msgid "terminate records with a NUL character"
-msgstr "chấm dứt các bản ghi bằng ký tự NULL"
+msgstr "kết thúc các bản ghi bằng ký tự NULL"
 
 #, c-format
 msgid "'%s' is not a working tree"
 msgstr "%s không phải là cây làm việc"
 
 msgid "The main working tree cannot be locked or unlocked"
-msgstr "Cây thư mục làm việc chính không thể khóa hay bỏ khóa được"
+msgstr "Cây làm việc chính không thể khóa hay bỏ khóa được"
 
 #, c-format
 msgid "'%s' is already locked, reason: %s"
-msgstr "“%s” đã được khóa rồi, lý do: %s"
+msgstr "'%s' đã được khóa rồi, lý do: %s"
 
 #, c-format
 msgid "'%s' is already locked"
-msgstr "“%s” đã được khóa rồi"
+msgstr "'%s' đã được khóa rồi"
 
 #, c-format
 msgid "'%s' is not locked"
-msgstr "“%s” chưa bị khóa"
+msgstr "'%s' chưa bị khóa"
 
 msgid "working trees containing submodules cannot be moved or removed"
 msgstr "cây làm việc có chứa mô-đun-con không thể di chuyển hay xóa bỏ"
@@ -13101,11 +13604,11 @@
 
 #, c-format
 msgid "'%s' is a main working tree"
-msgstr "“%s” là cây làm việc chính"
+msgstr "'%s' là cây làm việc chính"
 
 #, c-format
 msgid "could not figure out destination name from '%s'"
-msgstr "không thể phác họa ra tên đích đến “%s”"
+msgstr "không thể phác họa ra tên đích đến '%s'"
 
 #, c-format
 msgid ""
@@ -13113,14 +13616,14 @@
 "use 'move -f -f' to override or unlock first"
 msgstr ""
 "không thể di chuyển một cây-làm-việc bị khóa, khóa vì: %s\n"
-"dùng “move -f -f” để ghi đè hoặc mở khóa trước đã"
+"dùng 'move -f -f' để ghi đè hoặc mở khóa trước đã"
 
 msgid ""
 "cannot move a locked working tree;\n"
 "use 'move -f -f' to override or unlock first"
 msgstr ""
 "không thể di chuyển một cây-làm-việc bị khóa;\n"
-"dùng “move -f -f” để ghi đè hoặc mở khóa trước đã"
+"dùng 'move -f -f' để ghi đè hoặc mở khóa trước đã"
 
 #, c-format
 msgid "validation failed, cannot move working tree: %s"
@@ -13128,21 +13631,21 @@
 
 #, c-format
 msgid "failed to move '%s' to '%s'"
-msgstr "gặp lỗi khi chuyển “%s” sang “%s”"
+msgstr "gặp lỗi khi chuyển '%s' sang '%s'"
 
 #, c-format
 msgid "failed to run 'git status' on '%s'"
-msgstr "gặp lỗi khi chạy “git status” vào “%s”"
+msgstr "gặp lỗi khi chạy 'git status' vào '%s'"
 
 #, c-format
 msgid "'%s' contains modified or untracked files, use --force to delete it"
 msgstr ""
-"“%s” có chứa các tập tin đã bị sửa chữa hoặc chưa được theo dõi, hãy dùng --"
+"'%s' có chứa các tập tin đã bị sửa chữa hoặc chưa được theo dõi, hãy dùng --"
 "force để xóa nó"
 
 #, c-format
 msgid "failed to run 'git status' on '%s', code %d"
-msgstr "gặp lỗi khi chạy “git status” trong “%s”, mã %d"
+msgstr "gặp lỗi khi chạy 'git status' trong '%s', mã %d"
 
 msgid "force removal even if worktree is dirty or locked"
 msgstr "ép buộc di chuyển thậm chí cả khi cây làm việc đang bẩn hay bị khóa"
@@ -13153,14 +13656,14 @@
 "use 'remove -f -f' to override or unlock first"
 msgstr ""
 "không thể xóa bỏ một cây-làm-việc bị khóa, khóa vì: %s\n"
-"dùng “remove -f -f” để ghi đè hoặc mở khóa trước đã"
+"dùng 'remove -f -f' để ghi đè hoặc mở khóa trước đã"
 
 msgid ""
 "cannot remove a locked working tree;\n"
 "use 'remove -f -f' to override or unlock first"
 msgstr ""
 "không thể xóa bỏ một cây-làm-việc bị khóa;\n"
-"dùng “remove -f -f” để ghi đè hoặc mở khóa trước đã"
+"dùng 'remove -f -f' để ghi đè hoặc mở khóa trước đã"
 
 #, c-format
 msgid "validation failed, cannot remove working tree: %s"
@@ -13186,17 +13689,73 @@
 msgid "only useful for debugging"
 msgstr "chỉ hữu ích khi cần gỡ lỗi"
 
+msgid "core.fsyncMethod = batch is unsupported on this platform"
+msgstr "core.fsyncMethod = batch không được hỗ trợ trên nền tảng này"
+
+#, c-format
+msgid "could not parse bundle list key %s with value '%s'"
+msgstr "không thể đọc danh sách bundle khoá %s giá trị '%s'"
+
+#, c-format
+msgid "bundle list at '%s' has no mode"
+msgstr "bundle list at '%s' has no mode"
+
+msgid "failed to create temporary file"
+msgstr "không thể tạo tập tin tạm thời"
+
+msgid "insufficient capabilities"
+msgstr "không đủ quyền hạn"
+
+#, c-format
+msgid "file downloaded from '%s' is not a bundle"
+msgstr "tập tin lấy về từ '%s' không phải là bundle"
+
+msgid "failed to store maximum creation token"
+msgstr "gặp lỗi khi lưu token tạo tối đa"
+
+#, c-format
+msgid "unrecognized bundle mode from URI '%s'"
+msgstr "không nhận ra định dạng bundle từ URI '%s'"
+
+#, c-format
+msgid "exceeded bundle URI recursion limit (%d)"
+msgstr "vượt quá giới hạn đệ quy URI (%d)"
+
+#, c-format
+msgid "failed to download bundle from URI '%s'"
+msgstr "gặp lỗi khi tải bundle từ URI '%s'"
+
+#, c-format
+msgid "file at URI '%s' is not a bundle or bundle list"
+msgstr "tập tin ở URI '%s' không phải bundle hay danh sách bundle"
+
+#, c-format
+msgid "bundle-uri: unexpected argument: '%s'"
+msgstr "bundle-uri: không nhận ra đối số: '%s'"
+
+msgid "bundle-uri: expected flush after arguments"
+msgstr "bundle-uri: cần flush dữ liệu sau các tham số"
+
+msgid "bundle-uri: got an empty line"
+msgstr "bundle-uri: nhận được dòng trống"
+
+msgid "bundle-uri: line is not of the form 'key=value'"
+msgstr "bundle-uri: dòng không có dạng 'key=value'"
+
+msgid "bundle-uri: line has empty key or value"
+msgstr "bundle-uri: dòng có key trống hoặc value trống"
+
 #, c-format
 msgid "unrecognized bundle hash algorithm: %s"
-msgstr "không hiểu thuật toán băm dữ liệu bundle: %s"
+msgstr "không hiểu thuật toán băm bundle: %s"
 
 #, c-format
 msgid "unknown capability '%s'"
-msgstr "không hiểu dung lượng “%s”"
+msgstr "không hiểu dung lượng '%s'"
 
 #, c-format
 msgid "'%s' does not look like a v2 or v3 bundle file"
-msgstr "“%s” không giống như tập tin v2 hay v3 bundle (định dạng dump của git)"
+msgstr "'%s' không giống như tập tin bundle v2 hay v3 (định dạng dump của git)"
 
 #, c-format
 msgid "unrecognized header: %s%s (%d)"
@@ -13208,6 +13767,13 @@
 msgid "need a repository to verify a bundle"
 msgstr "cần một kho chứa để thẩm tra một bundle"
 
+msgid ""
+"some prerequisite commits exist in the object store, but are not connected "
+"to the repository's history"
+msgstr ""
+"một số lần chuyển giao tiên quyết tồn tại trong object store, nhưng không "
+"nằm trong lịch sử của kho chứa"
+
 #, c-format
 msgid "The bundle contains this ref:"
 msgid_plural "The bundle contains these %<PRIuMAX> refs:"
@@ -13221,18 +13787,26 @@
 msgid_plural "The bundle requires these %<PRIuMAX> refs:"
 msgstr[0] "Lệnh bundle yêu cầu %<PRIuMAX> tham chiếu này:"
 
+#, c-format
+msgid "The bundle uses this hash algorithm: %s"
+msgstr "Lệnh bundle dùng thuật toán băm sau: %s"
+
+#, c-format
+msgid "The bundle uses this filter: %s"
+msgstr "Lệnh bundle dùng bộ lọc sau: %s"
+
 msgid "unable to dup bundle descriptor"
-msgstr "không thể nhân đôi bộ mô tả bundle"
+msgstr "không thể dup bundle descriptor"
 
 msgid "Could not spawn pack-objects"
-msgstr "Không thể sản sinh đối tượng gói"
+msgstr "Không thể spawn pack-objects"
 
 msgid "pack-objects died"
-msgstr "đối tượng gói đã chết"
+msgstr "pack-objects đã chết"
 
 #, c-format
 msgid "ref '%s' is excluded by the rev-list options"
-msgstr "th.chiếu “%s” bị loại trừ bởi các tùy chọn rev-list"
+msgstr "th.chiếu '%s' bị loại trừ bởi các tùy chọn rev-list"
 
 #, c-format
 msgid "unsupported bundle version %d"
@@ -13247,25 +13821,29 @@
 
 #, c-format
 msgid "cannot create '%s'"
-msgstr "không thể tạo “%s”"
+msgstr "không thể tạo '%s'"
 
 msgid "index-pack died"
-msgstr "mục lục gói đã chết"
+msgstr "index-pack đã chết"
 
 msgid "terminating chunk id appears earlier than expected"
-msgstr "mã mảnh kết thúc sớm hơn bình thường"
+msgstr "id chunk kết thúc sớm hơn bình thường"
+
+#, c-format
+msgid "chunk id %<PRIx32> not %d-byte aligned"
+msgstr "id chunk %<PRIx32> không thẳng %d-byte"
 
 #, c-format
 msgid "improper chunk offset(s) %<PRIx64> and %<PRIx64>"
-msgstr "bù mảnh không đúng cách %<PRIx64> và %<PRIx64>"
+msgstr "chunk offset bất thường %<PRIx64> và %<PRIx64>"
 
 #, c-format
 msgid "duplicate chunk ID %<PRIx32> found"
-msgstr "tìm thấy ID của mảnh bị trùng lặp %<PRIx32>"
+msgstr "tìm thấy ID của chunk bị trùng lặp %<PRIx32>"
 
 #, c-format
 msgid "final chunk has non-zero id %<PRIx32>"
-msgstr "mảnh cuối cùng có id không bằng không %<PRIx32>"
+msgstr "chunk cuối cùng có id không bằng không %<PRIx32>"
 
 msgid "invalid hash version"
 msgstr "phiên bản băm không hợp lệ"
@@ -13275,7 +13853,7 @@
 msgstr "giá trị màu không hợp lệ: %.*s"
 
 msgid "Add file contents to the index"
-msgstr "Thêm nội dung tập tin vào bảng mục lục"
+msgstr "Thêm nội dung tập tin vào chỉ mục"
 
 msgid "Apply a series of patches from a mailbox"
 msgstr "Áp dụng một chuỗi các miếng và từ một mailbox"
@@ -13284,8 +13862,7 @@
 msgstr "Các dòng diễn giải tập tin với thông tin chuyển giao"
 
 msgid "Apply a patch to files and/or to the index"
-msgstr ""
-"Áp dụng một miếng vá cho các tập tin đã chỉ ra và/hoặc vào bảng mục lục"
+msgstr "Áp dụng một bản vá cho các tập tin đã chỉ ra và/hoặc vào chỉ mục"
 
 msgid "Import a GNU Arch repository into Git"
 msgstr "Nhập một kho GNU Arch vào một kho Git"
@@ -13310,8 +13887,8 @@
 msgid "Move objects and refs by archive"
 msgstr "Di chuyển các đối tượng và tham chiếu theo kho lưu"
 
-msgid "Provide content or type and size information for repository objects"
-msgstr "Cung cấp nội dung hoặc thông tin về kiểu và cỡ cho các đối tượng kho"
+msgid "Provide contents or details of repository objects"
+msgstr "Cung cấp nội dung hoặc thông tin về các đối tượng kho"
 
 msgid "Display gitattributes information"
 msgstr "Hiển thị thông tin gitattributes"
@@ -13326,13 +13903,13 @@
 msgstr "Đảm bảo rằng một tên tham chiếu ở dạng thức tốt"
 
 msgid "Switch branches or restore working tree files"
-msgstr "Chuyển các nhánh hoặc phục hồi lại các tập tin cây làm việc"
+msgstr "Chuyển các nhánh hoặc phục hồi lại các tập tin trong cây làm việc"
 
 msgid "Copy files from the index to the working tree"
-msgstr "Sao chép các tập tin từ mục lục ra cây làm việc"
+msgstr "Sao chép các tập tin từ chỉ mục ra cây làm việc"
 
 msgid "Find commits yet to be applied to upstream"
-msgstr "Tìm những lần chuyển giao còn chưa được áp dụng lên thượng nguồn"
+msgstr "Tìm những lần chuyển giao chưa được đẩy lên thượng nguồn"
 
 msgid "Apply the changes introduced by some existing commits"
 msgstr "Áp dụng các thay đổi được đưa ra bởi một số lần chuyển giao sẵn có"
@@ -13369,13 +13946,13 @@
 msgstr "Nhận và lưu chứng nhận của người dùng"
 
 msgid "Helper to temporarily store passwords in memory"
-msgstr "Bộ hỗ trợ để lưu mật khẩu tạm thời trong bộ nhớ"
+msgstr "helper để lưu mật khẩu tạm thời trong bộ nhớ"
 
 msgid "Helper to store credentials on disk"
-msgstr "Bộ hỗ trợ để lưu chứng nhận vào đĩa"
+msgstr "helper để lưu chứng nhận vào đĩa"
 
 msgid "Export a single commit to a CVS checkout"
-msgstr "Xuất một lần chuyển giao thành một lần lấy ra CVS"
+msgstr "Xuất một lần chuyển giao thành một lần checkout CVS"
 
 msgid "Salvage your data out of another SCM people love to hate"
 msgstr "Xem xét giá trị dữ liệu của bạn khỏi người khác yêu SCM để ghét"
@@ -13384,23 +13961,26 @@
 msgstr "Một bộ mô phỏng máy dịch vụ CVS cho Git"
 
 msgid "A really simple server for Git repositories"
-msgstr "Một máy phục vụ thực sự đơn giản dành cho kho Git"
+msgstr "Một máy chủ thực sự đơn giản dành cho kho Git"
 
 msgid "Give an object a human readable name based on an available ref"
 msgstr ""
 "Đưa ra một đối tượng dựa trên một tên ở dạng con người đọc được trên một "
 "tham chiếu sẵn có"
 
+msgid "Generate a zip archive of diagnostic information"
+msgstr "tạo tập tin nén zip của bản báo cáo"
+
 msgid "Show changes between commits, commit and working tree, etc"
 msgstr ""
 "Hiển thị các thay đổi giữa những lần chuyển giao, giữa một lần chuyển giao "
 "và cây làm việc, v.v.."
 
 msgid "Compares files in the working tree and the index"
-msgstr "So sánh các tập tin trong cây làm việc và bảng mục lục"
+msgstr "So sánh các tập tin trong cây làm việc và chỉ mục"
 
 msgid "Compare a tree to the working tree or index"
-msgstr "So sánh các cây trong cây làm việc hoặc bảng mục lục"
+msgstr "So sánh các cây trong cây làm việc hoặc chỉ mục"
 
 msgid "Compares the content and mode of blobs found via two tree objects"
 msgstr ""
@@ -13434,7 +14014,7 @@
 msgstr "Chạy lệnh Git trên danh sách các kho chứa"
 
 msgid "Prepare patches for e-mail submission"
-msgstr "Chuẩn bị các miếng vá để gửi qua thư điện tử"
+msgstr "Chuẩn bị các bản vá để gửi qua thư điện tử"
 
 msgid "Verifies the connectivity and validity of the objects in the database"
 msgstr ""
@@ -13454,8 +14034,8 @@
 msgid "A portable graphical interface to Git"
 msgstr "Một giao diện đồ họa khả chuyển cho Git"
 
-msgid "Compute object ID and optionally creates a blob from a file"
-msgstr "Tính toán ID đối tượng và tùy chọn là tạo một blob từ một tập tin"
+msgid "Compute object ID and optionally create an object from a file"
+msgstr "Tính toán ID đối tượng và tùy tạo một object từ một tập tin"
 
 msgid "Display help information about Git"
 msgstr "Hiển thị thông tin trợ giúp về Git"
@@ -13464,7 +14044,7 @@
 msgstr "Chạy các móc git"
 
 msgid "Server side implementation of Git over HTTP"
-msgstr "Thi hành phía máy chủ của Git qua HTTP"
+msgstr "Hỗ trợ phía máy chủ của Git qua HTTP"
 
 msgid "Download from a remote Git repository via HTTP"
 msgstr "Tải về từ một kho chứa Git trên mạng thông qua HTTP"
@@ -13473,11 +14053,10 @@
 msgstr "Đẩy các đối tượng lên thông qua HTTP/DAV đến kho chứa khác"
 
 msgid "Send a collection of patches from stdin to an IMAP folder"
-msgstr ""
-"Gửi một bộ sưu tập các miếng vá từ đầu vào tiêu chuẩn đến một thư mục IMAP"
+msgstr "Gửi một bộ sưu tập các bản vá từ stdin đến một thư mục IMAP"
 
 msgid "Build pack index file for an existing packed archive"
-msgstr "Xây dựng tập tin mục lục gói cho một kho nén đã đóng gói sẵn có"
+msgstr "Xây dựng tập tin chỉ mục gói cho một kho nén đã đóng gói sẵn có"
 
 msgid "Create an empty Git repository or reinitialize an existing one"
 msgstr "Tạo một kho git mới hay khởi tạo lại một kho đã tồn tại từ trước"
@@ -13486,13 +14065,13 @@
 msgstr "Duyệt ngay kho làm việc của bạn trong gitweb"
 
 msgid "Add or parse structured information in commit messages"
-msgstr "Thêm hay phân tích thông tin cấu trúc trong ghi chú lần chuyển giao"
+msgstr "Thêm hay đọc thông tin cấu trúc trong ghi chú lần chuyển giao"
 
 msgid "Show commit logs"
 msgstr "Hiển thị nhật ký các lần chuyển giao"
 
 msgid "Show information about files in the index and the working tree"
-msgstr "Hiển thị thông tin về các tập tin trong bảng mục lục và cây làm việc"
+msgstr "Hiển thị thông tin về các tập tin trong chỉ mục và cây làm việc"
 
 msgid "List references in a remote repository"
 msgstr "Liệt kê các tham chiếu trong một kho chứa trên mạng"
@@ -13516,7 +14095,7 @@
 msgstr "Tìm các tổ tiên chung tốt có thể được cho hòa trộn"
 
 msgid "Run a three-way file merge"
-msgstr "Chạy một hòa trộn tập tin “3-đường”"
+msgstr "Chạy một hòa trộn tập tin '3-đường'"
 
 msgid "Run a merge for files needing merging"
 msgstr "Chạy một hòa trộn cho các tập tin cần hòa trộn"
@@ -13524,13 +14103,12 @@
 msgid "The standard helper program to use with git-merge-index"
 msgstr "Một chương trình hỗ trợ tiêu chuẩn dùng với git-merge-index"
 
-msgid "Show three-way merge without touching index"
-msgstr "Hiển thị hòa trộn ba-đường mà không đụng chạm đến mục lục"
+msgid "Perform merge without touching index or working tree"
+msgstr "Áp dụng một bản vá mà không động chạm đến cây làm việc"
 
 msgid "Run merge conflict resolution tools to resolve merge conflicts"
 msgstr ""
-"Chạy công cụ phân giải xung đột hòa trộn để mà giải quyết các xung đột hòa "
-"trộn"
+"Chạy công cụ phân giải xung đột hòa trộn để giải quyết các xung đột hòa trộn"
 
 msgid "Creates a tag object with extra validation"
 msgstr "Tạo một đối tượng thẻ với kiểm tra mở rộng"
@@ -13563,7 +14141,7 @@
 msgstr "Đóng gói các phần đầu và thẻ để truy cập kho hiệu quả hơn"
 
 msgid "Compute unique ID for a patch"
-msgstr "Tính toán ID duy nhất cho một miếng vá"
+msgstr "Tính toán ID duy nhất cho một bản vá"
 
 msgid "Prune all unreachable objects from the object database"
 msgstr ""
@@ -13579,16 +14157,16 @@
 msgstr "Cập nhật th.chiếu máy chủ cùng với các đối tượng liên quan đến nó"
 
 msgid "Applies a quilt patchset onto the current branch"
-msgstr "Ấp dụng một bộ miếng vá quilt vào trong nhánh hiện hành"
+msgstr "Ấp dụng một bộ bản vá quilt vào trong nhánh hiện hành"
 
 msgid "Compare two commit ranges (e.g. two versions of a branch)"
 msgstr "So sánh hai vùng chuyển giao (vd: hai phiên bản của một nhánh)"
 
 msgid "Reads tree information into the index"
-msgstr "Đọc thông tin cây vào trong mục lục"
+msgstr "Đọc thông tin cây vào trong chỉ mục"
 
 msgid "Reapply commits on top of another base tip"
-msgstr "Thu hoạch các lần chuyển giao trên đỉnh của đầu mút cơ sở khác"
+msgstr "Thu hoạch các lần chuyển giao trên đỉnh của đỉnh cơ sở khác"
 
 msgid "Receive what is pushed into the repository"
 msgstr "Nhận cái mà được đẩy vào trong kho"
@@ -13605,6 +14183,11 @@
 msgid "Create, list, delete refs to replace objects"
 msgstr "Tạo, liệt kê, xóa các tham chiếu để thay thế các đối tượng"
 
+msgid "EXPERIMENTAL: Replay commits on a new base, works with bare repos too"
+msgstr ""
+"ĐANG TRONG QUÁ TRÌNH THỬ NGHIỆM: Phát lại lần chuyển giao vào gốc mới, dùng "
+"được trong kho chứa bare"
+
 msgid "Generates a summary of pending changes"
 msgstr "Tạo ra một tóm tắt các thay đổi còn treo"
 
@@ -13627,10 +14210,10 @@
 msgstr "Hoàn lại một số lần chuyển giao sẵn có"
 
 msgid "Remove files from the working tree and from the index"
-msgstr "Gỡ bỏ các tập tin từ cây làm việc và từ bảng mục lục"
+msgstr "Gỡ bỏ các tập tin từ cây làm việc và từ chỉ mục"
 
 msgid "Send a collection of patches as emails"
-msgstr "Gửi một tập hợp của các miếng vá ở dạng thư điện tử"
+msgstr "Gửi một tập hợp của các bản vá ở dạng thư điện tử"
 
 msgid "Push objects over Git protocol to another repository"
 msgstr "Đẩy các đối tượng lên thông qua giao thức Git đến kho chứa khác"
@@ -13645,7 +14228,7 @@
 msgstr "Hệ vỏ đăng nhập có hạn chế cho truy cập SSH chỉ-Git"
 
 msgid "Summarize 'git log' output"
-msgstr "Kết xuất “git log” dạng tóm tắt"
+msgstr "Kết xuất 'git log' dạng tóm tắt"
 
 msgid "Show various types of objects"
 msgstr "Hiển thị các kiểu khác nhau của các đối tượng"
@@ -13698,7 +14281,7 @@
 msgstr "Gỡ các đối tượng khỏi một kho lưu đã đóng gói"
 
 msgid "Register file contents in the working tree to the index"
-msgstr "Đăng ký nội dung tập tin từ cây làm việc đến bảng mục lục"
+msgstr "Đăng ký nội dung tập tin từ cây làm việc đến chỉ mục"
 
 msgid "Update the object name stored in a ref safely"
 msgstr "Cập nhật tên đối tượng được lưu trong một tham chiếu một cách an toàn"
@@ -13724,20 +14307,23 @@
 msgid "Check the GPG signature of tags"
 msgstr "Kiểm tra chữ ký GPG của các thẻ"
 
-msgid "Show logs with difference each commit introduces"
-msgstr "Hiển thị các nhật ký với từng lần chuyển giao khác nhau đưa ra"
+msgid "Display version information about Git"
+msgstr "Hiển thị thông tin về phiên bản Git"
+
+msgid "Show logs with differences each commit introduces"
+msgstr "Hiển thị nhật ký với thay đổi của từng lần chuyển giao"
 
 msgid "Manage multiple working trees"
 msgstr "Quản lý nhiều cây làm việc"
 
 msgid "Create a tree object from the current index"
-msgstr "Tạo một đối tượng cây từ đầu vào tiêu chuẩn stdin hiện tại"
+msgstr "Tạo một đối tượng cây từ chỉ mục hiện tại"
 
 msgid "Defining attributes per path"
 msgstr "Định nghĩa các thuộc tính cho mỗi đường dẫn"
 
 msgid "Git command-line interface and conventions"
-msgstr "Giao diện dòng lệnh Git và quy ước"
+msgstr "Giao diện dòng lệnh Git và các quy ước"
 
 msgid "A Git core tutorial for developers"
 msgstr "Hướng dẫn Git cơ bản cho nhà phát triển"
@@ -13752,22 +14338,40 @@
 msgstr "Chỉnh kết xuất diff"
 
 msgid "A useful minimum set of commands for Everyday Git"
-msgstr "Một tập hợp lệnh hữu dụng tối thiểu để dùng Git hàng ngày"
+msgstr "Tập hợp lệnh hữu dụng tối thiểu để dùng Git hàng ngày"
 
 msgid "Frequently asked questions about using Git"
 msgstr "Các câu hỏi thường gặp về cách sử dụng Git"
 
+msgid "The bundle file format"
+msgstr "Định dạng tập tin bundle"
+
+msgid "Chunk-based file formats"
+msgstr "Định dạng tập tin dạng khúc"
+
+msgid "Git commit-graph format"
+msgstr "Định dạng đồ-thị-chuyển-giao"
+
+msgid "Git index format"
+msgstr "Định dạng chỉ mục"
+
+msgid "Git pack format"
+msgstr "Định dạng pack"
+
+msgid "Git cryptographic signature formats"
+msgstr "Định dạng chữ ký bảo mật Git"
+
 msgid "A Git Glossary"
 msgstr "Thuật ngữ chuyên môn Git"
 
 msgid "Hooks used by Git"
-msgstr "Các móc được sử dụng bởi Git"
+msgstr "Các hook được sử dụng bởi Git"
 
 msgid "Specifies intentionally untracked files to ignore"
 msgstr "Chỉ định các tập tin không cần theo dõi"
 
 msgid "The Git repository browser"
-msgstr "Bộ duyện kho Git"
+msgstr "Bộ duyệt kho Git"
 
 msgid "Map author/committer names and/or E-Mail addresses"
 msgstr "Ánh xạ tên tác giả/người chuyển giao và/hoặc địa chỉ E-Mail"
@@ -13778,8 +14382,23 @@
 msgid "Git namespaces"
 msgstr "Không gian tên Git"
 
+msgid "Protocol v0 and v1 capabilities"
+msgstr "Capabilities của giao thức v0 và v1"
+
+msgid "Things common to various protocols"
+msgstr "Những thứ chung cho các giao thức"
+
+msgid "Git HTTP-based protocols"
+msgstr "Những giao thức Git dựa trên HTTP"
+
+msgid "How packs are transferred over-the-wire"
+msgstr "Gói được truyền thực tế (over-the-wire) như thế nào"
+
+msgid "Git Wire Protocol, Version 2"
+msgstr "Git Wire Protocol, Version 2"
+
 msgid "Helper programs to interact with remote repositories"
-msgstr "Các chương trình hỗ trợ để tương tác với các kho chứa trên máy chủ"
+msgstr "Các chương trình helper để tương tác với các kho chứa trên máy chủ"
 
 msgid "Git Repository Layout"
 msgstr "Bố cục kho Git"
@@ -13802,44 +14421,90 @@
 msgid "An overview of recommended workflows with Git"
 msgstr "Tổng quan về luồng công việc khuyến nghị nên dùng với Git"
 
+msgid "A tool for managing large Git repositories"
+msgstr "Công cụ quản lý các kho Git lớn"
+
 msgid "commit-graph file is too small"
-msgstr "tập tin đồ-thị-các-lần-chuyển-giao quá nhỏ"
+msgstr "tập tin đồ-thị-chuyển-giao quá nhỏ"
+
+msgid "commit-graph oid fanout chunk is wrong size"
+msgstr "đồ-thị-chuyển-giao có kích cỡ oid fanout chunk không đúng"
+
+msgid "commit-graph fanout values out of order"
+msgstr "đồ-thị-chuyển-giao có giá trị fanout không đúng"
+
+msgid "commit-graph OID lookup chunk is the wrong size"
+msgstr "đồ-thị-chuyển-giao có kích cỡ OID lookup chunk không đúng"
+
+msgid "commit-graph commit data chunk is wrong size"
+msgstr "đồ-thị-chuyển-giao có kích cỡ commit data chunk không đúng"
+
+msgid "commit-graph generations chunk is wrong size"
+msgstr "đồ-thị-chuyển-giao có kích cỡ generations chunk không đúng"
+
+msgid "commit-graph changed-path index chunk is too small"
+msgstr "đồ-thị-chuyển-giao có changed-path index chunk quá nhỏ"
+
+#, c-format
+msgid ""
+"ignoring too-small changed-path chunk (%<PRIuMAX> < %<PRIuMAX>) in commit-"
+"graph file"
+msgstr ""
+"bỏ qua chunk thay-đổi-đường-dẫn quá nhỏ (%<PRIuMAX> < %<PRIuMAX>) trong tập "
+"tin đồ-thị-chuyển-giao"
 
 #, c-format
 msgid "commit-graph signature %X does not match signature %X"
-msgstr "chữ ký đồ-thị-các-lần-chuyển-giao %X không khớp chữ ký %X"
+msgstr "chữ ký đồ-thị-chuyển-giao %X không khớp chữ ký %X"
 
 #, c-format
 msgid "commit-graph version %X does not match version %X"
-msgstr "phiên bản đồ-thị-các-lần-chuyển-giao %X không khớp phiên bản %X"
+msgstr "phiên bản đồ-thị-chuyển-giao %X không khớp phiên bản %X"
 
 #, c-format
 msgid "commit-graph hash version %X does not match version %X"
-msgstr "phiên bản đồ-thị-các-lần-chuyển-giao %X không khớp phiên bản %X"
+msgstr "phiên bản đồ-thị-chuyển-giao %X không khớp phiên bản %X"
 
 #, c-format
 msgid "commit-graph file is too small to hold %u chunks"
-msgstr "tập tin đồ-thị-các-lần-chuyển-giao quá nhỏ để giữ %u mảnh dữ liệu"
+msgstr "tập tin đồ-thị-chuyển-giao quá nhỏ để giữ %u chunk"
+
+msgid "commit-graph required OID fanout chunk missing or corrupted"
+msgstr "đồ-thị-chuyển-giao thiếu chunk OID fanout cần thiết hoặc bị hỏng"
+
+msgid "commit-graph required OID lookup chunk missing or corrupted"
+msgstr "đồ-thị-chuyển-giao thiếu chunk OID lookup cần thiết hoặc bị hỏng"
+
+msgid "commit-graph required commit data chunk missing or corrupted"
+msgstr "đồ-thị-chuyển-giao thiếu chunk commit data cần thiết hoặc bị hỏng"
 
 msgid "commit-graph has no base graphs chunk"
-msgstr "đồ-thị-các-lần-chuyển-giao có không có mảnh các đồ họa cơ sở"
+msgstr "đồ thị chuyển giao không có chunk đồ thị cơ sở"
+
+msgid "commit-graph base graphs chunk is too small"
+msgstr "đồ thị chuyển giao có chunk đồ thị cơ sở quá nhỏ"
 
 msgid "commit-graph chain does not match"
-msgstr "móc xích đồ-thị-các-lần-chuyển-giao không khớp"
+msgstr "chuỗi đồ-thị-chuyển-giao không khớp"
+
+#, c-format
+msgid "commit count in base graph too high: %<PRIuMAX>"
+msgstr "số lần chuyển giao trong đồ thị cơ sở quá lớn: %<PRIuMAX>"
+
+msgid "commit-graph chain file too small"
+msgstr "tập tin chuỗi đồ-thị-chuyển-giao quá nhỏ"
 
 #, c-format
 msgid "invalid commit-graph chain: line '%s' not a hash"
 msgstr ""
-"móc xích đồ-thị-các-lần-chuyển-giao không hợp lệ: dòng “%s” không phải là "
-"một mã băm"
+"chuỗi đồ-thị-chuyển-giao không hợp lệ: dòng '%s' không phải là một mã băm"
 
 msgid "unable to find all commit-graph files"
-msgstr "không thể tìm thấy tất cả các tập tin đồ-thị-các-lần-chuyển-giao"
+msgstr "không thể tìm thấy tất cả các tập tin đồ-thị-chuyển-giao"
 
 msgid "invalid commit position. commit-graph is likely corrupt"
 msgstr ""
-"vị trí lần chuyển giao không hợp lệ. đồ-thị-các-lần-chuyển-giao có vẻ như đã "
-"bị hỏng"
+"vị trí lần chuyển giao không hợp lệ. đồ-thị-chuyển-giao có vẻ như đã bị hỏng"
 
 #, c-format
 msgid "could not find commit %s"
@@ -13848,6 +14513,12 @@
 msgid "commit-graph requires overflow generation data but has none"
 msgstr "commit-graph yêu cầu dữ liệu tạo tràn nhưng không có"
 
+msgid "commit-graph overflow generation data is too small"
+msgstr "commit-graph yêu cầu dữ liệu tạo tràn nhưng quá nhỏ"
+
+msgid "commit-graph extra-edges pointer out of bounds"
+msgstr "con trỏ extra-edge của đồ thị chuyển giao nằm ngoài biên"
+
 msgid "Loading known commits in commit graph"
 msgstr "Đang tải các lần chuyển giao chưa biết trong đồ thị lần chuyển giao"
 
@@ -13883,7 +14554,7 @@
 
 #, c-format
 msgid "error opening index for %s"
-msgstr "gặp lỗi khi mở mục lục cho “%s”"
+msgstr "gặp lỗi khi mở chỉ mục cho '%s'"
 
 msgid "Finding commits for commit graph among packed objects"
 msgstr ""
@@ -13901,7 +14572,7 @@
 
 #, c-format
 msgid "unable to adjust shared permissions for '%s'"
-msgstr "không thể chỉnh sửa quyền chia sẻ thành “%s”"
+msgstr "không thể chỉnh sửa quyền chia sẻ thành '%s'"
 
 #, c-format
 msgid "Writing out commit graph in %d pass"
@@ -13912,20 +14583,28 @@
 msgstr "không thể mở tập tin mắt xích đồ thị chuyển giao"
 
 msgid "failed to rename base commit-graph file"
-msgstr "gặp lỗi khi đổi tên tập tin đồ-thị-các-lần-chuyển-giao"
+msgstr "gặp lỗi khi đổi tên tập tin đồ-thị-chuyển-giao"
 
 msgid "failed to rename temporary commit-graph file"
-msgstr "gặp lỗi khi đổi tên tập tin đồ-thị-các-lần-chuyển-giao tạm thời"
+msgstr "gặp lỗi khi đổi tên tập tin đồ-thị-chuyển-giao tạm thời"
+
+#, c-format
+msgid "cannot merge graphs with %<PRIuMAX>, %<PRIuMAX> commits"
+msgstr "không thể kết hợp đồ thị với %<PRIuMAX>, %<PRIuMAX> lần chuyển giao"
+
+#, c-format
+msgid "cannot merge graph %s, too many commits: %<PRIuMAX>"
+msgstr "không thể kết hợp đồ thị %s, quá nhiều lần chuyển giao: %<PRIuMAX>"
 
 msgid "Scanning merged commits"
 msgstr "Đang quét các lần chuyển giao đã hòa trộn"
 
 msgid "Merging commit-graph"
-msgstr "Đang hòa trộn đồ-thị-các-lần-chuyển-giao"
+msgstr "Đang hòa trộn đồ-thị-chuyển-giao"
 
 msgid "attempting to write a commit-graph, but 'core.commitGraph' is disabled"
 msgstr ""
-"cố gắng để ghi một đồ thị các lần chuyển giao, nhưng “core.commitGraph” bị "
+"cố gắng để ghi một đồ thị các lần chuyển giao, nhưng 'core.commitGraph' bị "
 "vô hiệu hóa"
 
 msgid "too many commits to write graph"
@@ -13933,78 +14612,70 @@
 
 msgid "the commit-graph file has incorrect checksum and is likely corrupt"
 msgstr ""
-"tập tin đồ-thị-các-lần-chuyển-giao có tổng kiểm không đúng và có vẻ như là "
-"đã hỏng"
+"tập tin đồ-thị-chuyển-giao có tổng kiểm không đúng và có vẻ như là đã hỏng"
 
 #, c-format
 msgid "commit-graph has incorrect OID order: %s then %s"
-msgstr "đồ-thị-các-lần-chuyển-giao có thứ tự OID không đúng: %s sau %s"
+msgstr "đồ-thị-chuyển-giao có thứ tự OID không đúng: %s sau %s"
 
 #, c-format
 msgid "commit-graph has incorrect fanout value: fanout[%d] = %u != %u"
-msgstr ""
-"đồ-thị-các-lần-chuyển-giao có giá trị fanout không đúng: fanout[%d] = %u != "
-"%u"
+msgstr "đồ-thị-chuyển-giao có giá trị fanout không đúng: fanout[%d] = %u != %u"
 
 #, c-format
 msgid "failed to parse commit %s from commit-graph"
-msgstr "gặp lỗi khi phân tích lần chuyển giao từ %s đồ-thị-các-lần-chuyển-giao"
+msgstr "gặp lỗi khi đọc lần chuyển giao từ %s đồ-thị-chuyển-giao"
+
+#, c-format
+msgid "failed to parse commit %s from object database for commit-graph"
+msgstr ""
+"gặp lỗi khi đọc lần chuyển giao %s từ cơ sở dữ liệu đối tượng cho đồ thị lần "
+"chuyển giao"
+
+#, c-format
+msgid "root tree OID for commit %s in commit-graph is %s != %s"
+msgstr ""
+"OID cây gốc cho lần chuyển giao %s trong đồ-thị-chuyển-giao là %s != %s"
+
+#, c-format
+msgid "commit-graph parent list for commit %s is too long"
+msgstr "danh sách cha mẹ đồ-thị-chuyển-giao cho lần chuyển giao %s là quá dài"
+
+#, c-format
+msgid "commit-graph parent for %s is %s != %s"
+msgstr "cha mẹ đồ-thị-chuyển-giao cho %s là %s != %s"
+
+#, c-format
+msgid "commit-graph parent list for commit %s terminates early"
+msgstr ""
+"danh sách cha mẹ đồ-thị-chuyển-giao cho lần chuyển giao %s bị chấm dứt quá "
+"sớm"
+
+#, c-format
+msgid "commit-graph generation for commit %s is %<PRIuMAX> < %<PRIuMAX>"
+msgstr ""
+"tạo đồ-thị-chuyển-giao cho lần chuyển giao %s là %<PRIuMAX> < %<PRIuMAX>"
+
+#, c-format
+msgid "commit date for commit %s in commit-graph is %<PRIuMAX> != %<PRIuMAX>"
+msgstr ""
+"ngày chuyển giao cho lần chuyển giao %s trong đồ-thị-chuyển-giao là "
+"%<PRIuMAX> != %<PRIuMAX>"
+
+#, c-format
+msgid ""
+"commit-graph has both zero and non-zero generations (e.g., commits '%s' and "
+"'%s')"
+msgstr ""
+"đồ-thị-chuyển-giao có số thế hệ không và khác không (v.d. lần chuyển giao "
+"'%s' và '%s')"
 
 msgid "Verifying commits in commit graph"
 msgstr "Đang thẩm tra các lần chuyển giao trong đồ thị lần chuyển giao"
 
 #, c-format
-msgid "failed to parse commit %s from object database for commit-graph"
-msgstr ""
-"gặp lỗi khi phân tích lần chuyển giao %s từ cơ sở dữ liệu đối tượng cho đồ "
-"thị lần chuyển giao"
-
-#, c-format
-msgid "root tree OID for commit %s in commit-graph is %s != %s"
-msgstr ""
-"OID cây gốc cho lần chuyển giao %s trong đồ-thị-các-lần-chuyển-giao là %s != "
-"%s"
-
-#, c-format
-msgid "commit-graph parent list for commit %s is too long"
-msgstr ""
-"danh sách cha mẹ đồ-thị-các-lần-chuyển-giao cho lần chuyển giao %s là quá dài"
-
-#, c-format
-msgid "commit-graph parent for %s is %s != %s"
-msgstr "cha mẹ đồ-thị-các-lần-chuyển-giao cho %s là %s != %s"
-
-#, c-format
-msgid "commit-graph parent list for commit %s terminates early"
-msgstr ""
-"danh sách cha mẹ đồ-thị-các-lần-chuyển-giao cho lần chuyển giao %s bị chấm "
-"dứt quá sớm"
-
-#, c-format
-msgid ""
-"commit-graph has generation number zero for commit %s, but non-zero elsewhere"
-msgstr ""
-"đồ-thị-các-lần-chuyển-giao có con số không lần tạo cho lần chuyển giao %s, "
-"nhưng không phải số không ở chỗ khác"
-
-#, c-format
-msgid ""
-"commit-graph has non-zero generation number for commit %s, but zero elsewhere"
-msgstr ""
-"đồ-thị-các-lần-chuyển-giao có con số không phải không lần tạo cho lần chuyển "
-"giao %s, nhưng số không ở chỗ khác"
-
-#, c-format
-msgid "commit-graph generation for commit %s is %<PRIuMAX> < %<PRIuMAX>"
-msgstr ""
-"tạo đồ-thị-các-lần-chuyển-giao cho lần chuyển giao %s là %<PRIuMAX> < "
-"%<PRIuMAX>"
-
-#, c-format
-msgid "commit date for commit %s in commit-graph is %<PRIuMAX> != %<PRIuMAX>"
-msgstr ""
-"ngày chuyển giao cho lần chuyển giao %s trong đồ-thị-các-lần-chuyển-giao là "
-"%<PRIuMAX> != %<PRIuMAX>"
+msgid "could not parse commit %s"
+msgstr "không thể đọc lần chuyển giao %s"
 
 #, c-format
 msgid "%s %s is not a commit!"
@@ -14020,7 +14691,7 @@
 "Turn this message off by running\n"
 "\"git config advice.graftFileDeprecated false\""
 msgstr ""
-"Việc hỗ trợ cho <GIT_DIR>/info/grafts đã lạc hậu\n"
+"Hỗ trợ cho <GIT_DIR>/info/grafts đã không còn\n"
 "và sẽ bị xóa bỏ ở phiên bản Git tương lai.\n"
 "\n"
 "Vui lòng dùng \"git replace --convert-graft-file\"\n"
@@ -14030,6 +14701,12 @@
 "\"git config advice.graftFileDeprecated false\""
 
 #, c-format
+msgid "commit %s exists in commit-graph but not in the object database"
+msgstr ""
+"commit %s tồn tại trong đồ-thị-chuyển-giao nhưng không có trong cơ sở dữ "
+"liệu đối tượng"
+
+#, c-format
 msgid "Commit %s has an untrusted GPG signature, allegedly by %s."
 msgstr ""
 "Lần chuyển giao %s có một chữ ký GPG không đáng tin, được cho là bởi %s."
@@ -14062,6 +14739,14 @@
 msgstr "không có thông tin về libc\n"
 
 #, c-format
+msgid "could not determine free disk size for '%s'"
+msgstr "không thể dò tìm chỗ trống trên đĩa  cho '%s'"
+
+#, c-format
+msgid "could not get info for '%s'"
+msgstr "không thể lấy thông tin cho '%s'"
+
+#, c-format
 msgid "[GLE %ld] health thread could not open '%ls'"
 msgstr "[GLE %ld] không thể mở tuyến trình sức khỏe '%ls'"
 
@@ -14085,6 +14770,10 @@
 msgid "health thread wait failed [GLE %ld]"
 msgstr "gặp lỗi khi chờ tiến trình sức khỏe [GLE %ld]"
 
+#, c-format
+msgid "Invalid path: %s"
+msgstr "đường dẫn không hợp lệ: %s"
+
 msgid "Unable to create FSEventStream."
 msgstr "Không thể tạo FSEventStream."
 
@@ -14116,6 +14805,30 @@
 msgstr "không thể đọc các thay đổi thư mục [GLE %ld]"
 
 #, c-format
+msgid "opendir('%s') failed"
+msgstr "opendir('%s') gặp lỗi"
+
+#, c-format
+msgid "lstat('%s') failed"
+msgstr "lstat('%s') gặp lỗi"
+
+#, c-format
+msgid "strbuf_readlink('%s') failed"
+msgstr "strbuf_readlink('%s') gặp lỗi"
+
+#, c-format
+msgid "closedir('%s') failed"
+msgstr "closedir('%s') gặp lỗi"
+
+#, c-format
+msgid "[GLE %ld] unable to open for read '%ls'"
+msgstr "[GLE %ld] không thể mở hay đọc '%ls'"
+
+#, c-format
+msgid "[GLE %ld] unable to get protocol information for '%ls'"
+msgstr "[GLE %ld] không thể lấy thông tin giao thức cho '%ls'"
+
+#, c-format
 msgid "failed to copy SID (%ld)"
 msgstr "gặp lỗi khi sao chép SID (%ld)"
 
@@ -14154,7 +14867,7 @@
 msgstr "Chưa khớp ( hay \\("
 
 msgid "Unmatched \\{"
-msgstr "Chưa khớp cặp “\\{”"
+msgstr "Chưa khớp cặp '\\{'"
 
 msgid "Invalid content of \\{\\}"
 msgstr "Nội dung của \\{\\} không hợp lệ"
@@ -14188,11 +14901,11 @@
 
 #, c-format
 msgid "could not start accept_thread '%s'"
-msgstr "không thể khởi chạy accept_thread “%s”"
+msgstr "không thể khởi chạy accept_thread '%s'"
 
 #, c-format
 msgid "could not start worker[0] for '%s'"
-msgstr "không thể khởi chạy bộ làm việc worker[0] cho “%s”"
+msgstr "không thể khởi chạy bộ làm việc worker[0] cho '%s'"
 
 #, c-format
 msgid "ConnectNamedPipe failed for '%s' (%lu)"
@@ -14204,11 +14917,11 @@
 
 #, c-format
 msgid "could not start thread[0] for '%s'"
-msgstr "không thể khởi chạy tiến trình[0] cho “%s”"
+msgstr "không thể khởi chạy tiến trình[0] cho '%s'"
 
 #, c-format
 msgid "wait for hEvent failed for '%s'"
-msgstr "chờ cho hEvent gặp lỗi với “%s”"
+msgstr "chờ cho hEvent gặp lỗi với '%s'"
 
 msgid "cannot resume in the background, please use 'fg' to resume"
 msgstr ""
@@ -14234,7 +14947,7 @@
 
 #, c-format
 msgid "could not expand include path '%s'"
-msgstr "không thể khai triển đường dẫn “%s”"
+msgstr "không thể khai triển đường dẫn '%s'"
 
 msgid "relative config includes must come from files"
 msgstr "các bao gồm cấu hình liên quan phải đến từ các tập tin"
@@ -14246,7 +14959,7 @@
 "remote URLs cannot be configured in file directly or indirectly included by "
 "includeIf.hasconfig:remote.*.url"
 msgstr ""
-"các URL máy chủ không thể được cấu hình trong tệp trực tiếp hoặc gián tiếp "
+"các URL máy chủ không thể được cấu hình trong tập trực tiếp hoặc gián tiếp "
 "được bao gồm bởi includeIf.hasconfig:remote.*.url"
 
 #, c-format
@@ -14255,11 +14968,11 @@
 
 #, c-format
 msgid "missing environment variable name for configuration '%.*s'"
-msgstr "thiếu tên biến môi trường cho cấu hình “%.*s”"
+msgstr "thiếu tên biến môi trường cho cấu hình '%.*s'"
 
 #, c-format
 msgid "missing environment variable '%s' for configuration '%.*s'"
-msgstr "thiếu biến môi trường “%s” cho cấu hình “%.*s”"
+msgstr "thiếu biến môi trường '%s' cho cấu hình '%.*s'"
 
 #, c-format
 msgid "key does not contain a section: %s"
@@ -14271,7 +14984,7 @@
 
 #, c-format
 msgid "invalid key: %s"
-msgstr "khóa không đúng: %s"
+msgstr "khóa không hợp lệ: %s"
 
 #, c-format
 msgid "invalid key (newline): %s"
@@ -14298,11 +15011,11 @@
 
 #, c-format
 msgid "missing config key %s"
-msgstr "thiếu khóa cấu hình “%s”"
+msgstr "thiếu khóa cấu hình '%s'"
 
 #, c-format
 msgid "missing config value %s"
-msgstr "thiếu giá trị cấu hình “%s”"
+msgstr "thiếu giá trị cấu hình '%s'"
 
 #, c-format
 msgid "bad config line %d in blob %s"
@@ -14314,7 +15027,7 @@
 
 #, c-format
 msgid "bad config line %d in standard input"
-msgstr "cấu hình sai tại dòng %d trong đầu vào tiêu chuẩn"
+msgstr "cấu hình sai tại dòng %d từ stdin"
 
 #, c-format
 msgid "bad config line %d in submodule-blob %s"
@@ -14336,33 +15049,32 @@
 
 #, c-format
 msgid "bad numeric config value '%s' for '%s': %s"
-msgstr "sai giá trị bằng số của cấu hình “%s” cho “%s”: %s"
+msgstr "sai giá trị bằng số của cấu hình '%s' cho '%s': %s"
 
 #, c-format
 msgid "bad numeric config value '%s' for '%s' in blob %s: %s"
-msgstr "sai giá trị bằng số của cấu hình “%s” cho “%s” trong blob %s: %s"
+msgstr "sai giá trị bằng số của cấu hình '%s' cho '%s' trong blob %s: %s"
 
 #, c-format
 msgid "bad numeric config value '%s' for '%s' in file %s: %s"
-msgstr "sai giá trị bằng số của cấu hình “%s” cho “%s” trong tập tin %s: %s"
+msgstr "sai giá trị bằng số của cấu hình '%s' cho '%s' trong tập tin %s: %s"
 
 #, c-format
 msgid "bad numeric config value '%s' for '%s' in standard input: %s"
-msgstr ""
-"sai giá trị bằng số của cấu hình “%s” cho “%s” trong đầu vào tiêu chuẩn: %s"
+msgstr "sai giá trị bằng số của cấu hình '%s' cho '%s' trong stdin: %s"
 
 #, c-format
 msgid "bad numeric config value '%s' for '%s' in submodule-blob %s: %s"
 msgstr ""
-"sai giá trị bằng số của cấu hình “%s” cho “%s” trong submodule-blob %s: %s"
+"sai giá trị bằng số của cấu hình '%s' cho '%s' trong submodule-blob %s: %s"
 
 #, c-format
 msgid "bad numeric config value '%s' for '%s' in command line %s: %s"
-msgstr "sai giá trị bằng số của cấu hình “%s” cho “%s” trong dòng lệnh %s: %s"
+msgstr "sai giá trị bằng số của cấu hình '%s' cho '%s' trong dòng lệnh %s: %s"
 
 #, c-format
 msgid "bad numeric config value '%s' for '%s' in %s: %s"
-msgstr "sai giá trị bằng số của cấu hình “%s” cho “%s” trong %s: %s"
+msgstr "sai giá trị bằng số của cấu hình '%s' cho '%s' trong %s: %s"
 
 #, c-format
 msgid "invalid value for variable %s"
@@ -14374,15 +15086,15 @@
 
 #, c-format
 msgid "bad boolean config value '%s' for '%s'"
-msgstr "sai giá trị kiểu lô-gíc của cấu hình “%s” cho “%s”"
+msgstr "sai giá trị kiểu boolean của cấu hình '%s' cho '%s'"
 
 #, c-format
 msgid "failed to expand user dir in: '%s'"
-msgstr "gặp lỗi mở rộng thư mục người dùng trong: “%s”"
+msgstr "gặp lỗi mở rộng thư mục người dùng trong: '%s'"
 
 #, c-format
 msgid "'%s' for '%s' is not a valid timestamp"
-msgstr "“%s” dành cho “%s” không phải là dấu vết thời gian hợp lệ"
+msgstr "'%s' dành cho '%s' không phải là dấu vết thời gian hợp lệ"
 
 #, c-format
 msgid "abbrev length out of range: %d"
@@ -14392,8 +15104,13 @@
 msgid "bad zlib compression level %d"
 msgstr "mức nén zlib %d là sai"
 
-msgid "core.commentChar should only be one character"
-msgstr "core.commentChar chỉ được có một ký tự"
+#, c-format
+msgid "%s cannot contain newline"
+msgstr "%s không thể chứa ký tự xuống dòng"
+
+#, c-format
+msgid "%s must have at least one character"
+msgstr "%s phải có ít nhất một ký tự"
 
 #, c-format
 msgid "ignoring unknown core.fsyncMethod value '%s'"
@@ -14419,45 +15136,41 @@
 
 #, c-format
 msgid "unable to load config blob object '%s'"
-msgstr "không thể tải đối tượng blob cấu hình “%s”"
+msgstr "không thể tải đối tượng blob cấu hình '%s'"
 
 #, c-format
 msgid "reference '%s' does not point to a blob"
-msgstr "tham chiếu “%s” không chỉ đến một blob nào cả"
+msgstr "tham chiếu '%s' không chỉ đến một blob nào cả"
 
 #, c-format
 msgid "unable to resolve config blob '%s'"
-msgstr "không thể phân giải điểm xét duyệt “%s”"
-
-#, c-format
-msgid "failed to parse %s"
-msgstr "gặp lỗi khi phân tích cú pháp %s"
+msgstr "không thể phân giải điểm xét duyệt '%s'"
 
 msgid "unable to parse command-line config"
-msgstr "không thể phân tích cấu hình dòng lệnh"
+msgstr "không thể đọc cấu hình dòng lệnh"
 
 msgid "unknown error occurred while reading the configuration files"
 msgstr "đã có lỗi chưa biết xảy ra trong khi đọc các tập tin cấu hình"
 
 #, c-format
 msgid "Invalid %s: '%s'"
-msgstr "%s không hợp lệ: “%s”"
+msgstr "%s không hợp lệ: '%s'"
 
 #, c-format
 msgid "splitIndex.maxPercentChange value '%d' should be between 0 and 100"
-msgstr "giá trị splitIndex.maxPercentChange “%d” phải nằm giữa 0 và 100"
+msgstr "giá trị splitIndex.maxPercentChange '%d' phải nằm giữa 0 và 100"
 
 #, c-format
 msgid "unable to parse '%s' from command-line config"
-msgstr "không thể phân tích “%s” từ cấu hình dòng lệnh"
+msgstr "không thể đọc '%s' từ cấu hình dòng lệnh"
 
 #, c-format
 msgid "bad config variable '%s' in file '%s' at line %d"
-msgstr "sai biến cấu hình “%s” trong tập tin “%s” tại dòng %d"
+msgstr "sai biến cấu hình '%s' trong tập tin '%s' tại dòng %d"
 
 #, c-format
 msgid "invalid section name '%s'"
-msgstr "tên của phần không hợp lệ “%s”"
+msgstr "tên của phần không hợp lệ '%s'"
 
 #, c-format
 msgid "%s has multiple values"
@@ -14465,7 +15178,11 @@
 
 #, c-format
 msgid "failed to write new configuration file %s"
-msgstr "gặp lỗi khi ghi tập tin cấu hình “%s”"
+msgstr "gặp lỗi khi ghi tập tin cấu hình '%s'"
+
+#, c-format
+msgid "no multi-line comment allowed: '%s'"
+msgstr "không cho phép ghi chú nhiều dòng: '%s'"
 
 #, c-format
 msgid "could not lock config file %s"
@@ -14473,11 +15190,11 @@
 
 #, c-format
 msgid "opening %s"
-msgstr "đang mở “%s”"
+msgstr "đang mở '%s'"
 
 #, c-format
 msgid "invalid config file %s"
-msgstr "tập tin cấu hình “%s” không hợp lệ"
+msgstr "tập tin cấu hình '%s' không hợp lệ"
 
 #, c-format
 msgid "fstat on %s failed"
@@ -14485,7 +15202,7 @@
 
 #, c-format
 msgid "unable to mmap '%s'%s"
-msgstr "không thể mmap “%s”%s"
+msgstr "không thể mmap '%s'%s"
 
 #, c-format
 msgid "chmod on %s failed"
@@ -14493,19 +15210,23 @@
 
 #, c-format
 msgid "could not write config file %s"
-msgstr "không thể ghi tập tin cấu hình “%s”"
+msgstr "không thể ghi tập tin cấu hình '%s'"
 
 #, c-format
 msgid "could not set '%s' to '%s'"
-msgstr "không thể đặt “%s” thành “%s”"
+msgstr "không thể đặt '%s' thành '%s'"
 
 #, c-format
 msgid "invalid section name: %s"
 msgstr "tên của phần không hợp lệ: %s"
 
 #, c-format
+msgid "refusing to work with overly long line in '%s' on line %<PRIuMAX>"
+msgstr "từ chối làm việc với dòng quá dài '%s' trên dòng %<PRIuMAX>"
+
+#, c-format
 msgid "missing value for '%s'"
-msgstr "thiếu giá trị cho cho “%s”"
+msgstr "thiếu giá trị cho cho '%s'"
 
 msgid "the remote end hung up upon initial contact"
 msgstr "máy chủ bị treo trên lần tiếp xúc đầu tiên"
@@ -14523,25 +15244,25 @@
 
 #, c-format
 msgid "server doesn't support '%s'"
-msgstr "máy chủ không hỗ trợ “%s”"
+msgstr "máy chủ không hỗ trợ '%s'"
 
 #, c-format
 msgid "server doesn't support feature '%s'"
-msgstr "máy chủ không hỗ trợ tính năng “%s”"
+msgstr "máy chủ không hỗ trợ tính năng '%s'"
 
 msgid "expected flush after capabilities"
 msgstr "cần đẩy dữ liệu lên đĩa sau các capabilities"
 
 #, c-format
 msgid "ignoring capabilities after first line '%s'"
-msgstr "bỏ qua capabilities sau dòng đầu tiên “%s”"
+msgstr "bỏ qua capabilities sau dòng đầu tiên '%s'"
 
 msgid "protocol error: unexpected capabilities^{}"
-msgstr "lỗi giao thức: không cần capabilities^{}"
+msgstr "lỗi giao thức: capabilities^{} bất thường"
 
 #, c-format
 msgid "protocol error: expected shallow sha-1, got '%s'"
-msgstr "lỗi giao thức: cần sha-1 shallow, nhưng lại nhận được “%s”"
+msgstr "lỗi giao thức: cần sha-1 shallow, nhưng lại có '%s'"
 
 msgid "repository on the other end cannot be shallow"
 msgstr "kho đã ở điểm cuối khoác nên không thể được shallow"
@@ -14551,11 +15272,21 @@
 
 #, c-format
 msgid "protocol error: unexpected '%s'"
-msgstr "lỗi giao thức: không cần “%s”"
+msgstr "lỗi giao thức: '%s' bất thường"
 
 #, c-format
 msgid "unknown object format '%s' specified by server"
-msgstr "không hiểu định dạng đối tượng “%s” được chỉ định bởi máy phục vụ"
+msgstr "không hiểu định dạng đối tượng '%s' được chỉ định bởi máy chủ"
+
+#, c-format
+msgid "error on bundle-uri response line %d: %s"
+msgstr "lỗi trên dòng phản hồi bundle-uri thứ %d: %s"
+
+msgid "expected flush after bundle-uri listing"
+msgstr "cần đẩy dữ liệu lên đĩa sau khi liệt kê bundle-uri"
+
+msgid "expected response end packet after ref listing"
+msgstr "cần nhận được trả lời là kết thúc gói sau khi liệt kê tham chiếu"
 
 #, c-format
 msgid "invalid ls-refs response: %s"
@@ -14564,19 +15295,16 @@
 msgid "expected flush after ref listing"
 msgstr "cần đẩy dữ liệu lên đĩa sau khi liệt kê tham chiếu"
 
-msgid "expected response end packet after ref listing"
-msgstr "cần nhận được trả lời là kết thúc gói sau khi liệt kê tham chiếu"
-
 #, c-format
 msgid "protocol '%s' is not supported"
-msgstr "giao thức “%s” chưa được hỗ trợ"
+msgstr "giao thức '%s' chưa được hỗ trợ"
 
 msgid "unable to set SO_KEEPALIVE on socket"
 msgstr "không thể đặt SO_KEEPALIVE trên ổ cắm"
 
 #, c-format
 msgid "Looking up %s ... "
-msgstr "Đang tìm kiếm %s … "
+msgstr "Đang tìm kiếm %s ... "
 
 #, c-format
 msgid "unable to look up %s (port %s) (%s)"
@@ -14589,7 +15317,7 @@
 "Connecting to %s (port %s) ... "
 msgstr ""
 "xong.\n"
-"Đang kết nối đến %s (cổng %s) … "
+"Đang kết nối đến %s (cổng %s) ... "
 
 #, c-format
 msgid ""
@@ -14613,221 +15341,46 @@
 
 #, c-format
 msgid "strange hostname '%s' blocked"
-msgstr "đã khóa tên máy lạ “%s”"
+msgstr "đã khóa tên máy lạ '%s'"
 
 #, c-format
 msgid "strange port '%s' blocked"
-msgstr "đã khóa cổng lạ “%s”"
+msgstr "đã khóa cổng lạ '%s'"
 
 #, c-format
 msgid "cannot start proxy %s"
-msgstr "không thể khởi chạy ủy nhiệm “%s”"
+msgstr "không thể khởi chạy ủy nhiệm '%s'"
 
 msgid "no path specified; see 'git help pull' for valid url syntax"
-msgstr "chưa chỉ định đường dẫn; xem'git help pull” để biết cú pháp url hợp lệ"
+msgstr "chưa chỉ định đường dẫn; xem'git help pull' để biết cú pháp url hợp lệ"
 
 msgid "newline is forbidden in git:// hosts and repo paths"
-msgstr "newline bị cấm trong các git:// máy chủ và đường dẫn repo"
+msgstr "ký tự xuống dòng bị cấm trong các git:// máy chủ và đường dẫn repo"
 
 msgid "ssh variant 'simple' does not support -4"
-msgstr "ssh biến thể “simple” không hỗ trợ -4"
+msgstr "ssh biến thể 'simple' không hỗ trợ -4"
 
 msgid "ssh variant 'simple' does not support -6"
-msgstr "ssh biến thể “simple” không hỗ trợ -6"
+msgstr "ssh biến thể 'simple' không hỗ trợ -6"
 
 msgid "ssh variant 'simple' does not support setting port"
-msgstr "ssh biến thể “simple” không hỗ trợ đặt cổng"
+msgstr "ssh biến thể 'simple' không hỗ trợ đặt cổng"
 
 #, c-format
 msgid "strange pathname '%s' blocked"
-msgstr "đã khóa tên đường dẫn lạ “%s”"
+msgstr "đã khóa tên đường dẫn lạ '%s'"
 
 msgid "unable to fork"
 msgstr "không thể rẽ nhánh tiến trình con"
 
 msgid "Could not run 'git rev-list'"
-msgstr "Không thể chạy “git rev-list”"
+msgstr "Không thể chạy 'git rev-list'"
 
 msgid "failed write to rev-list"
 msgstr "gặp lỗi khi ghi vào rev-list"
 
 msgid "failed to close rev-list's stdin"
-msgstr "gặp lỗi khi đóng đầu vào chuẩn stdin của rev-list"
-
-#, c-format
-msgid "'%s' does not exist"
-msgstr "\"%s\" không tồn tại"
-
-msgid "need a working directory"
-msgstr "cần một thư mục làm việc"
-
-msgid "could not find enlistment root"
-msgstr "không tìm thấy gốc enlistment"
-
-#, c-format
-msgid "could not switch to '%s'"
-msgstr "không thể chuyển đến '%s'"
-
-#, c-format
-msgid "could not configure %s=%s"
-msgstr "không thể đóng cấu hình %s=%s"
-
-msgid "could not configure log.excludeDecoration"
-msgstr "không thể cấu hình log.excludeDecoration"
-
-msgid "Scalar enlistments require a worktree"
-msgstr "'Scalar enlistments' cần một cây làm việc"
-
-#, c-format
-msgid "could not open directory '%s'"
-msgstr "không thể mở thư mục “%s”"
-
-#, c-format
-msgid "skipping '%s', which is neither file nor directory"
-msgstr ""
-"đang bỏ qua “%s”, cái không phải là một tập tin, cũng không phải thư mục"
-
-#, c-format
-msgid "could not determine free disk size for '%s'"
-msgstr "không thể dò tìm chỗ trống trên đĩa  cho “%s”"
-
-#, c-format
-msgid "could not get info for '%s'"
-msgstr "không thể lấy thông tin cho “%s”"
-
-#, c-format
-msgid "remote HEAD is not a branch: '%.*s'"
-msgstr "HEAD của máy chủ không phải một nhánh: '%.*s'"
-
-msgid "failed to get default branch name from remote; using local default"
-msgstr "gặp lỗi khi lấy tên nhánh mặc định từ máy chủ; sử dụng mặc định nội bộ"
-
-msgid "failed to get default branch name"
-msgstr "gặp lỗi khi lấy tên nhánh mặc định"
-
-msgid "failed to unregister repository"
-msgstr "gặp lỗi khi hủy đăng ký kho chứa"
-
-msgid "failed to delete enlistment directory"
-msgstr "gặp lỗi khi xóa thư mục dành được"
-
-msgid "branch to checkout after clone"
-msgstr "nhánh để lấy ra sau khi nhân bản"
-
-msgid "when cloning, create full working directory"
-msgstr "khi nhân bản, tạo đầy đủ thư mục làm việc"
-
-msgid "only download metadata for the branch that will be checked out"
-msgstr "chỉ siêu dữ liệu tải về cho nhánh mà sẽ được lấy ra"
-
-msgid "scalar clone [<options>] [--] <repo> [<dir>]"
-msgstr "scalar clone [<các tùy chọn>] [--] <kho> [<t.mục>]"
-
-#, c-format
-msgid "cannot deduce worktree name from '%s'"
-msgstr "không thể suy diễn tên cây làm việc từ '%s'"
-
-#, c-format
-msgid "directory '%s' exists already"
-msgstr "thư mục '%s' đã sẵn có"
-
-#, c-format
-msgid "failed to get default branch for '%s'"
-msgstr "gặp lỗi khi lấy nhánh mặc định cho '%s'"
-
-#, c-format
-msgid "could not configure remote in '%s'"
-msgstr "không thể cấu hình máy chủ trong '%s'"
-
-#, c-format
-msgid "could not configure '%s'"
-msgstr "không thể cấu hình '%s'"
-
-msgid "partial clone failed; attempting full clone"
-msgstr "nhân bản từng phần gặp lỗi; đang cố thử nhân bản đầy đủ"
-
-msgid "could not configure for full clone"
-msgstr "không thể cấu hình cho nhân bản đầy đủ"
-
-msgid "scalar diagnose [<enlistment>]"
-msgstr "scalar diagnose [<enlistment>]"
-
-#, c-format
-msgid "could not create directory for '%s'"
-msgstr "không thể tạo thư mục cho “%s”"
-
-msgid "could not duplicate stdout"
-msgstr "không thể nhân đôi đầu vào tiêu chuẩn"
-
-msgid "failed to write archive"
-msgstr "gặp lỗi khi khi kho nén"
-
-msgid "`scalar list` does not take arguments"
-msgstr "`scalar list` không nhận các tham số"
-
-msgid "scalar register [<enlistment>]"
-msgstr "scalar register [<enlistment>]"
-
-msgid "reconfigure all registered enlistments"
-msgstr "cấu hình mọi enlistments đã đăng ký"
-
-msgid "scalar reconfigure [--all | <enlistment>]"
-msgstr "scalar reconfigure [--all | <enlistment>]"
-
-msgid "--all or <enlistment>, but not both"
-msgstr "--all hoặc <enlistment>, không thể là cả hai"
-
-#, c-format
-msgid "git repository gone in '%s'"
-msgstr "kho git ra đi trong '%s'"
-
-msgid ""
-"scalar run <task> [<enlistment>]\n"
-"Tasks:\n"
-msgstr ""
-"scalar run <task> [<enlistment>]\n"
-"Nhiệm vụ:\n"
-
-#, c-format
-msgid "no such task: '%s'"
-msgstr "không có nhiệm vụ nào như thế: “%s”"
-
-msgid "scalar unregister [<enlistment>]"
-msgstr "scalar unregister [<enlistment>]"
-
-msgid "scalar delete <enlistment>"
-msgstr "scalar delete <enlistment>"
-
-msgid "refusing to delete current working directory"
-msgstr "từ chối gỡ bỏ thư mục làm việc hiện tại"
-
-msgid "include Git version"
-msgstr "bao gồm phiên bản Git"
-
-msgid "include Git's build options"
-msgstr "bao gồm các tùy chọn biên dịch của Git"
-
-msgid "scalar verbose [-v | --verbose] [--build-options]"
-msgstr "scalar verbose [-v | --verbose] [--build-options]"
-
-msgid "-C requires a <directory>"
-msgstr "-C cần một <thư_mục>"
-
-#, c-format
-msgid "could not change to '%s'"
-msgstr "không thể chuyển sang “%s”"
-
-msgid "-c requires a <key>=<value> argument"
-msgstr "-c cần một tham số <key>=<value>"
-
-msgid ""
-"scalar [-C <directory>] [-c <key>=<value>] <command> [<options>]\n"
-"\n"
-"Commands:\n"
-msgstr ""
-"scalar [-C </thư/mục/>] [-c <khóa>=<giá trị>] <lệnh> [<các tùy chọn>]\n"
-"\n"
-"Các lệnh:\n"
+msgstr "gặp lỗi khi đóng stdin của rev-list"
 
 #, c-format
 msgid "illegal crlf_action %d"
@@ -14859,55 +15412,55 @@
 
 #, c-format
 msgid "BOM is prohibited in '%s' if encoded as %s"
-msgstr "BOM bị cấm trong “%s” nếu được mã hóa là %s"
+msgstr "BOM bị cấm trong '%s' nếu được mã hóa là %s"
 
 #, c-format
 msgid ""
 "The file '%s' contains a byte order mark (BOM). Please use UTF-%.*s as "
 "working-tree-encoding."
 msgstr ""
-"Tập tin “%s” có chứa ký hiệu thứ tự byte (BOM). Vui lòng dùng UTF-%.*s như "
+"Tập tin '%s' có chứa ký hiệu thứ tự byte (BOM). Vui lòng dùng UTF-%.*s như "
 "là bảng mã cây làm việc."
 
 #, c-format
 msgid "BOM is required in '%s' if encoded as %s"
-msgstr "BOM là bắt buộc trong “%s” nếu được mã hóa là %s"
+msgstr "BOM là bắt buộc trong '%s' nếu được mã hóa là %s"
 
 #, c-format
 msgid ""
 "The file '%s' is missing a byte order mark (BOM). Please use UTF-%sBE or UTF-"
 "%sLE (depending on the byte order) as working-tree-encoding."
 msgstr ""
-"Tập tin “%s” còn thiếu ký hiệu thứ tự byte (BOM). Vui lòng dùng UTF-%sBE hay "
+"Tập tin '%s' còn thiếu ký hiệu thứ tự byte (BOM). Vui lòng dùng UTF-%sBE hay "
 "UTF-%sLE (còn phục thuộc vào thứ tự byte) như là bảng mã cây làm việc."
 
 #, c-format
 msgid "failed to encode '%s' from %s to %s"
-msgstr "gặp lỗi khi mã hóa “%s”  từ “%s” sang “%s”"
+msgstr "gặp lỗi khi mã hóa '%s' từ '%s' sang '%s'"
 
 #, c-format
 msgid "encoding '%s' from %s to %s and back is not the same"
-msgstr "mã hóa “%s” từ %s thành %s và ngược trở lại không phải là cùng"
+msgstr "mã hóa '%s' từ %s thành %s và ngược trở lại không phải là cùng"
 
 #, c-format
 msgid "cannot fork to run external filter '%s'"
-msgstr "không thể rẽ nhánh tiến trình để chạy bộ lọc bên ngoài “%s”"
+msgstr "không thể rẽ nhánh tiến trình để chạy bộ lọc bên ngoài '%s'"
 
 #, c-format
 msgid "cannot feed the input to external filter '%s'"
-msgstr "không thể cấp đầu vào cho bộ lọc bên ngoài “%s”"
+msgstr "không thể cấp đầu vào cho bộ lọc bên ngoài '%s'"
 
 #, c-format
 msgid "external filter '%s' failed %d"
-msgstr "chạy bộ lọc bên ngoài “%s” gặp lỗi %d"
+msgstr "chạy bộ lọc bên ngoài '%s' gặp lỗi %d"
 
 #, c-format
 msgid "read from external filter '%s' failed"
-msgstr "đọc từ bộ lọc bên ngoài “%s” gặp lỗi"
+msgstr "đọc từ bộ lọc bên ngoài '%s' gặp lỗi"
 
 #, c-format
 msgid "external filter '%s' failed"
-msgstr "gặp lỗi khi chạy bộ lọc bên ngoài “%s”"
+msgstr "gặp lỗi khi chạy bộ lọc bên ngoài '%s'"
 
 msgid "unexpected filter type"
 msgstr "gặp kiểu bộ lọc thừa"
@@ -14920,23 +15473,23 @@
 "external filter '%s' is not available anymore although not all paths have "
 "been filtered"
 msgstr ""
-"bộ lọc bên ngoài “%s” không sẵn sàng nữa mặc dù không phải tất cả các đường "
-"dẫn đã được lọc"
+"bộ lọc ngoài '%s' không còn nữa mặc dù không phải tất cả các đường dẫn đã "
+"được lọc"
 
 msgid "true/false are no valid working-tree-encodings"
-msgstr "true/false là không phải bảng-mã-cây-làm-việc hợp lệ"
+msgstr "true/false không phải là bảng mã cây làm việc hợp lệ"
 
 #, c-format
 msgid "%s: clean filter '%s' failed"
-msgstr "%s: gặp lỗi khi xóa bộ lọc “%s”"
+msgstr "%s: bộ lọc clean '%s' gặp lỗi"
 
 #, c-format
 msgid "%s: smudge filter %s failed"
-msgstr "%s: smudge bộ lọc %s gặp lỗi"
+msgstr "%s: bộ lọc smudge %s gặp lỗi"
 
 #, c-format
 msgid "skipping credential lookup for key: credential.%s"
-msgstr "bỏ qua tìm kiếm giấy chứng chực cho khóa: credential.%s"
+msgstr "bỏ qua tìm kiếm giấy chứng thực cho khóa: credential.%s"
 
 msgid "refusing to work with credential missing host field"
 msgstr "từ chối làm việc với giấy chứng thực thiếu trường máy chủ"
@@ -14954,10 +15507,10 @@
 
 #, c-format
 msgid "credential url cannot be parsed: %s"
-msgstr "không thể phân tích cú pháp giấy chứng thực url: %s"
+msgstr "không hiểu cú pháp giấy chứng thực url: %s"
 
 msgid "in the future"
-msgstr "ở thời tương lai"
+msgstr "ở tương lai"
 
 #, c-format
 msgid "%<PRIuMAX> second ago"
@@ -15010,35 +15563,64 @@
 
 #, c-format
 msgid "bad tree object %s"
-msgstr "đối tượng cây sai “%s”"
+msgstr "đối tượng cây sai '%s'"
 
 #, c-format
 msgid "failed to load island regex for '%s': %s"
-msgstr "gặp lỗi khi tải biểu thức chính quy island cho “%s”: %s"
+msgstr "gặp lỗi khi tải biểu thức chính quy island cho '%s': %s"
 
 #, c-format
 msgid "island regex from config has too many capture groups (max=%d)"
 msgstr ""
-"biểu thức chính quy island từ cấu hình có quá nhiều nhóm chụp (tối đa=%d)"
+"biểu thức chính quy island từ cấu hình có quá nhiều nhóm chọn (tối đa=%d)"
 
 #, c-format
 msgid "Marked %d islands, done.\n"
 msgstr "Đã đánh dấu %d island, xong.\n"
 
-msgid "--merge-base does not work with ranges"
-msgstr "--merge-base không hoạt động với phạm vi"
+#, c-format
+msgid "invalid --%s value '%s'"
+msgstr "giá trị --%s không hợp lệ: '%s'"
 
-msgid "--merge-base only works with commits"
-msgstr "--merge-base chỉ hoạt động với các lần chuyển giao"
+#, c-format
+msgid "could not archive missing directory '%s'"
+msgstr "không thể nén thư mục '%s' không còn tồn tại"
+
+#, c-format
+msgid "could not open directory '%s'"
+msgstr "không thể mở thư mục '%s'"
+
+#, c-format
+msgid "skipping '%s', which is neither file nor directory"
+msgstr "đang bỏ qua '%s', không phải là một tập tin hay thư mục"
+
+msgid "could not duplicate stdout"
+msgstr "không thể nhân bản stdout"
+
+#, c-format
+msgid "could not add directory '%s' to archiver"
+msgstr "không thể thêm thư mục '%s' vào kho nén"
+
+msgid "failed to write archive"
+msgstr "gặp lỗi khi ghi kho nén"
+
+msgid "--merge-base does not work with ranges"
+msgstr "--merge-base không thể dùng với chỉ vùng"
 
 msgid "unable to get HEAD"
 msgstr "không thể lấy HEAD"
 
 msgid "no merge base found"
-msgstr "không tìm thấy cơ sở để hòa trộn"
+msgstr "không tìm thấy gốc hòa trộn"
 
 msgid "multiple merge bases found"
-msgstr "có nhiều cơ sở để hòa trộn"
+msgstr "có nhiều hơn một gốc hòa trộn"
+
+msgid "cannot compare stdin to a directory"
+msgstr "không thể so sánh stdin và thư mục"
+
+msgid "cannot compare a named pipe to a directory"
+msgstr "không thể so sánh pipe có tên và thư mục"
 
 msgid "git diff --no-index [<options>] <path> <path>"
 msgstr "git diff --no-index [<các tùy chọn>] </đường/dẫn> </đường/dẫn>"
@@ -15048,54 +15630,65 @@
 "tree"
 msgstr ""
 "Không phải là một thư mục git. Dùng --no-index để so sánh hai đường dẫn bên "
-"ngoài một cây làm việc"
+"ngoài cây làm việc"
 
 #, c-format
 msgid "  Failed to parse dirstat cut-off percentage '%s'\n"
-msgstr "  Gặp lỗi khi phân tích dirstat cắt bỏ phần trăm “%s”\n"
+msgstr "  Gặp lỗi khi đọc phần trăm cắt bỏ dirstat '%s'\n"
 
 #, c-format
 msgid "  Unknown dirstat parameter '%s'\n"
-msgstr "  Không hiểu đối số dirstat “%s”\n"
+msgstr "  Không hiểu đối số dirstat '%s'\n"
 
 msgid ""
 "color moved setting must be one of 'no', 'default', 'blocks', 'zebra', "
 "'dimmed-zebra', 'plain'"
 msgstr ""
-"cài đặt màu đã di chuyển phải là một trong “no”, “default”, “blocks”, "
-"“zebra”, “dimmed-zebra”, “plain”"
+"cài đặt color moved phải là một trong 'no', 'default', 'blocks', 'zebra', "
+"'dimmed-zebra', 'plain'"
 
 #, c-format
 msgid ""
 "unknown color-moved-ws mode '%s', possible values are 'ignore-space-change', "
 "'ignore-space-at-eol', 'ignore-all-space', 'allow-indentation-change'"
 msgstr ""
-"không hiểu chế độ color-moved-ws “%s”, các giá trị có thể là “ignore-space-"
-"change”, “ignore-space-at-eol”, “ignore-all-space”, “allow-indentation-"
-"change”"
+"không hiểu chế độ color-moved-ws '%s', các giá trị có thể là 'ignore-space-"
+"change', 'ignore-space-at-eol', 'ignore-all-space', 'allow-indentation-"
+"change'"
 
 msgid ""
 "color-moved-ws: allow-indentation-change cannot be combined with other "
 "whitespace modes"
 msgstr ""
-"color-moved-ws: allow-indentation-change không thể tổ hợp cùng với các chế "
+"color-moved-ws: allow-indentation-change không thể kết hợp cùng với các chế "
 "độ khoảng trắng khác"
 
 #, c-format
 msgid "Unknown value for 'diff.submodule' config variable: '%s'"
-msgstr "Không hiểu giá trị cho biến cấu hình “diff.submodule”: “%s”"
+msgstr "Không hiểu giá trị cho biến cấu hình 'diff.submodule': '%s'"
+
+#, c-format
+msgid "unknown value for config '%s': %s"
+msgstr "không hiểu giá trị cho cho cấu hình '%s': %s"
 
 #, c-format
 msgid ""
 "Found errors in 'diff.dirstat' config variable:\n"
 "%s"
 msgstr ""
-"Tìm thấy các lỗi trong biến cấu hình “diff.dirstat”:\n"
+"Tìm thấy các lỗi trong biến cấu hình 'diff.dirstat':\n"
 "%s"
 
 #, c-format
 msgid "external diff died, stopping at %s"
-msgstr "phần mềm diff ở bên ngoài đã chết, dừng tại %s"
+msgstr "phần mềm diff ở bên ngoài đã thoát, dừng tại %s"
+
+msgid "--follow requires exactly one pathspec"
+msgstr "--follow cần đúng một đặc tả đường dẫn"
+
+#, c-format
+msgid "pathspec magic not supported by --follow: %s"
+msgstr "đặc tả đường dẫn đặc biệt chưa được hỗ trợ bởi --follow: %s"
 
 #, c-format
 msgid "options '%s', '%s', '%s', and '%s' cannot be used together"
@@ -15111,28 +15704,25 @@
 msgstr ""
 "tùy chọn '%s' và '%s' không thể dùng cùng nhau, dùng '%s' với '%s' và '%s'"
 
-msgid "--follow requires exactly one pathspec"
-msgstr "--follow cần chính xác một đặc tả đường dẫn"
-
 #, c-format
 msgid "invalid --stat value: %s"
-msgstr "giá trị --stat không hợp lệ: “%s”"
+msgstr "giá trị --stat không hợp lệ: '%s'"
 
 #, c-format
 msgid "%s expects a numerical value"
-msgstr "tùy chọn “%s” cần một giá trị bằng số"
+msgstr "tùy chọn '%s' cần một giá trị số"
 
 #, c-format
 msgid ""
 "Failed to parse --dirstat/-X option parameter:\n"
 "%s"
 msgstr ""
-"Gặp lỗi khi phân tích đối số tùy chọn --dirstat/-X:\n"
+"Gặp lỗi khi đọc đối số tùy chọn --dirstat/-X:\n"
 "%s"
 
 #, c-format
 msgid "unknown change class '%c' in --diff-filter=%s"
-msgstr "không hiểu lớp thay đổi “%c” trong --diff-filter=%s"
+msgstr "không hiểu change class '%c' trong --diff-filter=%s"
 
 #, c-format
 msgid "unknown value after ws-error-highlight=%.*s"
@@ -15140,7 +15730,7 @@
 
 #, c-format
 msgid "unable to resolve '%s'"
-msgstr "không thể phân giải “%s”"
+msgstr "không thể phân giải '%s'"
 
 #, c-format
 msgid "%s expects <n>/<m> form"
@@ -15148,7 +15738,7 @@
 
 #, c-format
 msgid "%s expects a character, got '%s'"
-msgstr "%s cần một ký tự, nhưng lại nhận được “%s”"
+msgstr "%s cần một ký tự, nhưng lại có '%s'"
 
 #, c-format
 msgid "bad --color-moved argument: %s"
@@ -15156,14 +15746,7 @@
 
 #, c-format
 msgid "invalid mode '%s' in --color-moved-ws"
-msgstr "chế độ “%s” không hợp lệ trong --color-moved-ws"
-
-msgid ""
-"option diff-algorithm accepts \"myers\", \"minimal\", \"patience\" and "
-"\"histogram\""
-msgstr ""
-"tùy chọn  diff-algorithm chấp nhận \"myers\", \"minimal\", \"patience\" và "
-"\"histogram\""
+msgstr "chế độ '%s' không hợp lệ trong --color-moved-ws"
 
 #, c-format
 msgid "invalid argument to %s"
@@ -15171,11 +15754,11 @@
 
 #, c-format
 msgid "invalid regex given to -I: '%s'"
-msgstr "đưa cho -I biểu thức chính quy không hợp lệ: “%s”"
+msgstr "đưa cho -I biểu thức chính quy không hợp lệ: '%s'"
 
 #, c-format
 msgid "failed to parse --submodule option parameter: '%s'"
-msgstr "gặp lỗi khi phân tích đối số tùy chọn --submodule: “%s”"
+msgstr "gặp lỗi khi đọc đối số tùy chọn --submodule: '%s'"
 
 #, c-format
 msgid "bad --word-diff argument: %s"
@@ -15185,7 +15768,7 @@
 msgstr "Các tùy chọn định dạng khi xuất các khác biệt"
 
 msgid "generate patch"
-msgstr "tạo miếng vá"
+msgstr "tạo bản vá"
 
 msgid "<n>"
 msgstr "<n>"
@@ -15197,10 +15780,10 @@
 msgstr "tạo khác biệt ở định dạng thô"
 
 msgid "synonym for '-p --raw'"
-msgstr "đồng nghĩa với “-p --raw”"
+msgstr "đồng nghĩa với '-p --raw'"
 
 msgid "synonym for '-p --stat'"
-msgstr "đồng nghĩa với “-p --stat”"
+msgstr "đồng nghĩa với '-p --stat'"
 
 msgid "machine friendly --stat"
 msgstr "--stat thuận tiện cho máy đọc"
@@ -15208,8 +15791,8 @@
 msgid "output only the last line of --stat"
 msgstr "chỉ xuất những dòng cuối của --stat"
 
-msgid "<param1,param2>..."
-msgstr "<tham_số_1,tham_số_2>…"
+msgid "<param1>,<param2>..."
+msgstr "<tham_số_1>,<tham_số_2>..."
 
 msgid ""
 "output the distribution of relative amount of changes for each sub-directory"
@@ -15218,8 +15801,8 @@
 msgid "synonym for --dirstat=cumulative"
 msgstr "đồng nghĩa với --dirstat=cumulative"
 
-msgid "synonym for --dirstat=files,param1,param2..."
-msgstr "đồng nghĩa với --dirstat=files,param1,param2…"
+msgid "synonym for --dirstat=files,<param1>,<param2>..."
+msgstr "đồng nghĩa với --dirstat=files,<tham_số_1>,<tham_số_2>..."
 
 msgid "warn if changes introduce conflict markers or whitespace errors"
 msgstr ""
@@ -15266,8 +15849,8 @@
 
 msgid "show full pre- and post-image object names on the \"index\" lines"
 msgstr ""
-"hiển thị đầy đủ các tên đối tượng pre- và post-image trên các dòng \"mục lục"
-"\""
+"hiển thị đầy đủ các tên đối tượng pre- và post-image trên các dòng \"mục "
+"lục\""
 
 msgid "show colored diff"
 msgstr "hiển thị thay đổi được tô màu"
@@ -15279,7 +15862,7 @@
 "highlight whitespace errors in the 'context', 'old' or 'new' lines in the "
 "diff"
 msgstr ""
-"tô sáng các lỗi về khoảng trắng trong các dòng “context”, “old” và “new” "
+"tô sáng các lỗi về khoảng trắng trong các dòng 'context', 'old' và 'new' "
 "trong khác biệt"
 
 msgid ""
@@ -15290,7 +15873,7 @@
 "trong --raw hay --numstat"
 
 msgid "<prefix>"
-msgstr "<tiền_tố>"
+msgstr "<tiền tố>"
 
 msgid "show the given source prefix instead of \"a/\""
 msgstr "hiển thị tiền tố nguồn đã cho thay cho \"a/\""
@@ -15304,6 +15887,9 @@
 msgid "do not show any source or destination prefix"
 msgstr "đừng hiển thị bất kỳ tiền tố nguồn hay đích"
 
+msgid "use default prefixes a/ and b/"
+msgstr "dùng tiền tố mặc định a/ và b/"
+
 msgid "show context between diff hunks up to the specified number of lines"
 msgstr ""
 "hiển thị ngữ cảnh giữa các khúc khác biệt khi đạt đến số lượng dòng đã chỉ "
@@ -15313,13 +15899,13 @@
 msgstr "<ký_tự>"
 
 msgid "specify the character to indicate a new line instead of '+'"
-msgstr "chỉ định một ký tự để biểu thị một dòng được thêm mới thay cho “+”"
+msgstr "chỉ định một ký tự để biểu thị một dòng được thêm mới thay cho '+'"
 
 msgid "specify the character to indicate an old line instead of '-'"
-msgstr "chỉ định một ký tự để biểu thị một dòng đã cũ thay cho “-”"
+msgstr "chỉ định một ký tự để biểu thị một dòng đã cũ thay cho '-'"
 
 msgid "specify the character to indicate a context instead of ' '"
-msgstr "chỉ định một ký tự để biểu thị một ngữ cảnh thay cho “”"
+msgstr "chỉ định một ký tự để biểu thị một ngữ cảnh thay cho ''"
 
 msgid "Diff rename options"
 msgstr "Tùy chọn khác biệt đổi tên"
@@ -15365,13 +15951,13 @@
 msgstr "sản sinh khác biệt ít nhất có thể"
 
 msgid "ignore whitespace when comparing lines"
-msgstr "lờ đi sự thay đổi do khoảng trắng gây ra khi so sánh các dòng"
+msgstr "bỏ qua sự thay đổi do khoảng trắng gây ra khi so sánh các dòng"
 
 msgid "ignore changes in amount of whitespace"
-msgstr "lờ đi sự thay đổi do số lượng khoảng trắng gây ra"
+msgstr "bỏ qua sự thay đổi do số lượng khoảng trắng gây ra"
 
 msgid "ignore changes in whitespace at EOL"
-msgstr "lờ đi sự thay đổi do khoảng trắng gây ra khi ở cuối dòng EOL"
+msgstr "bỏ qua sự thay đổi do khoảng trắng gây ra khi ở cuối dòng EOL"
 
 msgid "ignore carrier-return at the end of line"
 msgstr "bỏ qua ký tự về đầu dòng tại cuối dòng"
@@ -15394,12 +15980,6 @@
 msgid "generate diff using the \"histogram diff\" algorithm"
 msgstr "tạo khác biệt sử dung thuật toán \"histogram diff\""
 
-msgid "<algorithm>"
-msgstr "<thuật toán>"
-
-msgid "choose a diff algorithm"
-msgstr "chọn một thuật toán khác biệt"
-
 msgid "<text>"
 msgstr "<văn bản>"
 
@@ -15446,7 +16026,7 @@
 msgstr "tắt mọi kết xuất của chương trình"
 
 msgid "allow an external diff helper to be executed"
-msgstr "cho phép mộ bộ hỗ trợ xuất khác biệt ở bên ngoài được phép thực thi"
+msgstr "cho phép mộ helper xuất khác biệt ở bên ngoài được phép thực thi"
 
 msgid "run external text conversion filters when comparing binary files"
 msgstr ""
@@ -15466,10 +16046,10 @@
 msgstr "chi định khác biệt bao nhiêu trong các mô đun con được hiển thị"
 
 msgid "hide 'git add -N' entries from the index"
-msgstr "ẩn các mục “git add -N” từ bảng mục lục"
+msgstr "ẩn các mục 'git add -N' từ chỉ mục"
 
 msgid "treat 'git add -N' entries as real in the index"
-msgstr "coi các mục “git add -N” như là có thật trong bảng mục lục"
+msgstr "coi các mục 'git add -N' như là có thật trong chỉ mục"
 
 msgid "<string>"
 msgstr "<chuỗi>"
@@ -15492,19 +16072,19 @@
 msgstr "hiển thị tất cả các thay đổi trong một bộ các thay đổi với -S hay -G"
 
 msgid "treat <string> in -S as extended POSIX regular expression"
-msgstr "coi <chuỗi> trong -S như là biểu thức chính qui POSIX có mở rộng"
+msgstr "coi <chuỗi> trong -S là biểu thức chính quy POSIX mở rộng"
 
 msgid "control the order in which files appear in the output"
-msgstr "điều khiển thứ tự xuát hiện các tập tin trong kết xuất"
+msgstr "điều khiển thứ tự xuất hiện các tập tin trong đầu ra"
 
 msgid "<path>"
 msgstr "<đường-dẫn>"
 
 msgid "show the change in the specified path first"
-msgstr "hiển thị các thay đổi trong đường dẫn đã cho đầu tiên"
+msgstr "hiển thị các thay đổi trong đường dẫn đã cho ở đầu"
 
 msgid "skip the output to the specified path"
-msgstr "bỏ qua đầu ra đến đường dẫn đã cho"
+msgstr "bỏ qua đầu ra với đường dẫn đã cho"
 
 msgid "<object-id>"
 msgstr "<mã-số-đối-tượng>"
@@ -15512,42 +16092,38 @@
 msgid ""
 "look for differences that change the number of occurrences of the specified "
 "object"
-msgstr ""
-"tìm các khác biệt cái mà thay đổi số lượng xảy ra của các phát sinh của đối "
-"tượng được chỉ ra"
+msgstr "tìm các diff có thay đổi số lượng xuất hiện của đối tượng"
 
 msgid "[(A|C|D|M|R|T|U|X|B)...[*]]"
-msgstr "[(A|C|D|M|R|T|U|X|B)…[*]]"
+msgstr "[(A|C|D|M|R|T|U|X|B)...[*]]"
 
 msgid "select files by diff type"
 msgstr "chọn các tập tin theo kiểu khác biệt"
 
 msgid "<file>"
-msgstr "<tập_tin>"
+msgstr "<tập tin>"
 
 msgid "output to a specific file"
-msgstr "xuất ra một tập tin cụ thể"
+msgstr "xuất ra tập tin này"
 
 msgid "exhaustive rename detection was skipped due to too many files."
-msgstr "nhận thấy đổi tên toàn diện đã bị bỏ qua bởi có quá nhiều tập tin."
+msgstr "bỏ tìm tất cả các lần đổi tên vì có quá nhiều tập tin."
 
 msgid "only found copies from modified paths due to too many files."
 msgstr ""
-"chỉ tìm thấy các bản sao từ đường dẫn đã sửa đổi bởi vì có quá nhiều tập tin."
+"chỉ tìm các lần sao chép từ đường dẫn đã sửa đổi vì có quá nhiều tập tin."
 
 #, c-format
 msgid ""
 "you may want to set your %s variable to at least %d and retry the command."
-msgstr ""
-"bạn có lẽ muốn đặt biến %s của bạn thành ít nhất là %d và thử lại lệnh lần "
-"nữa."
+msgstr "bạn có lẽ muốn đặt biến %s của bạn thành ít nhất là %d và thử lại."
 
 #, c-format
 msgid "failed to read orderfile '%s'"
-msgstr "gặp lỗi khi đọc tập-tin-thứ-tự “%s”"
+msgstr "gặp lỗi khi đọc orderfile '%s'"
 
 msgid "Performing inexact rename detection"
-msgstr "Đang thực hiện dò tìm đổi tên không chính xác"
+msgstr "Đang thực hiện inexact rename detection (tìm sơ bộ các lần đổi tên)"
 
 #, c-format
 msgid "No such path '%s' in the diff"
@@ -15555,43 +16131,43 @@
 
 #, c-format
 msgid "pathspec '%s' did not match any file(s) known to git"
-msgstr "đặc tả đường dẫn “%s” không khớp với bất kỳ tập tin nào mà git biết"
+msgstr "đặc tả đường dẫn '%s' không khớp với bất kỳ tập tin nào mà git biết"
 
 #, c-format
 msgid "unrecognized pattern: '%s'"
-msgstr "mẫu không được thừa nhận: “%s”"
+msgstr "không hiểu mẫu: '%s'"
 
 #, c-format
 msgid "unrecognized negative pattern: '%s'"
-msgstr "mẫu âm không được thừa nhận: “%s”"
+msgstr "không hiểu mẫu loại trừ: '%s'"
 
 #, c-format
 msgid "your sparse-checkout file may have issues: pattern '%s' is repeated"
-msgstr "tập tin sparse-checkout của bạn có lẽ gặp lỗi: mẫu “%s” đã bị lặp lại"
+msgstr "tập tin sparse-checkout của bạn có lẽ gặp lỗi: mẫu '%s' đã bị lặp lại"
 
 msgid "disabling cone pattern matching"
-msgstr "vô hiệu khớp mẫu nón"
+msgstr "vô hiệu cone pattern matching (khớp mẫu nón)"
 
 #, c-format
 msgid "cannot use %s as an exclude file"
-msgstr "không thể dùng %s như là một tập tin loại trừ"
+msgstr "không thể dùng %s như là tập tin loại trừ"
 
 msgid "failed to get kernel name and information"
-msgstr "gặp lỗi khi lấy tên và thông tin của nhân"
+msgstr "gặp lỗi khi lấy tên và thông tin của kernel"
 
 msgid "untracked cache is disabled on this system or location"
-msgstr "bộ nhớ tạm không theo vết bị tắt trên hệ thống hay vị trí này"
+msgstr "bộ nhớ tạm không theo vết bị vô hiệu trên hệ thống hay vị trí này"
 
 msgid ""
 "No directory name could be guessed.\n"
 "Please specify a directory on the command line"
 msgstr ""
 "Không đoán được thư mục tên là gì.\n"
-"Vui lòng chỉ định tên một thư mục trên dòng lệnh"
+"Vui lòng chỉ định tên thư mục trên dòng lệnh"
 
 #, c-format
 msgid "index file corrupt in repo %s"
-msgstr "tập tin ghi bảng mục lục bị hỏng trong kho %s"
+msgstr "tập tin ghi chỉ mục bị hỏng trong kho %s"
 
 #, c-format
 msgid "could not create directories for %s"
@@ -15599,18 +16175,26 @@
 
 #, c-format
 msgid "could not migrate git directory from '%s' to '%s'"
-msgstr "không thể di dời thư mục git từ “%s” sang “%s”"
+msgstr "không thể di dời thư mục git từ '%s' sang '%s'"
 
 #, c-format
 msgid "hint: Waiting for your editor to close the file...%c"
-msgstr "gợi ý: Chờ trình biên soạn của bạn đóng tập tin…%c"
+msgstr "gợi ý: Chờ trình biên soạn của bạn đóng tập tin...%c"
+
+#, c-format
+msgid "could not write to '%s'"
+msgstr "không thể ghi vào '%s'"
+
+#, c-format
+msgid "could not edit '%s'"
+msgstr "không thể sửa '%s'"
 
 msgid "Filtering content"
 msgstr "Nội dung lọc"
 
 #, c-format
 msgid "could not stat file '%s'"
-msgstr "không thể lấy thống kê tập tin “%s”"
+msgstr "không thể lấy thống kê tập tin '%s'"
 
 #, c-format
 msgid "bad git namespace path \"%s\""
@@ -15624,17 +16208,20 @@
 msgstr "git fetch-pack: cần danh sách shallow"
 
 msgid "git fetch-pack: expected a flush packet after shallow list"
-msgstr "git fetch-pack: cần một gói đẩy sau danh sách shallow"
+msgstr "git fetch-pack: cần một gói flush sau danh sách shallow"
 
 msgid "git fetch-pack: expected ACK/NAK, got a flush packet"
 msgstr "git fetch-pack: cần ACK/NAK, nhưng lại nhận được một gói flush"
 
 #, c-format
 msgid "git fetch-pack: expected ACK/NAK, got '%s'"
-msgstr "git fetch-pack: cần ACK/NAK, nhưng lại nhận được “%s”"
+msgstr "git fetch-pack: cần ACK/NAK, nhưng lại nhận được '%s'"
 
 msgid "unable to write to remote"
-msgstr "không thể ghi lên máy phục vụ"
+msgstr "không thể ghi lên máy chủ"
+
+msgid "Server supports filter"
+msgstr "Máy chủ hỗ trợ bộ lọc"
 
 #, c-format
 msgid "invalid shallow line: %s"
@@ -15658,7 +16245,7 @@
 
 #, c-format
 msgid "expected shallow/unshallow, got %s"
-msgstr "cần shallow/unshallow, nhưng lại nhận được %s"
+msgstr "cần shallow/unshallow, nhưng lại có %s"
 
 #, c-format
 msgid "got %s %d %s"
@@ -15741,28 +16328,25 @@
 
 #, c-format
 msgid "the server does not support algorithm '%s'"
-msgstr "máy chủ không hỗ trợ thuật toán “%s”"
+msgstr "máy chủ không hỗ trợ thuật toán '%s'"
 
 msgid "Server does not support shallow requests"
 msgstr "Máy chủ không hỗ trợ yêu cầu shallow"
 
-msgid "Server supports filter"
-msgstr "Máy chủ hỗ trợ bộ lọc"
-
 msgid "unable to write request to remote"
-msgstr "không thể ghi các yêu cầu lên máy phục vụ"
+msgstr "không thể ghi các yêu cầu lên máy chủ"
 
 #, c-format
 msgid "expected '%s', received '%s'"
-msgstr "cần “%s”, nhưng lại nhận “%s”"
+msgstr "cần '%s', nhưng lại nhận '%s'"
 
 #, c-format
 msgid "expected '%s'"
-msgstr "cần “%s”"
+msgstr "cần '%s'"
 
 #, c-format
 msgid "unexpected acknowledgment line: '%s'"
-msgstr "gặp dòng không được thừa nhận: “%s”"
+msgstr "gặp dòng không được thừa nhận: '%s'"
 
 #, c-format
 msgid "error processing acks: %d"
@@ -15773,14 +16357,14 @@
 #.
 #, c-format
 msgid "expected packfile to be sent after '%s'"
-msgstr "cần tập tin gói để gửi sau “%s”"
+msgstr "cần tập tin gói để gửi sau '%s'"
 
 #. TRANSLATORS: The parameter will be 'ready', a protocol
 #. keyword.
 #.
 #, c-format
 msgid "expected no other sections to be sent after no '%s'"
-msgstr "không cần thêm phần nào để gửi sau không “%s”"
+msgstr "không có phần nào để gửi khi không có '%s'"
 
 #, c-format
 msgid "error processing shallow info: %d"
@@ -15788,11 +16372,11 @@
 
 #, c-format
 msgid "expected wanted-ref, got '%s'"
-msgstr "cần wanted-ref, nhưng lại nhận được “%s”"
+msgstr "cần wanted-ref, nhưng lại nhận được '%s'"
 
 #, c-format
 msgid "unexpected wanted-ref: '%s'"
-msgstr "wanted-ref không được mong đợi: “%s”"
+msgstr "wanted-ref không được mong đợi: '%s'"
 
 #, c-format
 msgid "error processing wanted refs: %d"
@@ -15805,7 +16389,7 @@
 msgstr "không khớp phần đầu máy chủ"
 
 msgid "unexpected 'ready' from remote"
-msgstr "gặp “ready” đột xuất từ máy chủ"
+msgstr "gặp 'ready' đột xuất từ máy chủ"
 
 #, c-format
 msgid "no such remote ref %s"
@@ -15813,8 +16397,7 @@
 
 #, c-format
 msgid "Server does not allow request for unadvertised object %s"
-msgstr ""
-"Máy phục vụ không cho phép yêu cầu cho đối tượng không được báo trước %s"
+msgstr "máy chủ không cho phép yêu cầu cho đối tượng không được báo trước %s"
 
 #, c-format
 msgid "fsmonitor_ipc__send_query: invalid path '%s'"
@@ -15833,7 +16416,7 @@
 
 #, c-format
 msgid "bare repository '%s' is incompatible with fsmonitor"
-msgstr "kho thuần '%s' là không tương thích với fsmonitor"
+msgstr "kho bare '%s' là không tương thích với fsmonitor"
 
 #, c-format
 msgid "repository '%s' is incompatible with fsmonitor due to errors"
@@ -15849,8 +16432,11 @@
 
 #, c-format
 msgid ""
-"repository '%s' is incompatible with fsmonitor due to lack of Unix sockets"
-msgstr "kho '%s' là không tương thích với fsmonitor bởi vì thiếu Unix sockets"
+"socket directory '%s' is incompatible with fsmonitor due to lack of Unix "
+"sockets support"
+msgstr ""
+"thư mục socket '%s' không tương thích với fsmonitor bởi vì thiếu hỗ trợ Unix "
+"socket"
 
 msgid ""
 "git [-v | --version] [-h | --help] [-C <path>] [-c <name>=<value>]\n"
@@ -15858,18 +16444,16 @@
 "           [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--"
 "bare]\n"
 "           [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]\n"
-"           [--super-prefix=<path>] [--config-env=<name>=<envvar>]\n"
-"           <command> [<args>]"
+"           [--config-env=<name>=<envvar>] <command> [<args>]"
 msgstr ""
-"git [--version] [-h | --help] [-C </đường/dẫn/>] [-c <tên>=<giá trị>]\n"
+"git [-v | --version] [-h | --help] [-C </đường/dẫn/>] [-c <tên>=<giá trị>]\n"
 "           [--exec-path[=</đường/dẫn/>]] [--html-path] [--man-path] [--info-"
 "path]\n"
 "           [-p | --paginate | -P --no-pager] [--no-replace-objects] [--"
 "bare]\n"
 "           [--git-dir=</đường/dẫn/>] [--work-tree=</đường/dẫn/>] [--"
 "namespace=<tên>]\n"
-"           [--super-prefix=</đường/dẫn/>] [--config-env=<tên>=<envvar>]\n"
-"           <lệnh> [<các tham số>]"
+"           [--config-env=<tên>=<envvar>] <lệnh> [<các tham số>]"
 
 msgid ""
 "'git help -a' and 'git help -g' list available subcommands and some\n"
@@ -15877,14 +16461,14 @@
 "to read about a specific subcommand or concept.\n"
 "See 'git help git' for an overview of the system."
 msgstr ""
-"“git help -a” và “git help -g” liệt kê các câu lệnh con sẵn có và một số\n"
-"hướng dẫn về khái niệm. Xem “git help <lệnh>” hay “git help <khái-niệm>”\n"
+"'git help -a' và 'git help -g' liệt kê các câu lệnh con sẵn có và một số\n"
+"hướng dẫn về khái niệm. Xem 'git help <lệnh>' hay 'git help <khái-niệm>'\n"
 "để xem các đặc tả cho lệnh hay khái niệm cụ thể.\n"
-"Xem “git help git” để biết tổng quan của hệ thống."
+"Xem 'git help git' để biết tổng quan của hệ thống."
 
 #, c-format
 msgid "unsupported command listing type '%s'"
-msgstr "không hỗ trợ liệt kê lệnh kiểu “%s”"
+msgstr "không hỗ trợ liệt kê lệnh kiểu '%s'"
 
 #, c-format
 msgid "no directory given for '%s' option\n"
@@ -15895,10 +16479,6 @@
 msgstr "chưa đưa ra không gian làm việc cho --namespace\n"
 
 #, c-format
-msgid "no prefix given for --super-prefix\n"
-msgstr "chưa đưa ra tiền tố cho --super-prefix\n"
-
-#, c-format
 msgid "-c expects a configuration string\n"
 msgstr "-c cần một chuỗi cấu hình\n"
 
@@ -15907,20 +16487,24 @@
 msgstr "không đưa ra khóa cấu hình cho --config-env\n"
 
 #, c-format
+msgid "no attribute source given for --attr-source\n"
+msgstr "không đưa ra nguồn thuộc tính cho --attr-source\n"
+
+#, c-format
 msgid "unknown option: %s\n"
 msgstr "không hiểu tùy chọn: %s\n"
 
 #, c-format
 msgid "while expanding alias '%s': '%s'"
-msgstr "trong khi triển khai bí danh “%s”: “%s”"
+msgstr "trong khi triển khai bí danh '%s': '%s'"
 
 #, c-format
 msgid ""
 "alias '%s' changes environment variables.\n"
 "You can use '!git' in the alias to do this"
 msgstr ""
-"bí danh “%s” thay đổi biến môi trường.\n"
-"Bạn có thể sử dụng “!git” trong đặt bí danh để làm việc này"
+"bí danh '%s' thay đổi biến môi trường.\n"
+"Bạn có thể sử dụng '!git' trong đặt bí danh để làm việc này"
 
 #, c-format
 msgid "empty alias for %s"
@@ -15931,22 +16515,22 @@
 msgstr "đệ quy các bí danh: %s"
 
 msgid "write failure on standard output"
-msgstr "lỗi ghi nghiêm trong trên đầu ra tiêu chuẩn"
+msgstr "lỗi khi ghi ra stdout"
 
 msgid "unknown write failure on standard output"
-msgstr "lỗi nghiêm trọng chưa biết khi ghi ra đầu ra tiêu chuẩn"
+msgstr "lỗi không rõ khi ghi ra stdout"
 
 msgid "close failed on standard output"
-msgstr "gặp lỗi khi đóng đầu ra tiêu chuẩn"
+msgstr "lỗi khi đóng stdout"
 
 #, c-format
 msgid "alias loop detected: expansion of '%s' does not terminate:%s"
 msgstr ""
-"dò tìm thấy các bí danh quẩn tròn: biểu thức của “%s” không có điểm kết:%s"
+"dò tìm thấy các bí danh quẩn tròn: biểu thức của '%s' không có điểm kết:%s"
 
 #, c-format
 msgid "cannot handle %s as a builtin"
-msgstr "không thể xử lý %s như là một phần bổ sung"
+msgstr "không thể xử lý %s như là builtin"
 
 #, c-format
 msgid ""
@@ -15958,18 +16542,18 @@
 
 #, c-format
 msgid "expansion of alias '%s' failed; '%s' is not a git command\n"
-msgstr "gặp lỗi khi khai triển bí danh “%s”; “%s” không phải là lệnh git\n"
+msgstr "gặp lỗi khi khai triển bí danh '%s'; '%s' không phải là lệnh git\n"
 
 #, c-format
 msgid "failed to run command '%s': %s\n"
-msgstr "gặp lỗi khi chạy lệnh “%s”: %s\n"
+msgstr "gặp lỗi khi chạy lệnh '%s': %s\n"
 
 msgid "could not create temporary file"
 msgstr "không thể tạo tập tin tạm thời"
 
 #, c-format
 msgid "failed writing detached signature to '%s'"
-msgstr "gặp lỗi khi ghi chữ ký đính kèm vào “%s”"
+msgstr "gặp lỗi khi ghi chữ ký đính kèm vào '%s'"
 
 msgid ""
 "gpg.ssh.allowedSignersFile needs to be configured and exist for ssh "
@@ -15991,11 +16575,11 @@
 
 #, c-format
 msgid "bad/incompatible signature '%s'"
-msgstr "chữ sai / không tương thích “%s”"
+msgstr "chữ sai / không tương thích '%s'"
 
 #, c-format
 msgid "failed to get the ssh fingerprint for key '%s'"
-msgstr "gặp lỗi khi lấy dấu vân tay ssh cho khóa “%s”"
+msgstr "gặp lỗi khi lấy dấu vân tay ssh cho khóa '%s'"
 
 msgid ""
 "either user.signingkey or gpg.ssh.defaultKeyCommand needs to be configured"
@@ -16011,19 +16595,24 @@
 msgid "gpg.ssh.defaultKeyCommand failed: %s %s"
 msgstr "gpg.ssh.defaultKeyCommand gặp lỗi: %s %s"
 
-msgid "gpg failed to sign the data"
-msgstr "gpg gặp lỗi khi ký dữ liệu"
+#, c-format
+msgid ""
+"gpg failed to sign the data:\n"
+"%s"
+msgstr ""
+"gpg gặp lỗi khi ký dữ liệu:\n"
+"%s"
 
 msgid "user.signingKey needs to be set for ssh signing"
 msgstr "user.signingKey cần được đặt cho ký ssh"
 
 #, c-format
 msgid "failed writing ssh signing key to '%s'"
-msgstr "gặp lỗi khi ghi chìa khóa ký ssh vào “%s”"
+msgstr "gặp lỗi khi ghi chìa khóa ký ssh vào '%s'"
 
 #, c-format
 msgid "failed writing ssh signing key buffer to '%s'"
-msgstr "gặp lỗi khi ghi bộ đệm chìa khóa ký ssh vào “%s”"
+msgstr "gặp lỗi khi ghi bộ đệm chìa khóa ký ssh vào '%s'"
 
 msgid ""
 "ssh-keygen -Y sign is needed for ssh signing (available in openssh version "
@@ -16034,11 +16623,11 @@
 
 #, c-format
 msgid "failed reading ssh signing data buffer from '%s'"
-msgstr "gặp lỗi khi đọc bộ đệm dữ liệu chữ ký ssh từ “%s”"
+msgstr "gặp lỗi khi đọc bộ đệm dữ liệu chữ ký ssh từ '%s'"
 
 #, c-format
 msgid "ignored invalid color '%.*s' in log.graphColors"
-msgstr "bỏ qua màu không hợp lệ “%.*s” trong log.graphColors"
+msgstr "bỏ qua màu không hợp lệ '%.*s' trong log.graphColors"
 
 msgid ""
 "given pattern contains NULL byte (via -f <file>). This is only supported "
@@ -16049,11 +16638,11 @@
 
 #, c-format
 msgid "'%s': unable to read %s"
-msgstr "“%s”: không thể đọc %s"
+msgstr "'%s': không thể đọc %s"
 
 #, c-format
 msgid "'%s': short read"
-msgstr "“%s”: đọc ngắn"
+msgstr "'%s': đọc ngắn"
 
 msgid "start a working area (see also: git help tutorial)"
 msgstr "bắt đầu một vùng làm việc (xem thêm: git help tutorial)"
@@ -16094,9 +16683,15 @@
 msgid "Low-level Commands / Internal Helpers"
 msgstr "Lệnh/Hỗ trợ nội tại ở mức thấp"
 
+msgid "User-facing repository, command and file interfaces"
+msgstr "Các giao diện kho, lệnh và tập tin hướng người dùng"
+
+msgid "Developer-facing file formats, protocols and other interfaces"
+msgstr "Các giao diện tập tin, giao thức và khác cho lập trình viên"
+
 #, c-format
 msgid "available git commands in '%s'"
-msgstr "các lệnh git sẵn có trong thư mục “%s”:"
+msgstr "các lệnh git sẵn có trong thư mục '%s':"
 
 msgid "git commands available from elsewhere on your $PATH"
 msgstr "các lệnh git sẵn có từ một nơi khác trong $PATH của bạn"
@@ -16107,6 +16702,12 @@
 msgid "The Git concept guides are:"
 msgstr "Các chỉ dẫn khái niệm về Git là:"
 
+msgid "User-facing repository, command and file interfaces:"
+msgstr "Các giao diện kho, lệnh và tập tin hướng người dùng"
+
+msgid "File formats, protocols and other developer interfaces:"
+msgstr "Các giao diện tập tin, giao thức và khác cho lập trình viên"
+
 msgid "External commands"
 msgstr "Các lệnh bên ngoài"
 
@@ -16114,38 +16715,38 @@
 msgstr "Các bí danh lệnh"
 
 msgid "See 'git help <command>' to read about a specific subcommand"
-msgstr "Xem “git help <lệnh>” để đọc các đặc tả của lệnh con"
+msgstr "Xem 'git help <lệnh>' để đọc các đặc tả của lệnh con"
 
 #, c-format
 msgid ""
 "'%s' appears to be a git command, but we were not\n"
 "able to execute it. Maybe git-%s is broken?"
 msgstr ""
-"“%s” trông như là một lệnh git, nhưng chúng tôi không\n"
+"'%s' trông như là một lệnh git, nhưng chúng tôi không\n"
 "thể thực thi nó. Có lẽ là lệnh git-%s đã bị hỏng?"
 
 #, c-format
 msgid "git: '%s' is not a git command. See 'git --help'."
-msgstr "git: “%s” không phải là một lệnh của git. Xem “git --help”."
+msgstr "git: '%s' không phải là một lệnh của git. Xem 'git --help'."
 
 msgid "Uh oh. Your system reports no Git commands at all."
 msgstr "Ối chà. Hệ thống của bạn báo rằng chẳng có lệnh Git nào cả."
 
 #, c-format
 msgid "WARNING: You called a Git command named '%s', which does not exist."
-msgstr "CẢNH BÁO: Bạn đã gọi lệnh Git có tên “%s”, mà nó lại không có sẵn."
+msgstr "CẢNH BÁO: Bạn đã gọi lệnh Git có tên '%s', mà nó lại không có sẵn."
 
 #, c-format
 msgid "Continuing under the assumption that you meant '%s'."
-msgstr "Tiếp tục và coi rằng ý bạn là “%s”."
+msgstr "Tiếp tục và coi rằng ý bạn là '%s'."
 
 #, c-format
 msgid "Run '%s' instead [y/N]? "
-msgstr "Chạy “%s” để thay thế? (y/N)? "
+msgstr "Chạy '%s' để thay thế? (y/N)? "
 
 #, c-format
 msgid "Continuing in %0.1f seconds, assuming that you meant '%s'."
-msgstr "Tiếp tục trong %0.1f giây,và coi rằng ý bạn là “%s”."
+msgstr "Tiếp tục trong %0.1f giây,và coi rằng ý bạn là '%s'."
 
 msgid ""
 "\n"
@@ -16157,8 +16758,8 @@
 "\n"
 "Những lệnh giống nhất là"
 
-msgid "git version [<options>]"
-msgstr "git version [<các tùy chọn>]"
+msgid "git version [--build-options]"
+msgstr "git version [--build-options]"
 
 #, c-format
 msgid "%s: %s - %s"
@@ -16179,16 +16780,12 @@
 "The '%s' hook was ignored because it's not set as executable.\n"
 "You can disable this warning with `git config advice.ignoredHook false`."
 msgstr ""
-"Móc “%s” bị bỏ qua bởi vì nó không thể đặt là thực thi được.\n"
-"Bạn có thể tắt cảnh báo này bằng “git config advice.ignoredHook false“."
-
-#, c-format
-msgid "Couldn't start hook '%s'\n"
-msgstr "Không thể khởi chạy móc “%s”\n"
+"Móc '%s' bị bỏ qua bởi vì nó không thể đặt là thực thi được.\n"
+"Bạn có thể tắt cảnh báo này bằng 'git config advice.ignoredHook false'."
 
 #, c-format
 msgid "argument to --packfile must be a valid hash (got '%s')"
-msgstr "tham số cho --packfile phải là một giá trị băm hợp lệ (nhận được “%s”)"
+msgstr "tham số cho --packfile phải là một giá trị băm hợp lệ (có '%s')"
 
 msgid "not a git repository"
 msgstr "không phải là kho git"
@@ -16209,18 +16806,18 @@
 #, c-format
 msgid "Unsupported SSL backend '%s'. Supported SSL backends:"
 msgstr ""
-"Không hỗ trợ ứng dụng SSL chạy phía sau “%s”. Hỗ trợ ứng dụng SSL chạy phía "
+"Không hỗ trợ ứng dụng SSL chạy phía sau '%s'. Hỗ trợ ứng dụng SSL chạy phía "
 "sau:"
 
 #, c-format
 msgid "Could not set SSL backend to '%s': cURL was built without SSL backends"
 msgstr ""
-"Không thể đặt ứng dụng chạy SSL phía sau “%s”: cURL được biên dịch không có "
+"Không thể đặt ứng dụng chạy SSL phía sau '%s': cURL được biên dịch không có "
 "sự hỗ trợ ứng dụng chạy phía sau SSL"
 
 #, c-format
 msgid "Could not set SSL backend to '%s': already set"
-msgstr "Không thể đặt ứng dụng chạy sau SSL cho “%s”: đã đặt rồi"
+msgstr "Không thể đặt ứng dụng chạy sau SSL cho '%s': đã đặt rồi"
 
 #, c-format
 msgid ""
@@ -16268,14 +16865,14 @@
 
 #, c-format
 msgid "unable to auto-detect email address (got '%s')"
-msgstr "không thể tự dò tìm địa chỉ thư điện tử (nhận “%s”)"
+msgstr "không thể tự dò tìm địa chỉ thư điện tử (nhận '%s')"
 
 msgid "no name was given and auto-detection is disabled"
 msgstr "chưa chỉ ra tên và tự-động-dò-tìm bị tắt"
 
 #, c-format
 msgid "unable to auto-detect name (got '%s')"
-msgstr "không thể dò-tìm-tự động tên (đã nhận “%s”)"
+msgstr "không thể dò-tìm-tự động tên (đã nhận '%s')"
 
 #, c-format
 msgid "empty ident name (for <%s>) not allowed"
@@ -16286,22 +16883,22 @@
 msgstr "tên chỉ được phép bao gồm các ký tự sau: %s"
 
 msgid "expected 'tree:<depth>'"
-msgstr "cần “tree:<depth>”"
+msgstr "cần 'tree:<depth>'"
 
 msgid "sparse:path filters support has been dropped"
-msgstr "việc hỗ trợ bộ lọc sparse:đường/dẫn đã bị bỏ"
+msgstr "hỗ trợ bộ lọc sparse:đường/dẫn đã không còn"
 
 #, c-format
 msgid "'%s' for 'object:type=<type>' is not a valid object type"
-msgstr "“%s” dành cho “object:type=<type>” không phải là kiểu đối tượng hợp lệ"
+msgstr "'%s' dành cho 'object:type=<type>' không phải là kiểu đối tượng hợp lệ"
 
 #, c-format
 msgid "invalid filter-spec '%s'"
-msgstr "đặc tả bộ lọc không hợp lệ “%s”"
+msgstr "đặc tả bộ lọc không hợp lệ '%s'"
 
 #, c-format
 msgid "must escape char in sub-filter-spec: '%c'"
-msgstr "phải thoát char trong sub-filter-spec: “%c”"
+msgstr "phải thoát char trong sub-filter-spec: '%c'"
 
 msgid "expected something after combine:"
 msgstr "mong đợi một cái gì đó sau khi kết hợp:"
@@ -16320,23 +16917,23 @@
 
 #, c-format
 msgid "unable to access sparse blob in '%s'"
-msgstr "không thể truy cập các blob rải rác trong “%s”"
+msgstr "không thể truy cập các blob rải rác trong '%s'"
 
 #, c-format
 msgid "unable to parse sparse filter data in %s"
-msgstr "không thể phân tích dữ liệu bộ lọc rải rác trong %s"
+msgstr "không thể đọc dữ liệu bộ lọc rải rác trong %s"
 
 #, c-format
 msgid "entry '%s' in tree %s has tree mode, but is not a tree"
-msgstr "mục “%s” trong cây %s có nút cây, nhưng không phải là một cây"
+msgstr "mục '%s' trong cây %s có nút cây, nhưng không phải là một cây"
 
 #, c-format
 msgid "entry '%s' in tree %s has blob mode, but is not a blob"
-msgstr "mục “%s” trong cây %s có nút blob, nhưng không phải là một blob"
+msgstr "mục '%s' trong cây %s có nút blob, nhưng không phải là một blob"
 
 #, c-format
 msgid "unable to load root tree for commit %s"
-msgstr "không thể tải cây gốc cho lần chuyển giao “%s”"
+msgstr "không thể tải cây gốc cho lần chuyển giao '%s'"
 
 #, c-format
 msgid ""
@@ -16348,21 +16945,29 @@
 "may have crashed in this repository earlier:\n"
 "remove the file manually to continue."
 msgstr ""
-"Không thể tạo “%s.lock”: %s.\n"
+"Không thể tạo '%s.lock': %s.\n"
 "\n"
 "Tiến trình git khác có lẽ đang chạy ở kho này, ví dụ\n"
-"một trình soạn thảo được mở bởi “git commit”. Vui lòng chắc chắn\n"
-"rằng mọi tiến trình đã chấm dứt và sau đó thử lại. Nếu vẫn lỗi,\n"
-"một tiến trình git có lẽ đã đổ vỡ khi thực hiện ở kho này trước đó:\n"
+"một trình soạn thảo được mở bởi 'git commit'. Vui lòng chắc chắn\n"
+"rằng mọi tiến trình đã kết thúc và sau đó thử lại. Nếu vẫn lỗi,\n"
+"một tiến trình git có lẽ đã crash khi thực hiện ở kho này trước đó:\n"
 "gõ bỏ tập tin một cách thủ công để tiếp tục."
 
 #, c-format
 msgid "Unable to create '%s.lock': %s"
-msgstr "Không thể tạo “%s.lock”: %s"
+msgstr "Không thể tạo '%s.lock': %s"
+
+#, c-format
+msgid "could not write loose object index %s"
+msgstr "không thể ghi tập tin đối tượng loose %s"
+
+#, c-format
+msgid "failed to write loose object index %s\n"
+msgstr "ghi chỉ mục đối tượng loose %s thất bại\n"
 
 #, c-format
 msgid "unexpected line: '%s'"
-msgstr "dòng không cần: “%s”"
+msgstr "dòng bất thường: '%s'"
 
 msgid "expected flush after ls-refs arguments"
 msgstr "cần đẩy dữ liệu lên đĩa sau tham số ls-refs (liệt kê tham chiếu)"
@@ -16371,73 +16976,57 @@
 msgstr "phát hiện CRLF được trích dẫn"
 
 #, c-format
-msgid ""
-"Your local changes to the following files would be overwritten by merge:\n"
-"  %s"
-msgstr ""
-"Các thay đổi nội bộ của bạn với các tập tin sau đây sẽ bị ghi đè bởi lệnh "
-"hòa trộn:\n"
-"  %s"
+msgid "unable to format message: %s"
+msgstr "không thể định dạng thông điệp: %s"
 
 #, c-format
 msgid "Failed to merge submodule %s (not checked out)"
-msgstr "Gặp lỗi khi hòa trộn mô-đun-con “%s” (không lấy ra được)"
+msgstr "Gặp lỗi khi hòa trộn mô-đun-con %s (không checkout được)"
+
+#, c-format
+msgid "Failed to merge submodule %s (no merge base)"
+msgstr "Gặp lỗi khi hòa trộn mô-đun-con %s (không có gốc hoà trộn)"
 
 #, c-format
 msgid "Failed to merge submodule %s (commits not present)"
-msgstr "Gặp lỗi khi hòa trộn mô-đun-con “%s” (lần chuyển giao không hiện diện)"
+msgstr "Gặp lỗi khi hòa trộn mô-đun-con %s (lần chuyển giao không hiện diện)"
+
+#, c-format
+msgid "Failed to merge submodule %s (repository corrupt)"
+msgstr "Gặp lỗi khi hòa trộn mô-đun-con %s (kho chứa hỏng)"
 
 #, c-format
 msgid "Failed to merge submodule %s (commits don't follow merge-base)"
 msgstr ""
-"Gặp lỗi khi hòa trộn mô-đun-con “%s” (lần chuyển giao không theo sau nền-hòa-"
+"Gặp lỗi khi hòa trộn mô-đun-con %s (lần chuyển giao không theo sau gốc-hòa-"
 "trộn)"
 
 #, c-format
 msgid "Note: Fast-forwarding submodule %s to %s"
-msgstr "Chú ý: Chuyển-tiếp-nhanh mô-đun-con “%s” sang “%s”"
+msgstr "Chú ý: Chuyển-tiếp-nhanh mô-đun-con %s sang %s"
 
 #, c-format
 msgid "Failed to merge submodule %s"
-msgstr "Gặp lỗi khi hòa trộn mô-đun-con “%s”"
+msgstr "Gặp lỗi khi hòa trộn mô-đun-con %s"
 
 #, c-format
 msgid ""
-"Failed to merge submodule %s, but a possible merge resolution exists:\n"
-"%s\n"
-msgstr ""
-"Gặp lỗi khi hòa trộn mô-đun-con “%s”, nhưng có cách giải quyết:\n"
-"%s\n"
-
-#, c-format
-msgid ""
-"If this is correct simply add it to the index for example\n"
-"by using:\n"
-"\n"
-"  git update-index --cacheinfo 160000 %s \"%s\"\n"
-"\n"
-"which will accept this suggestion.\n"
-msgstr ""
-"Nếu đây là đúng đơn giản thêm nó vào mục lục ví dụ\n"
-"bằng cách dùng:\n"
-"\n"
-"  git update-index --cacheinfo 160000 %s \"%s\"\n"
-"\n"
-"cái mà sẽ chấp nhận gợi ý này.\n"
+"Failed to merge submodule %s, but a possible merge resolution exists: %s"
+msgstr "Gặp lỗi khi hòa trộn mô-đun-con %s, nhưng có cách giải quyết: %s"
 
 #, c-format
 msgid ""
 "Failed to merge submodule %s, but multiple possible merges exist:\n"
 "%s"
 msgstr ""
-"Gặp lỗi khi hòa trộn mô-đun-con “%s”, nhưng có nhiều cách giải quyết:\n"
+"Gặp lỗi khi hòa trộn mô-đun-con %s, nhưng có nhiều cách giải quyết:\n"
 "%s"
 
-msgid "Failed to execute internal merge"
+msgid "failed to execute internal merge"
 msgstr "Gặp lỗi khi thực hiện trộn nội bộ"
 
 #, c-format
-msgid "Unable to add %s to database"
+msgid "unable to add %s to database"
 msgstr "Không thể thêm %s vào cơ sở dữ liệu"
 
 #, c-format
@@ -16449,16 +17038,16 @@
 "CONFLICT (implicit dir rename): Existing file/dir at %s in the way of "
 "implicit directory rename(s) putting the following path(s) there: %s."
 msgstr ""
-"XUNG ĐỘT: (ngầm đổi tên thư mục): Tập tin/thư mục đã sẵn có tại %s theo cách "
-"của các đổi tên thư mục ngầm đặt (các) đường dẫn sau ở đây: %s."
+"XUNG ĐỘT: (ngầm đổi tên thư mục): Tập tin/thư mục đã sẵn có tại %s do việc "
+"đổi tên thư mục sẽ đặt các đường dẫn sau ở đó: %s."
 
 #, c-format
 msgid ""
 "CONFLICT (implicit dir rename): Cannot map more than one path to %s; "
 "implicit directory renames tried to put these paths there: %s"
 msgstr ""
-"XUNG ĐỘT: (ngầm đổi tên thư mục): Không thể ánh xạ một đường dẫn thành %s; "
-"các đổi tên thư mục ngầm cố đặt các đường dẫn ở đây: %s"
+"XUNG ĐỘT: (ngầm đổi tên thư mục): Không thể ánh xạ hơn một đường dẫn thành "
+"%s; việc đổi tên thư mục sẽ đặt các đường dẫn sau ở đó: %s"
 
 #, c-format
 msgid ""
@@ -16466,17 +17055,17 @@
 "renamed to multiple other directories, with no destination getting a "
 "majority of the files."
 msgstr ""
-"XUNG ĐỘT: (thư mục đổi tên chia tách): Không rõ ràng nơi để đổi tên %s "
-"thành; nó đã bị đổi tên thành nhiều thư mục khác, với không đích đến nhận "
-"một phần nhiều của các tập tin."
+"XUNG ĐỘT: (phân hoá đổi tên thư mục): Không rõ đổi tên %s về đâu; nó đã bị "
+"đổi tên thành nhiều thư mục khác, mà không bên nào nhận phần lớn các tập tin "
+"gốc."
 
 #, c-format
 msgid ""
 "WARNING: Avoiding applying %s -> %s rename to %s, because %s itself was "
 "renamed."
 msgstr ""
-"CẢNH BÁO: tránh áp dụng %s -> %s đổi thên thành %s, bởi vì bản thân %s cũng "
-"bị đổi tên."
+"CẢNH BÁO: Tránh áp dụng đổi tên %s -> %s cho %s, bởi vì bản thân %s đã bị "
+"đổi tên."
 
 #, c-format
 msgid ""
@@ -16484,7 +17073,7 @@
 "moving it to %s."
 msgstr ""
 "Đường dẫn đã được cập nhật: %s được thêm vào trong %s bên trong một thư mục "
-"đã được đổi tên trong %s; di chuyển nó đến %s."
+"đã được đổi tên trong %s; sẽ di chuyển nó đến %s."
 
 #, c-format
 msgid ""
@@ -16492,14 +17081,14 @@
 "%s; moving it to %s."
 msgstr ""
 "Đường dẫn đã được cập nhật: %s được đổi tên thành %s trong %s, bên trong một "
-"thư mục đã được đổi tên trong %s; di chuyển nó đến %s."
+"thư mục đã được đổi tên trong %s; sẽ di chuyển nó đến %s."
 
 #, c-format
 msgid ""
 "CONFLICT (file location): %s added in %s inside a directory that was renamed "
 "in %s, suggesting it should perhaps be moved to %s."
 msgstr ""
-"XUNG ĐỘT (vị trí tệp): %s được thêm vào trong %s trong một thư mục đã được "
+"XUNG ĐỘT (vị trí tập): %s được thêm vào trong %s trong một thư mục đã được "
 "đổi tên thành %s, đoán là nó nên được di chuyển đến %s."
 
 #, c-format
@@ -16507,7 +17096,7 @@
 "CONFLICT (file location): %s renamed to %s in %s, inside a directory that "
 "was renamed in %s, suggesting it should perhaps be moved to %s."
 msgstr ""
-"XUNG ĐỘT (vị trí tệp): %s được đổi tên thành %s trong %s, bên trong một thư "
+"XUNG ĐỘT (vị trí tập): %s được đổi tên thành %s trong %s, bên trong một thư "
 "mục đã được đổi tên thành %s, đoán là nó nên được di chuyển đến %s."
 
 #, c-format
@@ -16583,13 +17172,43 @@
 "XUNG ĐỘT (sửa/xóa): %s bị xóa trong %s và sửa trong %s. Phiên bản %s của %s "
 "còn lại trong cây (tree)."
 
+#. TRANSLATORS: This is a line of advice to resolve a merge
+#. conflict in a submodule. The first argument is the submodule
+#. name, and the second argument is the abbreviated id of the
+#. commit that needs to be merged.  For example:
+#.  - go to submodule (mysubmodule), and either merge commit abc1234"
+#.
 #, c-format
 msgid ""
-"Note: %s not up to date and in way of checking out conflicted version; old "
-"copy renamed to %s"
+" - go to submodule (%s), and either merge commit %s\n"
+"   or update to an existing commit which has merged those changes\n"
 msgstr ""
-"Lưu ý: %s không được cập nhật và theo cách lấy ra phiên bản xung đột; bản "
-"sao cũ được đổi tên thành %s"
+" - đi tới mô-đun con (%s), và hoà trộn lần chuyển giao %s\n"
+"   hoặc cập nhật tới một lần chuyển giao đã có hoà trộn các thay đổi\n"
+
+#, c-format
+msgid ""
+"Recursive merging with submodules currently only supports trivial cases.\n"
+"Please manually handle the merging of each conflicted submodule.\n"
+"This can be accomplished with the following steps:\n"
+"%s - come back to superproject and run:\n"
+"\n"
+"      git add %s\n"
+"\n"
+"   to record the above merge or update\n"
+" - resolve any other conflicts in the superproject\n"
+" - commit the resulting index in the superproject\n"
+msgstr ""
+"Hoà trộn đệ quy với mô-đun con hiện chỉ hỗ trợ các trường hợp đơn giản.\n"
+"Vui lòng hoà trộn các mô-đun con có xung đột bằng tay.\n"
+"Bạn có thể thực hiện theo các bước sau:\n"
+"%s - trở về project cha và chạy lệnh:\n"
+"\n"
+"      git add %s\n"
+"\n"
+"   để ghi lại hoà trộn hoặc cập nhật\n"
+" - giải quyết các xung đột trong project cha\n"
+" - chuyển giao kết quả trong project cha\n"
 
 #. TRANSLATORS: The %s arguments are: 1) tree hash of a merge
 #. base, and 2-3) the trees for the two trees we're merging.
@@ -16603,74 +17222,90 @@
 
 #, c-format
 msgid "add_cacheinfo failed for path '%s'; merge aborting."
-msgstr "add_cacheinfo gặp lỗi đối với đường dẫn “%s”; việc hòa trộn bị bãi bỏ."
+msgstr "add_cacheinfo gặp lỗi đối với đường dẫn '%s'; huỷ bỏ việc hòa trộn."
 
 #, c-format
 msgid "add_cacheinfo failed to refresh for path '%s'; merge aborting."
 msgstr ""
-"add_cacheinfo gặp lỗi khi làm mới đối với đường dẫn “%s”; việc hòa trộn bị "
-"bãi bỏ."
+"add_cacheinfo gặp lỗi khi làm mới đối với đường dẫn '%s'; huỷ bỏ việc hòa "
+"trộn."
 
 #, c-format
 msgid "failed to create path '%s'%s"
-msgstr "gặp lỗi khi tạo đường dẫn “%s”%s"
+msgstr "gặp lỗi khi tạo đường dẫn '%s'%s"
 
 #, c-format
 msgid "Removing %s to make room for subdirectory\n"
 msgstr "Gỡ bỏ %s để tạo chỗ (room) cho thư mục con\n"
 
 msgid ": perhaps a D/F conflict?"
-msgstr ": có lẽ là một xung đột D/F?"
+msgstr ": có lẽ là xung đột D/F (tập tin/thư mục)?"
 
 #, c-format
 msgid "refusing to lose untracked file at '%s'"
-msgstr "từ chối đóng tập tin không được theo dõi tại “%s”"
+msgstr "từ chối đóng tập tin không được theo dõi tại '%s'"
 
 #, c-format
 msgid "blob expected for %s '%s'"
-msgstr "mong đợi đối tượng blob cho %s “%s”"
+msgstr "mong đợi đối tượng blob cho %s '%s'"
 
 #, c-format
 msgid "failed to open '%s': %s"
-msgstr "gặp lỗi khi mở “%s”: %s"
+msgstr "gặp lỗi khi mở '%s': %s"
 
 #, c-format
 msgid "failed to symlink '%s': %s"
-msgstr "gặp lỗi khi tạo liên kết mềm (symlink) “%s”: %s"
+msgstr "gặp lỗi khi tạo liên kết mềm (symlink) '%s': %s"
 
 #, c-format
 msgid "do not know what to do with %06o %s '%s'"
-msgstr "không hiểu phải làm gì với %06o %s “%s”"
+msgstr "không hiểu phải làm gì với %06o %s '%s'"
 
 #, c-format
 msgid "Fast-forwarding submodule %s to the following commit:"
-msgstr "Chuyển-tiếp-nhanh mô-đun-con “%s” đến lần chuyển giao sau đây:"
+msgstr "Chuyển-tiếp-nhanh mô-đun-con '%s' đến lần chuyển giao sau đây:"
 
 #, c-format
 msgid "Fast-forwarding submodule %s"
-msgstr "Chuyển-tiếp-nhanh mô-đun-con “%s”"
+msgstr "Chuyển-tiếp-nhanh mô-đun-con '%s'"
 
 #, c-format
 msgid "Failed to merge submodule %s (merge following commits not found)"
 msgstr ""
-"Gặp lỗi khi hòa trộn mô-đun-con “%s” (không tìm thấy các lần chuyển giao "
+"Gặp lỗi khi hòa trộn mô-đun-con '%s' (không tìm thấy các lần chuyển giao "
 "theo sau hòa trộn)"
 
 #, c-format
 msgid "Failed to merge submodule %s (not fast-forward)"
-msgstr "Gặp lỗi khi hòa trộn mô-đun-con “%s” (không chuyển tiếp nhanh được)"
+msgstr "Gặp lỗi khi hòa trộn mô-đun-con '%s' (không chuyển tiếp nhanh được)"
 
 msgid "Found a possible merge resolution for the submodule:\n"
-msgstr "Tìm thấy một giải pháp hòa trộn có thể cho mô-đun-con:\n"
+msgstr "Tìm thấy một giải pháp hòa trộn khả thi cho mô-đun-con:\n"
+
+#, c-format
+msgid ""
+"If this is correct simply add it to the index for example\n"
+"by using:\n"
+"\n"
+"  git update-index --cacheinfo 160000 %s \"%s\"\n"
+"\n"
+"which will accept this suggestion.\n"
+msgstr ""
+"Nếu đây là đúng đơn giản thêm nó vào chỉ mục ví dụ\n"
+"bằng cách dùng:\n"
+"\n"
+"  git update-index --cacheinfo 160000 %s \"%s\"\n"
+"\n"
+"cái mà sẽ chấp nhận gợi ý này.\n"
 
 #, c-format
 msgid "Failed to merge submodule %s (multiple merges found)"
-msgstr "Gặp lỗi khi hòa trộn mô-đun-con “%s” (thấy nhiều hòa trộn đa trùng)"
+msgstr "Gặp lỗi khi hòa trộn mô-đun-con '%s' (thấy nhiều hòa trộn đa trùng)"
 
 #, c-format
 msgid "Error: Refusing to lose untracked file at %s; writing to %s instead."
 msgstr ""
-"Lỗi: từ chối đóng tập tin không được theo dõi tại “%s”; thay vào đó ghi vào "
+"Lỗi: từ chối đóng tập tin không được theo dõi tại '%s'; thay vào đó ghi vào "
 "%s."
 
 #, c-format
@@ -16713,12 +17348,12 @@
 
 #, c-format
 msgid "Refusing to lose dirty file at %s"
-msgstr "Từ chối đóng tập tin không được theo dõi tại “%s”"
+msgstr "Từ chối đóng tập tin không được theo dõi tại '%s'"
 
 #, c-format
 msgid "Refusing to lose untracked file at %s, even though it's in the way."
 msgstr ""
-"Từ chối đóng tập tin không được theo dõi tại “%s”, ngay cả khi nó ở trên "
+"Từ chối đóng tập tin không được theo dõi tại '%s', ngay cả khi nó ở trên "
 "đường."
 
 #, c-format
@@ -16733,13 +17368,13 @@
 #, c-format
 msgid "Refusing to lose untracked file at %s; adding as %s instead"
 msgstr ""
-"Từ chối đóng tập tin không được theo dõi tại “%s”; thay vào đó đang thêm "
+"Từ chối đóng tập tin không được theo dõi tại '%s'; thay vào đó đang thêm "
 "thành %s"
 
 #, c-format
 msgid ""
-"CONFLICT (rename/rename): Rename \"%s\"->\"%s\" in branch \"%s\" rename \"%s"
-"\"->\"%s\" in \"%s\"%s"
+"CONFLICT (rename/rename): Rename \"%s\"->\"%s\" in branch \"%s\" rename "
+"\"%s\"->\"%s\" in \"%s\"%s"
 msgstr ""
 "XUNG ĐỘT (đổi-tên/đổi-tên): Đổi tên \"%s\"->\"%s\" trong nhánh \"%s\" đổi "
 "tên \"%s\"->\"%s\" trong \"%s\"%s"
@@ -16758,9 +17393,9 @@
 "directory %s was renamed to multiple other directories, with no destination "
 "getting a majority of the files."
 msgstr ""
-"XUNG ĐỘT: (thư mục đổi tên chia tách): Không rõ ràng để đặt địa điểm %s bởi "
-"vì thư mục %s đã bị đổi tên thành nhiều thư mục khác, với không đích đến "
-"nhận một phần nhiều của các tập tin."
+"XUNG ĐỘT: (phân hoá đổi tên thư mục): Không rõ đặt %s ở đâu bởi vì thư mục "
+"%s đã bị đổi tên thành nhiều thư mục khác, mà không bên nào nhận phần lớn "
+"các tập tin gốc."
 
 #, c-format
 msgid ""
@@ -16825,13 +17460,100 @@
 
 #, c-format
 msgid "Could not parse object '%s'"
-msgstr "Không thể phân tích đối tượng “%s”"
+msgstr "Không thể đọc đối tượng '%s'"
 
 msgid "failed to read the cache"
 msgstr "gặp lỗi khi đọc bộ nhớ đệm"
 
+#, c-format
+msgid "failed to add packfile '%s'"
+msgstr "gặp lỗi khi thêm tập tin gói '%s'"
+
+#, c-format
+msgid "failed to open pack-index '%s'"
+msgstr "gặp lỗi khi mở pack-index '%s'"
+
+#, c-format
+msgid "failed to locate object %d in packfile"
+msgstr "gặp lỗi khi phân bổ đối tượng '%d' trong tập tin gói"
+
+msgid "cannot store reverse index file"
+msgstr "không thể lưu trữ tập tin ghi chỉ mục đảo ngược"
+
+#, c-format
+msgid "could not parse line: %s"
+msgstr "không hiểu cú pháp dòng: %s"
+
+#, c-format
+msgid "malformed line: %s"
+msgstr "dòng sai quy cách: %s"
+
+msgid "ignoring existing multi-pack-index; checksum mismatch"
+msgstr "bỏ qua multi-pack-index sẵn có; tổng kiểm không khớp"
+
+msgid "could not load pack"
+msgstr "không thể tải gói"
+
+#, c-format
+msgid "could not open index for %s"
+msgstr "không thể mở chỉ mục cho %s"
+
+msgid "Adding packfiles to multi-pack-index"
+msgstr "Đang thêm tập tin gói từ multi-pack-index"
+
+#, c-format
+msgid "unknown preferred pack: '%s'"
+msgstr "không hiểu \"preferred pack\": %s"
+
+#, c-format
+msgid "cannot select preferred pack %s with no objects"
+msgstr "không thể chọn gói ưa dùng %s với không đối tượng nào"
+
+#, c-format
+msgid "did not see pack-file %s to drop"
+msgstr "đã không thấy tập tin gói %s để xóa"
+
+#, c-format
+msgid "preferred pack '%s' is expired"
+msgstr "\"preferred pack\" '%s' đã hết hạn"
+
+msgid "no pack files to index."
+msgstr "không có tập tin gói để đánh chỉ mục."
+
+msgid "refusing to write multi-pack .bitmap without any objects"
+msgstr "từ chối ghi 'multi-pack bitmap' mà không có bất kỳ đối tượng nào"
+
+msgid "could not write multi-pack bitmap"
+msgstr "không thể ghi 'multi-pack bitmap'"
+
+msgid "could not write multi-pack-index"
+msgstr "không thể ghi 'multi-pack-index'"
+
+msgid "Counting referenced objects"
+msgstr "Đang đếm các đối tượng được tham chiếu"
+
+msgid "Finding and deleting unreferenced packfiles"
+msgstr "Đang tìm và xóa các gói không được tham chiếu"
+
+msgid "could not start pack-objects"
+msgstr "không thể khởi chạy pack-objects"
+
+msgid "could not finish pack-objects"
+msgstr "không thể hoàn thiện pack-objects"
+
 msgid "multi-pack-index OID fanout is of the wrong size"
-msgstr "fanout OID nhiều gói chỉ mục có kích thước sai"
+msgstr "fanout OID multi-pack-index có kích thước sai"
+
+#, c-format
+msgid ""
+"oid fanout out of order: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]"
+msgstr "fanout cũ sai thứ tự: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]"
+
+msgid "multi-pack-index OID lookup chunk is the wrong size"
+msgstr "OID lookup chunk multi-pack-index có kích thước sai"
+
+msgid "multi-pack-index object offset chunk is the wrong size"
+msgstr "object offset chunk multi-pack-index có kích thước sai"
 
 #, c-format
 msgid "multi-pack-index file %s is too small"
@@ -16849,99 +17571,49 @@
 msgid "multi-pack-index hash version %u does not match version %u"
 msgstr "phiên bản băm multi-pack-index %u không khớp phiên bản %u"
 
-msgid "multi-pack-index missing required pack-name chunk"
-msgstr "multi-pack-index thiếu mảnh pack-name cần thiết"
+msgid "multi-pack-index required pack-name chunk missing or corrupted"
+msgstr "multi-pack-index thiếu chunk pack-name cần thiết hoặc bị hỏng"
 
-msgid "multi-pack-index missing required OID fanout chunk"
-msgstr "multi-pack-index thiếu mảnh OID fanout cần thiết"
+msgid "multi-pack-index required OID fanout chunk missing or corrupted"
+msgstr "multi-pack-index thiếu chunk OID fanout cần thiết hoặc bị hỏng"
 
-msgid "multi-pack-index missing required OID lookup chunk"
-msgstr "multi-pack-index thiếu mảnh OID lookup cần thiết"
+msgid "multi-pack-index required OID lookup chunk missing or corrupted"
+msgstr "multi-pack-index thiếu chunk OID lookup cần thiết hoặc bị hỏng"
 
-msgid "multi-pack-index missing required object offsets chunk"
-msgstr "multi-pack-index thiếu mảnh các khoảng bù đối tượng cần thiết"
+msgid "multi-pack-index required object offsets chunk missing or corrupted"
+msgstr ""
+"multi-pack-index thiếu chunk các khoảng bù đối tượng cần thiết hoặc bị hỏng"
+
+msgid "multi-pack-index pack-name chunk is too short"
+msgstr "tập tin đồ thị multi-pack-index %s quá nhỏ"
 
 #, c-format
 msgid "multi-pack-index pack names out of order: '%s' before '%s'"
-msgstr "các tên gói multi-pack-index không đúng thứ tự: “%s” trước “%s”"
+msgstr "các tên gói multi-pack-index không đúng thứ tự: '%s' trước '%s'"
 
 #, c-format
 msgid "bad pack-int-id: %u (%u total packs)"
 msgstr "pack-int-id sai: %u (%u các gói tổng)"
 
+msgid "MIDX does not contain the BTMP chunk"
+msgstr "MIDX không chứa chunk BTMP"
+
+#, c-format
+msgid "could not load bitmapped pack %<PRIu32>"
+msgstr "không thể đọc gói bitmap %<PRIu32>"
+
 msgid "multi-pack-index stores a 64-bit offset, but off_t is too small"
-msgstr "multi-pack-index lưu trữ một khoảng bù 64-bít, nhưng off_t là quá nhỏ"
+msgstr "multi-pack-index lưu trữ một offset 64-bít, nhưng off_t là quá nhỏ"
 
-#, c-format
-msgid "failed to add packfile '%s'"
-msgstr "gặp lỗi khi thêm tập tin gói “%s”"
-
-#, c-format
-msgid "failed to open pack-index '%s'"
-msgstr "gặp lỗi khi mở pack-index “%s”"
-
-#, c-format
-msgid "failed to locate object %d in packfile"
-msgstr "gặp lỗi khi phân bổ đối tượng “%d” trong tập tin gói"
-
-msgid "cannot store reverse index file"
-msgstr "không thể lưu trữ tập tin ghi mục lục đảo ngược"
-
-#, c-format
-msgid "could not parse line: %s"
-msgstr "không thể phân tích cú pháp dòng: %s"
-
-#, c-format
-msgid "malformed line: %s"
-msgstr "dòng dị hình: %s"
-
-msgid "ignoring existing multi-pack-index; checksum mismatch"
-msgstr "bỏ qua multi-pack-index sẵn có; tổng kiểm không khớp"
-
-msgid "could not load pack"
-msgstr "không thể tải gói"
-
-#, c-format
-msgid "could not open index for %s"
-msgstr "không thể mở mục lục cho %s"
-
-msgid "Adding packfiles to multi-pack-index"
-msgstr "Đang thêm tập tin gói từ multi-pack-index"
-
-#, c-format
-msgid "unknown preferred pack: '%s'"
-msgstr "không hiểu \"preferred pack\": %s"
-
-#, c-format
-msgid "cannot select preferred pack %s with no objects"
-msgstr "không thể chọn gói ưa dùng %s với không đối tượng nào"
-
-#, c-format
-msgid "did not see pack-file %s to drop"
-msgstr "đã không thấy tập tin gói %s để mà xóa"
-
-#, c-format
-msgid "preferred pack '%s' is expired"
-msgstr "\"preferred pack\" “%s” đã hết hạn"
-
-msgid "no pack files to index."
-msgstr "không có tập tin gói để đánh mục lục."
-
-msgid "refusing to write multi-pack .bitmap without any objects"
-msgstr "từ chối ghi “multi-pack bitmap” mà không có bất kỳ đối tượng nào"
-
-msgid "could not write multi-pack bitmap"
-msgstr "không thể ghi “multi-pack bitmap”"
-
-msgid "could not write multi-pack-index"
-msgstr "không thể ghi “multi-pack-index”"
+msgid "multi-pack-index large offset out of bounds"
+msgstr "multi-pack-index large offset nằm ngoài biên"
 
 #, c-format
 msgid "failed to clear multi-pack-index at %s"
 msgstr "gặp lỗi khi xóa multi-pack-index tại %s"
 
 msgid "multi-pack-index file exists, but failed to parse"
-msgstr "đã có tập tin multi-pack-index, nhưng gặp lỗi khi phân tích cú pháp"
+msgstr "đã có tập tin multi-pack-index, nhưng gặp lỗi khi đọc cú pháp"
 
 msgid "incorrect checksum"
 msgstr "tổng kiểm không đúng"
@@ -16949,11 +17621,6 @@
 msgid "Looking for referenced packfiles"
 msgstr "Đang khóa cho các gói bị tham chiếu"
 
-#, c-format
-msgid ""
-"oid fanout out of order: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]"
-msgstr "fanout cũ sai thứ tự: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]"
-
 msgid "the midx contains no oid"
 msgstr "midx chẳng chứa oid nào"
 
@@ -16983,18 +17650,6 @@
 msgstr ""
 "khoảng bù đối tượng không đúng cho oid[%d] = %s: %<PRIx64> != %<PRIx64>"
 
-msgid "Counting referenced objects"
-msgstr "Đang đếm các đối tượng được tham chiếu"
-
-msgid "Finding and deleting unreferenced packfiles"
-msgstr "Đang tìm và xóa các gói không được tham chiếu"
-
-msgid "could not start pack-objects"
-msgstr "không thể lấy thông tin thống kê về các đối tượng gói"
-
-msgid "could not finish pack-objects"
-msgstr "không thể hoàn thiện các đối tượng gói"
-
 #, c-format
 msgid "unable to create lazy_dir thread: %s"
 msgstr "không thể tạo tuyến lazy_dir: %s"
@@ -17013,10 +17668,9 @@
 "Please, use 'git notes merge --commit' or 'git notes merge --abort' to "
 "commit/abort the previous merge before you start a new notes merge."
 msgstr ""
-"Bạn đã chưa hoàn tất hòa trộn ghi chú trước đây (%s vẫn còn).\n"
-"Vui lòng dùng “git notes merge --commit” hay “git notes merge --abort” để "
-"chuyển giao hay bãi bỏ lần hòa trộn trước đây và bắt đầu một hòa trộn ghi "
-"chú mới."
+"Bạn chưa hoàn tất lần hòa trộn ghi chú trước (%s vẫn còn).\n"
+"Vui lòng dùng 'git notes merge --commit' hay 'git notes merge --abort' để "
+"chuyển giao hay huỷ bỏ lần hòa trộn trước và bắt đầu hòa trộn ghi chú mới."
 
 #, c-format
 msgid "You have not concluded your notes merge (%s exists)."
@@ -17029,7 +17683,7 @@
 
 #, c-format
 msgid "Bad notes.rewriteMode value: '%s'"
-msgstr "Giá trị notes.rewriteMode sai: “%s”"
+msgstr "Giá trị notes.rewriteMode sai: '%s'"
 
 #, c-format
 msgid "Refusing to rewrite notes in %s (outside of refs/notes/)"
@@ -17041,7 +17695,26 @@
 #.
 #, c-format
 msgid "Bad %s value: '%s'"
-msgstr "Giá trị %s sai: “%s”"
+msgstr "Giá trị %s sai: '%s'"
+
+msgid "failed to decode tree entry"
+msgstr "giải mã mục cây thất bại"
+
+#, c-format
+msgid "failed to map tree entry for %s"
+msgstr "ánh xạ mục cây cho %s thất bại"
+
+#, c-format
+msgid "bad %s in commit"
+msgstr "ký tự không đúng %s trong lần chuyển giao"
+
+#, c-format
+msgid "unable to map %s %s in commit object"
+msgstr "không thể ánh xạ %s %s trong đối tượng chuyển giao"
+
+#, c-format
+msgid "Failed to convert object from %s to %s"
+msgstr "Chuyển đổi đối tượng từ %s sang %s thất bại"
 
 #, c-format
 msgid "object directory %s does not exist; check .git/objects/info/alternates"
@@ -17050,16 +17723,12 @@
 
 #, c-format
 msgid "unable to normalize alternate object path: %s"
-msgstr "không thể thường hóa đường dẫn đối tượng thay thế: “%s”"
+msgstr "không thể thường hóa đường dẫn đối tượng thay thế: '%s'"
 
 #, c-format
 msgid "%s: ignoring alternate object stores, nesting too deep"
 msgstr "%s: đang bỏ qua kho đối tượng thay thế, lồng nhau quá sâu"
 
-#, c-format
-msgid "unable to normalize object directory: %s"
-msgstr "không thể chuẩn hóa thư mục đối tượng: “%s”"
-
 msgid "unable to fdopen alternates lockfile"
 msgstr "không thể fdopen tập tin khóa thay thế"
 
@@ -17071,31 +17740,31 @@
 
 #, c-format
 msgid "path '%s' does not exist"
-msgstr "đường dẫn “%s” không tồn tại"
+msgstr "đường dẫn '%s' không tồn tại"
 
 #, c-format
 msgid "reference repository '%s' as a linked checkout is not supported yet."
-msgstr "kho tham chiếu “%s” như là lấy ra liên kết vẫn chưa được hỗ trợ."
+msgstr "kho tham chiếu '%s' như là checkout liên kết vẫn chưa được hỗ trợ."
 
 #, c-format
 msgid "reference repository '%s' is not a local repository."
-msgstr "kho tham chiếu “%s” không phải là một kho nội bộ."
+msgstr "kho tham chiếu '%s' không phải là một kho nội bộ."
 
 #, c-format
 msgid "reference repository '%s' is shallow"
-msgstr "kho tham chiếu “%s” là nông"
+msgstr "kho tham chiếu '%s' là nông"
 
 #, c-format
 msgid "reference repository '%s' is grafted"
-msgstr "kho tham chiếu “%s” bị cấy ghép"
+msgstr "kho tham chiếu '%s' bị cấy ghép"
 
 #, c-format
 msgid "could not find object directory matching %s"
-msgstr "không thể tìm thấy thư mục đối tượng khớp với “%s”"
+msgstr "không thể tìm thấy thư mục đối tượng khớp với '%s'"
 
 #, c-format
 msgid "invalid line while parsing alternate refs: %s"
-msgstr "dòng không hợp lệ trong khi phân tích các tham chiếu thay thế: %s"
+msgstr "dòng không hợp lệ trong khi đọc các tham chiếu thay thế: %s"
 
 #, c-format
 msgid "attempting to mmap %<PRIuMAX> over limit %<PRIuMAX>"
@@ -17111,15 +17780,19 @@
 
 #, c-format
 msgid "corrupt loose object '%s'"
-msgstr "đối tượng mất hỏng “%s”"
+msgstr "đối tượng mất hỏng '%s'"
 
 #, c-format
 msgid "garbage at end of loose object '%s'"
-msgstr "gặp rác tại cuối của đối tượng bị mất “%s”"
+msgstr "gặp rác tại cuối của đối tượng bị mất '%s'"
+
+#, c-format
+msgid "unable to open loose object %s"
+msgstr "không thể mở đối tượng mất %s"
 
 #, c-format
 msgid "unable to parse %s header"
-msgstr "không thể phân tích phần đầu của “%s”"
+msgstr "không thể đọc phần đầu của '%s'"
 
 msgid "invalid object type"
 msgstr "kiểu đối tượng không hợp lệ"
@@ -17133,31 +17806,28 @@
 msgstr "phần đầu cho %s quá dài, vượt quá %d byte"
 
 #, c-format
-msgid "failed to read object %s"
-msgstr "gặp lỗi khi đọc đối tượng “%s”"
+msgid "loose object %s (stored in %s) is corrupt"
+msgstr "đối tượng mất %s (được lưu trong %s) bị hỏng"
 
 #, c-format
 msgid "replacement %s not found for %s"
 msgstr "c%s thay thế không được tìm thấy cho %s"
 
 #, c-format
-msgid "loose object %s (stored in %s) is corrupt"
-msgstr "đối tượng mất %s (được lưu trong %s) bị hỏng"
-
-#, c-format
 msgid "packed object %s (stored in %s) is corrupt"
 msgstr "đối tượng đã đóng gói %s (được lưu trong %s) bị hỏng"
 
 #, c-format
+msgid "missing mapping of %s to %s"
+msgstr "thiếu ánh xạ %s sang %s"
+
+#, c-format
 msgid "unable to write file %s"
 msgstr "không thể ghi tập tin %s"
 
 #, c-format
 msgid "unable to set permission to '%s'"
-msgstr "không thể đặt quyền thành “%s”"
-
-msgid "file write error"
-msgstr "lỗi ghi tập tin"
+msgstr "không thể đặt quyền thành '%s'"
 
 msgid "error when closing loose object file"
 msgstr "gặp lỗi trong khi đóng tập tin đối tượng"
@@ -17175,7 +17845,7 @@
 
 #, c-format
 msgid "unable to deflate new object %s (%d)"
-msgstr "không thể xả nén đối tượng mới %s (%d)"
+msgstr "không thể giải nén đối tượng mới %s (%d)"
 
 #, c-format
 msgid "deflateEnd on object %s failed (%d)"
@@ -17186,22 +17856,43 @@
 msgstr "chưa rõ ràng baowir dữ liệu nguồn đối tượng không ổn định cho %s"
 
 #, c-format
+msgid "write stream object %ld != %<PRIuMAX>"
+msgstr "đối tượng ghi dòng %ld != %<PRIuMAX>"
+
+#, c-format
+msgid "unable to stream deflate new object (%d)"
+msgstr "không thể stream deflate đối tượng mới (%d)"
+
+#, c-format
+msgid "deflateEnd on stream object failed (%d)"
+msgstr "deflateEnd trên đối tượng stream gặp lỗi (%d)"
+
+#, c-format
+msgid "unable to create directory %s"
+msgstr "tạo thư mục \"%s\" gặp lỗi"
+
+#, c-format
 msgid "cannot read object for %s"
 msgstr "không thể đọc đối tượng cho %s"
 
-msgid "corrupt commit"
-msgstr "lần chuyển giao sai hỏng"
+#, c-format
+msgid "cannot map object %s to %s"
+msgstr "không thể ánh xạ đối tượng %s sang %s"
 
-msgid "corrupt tag"
-msgstr "thẻ sai hỏng"
+#, c-format
+msgid "object fails fsck: %s"
+msgstr "đối tượng không qua fsck (kiểm tra toàn vẹn): %s"
+
+msgid "refusing to create malformed object"
+msgstr "Từ chối tạo đối tượng lỗi"
 
 #, c-format
 msgid "read error while indexing %s"
-msgstr "gặp lỗi đọc khi đánh mục lục %s"
+msgstr "gặp lỗi đọc khi đánh chỉ mục %s"
 
 #, c-format
 msgid "short read while indexing %s"
-msgstr "không đọc ngắn khi đánh mục lục %s"
+msgstr "không đọc ngắn khi đánh chỉ mục %s"
 
 #, c-format
 msgid "%s: failed to insert into database"
@@ -17213,7 +17904,7 @@
 
 #, c-format
 msgid "%s is not a valid '%s' object"
-msgstr "%s không phải là một đối tượng “%s” hợp lệ"
+msgstr "%s không phải là một đối tượng '%s' hợp lệ"
 
 #, c-format
 msgid "unable to open %s"
@@ -17229,15 +17920,15 @@
 
 #, c-format
 msgid "unable to unpack header of %s"
-msgstr "không thể giải gói phần đầu của “%s”"
+msgstr "không thể giải gói phần đầu của '%s'"
 
 #, c-format
 msgid "unable to parse header of %s"
-msgstr "không thể phân tích phần đầu của “%s”"
+msgstr "không thể đọc phần đầu của '%s'"
 
 #, c-format
 msgid "unable to unpack contents of %s"
-msgstr "không thể giải gói nội dung của “%s”"
+msgstr "không thể giải gói nội dung của '%s'"
 
 #. TRANSLATORS: This is a line of ambiguous object
 #. output shown when we cannot look up or parse the
@@ -17279,7 +17970,7 @@
 #.
 #, c-format
 msgid "%s [bad tag, could not parse it]"
-msgstr "%s [thẻ sai, không thể phân tích cú pháp nó]"
+msgstr "%s [thẻ sai, không hiểu cú pháp nó]"
 
 #. TRANSLATORS: This is a line of ambiguous <type>
 #. object output. E.g. "deadbeef tree".
@@ -17322,65 +18013,64 @@
 "examine these refs and maybe delete them. Turn this message off by\n"
 "running \"git config advice.objectNameWarning false\""
 msgstr ""
-"Git thường không bao giờ tạo tham chiếu mà nó kết thúc với 40 ký tự hex\n"
-"bởi vì nó sẽ bị bỏ qua khi bạn chỉ định 40-hex. Những tham chiếu này\n"
-"có lẽ được tạo ra bởi một sai sót nào đó. Ví dụ,\n"
+"Git thường không bao giờ tạo tham chiếu kết thúc với 40 ký tự hex\n"
+"bởi vì nó sẽ bị bỏ qua khi bạn chỉ định 40 ký tự hex. Những tham chiếu\n"
+"này có lẽ đã được tạo nhầm. Ví dụ,\n"
 "\n"
-"  git switch -c $br $(git rev-parse …)\n"
+"  git switch -c $br $(git rev-parse ...)\n"
 "\n"
-"với \"$br\" không hiểu lý do vì sao trống rỗng và một tham chiếu 40-hex được "
-"tạo ra.\n"
-"Xin hãy kiểm tra những tham chiếu này và có thể xóa chúng đi. Tắt lời nhắn "
-"này\n"
-"bằng cách chạy lệnh \"git config advice.objectNameWarning false\""
+"với \"$br\" không hiểu lý do vì sao rỗng và tạo ra tham chiếu 40-hex.\n"
+" Xin hãy kiểm tra những tham chiếu này và xóa chúng đi nếu cần. Tắt\n"
+"lời nhắn này bằng cách chạy lệnh \"git config advice.objectNameWarning "
+"false\""
 
 #, c-format
 msgid "log for '%.*s' only goes back to %s"
-msgstr "nhật ký cho “%.*s” chỉ trở lại đến %s"
+msgstr "nhật ký cho '%.*s' chỉ kéo dài đến %s"
 
 #, c-format
 msgid "log for '%.*s' only has %d entries"
-msgstr "nhật ký cho “%.*s” chỉ có %d mục"
+msgstr "nhật ký cho '%.*s' chỉ có %d mục"
 
 #, c-format
 msgid "path '%s' exists on disk, but not in '%.*s'"
-msgstr "đường dẫn “%s” có ở trên đĩa, nhưng không trong “%.*s”"
+msgstr "đường dẫn '%s' có ở trên đĩa, nhưng không trong '%.*s'"
 
 #, c-format
 msgid ""
 "path '%s' exists, but not '%s'\n"
 "hint: Did you mean '%.*s:%s' aka '%.*s:./%s'?"
 msgstr ""
-"đường dẫn “%s” tồn tại, nhưng không phải “%s”\n"
-"gợi ý: Có phải ý bạn là “%.*s:%s” aka “%.*s:./%s”?"
+"đường dẫn '%s' tồn tại, nhưng không phải '%s'\n"
+"gợi ý: Có phải ý bạn là '%.*s:%s' aka '%.*s:./%s'?"
 
 #, c-format
 msgid "path '%s' does not exist in '%.*s'"
-msgstr "đường dẫn “%s” không tồn tại trong “%.*s”"
+msgstr "đường dẫn '%s' không tồn tại trong '%.*s'"
 
 #, c-format
 msgid ""
 "path '%s' is in the index, but not at stage %d\n"
 "hint: Did you mean ':%d:%s'?"
 msgstr ""
-"đường dẫn “%s” nằm trong chỉ mục, nhưng không phải ở giai đoạn %d\n"
-"gợi ý: Có phải ý bạn là “:%d:%s”?"
+"đường dẫn '%s' nằm trong chỉ mục, nhưng không phải ở giai đoạn %d\n"
+"gợi ý: Có phải ý bạn là ':%d:%s'?"
 
 #, c-format
 msgid ""
 "path '%s' is in the index, but not '%s'\n"
 "hint: Did you mean ':%d:%s' aka ':%d:./%s'?"
 msgstr ""
-"đường dẫn “%s” nằm trong chỉ mục, nhưng không phải “%s”\n"
-"gợi ý: Có phải ý bạn là “:% d:%s “ aka “:%d:./%s”?"
+"đường dẫn '%s' nằm trong chỉ mục, nhưng không phải '%s'\n"
+"gợi ý: Có phải ý bạn là ':% d:%s ' aka ':%d:./%s'?"
 
 #, c-format
 msgid "path '%s' exists on disk, but not in the index"
-msgstr "đường dẫn “%s” tồn tại trên đĩa, nhưng không có trong chỉ mục"
+msgstr "đường dẫn '%s' tồn tại trên đĩa, nhưng không có trong chỉ mục"
 
 #, c-format
 msgid "path '%s' does not exist (neither on disk nor in the index)"
-msgstr "đường dẫn “%s” không tồn tại (không trên đĩa cũng không trong mục lục)"
+msgstr "đường dẫn '%s' không tồn tại (không trên đĩa cũng không trong chỉ mục)"
 
 msgid "relative path syntax can't be used outside working tree"
 msgstr "cú pháp đường dẫn tương đối không thể thể dùng ngoài cây làm việc"
@@ -17391,7 +18081,7 @@
 
 #, c-format
 msgid "invalid object name '%.*s'."
-msgstr "“%.*s” không phải là tên đối tượng hợp lệ."
+msgstr "'%.*s' không phải là tên đối tượng hợp lệ."
 
 #, c-format
 msgid "invalid object type \"%s\""
@@ -17407,26 +18097,134 @@
 
 #, c-format
 msgid "unable to parse object: %s"
-msgstr "không thể phân tích đối tượng: “%s”"
+msgstr "không thể đọc đối tượng: '%s'"
 
 #, c-format
 msgid "hash mismatch %s"
 msgstr "mã băm không khớp %s"
 
+msgid "trying to write commit not in index"
+msgstr "đã thử ghi lần chuyển giao nằm ngoài chỉ mục"
+
+msgid "failed to load bitmap index (corrupted?)"
+msgstr "không thể đọc chỉ mục bitmap (bị hỏng?)"
+
+msgid "corrupted bitmap index (too small)"
+msgstr "chỉ mục bitmap bị hỏng (quá nhỏ)"
+
+msgid "corrupted bitmap index file (wrong header)"
+msgstr "tập tin chỉ mục bitmap bị hỏng (sai phần đầu)"
+
+#, c-format
+msgid "unsupported version '%d' for bitmap index file"
+msgstr "không hỗ trợ tập tin chỉ mục bitmap phiên bản '%d'"
+
+msgid "corrupted bitmap index file (too short to fit hash cache)"
+msgstr "tập tin chỉ mục bitmap bị hỏng (quá ngắn để chứa bộ đệm mã băm)"
+
+msgid "corrupted bitmap index file (too short to fit lookup table)"
+msgstr "tập tin chỉ mục bitmap bị hỏng (quá ngắn để chứa bảng tìm kiếm)"
+
+#, c-format
+msgid "duplicate entry in bitmap index: '%s'"
+msgstr "đối tượng trùng lặp trong bitmap: '%s'"
+
+#, c-format
+msgid "corrupt ewah bitmap: truncated header for entry %d"
+msgstr "ewah bitmap bị hỏng: phần đầu bị cắt ngắn cho mục thứ %d"
+
+#, c-format
+msgid "corrupt ewah bitmap: commit index %u out of range"
+msgstr "ewah bitmap bị hỏng: mục chuyển giao thứ %u nằm ngoài phạm vi"
+
+msgid "corrupted bitmap pack index"
+msgstr "chỉ mục gói bitmap bị hỏng"
+
+msgid "invalid XOR offset in bitmap pack index"
+msgstr "XOR offset không hợp lệ trong chỉ mục gói bitmap"
+
+msgid "cannot fstat bitmap file"
+msgstr "không thể fstat file bitmap"
+
+msgid "checksum doesn't match in MIDX and bitmap"
+msgstr "tổng kiểm ra trong MIDX và bitmap không khớp"
+
 msgid "multi-pack bitmap is missing required reverse index"
-msgstr "ánh xạ multi-pack thiếu mục lục để dành cần thiết"
+msgstr "bitmap multi-pack thiếu chỉ mục để dành cần thiết"
 
 #, c-format
 msgid "could not open pack %s"
-msgstr "không thể mở gói “%s”"
+msgstr "không thể mở gói '%s'"
+
+msgid "could not determine MIDX preferred pack"
+msgstr "không thể xác định gói MIDX ưa dùng"
 
 #, c-format
 msgid "preferred pack (%s) is invalid"
-msgstr "\"preferred pack\" (%s) không hợp lệ"
+msgstr "preferred pack (%s) không hợp lệ"
+
+msgid "corrupt bitmap lookup table: triplet position out of index"
+msgstr "bảng tìm kiếm bitmap bị hỏng: vị trí bộ ba nằm ngoài chỉ mục"
+
+msgid "corrupt bitmap lookup table: xor chain exceeds entry count"
+msgstr "bảng tìm kiếm bitmap bị hỏng: chuỗi xor vượt quá số lượng mục"
 
 #, c-format
-msgid "could not find %s in pack %s at offset %<PRIuMAX>"
-msgstr "không thể tìm thấy %s trong gói “%s” tại vị trí %<PRIuMAX>"
+msgid "corrupt bitmap lookup table: commit index %u out of range"
+msgstr "bảng tìm kiếm bitmap bị hỏng: mục chuyển giao thứ %u nằm ngoài phạm vi"
+
+#, c-format
+msgid "corrupt ewah bitmap: truncated header for bitmap of commit \"%s\""
+msgstr ""
+"ewah bitmap bị hỏng: bitmap lần chuyển giao \"%s\" có phần đầu bị cắt ngắn"
+
+#, c-format
+msgid "unable to load pack: '%s', disabling pack-reuse"
+msgstr "không thể đọc gói: '%s', vô hiệu sử dụng lại gói"
+
+msgid "unable to compute preferred pack, disabling pack-reuse"
+msgstr "không thể tính giá trị gói ưa dùng, vô hiệu sử dụng lại gói"
+
+#, c-format
+msgid "object '%s' not found in type bitmaps"
+msgstr "không tìm thấy đối tượng '%s' trong type bitmap"
+
+#, c-format
+msgid "object '%s' does not have a unique type"
+msgstr "đối tượng '%s' không có kiểu độc nhất"
+
+#, c-format
+msgid "object '%s': real type '%s', expected: '%s'"
+msgstr "đối tượng '%s': kiểu '%s', cần: '%s'"
+
+#, c-format
+msgid "object not in bitmap: '%s'"
+msgstr "không tìm thấy đối tượng trong bitmap: %s"
+
+msgid "failed to load bitmap indexes"
+msgstr "đọc chỉ mục bitmap thất bại"
+
+msgid "you must specify exactly one commit to test"
+msgstr "bạn phải chỉ định các lần chuyển giao muốn kiểm tra"
+
+#, c-format
+msgid "commit '%s' doesn't have an indexed bitmap"
+msgstr "lần chuyển giao '%s' không có chỉ mục bitmap"
+
+msgid "mismatch in bitmap results"
+msgstr "kết quả bitmap không khớp"
+
+#, c-format
+msgid "could not find '%s' in pack '%s' at offset %<PRIuMAX>"
+msgstr "không thể tìm thấy '%s' trong gói '%s' tại vị trí %<PRIuMAX>"
+
+#, c-format
+msgid "unable to get disk usage of '%s'"
+msgstr "không thể lấy dung lượng đĩa đã dùng của %s"
+
+#, c-format
+msgid "bitmap file '%s' has invalid checksum"
+msgstr "file bitmap '%s' có checksum không hợp lệ"
 
 #, c-format
 msgid "mtimes file %s is too small"
@@ -17438,7 +18236,7 @@
 
 #, c-format
 msgid "mtimes file %s has unsupported version %<PRIu32>"
-msgstr "tệp mtimes %s có phiên bản không được hỗ trợ %<PRIu32>"
+msgstr "tập mtimes %s có phiên bản không được hỗ trợ %<PRIu32>"
 
 #, c-format
 msgid "mtimes file %s has unsupported hash id %<PRIu32>"
@@ -17462,18 +18260,31 @@
 
 #, c-format
 msgid "reverse-index file %s has unsupported version %<PRIu32>"
-msgstr "tệp chỉ mục ngược %s có phiên bản không được hỗ trợ %<PRIu32>"
+msgstr "tập chỉ mục ngược %s có phiên bản không được hỗ trợ %<PRIu32>"
 
 #, c-format
 msgid "reverse-index file %s has unsupported hash id %<PRIu32>"
-msgstr "tệp chỉ mục ngược %s có id mã băm không được hỗ trợ %<PRIu32>"
+msgstr "tập chỉ mục ngược %s có id mã băm không được hỗ trợ %<PRIu32>"
+
+msgid "invalid checksum"
+msgstr "checksum không hợp lệ"
+
+#, c-format
+msgid "invalid rev-index position at %<PRIu64>: %<PRIu32> != %<PRIu32>"
+msgstr "vị trí mục xét duyệt không hợp lệ %<PRIu64>: %<PRIu32> != %<PRIu32>"
+
+msgid "multi-pack-index reverse-index chunk is the wrong size"
+msgstr "chunk chỉ mục ngược của chỉ mục đa gói có kích thước sai"
+
+msgid "could not determine preferred pack"
+msgstr "không thể xác định gói ưa dùng"
 
 msgid "cannot both write and verify reverse index"
-msgstr "không thể cùng lúc đọc và xác minh được bảng mục lục đảo ngược"
+msgstr "không thể cùng lúc gh và xác minh chỉ mục ngược"
 
 #, c-format
 msgid "could not stat: %s"
-msgstr "không thể lấy thông tin thống kê: %s"
+msgstr "không thể stat: %s"
 
 #, c-format
 msgid "failed to make %s readable"
@@ -17481,7 +18292,7 @@
 
 #, c-format
 msgid "could not write '%s' promisor file"
-msgstr "không thể ghi tập tin promisor “%s”"
+msgstr "không thể ghi tập tin promisor '%s'"
 
 msgid "offset before end of packfile (broken .idx?)"
 msgstr "vị trí tương đối trước điểm kết thúc của tập tin gói (.idx hỏng à?)"
@@ -17492,44 +18303,36 @@
 
 #, c-format
 msgid "offset before start of pack index for %s (corrupt index?)"
-msgstr "vị trí tương đối nằm trước chỉ mục gói cho %s (mục lục bị hỏng à?)"
+msgstr "vị trí tương đối nằm trước chỉ mục gói cho %s (chỉ mục bị hỏng à?)"
 
 #, c-format
 msgid "offset beyond end of pack index for %s (truncated index?)"
 msgstr ""
-"vị trí tương đối vượt quá cuối của chỉ mục gói cho %s (mục lục bị cắt cụt à?)"
+"vị trí tương đối vượt quá cuối của chỉ mục gói cho %s (chỉ mục bị cắt cụt à?)"
 
 #, c-format
 msgid "malformed expiration date '%s'"
-msgstr "ngày tháng hết hạn dị hình “%s”"
+msgstr "ngày tháng hết hạn sai quy cách '%s'"
 
 #, c-format
 msgid "option `%s' expects \"always\", \"auto\", or \"never\""
-msgstr "tùy chọn “%s” cần \"always\", \"auto\", hoặc \"never\""
+msgstr "tùy chọn '%s' cần \"always\", \"auto\", hoặc \"never\""
 
 #, c-format
 msgid "malformed object name '%s'"
-msgstr "tên đối tượng dị hình “%s”"
+msgstr "tên đối tượng sai quy cách '%s'"
 
 #, c-format
 msgid "option `%s' expects \"%s\" or \"%s\""
-msgstr "tùy chọn “%s” cần \"%s\" hoặc \"%s\""
+msgstr "tùy chọn '%s' cần \"%s\" hoặc \"%s\""
 
 #, c-format
 msgid "%s requires a value"
-msgstr "“%s” yêu cầu một giá trị"
-
-#, c-format
-msgid "%s is incompatible with %s"
-msgstr "%s là xung khắc với %s"
-
-#, c-format
-msgid "%s : incompatible with something else"
-msgstr "%s : xung khắc với các cái khác"
+msgstr "'%s' yêu cầu một giá trị"
 
 #, c-format
 msgid "%s takes no value"
-msgstr "%s k nhận giá trị"
+msgstr "%s không nhận giá trị"
 
 #, c-format
 msgid "%s isn't available"
@@ -17545,26 +18348,29 @@
 
 #, c-format
 msgid "did you mean `--%s` (with two dashes)?"
-msgstr "có phải ý bạn là “--%s“ (với hai dấu gạch ngang)?"
+msgstr "có phải ý bạn là '--%s' (với hai dấu gạch ngang)?"
 
 #, c-format
 msgid "alias of --%s"
 msgstr "bí danh của --%s"
 
+msgid "need a subcommand"
+msgstr "cần câu lệnh con"
+
 #, c-format
 msgid "unknown option `%s'"
-msgstr "không hiểu tùy chọn “%s”"
+msgstr "không hiểu tùy chọn '%s'"
 
 #, c-format
 msgid "unknown switch `%c'"
-msgstr "không hiểu tùy chọn “%c”"
+msgstr "không hiểu tùy chọn '%c'"
 
 #, c-format
 msgid "unknown non-ascii option in string: `%s'"
-msgstr "không hiểu tùy chọn non-ascii trong chuỗi: “%s”"
+msgstr "không hiểu tùy chọn non-ascii trong chuỗi: '%s'"
 
 msgid "..."
-msgstr "…"
+msgstr "..."
 
 #, c-format
 msgid "usage: %s"
@@ -17607,6 +18413,10 @@
 msgid "-NUM"
 msgstr "-SỐ"
 
+#, c-format
+msgid "opposite of --no-%s"
+msgstr "ngược lại với --no-%s"
+
 msgid "expiry-date"
 msgstr "ngày hết hạn"
 
@@ -17622,8 +18432,11 @@
 msgid "use <n> digits to display object names"
 msgstr "sử dụng <n> chữ số để hiển thị tên đối tượng"
 
+msgid "prefixed path to initial superproject"
+msgstr "đường dẫn tiền tố đến project cha ban đầu"
+
 msgid "how to strip spaces and #comments from message"
-msgstr "làm thế nào để cắt bỏ khoảng trắng và #ghichú từ mẩu tin nhắn"
+msgstr "làm thế nào để cắt bỏ khoảng trắng và #ghi-chú từ tin nhắn"
 
 msgid "read pathspec from file"
 msgstr "đọc đặc tả đường dẫn từ tập tin"
@@ -17635,15 +18448,23 @@
 "tự NULL"
 
 #, c-format
+msgid "bad boolean environment value '%s' for '%s'"
+msgstr "sai giá trị kiểu boolean của cấu hình '%s' cho '%s'"
+
+#, c-format
+msgid "failed to parse %s"
+msgstr "gặp lỗi khi đọc cú pháp %s"
+
+#, c-format
 msgid "Could not make %s writable by group"
 msgstr "Không thể làm %s được ghi bởi nhóm"
 
 msgid "Escape character '\\' not allowed as last character in attr value"
 msgstr ""
-"Ký tự thoát chuỗi “\\” không được phép là ký tự cuối trong giá trị thuộc tính"
+"Ký tự thoát chuỗi '\\' không được phép là ký tự cuối trong giá trị thuộc tính"
 
 msgid "Only one 'attr:' specification is allowed."
-msgstr "Chỉ có một đặc tả “attr:” là được phép."
+msgstr "Chỉ có một đặc tả 'attr:' là được phép."
 
 msgid "attr spec must not be empty"
 msgstr "đặc tả attr phải không được để trống"
@@ -17653,42 +18474,45 @@
 msgstr "tên thuộc tính không hợp lệ %s"
 
 msgid "global 'glob' and 'noglob' pathspec settings are incompatible"
-msgstr ""
-"các cài đặt đặc tả đường dẫn “glob” và “noglob” toàn cục là xung khắc nhau"
+msgstr "các cài đặt đặc tả đường dẫn 'glob' và 'noglob' toàn cục là xung khắc"
 
 msgid ""
 "global 'literal' pathspec setting is incompatible with all other global "
 "pathspec settings"
 msgstr ""
-"cài đặt đặc tả đường dẫn “literal” toàn cục là xung khắc với các cài đặt đặc "
-"tả đường dẫn toàn cục khác"
+"cài đặt đặc tả đường dẫn 'literal' toàn cục không tương thích với các cài "
+"đặt đặc tả đường dẫn toàn cục khác"
 
 msgid "invalid parameter for pathspec magic 'prefix'"
-msgstr "tham số không hợp lệ cho “tiền tố” màu nhiệm đặc tả đường đẫn"
+msgstr "tham số không hợp lệ cho đặc tả đường đẫn đặc biệt 'prefix'"
 
 #, c-format
 msgid "Invalid pathspec magic '%.*s' in '%s'"
-msgstr "Số màu nhiệm đặc tả đường dẫn không hợp lệ “%.*s” trong “%s”"
+msgstr "Đặc tả đường dẫn không hợp lệ '%.*s' trong '%s'"
 
 #, c-format
 msgid "Missing ')' at the end of pathspec magic in '%s'"
-msgstr "Thiếu “)” tại cuối của số màu nhiệm đặc tả đường dẫn trong “%s”"
+msgstr "Thiếu ')' tại cuối của đặc tả đường dẫn trong '%s'"
 
 #, c-format
 msgid "Unimplemented pathspec magic '%c' in '%s'"
-msgstr "Chưa viết mã cho số màu nhiệm đặc tả đường dẫn “%c” trong “%s”"
+msgstr "Chưa hỗ trợ đặc tả đường dẫn '%c' trong '%s'"
 
 #, c-format
 msgid "%s: 'literal' and 'glob' are incompatible"
-msgstr "%s: “literal” và “glob” xung khắc nhau"
+msgstr "%s: 'literal' và 'glob' xung khắc"
+
+#, c-format
+msgid "'%s' is outside the directory tree"
+msgstr "'%s' nằm ngoài cây thư mục"
 
 #, c-format
 msgid "%s: '%s' is outside repository at '%s'"
-msgstr "%s: “%s” ngoài một kho chứa tại “%s”"
+msgstr "%s: '%s' nằm ngoài một kho chứa tại '%s'"
 
 #, c-format
 msgid "'%s' (mnemonic: '%c')"
-msgstr "“%s” (mnemonic: “%c”)"
+msgstr "'%s' (mnemonic: '%c')"
 
 #, c-format
 msgid "%s: pathspec magic not supported by this command: %s"
@@ -17696,7 +18520,7 @@
 
 #, c-format
 msgid "pathspec '%s' is beyond a symbolic link"
-msgstr "đặc tả đường dẫn “%s” vượt ra ngoài liên kết mềm"
+msgstr "đặc tả đường dẫn '%s' vượt ra ngoài liên kết mềm"
 
 #, c-format
 msgid "line is badly quoted: %s"
@@ -17746,14 +18570,14 @@
 msgstr "lỗi máy chủ: %s"
 
 msgid "Refreshing index"
-msgstr "Làm mới bảng mục lục"
+msgstr "Làm mới chỉ mục"
 
 #, c-format
 msgid "unable to create threaded lstat: %s"
-msgstr "không thể tạo tuyến trình lstat: %s"
+msgstr "không thể tạo tiến trình lstat: %s"
 
 msgid "unable to parse --pretty format"
-msgstr "không thể phân tích định dạng --pretty"
+msgstr "không thể đọc định dạng --pretty"
 
 msgid "promisor-remote: unable to fork off fetch subprocess"
 msgstr "promisor-remote: không thể rẽ nhánh tuyến trình con fetch"
@@ -17762,12 +18586,15 @@
 msgstr "promisor-remote: không thể ghi tiến trình con fetch"
 
 msgid "promisor-remote: could not close stdin to fetch subprocess"
-msgstr ""
-"promisor-remote: không thể đóng đầu vào tiêu chuẩn tiến trình con fetch"
+msgstr "promisor-remote: không thể đóng stdin tiến trình con fetch"
 
 #, c-format
 msgid "promisor remote name cannot begin with '/': %s"
-msgstr "tên máy chủ hứa hẹn không thể bắt đầu bằng “/”: %s"
+msgstr "tên máy chủ promisor không thể bắt đầu bằng '/': %s"
+
+#, c-format
+msgid "could not fetch %s from promisor remote"
+msgstr "không thể tải %s từ máy chủ promisor"
 
 msgid "object-info: expected flush after arguments"
 msgstr "object-info: cần đẩy dữ liệu lên đĩa sau các tham số"
@@ -17776,38 +18603,44 @@
 msgstr "Đang gỡ các đối tượng trùng lặp"
 
 msgid "could not start `log`"
-msgstr "không thể lấy thông tin thống kê về “log“"
+msgstr "không thể khởi chạy `log`"
 
 msgid "could not read `log` output"
-msgstr "không thể đọc kết xuất “log”"
+msgstr "không thể đọc đầu ra `log`"
 
 #, c-format
 msgid "could not parse commit '%s'"
-msgstr "không thể phân tích lần chuyển giao “%s”"
+msgstr "không thể đọc lần chuyển giao '%s'"
 
 #, c-format
 msgid ""
 "could not parse first line of `log` output: did not start with 'commit ': "
 "'%s'"
 msgstr ""
-"không thể phân tích cú pháp dòng đầu tiên của đầu ra “log”: không bắt đầu "
-"bằng “commit ”: “%s”"
+"không hiểu cú pháp dòng đầu tiên của đầu ra 'log': không bắt đầu bằng "
+"'commit ': '%s'"
 
 #, c-format
 msgid "could not parse git header '%.*s'"
-msgstr "không thể phân tích cú pháp phần đầu git “%.*s”"
+msgstr "không hiểu cú pháp phần đầu git '%.*s'"
 
 msgid "failed to generate diff"
 msgstr "gặp lỗi khi tạo khác biệt"
 
 #, c-format
 msgid "could not parse log for '%s'"
-msgstr "không thể phân tích nhật ký cho “%s”"
+msgstr "không thể đọc nhật ký cho '%s'"
+
+#, c-format
+msgid "invalid extra cruft tip: '%s'"
+msgstr "extra cruft tip không hợp lệ: '%s'"
+
+msgid "unable to enumerate additional recent objects"
+msgstr "không thể đếm các đối tượng mới thêm"
 
 #, c-format
 msgid "will not add file alias '%s' ('%s' already exists in index)"
-msgstr ""
-"sẽ không thêm các bí danh “%s” (“%s” đã có từ trước trong bảng mục lục)"
+msgstr "sẽ không thêm các bí danh '%s' ('%s' đã có từ trước trong chỉ mục)"
 
 msgid "cannot create an empty blob in the object database"
 msgstr "không thể tạo một blob rỗng trong cơ sở dữ liệu đối tượng"
@@ -17819,22 +18652,18 @@
 
 #, c-format
 msgid "unable to index file '%s'"
-msgstr "không thể đánh mục lục tập tin “%s”"
+msgstr "không thể đánh chỉ mục tập tin '%s'"
 
 #, c-format
 msgid "unable to add '%s' to index"
-msgstr "không thể thêm %s vào bảng mục lục"
-
-#, c-format
-msgid "unable to stat '%s'"
-msgstr "không thể lấy thống kê “%s”"
+msgstr "không thể thêm %s vào chỉ mục"
 
 #, c-format
 msgid "'%s' appears as both a file and as a directory"
-msgstr "%s có vẻ không phải là tập tin và cũng chẳng phải là một thư mục"
+msgstr "%s có vẻ vừa là tập tin và cũng vừa là thư mục"
 
 msgid "Refresh index"
-msgstr "Làm tươi mới bảng mục lục"
+msgstr "Làm mới chỉ mục"
 
 #, c-format
 msgid ""
@@ -17858,37 +18687,37 @@
 
 #, c-format
 msgid "bad index version %d"
-msgstr "phiên bản mục lục sai %d"
+msgstr "phiên bản chỉ mục sai %d"
 
 msgid "bad index file sha1 signature"
-msgstr "chữ ký dạng sha1 cho tập tin mục lục không đúng"
+msgstr "chữ ký dạng sha1 cho tập tin chỉ mục không đúng"
 
 #, c-format
 msgid "index uses %.4s extension, which we do not understand"
-msgstr "mục lục dùng phần mở rộng %.4s, cái mà chúng tôi không hiểu được"
+msgstr "chỉ mục dùng phần mở rộng %.4s, cái mà chúng tôi không hiểu được"
 
 #, c-format
 msgid "ignoring %.4s extension"
-msgstr "đang lờ đi phần mở rộng %.4s"
+msgstr "đang bỏ qua phần mở rộng %.4s"
 
 #, c-format
 msgid "unknown index entry format 0x%08x"
-msgstr "không hiểu định dạng mục lục 0x%08x"
+msgstr "không hiểu định dạng chỉ mục 0x%08x"
 
 #, c-format
 msgid "malformed name field in the index, near path '%s'"
-msgstr "trường tên sai sạng trong mục lục, gần đường dẫn “%s”"
+msgstr "trường tên sai sạng trong chỉ mục, gần đường dẫn '%s'"
 
 msgid "unordered stage entries in index"
-msgstr "các mục tin stage không đúng thứ tự trong mục lục"
+msgstr "các mục tin stage không đúng thứ tự trong chỉ mục"
 
 #, c-format
 msgid "multiple stage entries for merged file '%s'"
-msgstr "nhiều mục stage cho tập tin hòa trộn “%s”"
+msgstr "nhiều mục stage cho tập tin hòa trộn '%s'"
 
 #, c-format
 msgid "unordered stage entries for '%s'"
-msgstr "các mục tin stage không đúng thứ tự cho “%s”"
+msgstr "các mục tin stage không đúng thứ tự cho '%s'"
 
 #, c-format
 msgid "unable to create load_cache_entries thread: %s"
@@ -17900,19 +18729,19 @@
 
 #, c-format
 msgid "%s: index file open failed"
-msgstr "%s: mở tập tin mục lục gặp lỗi"
+msgstr "%s: mở tập tin chỉ mục gặp lỗi"
 
 #, c-format
 msgid "%s: cannot stat the open index"
-msgstr "%s: không thể lấy thống kê bảng mục lục đã mở"
+msgstr "%s: không thể stat chỉ mục đã mở"
 
 #, c-format
 msgid "%s: index file smaller than expected"
-msgstr "%s: tập tin mục lục nhỏ hơn mong đợi"
+msgstr "%s: tập tin chỉ mục nhỏ hơn mong đợi"
 
 #, c-format
 msgid "%s: unable to map index file%s"
-msgstr "%s: không thể ánh xạ tập tin mục lục%s"
+msgstr "%s: không thể ánh xạ tập tin chỉ mục%s"
 
 #, c-format
 msgid "unable to create load_index_extensions thread: %s"
@@ -17924,46 +18753,50 @@
 
 #, c-format
 msgid "could not freshen shared index '%s'"
-msgstr "không thể làm tươi mới mục lục đã chia sẻ “%s”"
+msgstr "không thể làm tươi mới chỉ mục đã chia sẻ '%s'"
 
 #, c-format
 msgid "broken index, expect %s in %s, got %s"
-msgstr "mục lục bị hỏng, cần %s trong %s, nhưng lại nhận được %s"
+msgstr "chỉ mục bị hỏng, cần %s trong %s, nhưng lại có %s"
 
 msgid "cannot write split index for a sparse index"
-msgstr "không thể ghi mục lục chia tách cho \"sparse index\""
+msgstr "không thể ghi chỉ mục chia tách cho \"sparse index\""
 
 msgid "failed to convert to a sparse-index"
 msgstr "gặp lỗi khi chuyển đổi sang \"sparse-index\""
 
 #, c-format
-msgid "could not stat '%s'"
-msgstr "không thể lấy thông tin thống kê về “%s”"
-
-#, c-format
 msgid "unable to open git dir: %s"
 msgstr "không thể mở thư mục git: %s"
 
 #, c-format
 msgid "unable to unlink: %s"
-msgstr "không thể bỏ liên kết (unlink): “%s”"
+msgstr "không thể bỏ liên kết (unlink): '%s'"
 
 #, c-format
 msgid "cannot fix permission bits on '%s'"
-msgstr "không thể sửa các bít phân quyền trên “%s”"
+msgstr "không thể sửa các bít phân quyền trên '%s'"
 
 #, c-format
 msgid "%s: cannot drop to stage #0"
 msgstr "%s: không thể xóa bỏ stage #0"
 
+#, c-format
+msgid "unexpected diff status %c"
+msgstr "trạng thái lệnh diff không như mong đợi %c"
+
+#, c-format
+msgid "remove '%s'\n"
+msgstr "gỡ bỏ '%s'\n"
+
 msgid ""
 "You can fix this with 'git rebase --edit-todo' and then run 'git rebase --"
 "continue'.\n"
 "Or you can abort the rebase with 'git rebase --abort'.\n"
 msgstr ""
-"Bạn có thể sửa nó bằng “git rebase --edit-todo” và sau đó chạy “git rebase --"
-"continue”.\n"
-"Hoặc là bạn có thể bãi bỏ việc cải tổ bằng “git rebase --abort”.\n"
+"Bạn có thể sửa nó bằng 'git rebase --edit-todo' và sau đó chạy 'git rebase --"
+"continue'.\n"
+"Hoặc là bạn có thể huỷ bỏ việc cải tổ bằng 'git rebase --abort'.\n"
 
 #, c-format
 msgid ""
@@ -17988,9 +18821,12 @@
 "l, label <label> = label current HEAD with a name\n"
 "t, reset <label> = reset HEAD to a label\n"
 "m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]\n"
-".       create a merge commit using the original merge commit's\n"
-".       message (or the oneline, if no original merge commit was\n"
-".       specified); use -c <commit> to reword the commit message\n"
+"        create a merge commit using the original merge commit's\n"
+"        message (or the oneline, if no original merge commit was\n"
+"        specified); use -c <commit> to reword the commit message\n"
+"u, update-ref <ref> = track a placeholder for the <ref> to be updated\n"
+"                      to this position in the new commits. The <ref> is\n"
+"                      updated at the end of the rebase\n"
 "\n"
 "These lines can be re-ordered; they are executed from top to bottom.\n"
 msgstr ""
@@ -17998,7 +18834,7 @@
 "Các lệnh:\n"
 "p, pick <commit> = dùng lần chuyển giao\n"
 "r, reword <commit> = dùng lần chuyển giao, nhưng sửa lại phần chú thích\n"
-"e, edit <commit> = dùng lần chuyển giao, nhưng dừng lại để tu bổ (amend)\n"
+"e, edit <commit> = dùng lần chuyển giao, nhưng dừng lại để tu bổ\n"
 "s, squash <commit> = dùng lần chuyển giao, nhưng trộn vào lần chuyển giao kế "
 "trước\n"
 "f, fixup [-C | -c] <commit> = giống như \"squash\", nhưng chỉ giữ lại phần "
@@ -18009,33 +18845,35 @@
 "nhưng\n"
 "                   mở trình biên soạn\n"
 "x, exec <commit> = chạy lệnh (phần còn lại của dòng) dùng hệ vỏ\n"
-"b, break = dừng tại đây (tiếp tục cải tổ sau này bằng “git rebase --"
-"continue”)\n"
+"b, break = dừng tại đây (tiếp tục cải tổ sau này bằng 'git rebase --"
+"continue')\n"
 "d, drop <commit> = xóa bỏ lần chuyển giao\n"
-"l, label <label> = đánh nhãn HEAD hiện tại bằng một tên\n"
-"t, reset <label> = đặt lại HEAD thành một nhãn\n"
+"l, label <label> = đánh tên nhãn HEAD hiện tại\n"
+"t, reset <label> = đặt lại HEAD về một nhãn\n"
 "m, merge [-C <commit> | -c <commit>] <nhãn> [# <một_dòng>]\n"
 ".       tạo một lần chuyển giao hòa trộn sử dụng chú thích của lần chuyển\n"
 ".       giao hòa trộn gốc (hoặc một_dòng, nếu không chỉ định lần chuyển giao "
 "hòa\n"
 ".       trộn gốc). Dùng -c <commit> để reword chú thích của lần chuyển "
 "giao.\n"
+"u, update-ref <ref> = track a placeholder for the <ref> to be updated\n"
+"                      to this position in the new commits. The <ref> is\n"
+"                      updated at the end of the rebase\n"
 "\n"
-"Những dòng này có thể được thay đổi thứ tự; chúng chạy từ trên đỉnh xuống "
-"dưới đáy.\n"
+"Những dòng này có thể được thay đổi thứ tự; chúng được thực thi từ trên "
+"xuống dưới.\n"
 
 #, c-format
 msgid "Rebase %s onto %s (%d command)"
 msgid_plural "Rebase %s onto %s (%d commands)"
-msgstr[0] "Cải tổ %s vào %s (%d lệnh )"
+msgstr[0] "Cải tổ %s vào %s (%d lệnh)"
 
 msgid ""
 "\n"
 "Do not remove any line. Use 'drop' explicitly to remove a commit.\n"
 msgstr ""
 "\n"
-"Đừng xóa bất kỳ dòng nào. Dùng “drop” một cách rõ ràng để xóa bỏ một lần "
-"chuyển giao.\n"
+"Đừng xóa bất kỳ dòng nào. Dùng 'drop' để xóa bỏ một lần chuyển giao.\n"
 
 msgid ""
 "\n"
@@ -18063,12 +18901,12 @@
 "\n"
 msgstr ""
 "\n"
-"Tuy nhiên, nếu bạn xóa bỏ mọi thứ, việc cải tổ sẽ bị bãi bỏ.\n"
+"Tuy nhiên, nếu bạn xóa bỏ mọi thứ, việc cải tổ sẽ bị huỷ bỏ.\n"
 "\n"
 
 #, c-format
 msgid "could not write '%s'."
-msgstr "không thể ghi “%s”."
+msgstr "không thể ghi '%s'."
 
 #, c-format
 msgid ""
@@ -18090,29 +18928,37 @@
 "Để tránh thông báo này, dùng \"drop\" một cách rõ ràng để xóa bỏ một lần "
 "chuyển giao.\n"
 "\n"
-"Dùng “git config rebase.missingCommitsCheck” để thay đổi mức độ của cảnh "
+"Dùng 'git config rebase.missingCommitsCheck' để thay đổi mức độ của cảnh "
 "báo.\n"
 "Cánh ứng xử có thể là: ignore, warn, error.\n"
 "\n"
 
 #, c-format
 msgid "%s: 'preserve' superseded by 'merges'"
-msgstr "%s: “preserve” bị cấm bởi “merges”"
+msgstr "%s: 'preserve' bị thay bởi 'merges'"
 
 msgid "gone"
-msgstr "đã ra đi"
+msgstr "đã xoá"
 
 #, c-format
 msgid "ahead %d"
-msgstr "phía trước %d"
+msgstr "đứng trước %d"
 
 #, c-format
 msgid "behind %d"
-msgstr "đằng sau %d"
+msgstr "đứng sau %d"
 
 #, c-format
 msgid "ahead %d, behind %d"
-msgstr "trước %d, sau %d"
+msgstr "đứng trước %d, đứng sau %d"
+
+#, c-format
+msgid "%%(%.*s) does not take arguments"
+msgstr "%%(%.*s) không nhận các đối số"
+
+#, c-format
+msgid "unrecognized %%(%.*s) argument: %s"
+msgstr "đối số không được thừa nhận %%(%.*s): %s"
 
 #, c-format
 msgid "expected format: %%(color:<color>)"
@@ -18131,22 +18977,6 @@
 msgstr "Giá trị nguyên cần tên tham chiếu:rstrip=%s"
 
 #, c-format
-msgid "unrecognized %%(%s) argument: %s"
-msgstr "đối số không được thừa nhận %%(%s): %s"
-
-#, c-format
-msgid "%%(objecttype) does not take arguments"
-msgstr "%%(objecttype) không nhận các đối số"
-
-#, c-format
-msgid "%%(deltabase) does not take arguments"
-msgstr "%%(deltabase) không nhận các đối số"
-
-#, c-format
-msgid "%%(body) does not take arguments"
-msgstr "%%(body) không nhận các đối số"
-
-#, c-format
 msgid "expected %%(trailers:key=<value>)"
 msgstr "cần %%(trailers:key=<giá trị>)"
 
@@ -18159,12 +18989,24 @@
 msgstr "cần nội dung mang giá trị dương:lines=%s"
 
 #, c-format
-msgid "positive value expected '%s' in %%(%s)"
-msgstr "cần giá trị dương “%s” trong %%(%s)"
+msgid "argument expected for %s"
+msgstr "cần đối số cho %s"
 
 #, c-format
-msgid "unrecognized email option: %s"
-msgstr "không nhận ra tùy chọn thư điện tử: “%s”"
+msgid "positive value expected %s=%s"
+msgstr "cần giá trị dương %s=%s"
+
+#, c-format
+msgid "cannot fully parse %s=%s"
+msgstr "không hiểu %s=%s"
+
+#, c-format
+msgid "value expected %s="
+msgstr "cần %s="
+
+#, c-format
+msgid "positive value expected '%s' in %%(%s)"
+msgstr "cần giá trị dương '%s' trong %%(%s)"
 
 #, c-format
 msgid "expected format: %%(align:<width>,<position>)"
@@ -18179,16 +19021,20 @@
 msgstr "chiều rộng không được thừa nhận:%s"
 
 #, c-format
-msgid "positive width expected with the %%(align) atom"
-msgstr "cần giá trị độ rộng dương với nguyên tử %%(align)"
+msgid "unrecognized %%(%s) argument: %s"
+msgstr "đối số không được thừa nhận %%(%s): %s"
 
 #, c-format
-msgid "%%(rest) does not take arguments"
-msgstr "%%(rest) không nhận các đối số"
+msgid "positive width expected with the %%(align) atom"
+msgstr "cần giá trị độ rộng dương với atom %%(align)"
+
+#, c-format
+msgid "expected format: %%(ahead-behind:<committish>)"
+msgstr "cần định dạng: %%(ahead-behind:<committish>)"
 
 #, c-format
 msgid "malformed field name: %.*s"
-msgstr "tên trường dị hình: %.*s"
+msgstr "tên trường sai quy cách: %.*s"
 
 #, c-format
 msgid "unknown field name: %.*s"
@@ -18198,32 +19044,32 @@
 msgid ""
 "not a git repository, but the field '%.*s' requires access to object data"
 msgstr ""
-"không phải là một kho git, nhưng trường “%.*s” yêu cầu truy cập vào dữ liệu "
+"không phải là một kho git, nhưng trường '%.*s' yêu cầu truy cập vào dữ liệu "
 "đối tượng"
 
 #, c-format
 msgid "format: %%(%s) atom used without a %%(%s) atom"
-msgstr "định dạng: nguyên tử %%(%s) được dùng mà không có nguyên tử %%(%s)"
+msgstr "định dạng: atom %%(%s) được dùng mà không có atom %%(%s)"
 
 #, c-format
 msgid "format: %%(then) atom used more than once"
-msgstr "định dạng: nguyên tử %%(then) được dùng nhiều hơn một lần"
+msgstr "định dạng: atom %%(then) được dùng nhiều hơn một lần"
 
 #, c-format
 msgid "format: %%(then) atom used after %%(else)"
-msgstr "định dạng: nguyên tử %%(then) được dùng sau %%(else)"
+msgstr "định dạng: atom %%(then) được dùng sau %%(else)"
 
 #, c-format
 msgid "format: %%(else) atom used more than once"
-msgstr "định dạng: nguyên tử %%(else) được dùng nhiều hơn một lần"
+msgstr "định dạng: atom %%(else) được dùng nhiều hơn một lần"
 
 #, c-format
 msgid "format: %%(end) atom used without corresponding atom"
-msgstr "định dạng: nguyên tử %%(end) được dùng mà không có nguyên tử tương ứng"
+msgstr "định dạng: atom %%(end) được dùng mà không có atom tương ứng"
 
 #, c-format
 msgid "malformed format string %s"
-msgstr "chuỗi định dạng dị hình %s"
+msgstr "chuỗi định dạng sai quy cách %s"
 
 #, c-format
 msgid "this command reject atom %%(%.*s)"
@@ -18233,6 +19079,9 @@
 msgid "--format=%.*s cannot be used with --python, --shell, --tcl"
 msgstr "--format=%.*s không thể được dùng với --python, --shell, --tcl"
 
+msgid "failed to run 'describe'"
+msgstr "gặp lỗi khi chạy 'describe'"
+
 #, c-format
 msgid "(no branch, rebasing %s)"
 msgstr "(không nhánh, đang cải tổ %s)"
@@ -18266,27 +19115,27 @@
 
 #, c-format
 msgid "malformed object at '%s'"
-msgstr "đối tượng dị hình tại “%s”"
+msgstr "đối tượng sai quy cách tại '%s'"
 
 #, c-format
 msgid "ignoring ref with broken name %s"
-msgstr "đang lờ đi tham chiếu với tên hỏng %s"
+msgstr "đang bỏ qua tham chiếu với tên hỏng %s"
 
 #, c-format
 msgid "ignoring broken ref %s"
-msgstr "đang lờ đi tham chiếu hỏng %s"
+msgstr "đang bỏ qua tham chiếu hỏng %s"
 
 #, c-format
 msgid "format: %%(end) atom missing"
-msgstr "định dạng: thiếu nguyên tử %%(end)"
+msgstr "định dạng: thiếu atom %%(end)"
 
 #, c-format
 msgid "malformed object name %s"
-msgstr "tên đối tượng dị hình %s"
+msgstr "tên đối tượng sai quy cách %s"
 
 #, c-format
 msgid "option `%s' must point to a commit"
-msgstr "tùy chọn “%s” phải chỉ đến một lần chuyển giao"
+msgstr "tùy chọn '%s' phải chỉ đến một lần chuyển giao"
 
 msgid "key"
 msgstr "khóa"
@@ -18294,17 +19143,20 @@
 msgid "field name to sort on"
 msgstr "tên trường cần sắp xếp"
 
+msgid "exclude refs which match pattern"
+msgstr "không bao gồm các tham chiếu khớp với mẫu"
+
 #, c-format
 msgid "not a reflog: %s"
 msgstr "không phải một reflog: %s"
 
 #, c-format
 msgid "no reflog for '%s'"
-msgstr "không reflog cho “%s”"
+msgstr "không reflog cho '%s'"
 
 #, c-format
 msgid "%s does not point to a valid object!"
-msgstr "“%s” không chỉ đến một lần chuyển giao hợp lệ nào cả!"
+msgstr "'%s' không chỉ đến một lần chuyển giao hợp lệ nào cả!"
 
 #, c-format
 msgid ""
@@ -18319,20 +19171,20 @@
 "\n"
 "\tgit branch -m <name>\n"
 msgstr ""
-"Sử dụng “%s” làm tên cho nhánh ban đầu. Tên nhánh mặc định này\n"
+"Sử dụng '%s' làm tên cho nhánh ban đầu. Tên nhánh mặc định này\n"
 "có thể thay đổi. Để cấu hình tên nhánh khởi đầu sử dụng trong tất cả\n"
 "kho lưu trữ mới của bạn, cái mà sẽ ngăn chặn cảnh báo này, gọi lệnh:\n"
 "\n"
 "\tgit config --global init.defaultBranch <tên>\n"
 "\n"
-"Tên thường được chọn thay cho “master” là “main”, “trunk” và\n"
-"“development”. Nhánh vừa tạo có thể được đổi tên thông qua lệnh:\n"
+"Tên thường được chọn thay cho 'master' là 'main', 'trunk' và\n"
+"'development'. Nhánh vừa tạo có thể được đổi tên thông qua lệnh:\n"
 "\n"
 "\tgit branch -m <tên>\n"
 
 #, c-format
 msgid "could not retrieve `%s`"
-msgstr "không thể lấy về “%s”"
+msgstr "không thể lấy về '%s'"
 
 #, c-format
 msgid "invalid branch name: %s = %s"
@@ -18340,7 +19192,7 @@
 
 #, c-format
 msgid "ignoring dangling symref %s"
-msgstr "đang lờ đi tham chiếu mềm thừa %s"
+msgstr "đang bỏ qua tham chiếu mềm thừa %s"
 
 #, c-format
 msgid "log for ref %s has gap after %s"
@@ -18356,33 +19208,29 @@
 
 #, c-format
 msgid "refusing to update ref with bad name '%s'"
-msgstr "từ chối cập nhật tham chiếu với tên sai “%s”"
+msgstr "từ chối cập nhật tham chiếu với tên sai '%s'"
 
 #, c-format
 msgid "update_ref failed for ref '%s': %s"
-msgstr "update_ref bị lỗi cho ref “%s”: %s"
+msgstr "update_ref bị lỗi cho ref '%s': %s"
 
 #, c-format
 msgid "multiple updates for ref '%s' not allowed"
-msgstr "không cho phép đa cập nhật cho tham chiếu “%s”"
+msgstr "không cho phép đa cập nhật cho tham chiếu '%s'"
 
 msgid "ref updates forbidden inside quarantine environment"
 msgstr "cập nhật tham chiếu bị cấm trong môi trường kiểm tra"
 
 msgid "ref updates aborted by hook"
-msgstr "các cập nhật tham chiếu bị bãi bỏ bởi móc"
+msgstr "các cập nhật tham chiếu bị huỷ bỏ bởi móc"
 
 #, c-format
 msgid "'%s' exists; cannot create '%s'"
-msgstr "“%s” sẵn có; không thể tạo “%s”"
+msgstr "'%s' sẵn có; không thể tạo '%s'"
 
 #, c-format
 msgid "cannot process '%s' and '%s' at the same time"
-msgstr "không thể xử lý “%s” và “%s” cùng một lúc"
-
-#, c-format
-msgid "could not remove reference %s"
-msgstr "không thể gỡ bỏ tham chiếu: %s"
+msgstr "không thể xử lý '%s' và '%s' cùng một lúc"
 
 #, c-format
 msgid "could not delete reference %s: %s"
@@ -18393,12 +19241,83 @@
 msgstr "không thể xóa bỏ tham chiếu: %s"
 
 #, c-format
+msgid "refname is dangerous: %s"
+msgstr "tên tham chiếu không an toàn: %s"
+
+#, c-format
+msgid "trying to write ref '%s' with nonexistent object %s"
+msgstr "thử ghi tham chiếu '%s' tới đối tượng %s không tồn tại"
+
+#, c-format
+msgid "trying to write non-commit object %s to branch '%s'"
+msgstr "thử ghi đối tượng không phải chuyển giao %s tới nhánh '%s'"
+
+#, c-format
+msgid ""
+"multiple updates for 'HEAD' (including one via its referent '%s') are not "
+"allowed"
+msgstr ""
+"không cho phép đa cập nhật cho tham chiếu HEAD (bao gồm cả thông qua tham "
+"chiếu '%s')"
+
+#, c-format
+msgid "cannot lock ref '%s': unable to resolve reference '%s'"
+msgstr "không thể khoá tham chiếu '%s': không thể phân giải tham chiếu '%s'"
+
+#, c-format
+msgid "cannot lock ref '%s': error reading reference"
+msgstr "không thể khoá tham chiếu '%s': lỗi khi đọc tham chiếu"
+
+#, c-format
+msgid ""
+"multiple updates for '%s' (including one via symref '%s') are not allowed"
+msgstr ""
+"không cho phép đa cập nhật cho tham chiếu '%s' (bao gồm cả thông qua tham "
+"chiếu biểu trưng '%s')"
+
+#, c-format
+msgid "cannot lock ref '%s': reference already exists"
+msgstr "không thể lock tham chiếu '%s': tham chiếu đã tồn tại"
+
+#, c-format
+msgid "cannot lock ref '%s': reference is missing but expected %s"
+msgstr "không thể lock tham chiếu '%s': không tồn tại tham chiếu nhưng cần %s"
+
+#, c-format
+msgid "cannot lock ref '%s': is at %s but expected %s"
+msgstr "không thể lock tham chiếu '%s': đang ở %s nhưng cần %s"
+
+#, c-format
+msgid "reftable: transaction prepare: %s"
+msgstr "reftable: chuẩn bị chuyển giao: %s"
+
+#, c-format
+msgid "reftable: transaction failure: %s"
+msgstr "reftable: chuyển giao thất bại: %s"
+
+#, c-format
+msgid "unable to compact stack: %s"
+msgstr "không thể nén stack: %s"
+
+#, c-format
+msgid "refname %s not found"
+msgstr "không tìm thấy tên tham chiếu %s"
+
+#, c-format
+msgid "refname %s is a symbolic ref, copying it is not supported"
+msgstr "tên tham chiếu %s là tham chiếu biểu trưng, không hỗ trợ sao chép"
+
+#, c-format
 msgid "invalid refspec '%s'"
-msgstr "refspec không hợp lệ “%s”"
+msgstr "refspec không hợp lệ '%s'"
 
 #, c-format
 msgid "invalid quoting in push-option value: '%s'"
-msgstr "sai trích dẫn trong giá trị push-option :“%s”"
+msgstr "sai trích dẫn trong giá trị push-option :'%s'"
+
+#, c-format
+msgid "unknown value for object-format: %s"
+msgstr "không hiểu giá trị cho object-format: %s"
 
 #, c-format
 msgid "%sinfo/refs not valid: is this a git repository?"
@@ -18406,38 +19325,37 @@
 
 msgid "invalid server response; expected service, got flush packet"
 msgstr ""
-"đáp ứng từ máy phục vụ không hợp lệ; cần dịch vụ, nhưng lại nhận được gói "
-"flush"
+"phản hồi từ máy chủ không hợp lệ; cần dịch vụ, nhưng lại nhận được gói flush"
 
 #, c-format
 msgid "invalid server response; got '%s'"
-msgstr "trả về của máy phục vụ không hợp lệ; nhận được %s"
+msgstr "phản hồi từ máy chủ không hợp lệ; nhận được %s"
 
 #, c-format
 msgid "repository '%s' not found"
-msgstr "không tìm thấy kho “%s”"
+msgstr "không tìm thấy kho '%s'"
 
 #, c-format
 msgid "Authentication failed for '%s'"
-msgstr "Xác thực gặp lỗi cho “%s”"
+msgstr "Xác thực gặp lỗi cho '%s'"
 
 #, c-format
 msgid "unable to access '%s' with http.pinnedPubkey configuration: %s"
-msgstr "không thể truy cập “%s” với cấu hình http.pinnedPubkey: %s"
+msgstr "không thể truy cập '%s' với cấu hình http.pinnedPubkey: %s"
 
 #, c-format
 msgid "unable to access '%s': %s"
-msgstr "không thể truy cập “%s”: %s"
+msgstr "không thể truy cập '%s': %s"
 
 #, c-format
 msgid "redirecting to %s"
 msgstr "chuyển hướng đến %s"
 
 msgid "shouldn't have EOF when not gentle on EOF"
-msgstr "không nên có EOF khi không gentle trên EOF"
+msgstr "không nên có EOF khi không thể xử lý EOF"
 
 msgid "remote server sent unexpected response end packet"
-msgstr "máy phục vụ gửi gói kết thúc không cần"
+msgstr "máy chủ gửi gói kết thúc bất thường"
 
 msgid "unable to rewind rpc post data - try increasing http.postBuffer"
 msgstr "không thể tua lại dữ liệu post rpc - thử tăng http.postBuffer"
@@ -18454,15 +19372,15 @@
 msgstr "RPC gặp lỗi; %s"
 
 msgid "cannot handle pushes this big"
-msgstr "không thể xử lý đẩy cái lớn này"
+msgstr "không thể xử lý đẩy lớn cỡ này"
 
 #, c-format
 msgid "cannot deflate request; zlib deflate error %d"
-msgstr "không thể giải nén yêu cầu; có lỗi khi giải nén của zlib %d"
+msgstr "không thể giải nén yêu cầu; lỗi zlib deflate %d"
 
 #, c-format
 msgid "cannot deflate request; zlib end error %d"
-msgstr "không thể giải nén yêu cầu; có lỗi ở cuối %d"
+msgstr "không thể giải nén yêu cầu; lỗi zlib end %d"
 
 #, c-format
 msgid "%d bytes of length header were received"
@@ -18483,12 +19401,19 @@
 
 #, c-format
 msgid "protocol error: expected sha/ref, got '%s'"
-msgstr "lỗi giao thức: cần sha/ref, nhưng lại nhận được “%s”"
+msgstr "lỗi giao thức: cần sha/ref, nhưng lại nhận được '%s'"
 
 #, c-format
 msgid "http transport does not support %s"
 msgstr "vận chuyển http không hỗ trợ %s"
 
+msgid "protocol error: expected '<url> <path>', missing space"
+msgstr "lỗi giao thức: cần '<url> <path>', thiếu dấu cách"
+
+#, c-format
+msgid "failed to download file at URL '%s'"
+msgstr "gặp lỗi khi tải tập tin tại URL '%s'"
+
 msgid "git-http-push failed"
 msgstr "git-http-push gặp lỗi"
 
@@ -18503,11 +19428,11 @@
 
 #, c-format
 msgid "remote-curl: unknown command '%s' from git"
-msgstr "remote-curl: không hiểu lệnh “%s” từ git"
+msgstr "remote-curl: không hiểu lệnh '%s' từ git"
 
 #, c-format
 msgid "config remote shorthand cannot begin with '/': %s"
-msgstr "cấu hình viết tắt máy chủ không thể bắt đầu bằng “/”: %s"
+msgstr "cấu hình viết tắt máy chủ không thể bắt đầu bằng '/': %s"
 
 msgid "more than one receivepack given, using the first"
 msgstr "đã đưa ra nhiều hơn một gói nhận về, đang sử dụng cái đầu tiên"
@@ -18537,19 +19462,19 @@
 
 #, c-format
 msgid "key '%s' of pattern had no '*'"
-msgstr "khóa “%s” của mẫu k có “*”"
+msgstr "khóa '%s' của mẫu k có '*'"
 
 #, c-format
 msgid "value '%s' of pattern has no '*'"
-msgstr "giá trị “%s” của mẫu k có “*”"
+msgstr "giá trị '%s' của mẫu k có '*'"
 
 #, c-format
 msgid "src refspec %s does not match any"
-msgstr "refspec %s nguồn không khớp bất kỳ cái gì"
+msgstr "refspec (đặc tả tham chiếu) nguồn %s không khớp bất kỳ cái gì"
 
 #, c-format
 msgid "src refspec %s matches more than one"
-msgstr "refspec %s nguồn khớp nhiều hơn một"
+msgstr "refspec (đặc tả tham chiếu) nguồn %s khớp nhiều hơn một"
 
 #. TRANSLATORS: "matches '%s'%" is the <dst> part of "git push
 #. <remote> <src>:<dst>" push, and "being pushed ('%s')" is
@@ -18567,17 +19492,16 @@
 "\n"
 "Neither worked, so we gave up. You must fully qualify the ref."
 msgstr ""
-"Đích bạn đã cung cấp không phải tên tham chiếu đầy đủ (tức là\n"
-"bắt đầu bằng \"refs/\"). Chúng tôi đã cố suy luận rằng ý của bạn là:\n"
+"Đích bạn đã cung cấp không phải tên tham chiếu đầy đủ\n"
+"(bắt đầu bằng \"refs/\"). Chúng tôi đã thử đoán ý của bạn theo hai cách:\n"
 "\n"
-"- Tìm kiếm một tham chiếu mà nó khớp “%s” bên phía máy chủ.\n"
-"- Kiểm tra xem <src> được đẩy lên (“%s”)\n"
-"  là một tham chiếu trong \"refs/{heads,tags}/\". Nếu thế chúng tôi thêm một "
-"tiền tố\n"
-"  refs/{heads,tags}/ tương ứng bên phía máy chủ.\n"
+"- Tìm kiếm một tham chiếu khớp '%s' bên phía máy chủ.\n"
+"- Kiểm tra xem <nguồn> được đẩy lên ('%s')\n"
+"  có là một tham chiếu trong \"refs/{heads,tags}/\", và nếu vậy thêm\n"
+"  tiền tố refs/{heads,tags}/ tương ứng bên phía máy chủ.\n"
 "\n"
-"Nếu cả hai là không thể, thì chúng tôi cũng chịu thua. Bạn phải dùng tham "
-"chiếu dạng đầy đủ."
+"Vì cả hai đều không thể, chúng tôi chịu. Bạn phải dùng tham chiếu dạng đầy "
+"đủ."
 
 #, c-format
 msgid ""
@@ -18585,9 +19509,9 @@
 "Did you mean to create a new branch by pushing to\n"
 "'%s:refs/heads/%s'?"
 msgstr ""
-"Phần <src> của đặc tả đường dẫn là một đối tượng lần chuyển giao.\n"
+"Phần <src> của đặc tả tham chiếu là một đối tượng lần chuyển giao.\n"
 "Có phải ý bạn là một tạo một nhánh mới bằng cách đẩy lên\n"
-"“%s:refs/heads/%s”?"
+"'%s:refs/heads/%s'?"
 
 #, c-format
 msgid ""
@@ -18595,9 +19519,9 @@
 "Did you mean to create a new tag by pushing to\n"
 "'%s:refs/tags/%s'?"
 msgstr ""
-"Phần <src> của đặc tả đường dẫn là một đối tượng thẻ.\n"
+"Phần <nguồn> của đặc tả tham chiếu là một đối tượng thẻ.\n"
 "Có phải ý bạn là một tạo một thẻ mới bằng cách đẩy lên\n"
-"“%s:refs/tags/%s”?"
+"'%s:refs/tags/%s'?"
 
 #, c-format
 msgid ""
@@ -18605,9 +19529,9 @@
 "Did you mean to tag a new tree by pushing to\n"
 "'%s:refs/tags/%s'?"
 msgstr ""
-"Phần <src> của đặc tả đường dẫn là một đối tượng cây.\n"
+"Phần <nguồn> của đặc tả tham chiếu là một đối tượng cây.\n"
 "Có phải ý bạn là một tạo một cây mới bằng cách đẩy lên\n"
-"“%s:refs/tags/%s”?"
+"'%s:refs/tags/%s'?"
 
 #, c-format
 msgid ""
@@ -18615,17 +19539,17 @@
 "Did you mean to tag a new blob by pushing to\n"
 "'%s:refs/tags/%s'?"
 msgstr ""
-"Phần <src> của đặc tả đường dẫn là một đối tượng blob.\n"
+"Phần <nguồn> của đặc tả tham chiếu là một đối tượng blob.\n"
 "Có phải ý bạn là một tạo một blob mới bằng cách đẩy lên\n"
-"“%s:refs/tags/%s”?"
+"'%s:refs/tags/%s'?"
 
 #, c-format
 msgid "%s cannot be resolved to branch"
-msgstr "“%s” không thể được phân giải thành nhánh"
+msgstr "'%s' không thể được phân giải thành nhánh"
 
 #, c-format
 msgid "unable to delete '%s': remote ref does not exist"
-msgstr "không thể xóa “%s”: tham chiếu trên máy chủ không tồn tại"
+msgstr "không thể xóa '%s': tham chiếu trên máy chủ không tồn tại"
 
 #, c-format
 msgid "dst refspec %s matches more than one"
@@ -18640,34 +19564,34 @@
 
 #, c-format
 msgid "no such branch: '%s'"
-msgstr "không có nhánh nào như thế: “%s”"
+msgstr "không có nhánh nào như thế: '%s'"
 
 #, c-format
 msgid "no upstream configured for branch '%s'"
-msgstr "không có thượng nguồn được cấu hình cho nhánh “%s”"
+msgstr "không có thượng nguồn được cấu hình cho nhánh '%s'"
 
 #, c-format
 msgid "upstream branch '%s' not stored as a remote-tracking branch"
 msgstr ""
-"nhánh thượng nguồn “%s” không được lưu lại như là một nhánh theo dõi máy chủ"
+"nhánh thượng nguồn '%s' không được lưu lại như là một nhánh theo dõi máy chủ"
 
 #, c-format
 msgid "push destination '%s' on remote '%s' has no local tracking branch"
-msgstr "đẩy lên đích “%s” trên máy chủ “%s” không có nhánh theo dõi nội bộ"
+msgstr "đẩy lên đích '%s' trên máy chủ '%s' không có nhánh theo dõi nội bộ"
 
 #, c-format
 msgid "branch '%s' has no remote for pushing"
-msgstr "nhánh “%s” không có máy chủ để đẩy lên"
+msgstr "nhánh '%s' không có máy chủ để đẩy lên"
 
 #, c-format
 msgid "push refspecs for '%s' do not include '%s'"
-msgstr "đẩy refspecs cho “%s” không bao gồm “%s”"
+msgstr "đẩy refspecs cho '%s' không bao gồm '%s'"
 
 msgid "push has no destination (push.default is 'nothing')"
-msgstr "đẩy lên mà không có đích (push.default là “nothing”)"
+msgstr "đẩy lên mà không có đích (push.default là 'nothing')"
 
 msgid "cannot resolve 'simple' push to a single destination"
-msgstr "không thể phân giải đẩy “đơn giản” đến một đích đơn"
+msgstr "không thể phân giải đẩy 'đơn giản' đến một đích đơn"
 
 #, c-format
 msgid "couldn't find remote ref %s"
@@ -18675,23 +19599,23 @@
 
 #, c-format
 msgid "* Ignoring funny ref '%s' locally"
-msgstr "* Đang bỏ qua tham chiếu thú vị nội bộ “%s”"
+msgstr "* Đang bỏ qua tham chiếu thú vị nội bộ '%s'"
 
 #, c-format
 msgid "Your branch is based on '%s', but the upstream is gone.\n"
 msgstr ""
-"Nhánh của bạn dựa trên cơ sở là “%s”, nhưng trên thượng nguồn không còn.\n"
+"Nhánh của bạn dựa trên cơ sở là '%s', nhưng trên thượng nguồn không còn.\n"
 
 msgid "  (use \"git branch --unset-upstream\" to fixup)\n"
 msgstr "   (dùng \" git branch --unset-upstream\" để sửa)\n"
 
 #, c-format
 msgid "Your branch is up to date with '%s'.\n"
-msgstr "Nhánh của bạn đã cập nhật với “%s”.\n"
+msgstr "Nhánh của bạn đã cập nhật với '%s'.\n"
 
 #, c-format
 msgid "Your branch and '%s' refer to different commits.\n"
-msgstr "Nhánh của bạn và “%s” tham chiếu đến các lần chuyển giao khác nhau.\n"
+msgstr "Nhánh của bạn và '%s' tham chiếu đến các lần chuyển giao khác nhau.\n"
 
 #, c-format
 msgid "  (use \"%s\" for details)\n"
@@ -18700,7 +19624,7 @@
 #, c-format
 msgid "Your branch is ahead of '%s' by %d commit.\n"
 msgid_plural "Your branch is ahead of '%s' by %d commits.\n"
-msgstr[0] "Nhánh của bạn đứng trước “%s” %d lần chuyển giao.\n"
+msgstr[0] "Nhánh của bạn đứng trước '%s' %d lần chuyển giao.\n"
 
 msgid "  (use \"git push\" to publish your local commits)\n"
 msgstr "  (dùng \"git push\" để xuất bản các lần chuyển giao nội bộ của bạn)\n"
@@ -18710,8 +19634,8 @@
 msgid_plural ""
 "Your branch is behind '%s' by %d commits, and can be fast-forwarded.\n"
 msgstr[0] ""
-"Nhánh của bạn đứng đằng sau “%s” %d lần chuyển giao, và có thể được chuyển-"
-"tiếp-nhanh.\n"
+"Nhánh của bạn đứng sau '%s' %d lần chuyển giao, và có thể được chuyển-tiếp-"
+"nhanh.\n"
 
 msgid "  (use \"git pull\" to update your local branch)\n"
 msgstr "  (dùng \"git pull\" để cập nhật nhánh nội bộ của bạn)\n"
@@ -18724,22 +19648,21 @@
 "Your branch and '%s' have diverged,\n"
 "and have %d and %d different commits each, respectively.\n"
 msgstr[0] ""
-"Nhánh của bạn và “%s” bị phân kỳ,\n"
-"và có %d và %d lần chuyển giao khác nhau cho từng cái,\n"
-"tương ứng với mỗi lần.\n"
+"Nhánh của bạn và '%s' bị phân kỳ,\n"
+"và tương ứng có %d và %d lần chuyển giao khác nhau cho từng nhánh.\n"
 
-msgid "  (use \"git pull\" to merge the remote branch into yours)\n"
+msgid ""
+"  (use \"git pull\" if you want to integrate the remote branch with yours)\n"
 msgstr ""
-"  (dùng \"git pull\" để hòa trộn nhánh trên máy chủ vào trong nhánh của "
-"bạn)\n"
+"  (dùng \"git pull\" để hòa trộn nhánh trên máy chủ vào nhánh của bạn)\n"
 
 #, c-format
 msgid "cannot parse expected object name '%s'"
-msgstr "không thể phân tích tên đối tượng mong muốn “%s”"
+msgstr "không thể đọc tên đối tượng mong muốn '%s'"
 
 #, c-format
 msgid "cannot strip one component off url '%s'"
-msgstr "không thể cắt bỏ một thành phần ra khỏi “%s” url"
+msgstr "không thể cắt bỏ một thành phần ra khỏi '%s' url"
 
 #, c-format
 msgid "bad replace ref name: %s"
@@ -18761,65 +19684,61 @@
 
 #, c-format
 msgid "there were errors while writing '%s' (%s)"
-msgstr "gặp lỗi đọc khi đang ghi “%s” (%s)"
+msgstr "gặp lỗi đọc khi đang ghi '%s' (%s)"
 
 #, c-format
 msgid "could not parse conflict hunks in '%s'"
-msgstr "không thể phân tích các mảnh xung đột trong “%s”"
+msgstr "không thể đọc các khúc xung đột trong '%s'"
 
 #, c-format
 msgid "failed utime() on '%s'"
-msgstr "gặp lỗi utime() trên “%s”"
+msgstr "gặp lỗi utime() trên '%s'"
 
 #, c-format
 msgid "writing '%s' failed"
-msgstr "gặp lỗi khi đang ghi “%s”"
+msgstr "gặp lỗi khi đang ghi '%s'"
 
 #, c-format
 msgid "Staged '%s' using previous resolution."
-msgstr "Đã tạm cất “%s” sử dụng cách phân giải kế trước."
+msgstr "Đã tạm cất '%s' sử dụng cách phân giải kế trước."
 
 #, c-format
 msgid "Recorded resolution for '%s'."
-msgstr "Cách giải quyết đã ghi lại cho “%s”."
+msgstr "Cách giải quyết đã ghi lại cho '%s'."
 
 #, c-format
 msgid "Resolved '%s' using previous resolution."
-msgstr "Đã phân giải giải “%s” sử dụng cách giải quyết kế trước."
+msgstr "Đã phân giải giải '%s' sử dụng cách giải quyết kế trước."
 
 #, c-format
 msgid "cannot unlink stray '%s'"
-msgstr "không thể unlink stray “%s”"
+msgstr "không thể unlink stray '%s'"
 
 #, c-format
 msgid "Recorded preimage for '%s'"
-msgstr "Preimage đã được ghi lại cho “%s”"
+msgstr "Preimage đã được ghi lại cho '%s'"
 
 #, c-format
 msgid "failed to update conflicted state in '%s'"
-msgstr "gặp lỗi khi chạy cập nhật trạng thái bị xung đột trong “%s”"
+msgstr "gặp lỗi khi chạy cập nhật trạng thái bị xung đột trong '%s'"
 
 #, c-format
 msgid "no remembered resolution for '%s'"
-msgstr "đừng nhó các giải quyết cho “%s”"
-
-#, c-format
-msgid "cannot unlink '%s'"
-msgstr "không thể unlink “%s”"
+msgstr "đừng nhó các giải quyết cho '%s'"
 
 #, c-format
 msgid "Updated preimage for '%s'"
-msgstr "Đã cập nhật preimage cho “%s”"
+msgstr "Đã cập nhật preimage cho '%s'"
 
 #, c-format
 msgid "Forgot resolution for '%s'\n"
-msgstr "Quên phân giải cho “%s”\n"
+msgstr "Quên phân giải cho '%s'\n"
 
 msgid "unable to open rr-cache directory"
 msgstr "không thể mở thư mục rr-cache"
 
 msgid "update the index with reused conflict resolution if possible"
-msgstr "cập nhật bảng mục lục với phân giải xung đột dùng lại nếu được"
+msgstr "cập nhật chỉ mục với phân giải xung đột dùng lại nếu được"
 
 msgid "could not determine HEAD revision"
 msgstr "không thể dò tìm điểm xét duyệt HEAD"
@@ -18828,15 +19747,45 @@
 msgid "failed to find tree of %s"
 msgstr "gặp lỗi khi tìm cây của %s"
 
+#, c-format
+msgid "unsupported section for hidden refs: %s"
+msgstr "không hỗ trợ mục cho tham chiếu ẩn: %s"
+
+msgid "--exclude-hidden= passed more than once"
+msgstr "--exclude-hidden= được dùng hơn một lần"
+
+#, c-format
+msgid "resolve-undo records `%s` which is missing"
+msgstr "resolve-undo ghi nhận '%s' bị thiếu"
+
+#, c-format
+msgid "%s exists but is a symbolic ref"
+msgstr "%s có tồn tại nhưng là tham chiếu biểu trưng"
+
+msgid ""
+"--merge requires one of the pseudorefs MERGE_HEAD, CHERRY_PICK_HEAD, "
+"REVERT_HEAD or REBASE_HEAD"
+msgstr ""
+"--merge yêu cầu tham chiếu ảo MERGE_HEAD, CHERRY_PICK_HEAD, REVERT_HEAD hoặc "
+"REBASE_HEAD"
+
+#, c-format
+msgid "could not get commit for --ancestry-path argument %s"
+msgstr "không tìm thấy lần chuyển giao ứng với đối số --ancestry-path %s"
+
 msgid "--unpacked=<packfile> no longer supported"
 msgstr "--unpacked=<packfile> không còn được hỗ trợ nữa"
 
+#, c-format
+msgid "invalid option '%s' in --stdin mode"
+msgstr "tùy chọn không hợp lệ '%s' trong chế độ --stdin"
+
 msgid "your current branch appears to be broken"
 msgstr "nhánh hiện tại của bạn có vẻ như bị hỏng"
 
 #, c-format
 msgid "your current branch '%s' does not have any commits yet"
-msgstr "nhánh hiện tại của bạn “%s” không có một lần chuyển giao nào cả"
+msgstr "nhánh hiện tại của bạn '%s' không có một lần chuyển giao nào cả"
 
 msgid "object filtering requires --objects"
 msgstr "lọc đối tượng yêu cầu --objects"
@@ -18848,13 +19797,210 @@
 msgid "cannot create async thread: %s"
 msgstr "không thể tạo tuyến trình async: %s"
 
+#, c-format
+msgid "'%s' does not exist"
+msgstr "\"%s\" không tồn tại"
+
+#, c-format
+msgid "could not switch to '%s'"
+msgstr "không thể chuyển đến '%s'"
+
+msgid "need a working directory"
+msgstr "cần một thư mục làm việc"
+
+msgid "Scalar enlistments require a worktree"
+msgstr "'Scalar enlistments' cần một cây làm việc"
+
+#, c-format
+msgid "could not configure %s=%s"
+msgstr "không thể đóng cấu hình %s=%s"
+
+msgid "could not configure log.excludeDecoration"
+msgstr "không thể cấu hình log.excludeDecoration"
+
+msgid "could not add enlistment"
+msgstr "không thể thêm enlistment"
+
+msgid "could not set recommended config"
+msgstr "không thể đặt cấu hình đề nghị"
+
+msgid "could not turn on maintenance"
+msgstr "không thể bật chế độ bảo trì"
+
+msgid "could not start the FSMonitor daemon"
+msgstr "không thể khởi chạy tiến trình nền FSMonitor"
+
+msgid "could not turn off maintenance"
+msgstr "không thể tắt chế độ bảo trì"
+
+msgid "could not remove enlistment"
+msgstr "không thể bỏ enlistment"
+
+#, c-format
+msgid "remote HEAD is not a branch: '%.*s'"
+msgstr "HEAD của máy chủ không phải một nhánh: '%.*s'"
+
+msgid "failed to get default branch name from remote; using local default"
+msgstr "gặp lỗi khi lấy tên nhánh mặc định từ máy chủ; sử dụng mặc định nội bộ"
+
+msgid "failed to get default branch name"
+msgstr "gặp lỗi khi lấy tên nhánh mặc định"
+
+msgid "failed to unregister repository"
+msgstr "gặp lỗi khi hủy đăng ký kho chứa"
+
+msgid "failed to stop the FSMonitor daemon"
+msgstr "Gặp lỗi khi dừng tiến trình nền FSMonitor"
+
+msgid "failed to delete enlistment directory"
+msgstr "gặp lỗi khi xóa thư mục enlistment"
+
+msgid "branch to checkout after clone"
+msgstr "nhánh để checkout sau khi nhân bản"
+
+msgid "when cloning, create full working directory"
+msgstr "khi nhân bản, tạo đầy đủ thư mục làm việc"
+
+msgid "only download metadata for the branch that will be checked out"
+msgstr "chỉ siêu dữ liệu tải về cho nhánh mà sẽ được checkout"
+
+msgid "create repository within 'src' directory"
+msgstr "tạo kho chứa trong thư mục 'src'"
+
+msgid ""
+"scalar clone [--single-branch] [--branch <main-branch>] [--full-clone]\n"
+"\t[--[no-]src] <url> [<enlistment>]"
+msgstr ""
+"scalar clone [--single-branch] [--branch <nhánh-chính>] [--full-clone]\n"
+"\t[--[no-]src] <url> [<enlistment>]"
+
+#, c-format
+msgid "cannot deduce worktree name from '%s'"
+msgstr "không thể suy diễn tên cây làm việc từ '%s'"
+
+#, c-format
+msgid "directory '%s' exists already"
+msgstr "thư mục '%s' đã sẵn có"
+
+#, c-format
+msgid "failed to get default branch for '%s'"
+msgstr "gặp lỗi khi lấy nhánh mặc định cho '%s'"
+
+#, c-format
+msgid "could not configure remote in '%s'"
+msgstr "không thể cấu hình máy chủ trong '%s'"
+
+#, c-format
+msgid "could not configure '%s'"
+msgstr "không thể cấu hình '%s'"
+
+msgid "partial clone failed; attempting full clone"
+msgstr "nhân bản từng phần gặp lỗi; đang cố thử nhân bản đầy đủ"
+
+msgid "could not configure for full clone"
+msgstr "không thể cấu hình cho nhân bản đầy đủ"
+
+msgid "scalar diagnose [<enlistment>]"
+msgstr "scalar diagnose [<enlistment>]"
+
+msgid "`scalar list` does not take arguments"
+msgstr "`scalar list` không nhận các tham số"
+
+msgid "scalar register [<enlistment>]"
+msgstr "scalar register [<enlistment>]"
+
+msgid "reconfigure all registered enlistments"
+msgstr "cấu hình mọi enlistments đã đăng ký"
+
+msgid "scalar reconfigure [--all | <enlistment>]"
+msgstr "scalar reconfigure [--all | <enlistment>]"
+
+msgid "--all or <enlistment>, but not both"
+msgstr "--all hoặc <enlistment>, không thể là cả hai"
+
+#, c-format
+msgid "could not remove stale scalar.repo '%s'"
+msgstr "không thể xoá scalar.repo đã cũ '%s'"
+
+#, c-format
+msgid "removed stale scalar.repo '%s'"
+msgstr "đã xoá scalar.repo đã cũ '%s'"
+
+#, c-format
+msgid "repository at '%s' has different owner"
+msgstr "kho '%s' thuộc quyền sở hữu của người khác"
+
+#, c-format
+msgid "repository at '%s' has a format issue"
+msgstr "kho '%s' có vấn đề định dạng"
+
+#, c-format
+msgid "repository not found in '%s'"
+msgstr "không tìm thấy kho trong '%s'"
+
+#, c-format
+msgid ""
+"to unregister this repository from Scalar, run\n"
+"\tgit config --global --unset --fixed-value scalar.repo \"%s\""
+msgstr ""
+"để bỏ đăng ký kho này khỏi Scalar, chạy lệnh\n"
+"\tgit config --global --unset --fixed-value scalar.repo \"%s\""
+
+msgid ""
+"scalar run <task> [<enlistment>]\n"
+"Tasks:\n"
+msgstr ""
+"scalar run <task> [<enlistment>]\n"
+"Nhiệm vụ:\n"
+
+#, c-format
+msgid "no such task: '%s'"
+msgstr "không có nhiệm vụ nào như thế: '%s'"
+
+msgid "scalar unregister [<enlistment>]"
+msgstr "scalar unregister [<enlistment>]"
+
+msgid "scalar delete <enlistment>"
+msgstr "scalar delete <enlistment>"
+
+msgid "refusing to delete current working directory"
+msgstr "từ chối gỡ bỏ thư mục làm việc hiện tại"
+
+msgid "include Git version"
+msgstr "bao gồm phiên bản Git"
+
+msgid "include Git's build options"
+msgstr "bao gồm các tùy chọn biên dịch của Git"
+
+msgid "scalar verbose [-v | --verbose] [--build-options]"
+msgstr "scalar verbose [-v | --verbose] [--build-options]"
+
+msgid "-C requires a <directory>"
+msgstr "-C cần một <thư_mục>"
+
+#, c-format
+msgid "could not change to '%s'"
+msgstr "không thể chuyển sang '%s'"
+
+msgid "-c requires a <key>=<value> argument"
+msgstr "-c cần một tham số <key>=<value>"
+
+msgid ""
+"scalar [-C <directory>] [-c <key>=<value>] <command> [<options>]\n"
+"\n"
+"Commands:\n"
+msgstr ""
+"scalar [-C </thư/mục/>] [-c <khóa>=<giá trị>] <lệnh> [<các tùy chọn>]\n"
+"\n"
+"Các lệnh:\n"
+
 msgid "unexpected flush packet while reading remote unpack status"
 msgstr ""
-"gặp gói flush không cần trong khi đọc tình trạng giải nén gói trên máy chủ"
+"gặp gói flush bất thường trong khi đọc tình trạng giải nén gói trên máy chủ"
 
 #, c-format
 msgid "unable to parse remote unpack status: %s"
-msgstr "không thể phân tích tình trạng unpack máy chủ: %s"
+msgstr "không thể đọc tình trạng unpack máy chủ: %s"
 
 #, c-format
 msgid "remote unpack failed: %s"
@@ -18890,11 +20036,11 @@
 
 #, c-format
 msgid "invalid commit message cleanup mode '%s'"
-msgstr "chế độ dọn dẹp ghi chú các lần chuyển giao không hợp lệ “%s”"
+msgstr "chế độ dọn dẹp ghi chú các lần chuyển giao không hợp lệ '%s'"
 
 #, c-format
 msgid "could not delete '%s'"
-msgstr "không thể xóa bỏ “%s”"
+msgstr "không thể xóa bỏ '%s'"
 
 msgid "revert"
 msgstr "hoàn nguyên"
@@ -18910,11 +20056,25 @@
 msgstr "không nhận ra thao tác: %d"
 
 msgid ""
+"Resolve all conflicts manually, mark them as resolved with\n"
+"\"git add/rm <conflicted_files>\", then run \"git rebase --continue\".\n"
+"You can instead skip this commit: run \"git rebase --skip\".\n"
+"To abort and get back to the state before \"git rebase\", run \"git rebase --"
+"abort\"."
+msgstr ""
+"Giải quyết vấn đề này thủ công, hãy đanh dấu chúng đã được giải quyết bằng\n"
+"hãy chạy lệnh \"git add/rm <các_tập tin_xung_đột>\", sau đó chạy \"git "
+"rebase --continue\".\n"
+"Bạn có thể bỏ qua bản vá, chạy \"git rebase --skip\".\n"
+"Để huỷ bỏ và quay trở lại trạng thái trước \"git rebase\", chạy \"git rebase "
+"--abort\"."
+
+msgid ""
 "after resolving the conflicts, mark the corrected paths\n"
 "with 'git add <paths>' or 'git rm <paths>'"
 msgstr ""
 "sau khi giải quyết các xung đột, đánh dấu đường dẫn đã sửa\n"
-"với lệnh “git add </các/đường/dẫn>” hoặc “git rm </các/đường/dẫn>”"
+"với lệnh 'git add </các/đường/dẫn>' hoặc 'git rm </các/đường/dẫn>'"
 
 msgid ""
 "After resolving the conflicts, mark them with\n"
@@ -18928,7 +20088,7 @@
 "\"git add/rm <pathspec>\", sai đó chạy\n"
 "\"git cherry-pick --continue\".\n"
 "Bạn có thể bỏ qua lần chuyển giao này với \"git cherry-pick --skip\".\n"
-"Để bãi bỏ và quay trở lại trạng thái trước khi \"git cherry-pick\",\n"
+"Để huỷ bỏ và quay trở lại trạng thái trước khi \"git cherry-pick\",\n"
 "chạy \"git cherry-pick --abort\"."
 
 msgid ""
@@ -18943,24 +20103,20 @@
 "\"git add/rm <đặc_tả_đường_dẫn_xung_đột>\", sau đó chạy\n"
 "\"git revert --continue\".\n"
 "Bạn có thể bỏ qua lần chuyển giao này với \"git rebase --skip\".\n"
-"Để bãi bỏ và quay trở lại trạng thái trước \"git revert\",\n"
+"Để huỷ bỏ và quay trở lại trạng thái trước \"git revert\",\n"
 "chạy \"git revert --abort\"."
 
 #, c-format
 msgid "could not lock '%s'"
-msgstr "không thể khóa “%s”"
-
-#, c-format
-msgid "could not write to '%s'"
-msgstr "không thể ghi vào “%s”"
+msgstr "không thể khóa '%s'"
 
 #, c-format
 msgid "could not write eol to '%s'"
-msgstr "không thể ghi eol vào “%s”"
+msgstr "không thể ghi eol vào '%s'"
 
 #, c-format
 msgid "failed to finalize '%s'"
-msgstr "gặp lỗi khi hoàn thành “%s”"
+msgstr "gặp lỗi khi hoàn thành '%s'"
 
 #, c-format
 msgid "your local changes would be overwritten by %s."
@@ -18969,16 +20125,12 @@
 msgid "commit your changes or stash them to proceed."
 msgstr "chuyển giao các thay đổi của bạn hay tạm cất (stash) chúng để xử lý."
 
-#, c-format
-msgid "%s: fast-forward"
-msgstr "%s: chuyển-tiếp-nhanh"
-
 #. TRANSLATORS: %s will be "revert", "cherry-pick" or
 #. "rebase".
 #.
 #, c-format
 msgid "%s: Unable to write new index file"
-msgstr "%s: Không thể ghi tập tin lưu bảng mục lục mới"
+msgstr "%s: Không thể ghi tập tin chỉ mục mới"
 
 msgid "unable to update cache tree"
 msgstr "không thể cập nhật cây bộ nhớ đệm"
@@ -18988,33 +20140,33 @@
 
 #, c-format
 msgid "no key present in '%.*s'"
-msgstr "không có khóa hiện diện trong “%.*s”"
+msgstr "không có khóa hiện diện trong '%.*s'"
 
 #, c-format
 msgid "unable to dequote value of '%s'"
-msgstr "không thể giải trích dẫn giá trị của “%s”"
+msgstr "không thể giải trích dẫn giá trị của '%s'"
 
 msgid "'GIT_AUTHOR_NAME' already given"
-msgstr "“GIT_AUTHOR_NAME” đã sẵn đưa ra rồi"
+msgstr "'GIT_AUTHOR_NAME' đã sẵn đưa ra rồi"
 
 msgid "'GIT_AUTHOR_EMAIL' already given"
-msgstr "“GIT_AUTHOR_EMAIL” đã sẵn đưa ra rồi"
+msgstr "'GIT_AUTHOR_EMAIL' đã sẵn đưa ra rồi"
 
 msgid "'GIT_AUTHOR_DATE' already given"
-msgstr "“GIT_AUTHOR_DATE” đã sẵn đưa ra rồi"
+msgstr "'GIT_AUTHOR_DATE' đã sẵn đưa ra rồi"
 
 #, c-format
 msgid "unknown variable '%s'"
-msgstr "không hiểu biến “%s”"
+msgstr "không hiểu biến '%s'"
 
 msgid "missing 'GIT_AUTHOR_NAME'"
-msgstr "thiếu “GIT_AUTHOR_NAME”"
+msgstr "thiếu 'GIT_AUTHOR_NAME'"
 
 msgid "missing 'GIT_AUTHOR_EMAIL'"
-msgstr "thiếu “GIT_AUTHOR_EMAIL”"
+msgstr "thiếu 'GIT_AUTHOR_EMAIL'"
 
 msgid "missing 'GIT_AUTHOR_DATE'"
-msgstr "thiếu “GIT_AUTHOR_DATE”"
+msgstr "thiếu 'GIT_AUTHOR_DATE'"
 
 #, c-format
 msgid ""
@@ -19045,7 +20197,7 @@
 "  git rebase --continue\n"
 
 msgid "'prepare-commit-msg' hook failed"
-msgstr "móc “prepare-commit-msg” bị lỗi"
+msgstr "móc 'prepare-commit-msg' bị lỗi"
 
 msgid ""
 "Your name and email address were configured automatically based\n"
@@ -19108,8 +20260,7 @@
 msgstr "không thể tìm thấy lần chuyển giao mới hơn đã được tạo"
 
 msgid "could not parse newly created commit"
-msgstr ""
-"không thể phân tích cú pháp của đối tượng chuyển giao mới hơn đã được tạo"
+msgstr "không hiểu cú pháp của đối tượng chuyển giao mới hơn đã được tạo"
 
 msgid "unable to resolve HEAD after creating commit"
 msgstr "không thể phân giải HEAD sau khi tạo lần chuyển giao"
@@ -19121,37 +20272,33 @@
 msgstr " (root-commit)"
 
 msgid "could not parse HEAD"
-msgstr "không thể phân tích HEAD"
+msgstr "không thể đọc HEAD"
 
 #, c-format
 msgid "HEAD %s is not a commit!"
 msgstr "HEAD %s không phải là một lần chuyển giao!"
 
 msgid "unable to parse commit author"
-msgstr "không thể phân tích tác giả của lần chuyển giao"
+msgstr "không thể đọc tác giả của lần chuyển giao"
 
 #, c-format
 msgid "unable to read commit message from '%s'"
-msgstr "không thể đọc phần chú thích (message) từ “%s”"
+msgstr "không thể đọc phần chú thích từ '%s'"
 
 #, c-format
 msgid "invalid author identity '%s'"
-msgstr "định danh tác giả không hợp lệ “%s”"
+msgstr "danh tính tác giả không hợp lệ '%s'"
 
 msgid "corrupt author: missing date information"
-msgstr "tác giả sai hỏng: thiếu thông tin ngày tháng"
+msgstr "hỏng tên tác giả: thiếu thông tin ngày tháng"
 
 #, c-format
 msgid "could not update %s"
 msgstr "không thể cập nhật %s"
 
 #, c-format
-msgid "could not parse commit %s"
-msgstr "không thể phân tích lần chuyển giao %s"
-
-#, c-format
 msgid "could not parse parent commit %s"
-msgstr "không thể phân tích lần chuyển giao cha mẹ “%s”"
+msgstr "không thể đọc lần chuyển giao mẹ '%s'"
 
 #, c-format
 msgid "unknown command: %d"
@@ -19162,14 +20309,14 @@
 
 #, c-format
 msgid "This is the commit message #%d:"
-msgstr "Đây là chú thích cho lần chuyển giao thứ #%d:"
+msgstr "Đây là chú thích cho lần chuyển giao thứ %d:"
 
 msgid "The 1st commit message will be skipped:"
 msgstr "Chú thích cho lần chuyển giao thứ nhất sẽ bị bỏ qua:"
 
 #, c-format
 msgid "The commit message #%d will be skipped:"
-msgstr "Chú thích cho lần chuyển giao thứ #%d sẽ bị bỏ qua:"
+msgstr "Chú thích cho lần chuyển giao thứ %d sẽ bị bỏ qua:"
 
 #, c-format
 msgid "This is a combination of %d commits."
@@ -19177,7 +20324,7 @@
 
 #, c-format
 msgid "cannot write '%s'"
-msgstr "không thể ghi “%s”"
+msgstr "không thể ghi '%s'"
 
 msgid "need a HEAD to fixup"
 msgstr "cần một HEAD để sửa"
@@ -19186,21 +20333,22 @@
 msgstr "không thể đọc HEAD"
 
 msgid "could not read HEAD's commit message"
-msgstr "không thể đọc phần chú thích (message) của HEAD"
+msgstr "không thể đọc phần chú thích của HEAD"
 
 #, c-format
 msgid "could not read commit message of %s"
-msgstr "không thể đọc phần chú thích (message) của %s"
+msgstr "không thể đọc phần chú thích của %s"
 
 msgid "your index file is unmerged."
-msgstr "tập tin lưu mục lục của bạn không được hòa trộn."
+msgstr "tập tin chỉ mục của bạn không được hòa trộn."
 
 msgid "cannot fixup root commit"
 msgstr "không thể sửa chữa lần chuyển giao gốc"
 
 #, c-format
 msgid "commit %s is a merge but no -m option was given."
-msgstr "lần chuyển giao %s là một lần hòa trộn nhưng không đưa ra tùy chọn -m."
+msgstr ""
+"lần chuyển giao %s là một lần hòa trộn nhưng lệnh không có tùy chọn -m."
 
 #, c-format
 msgid "commit %s does not have parent %d"
@@ -19214,35 +20362,43 @@
 #. "revert" or "pick", the second %s a SHA1.
 #, c-format
 msgid "%s: cannot parse parent commit %s"
-msgstr "%s: không thể phân tích lần chuyển giao mẹ của %s"
-
-#, c-format
-msgid "could not rename '%s' to '%s'"
-msgstr "không thể đổi tên “%s” thành “%s”"
+msgstr "%s: không thể đọc lần chuyển giao mẹ của %s"
 
 #, c-format
 msgid "could not revert %s... %s"
-msgstr "không thể hoàn nguyên %s… %s"
+msgstr "không thể hoàn nguyên %s... %s"
 
 #, c-format
 msgid "could not apply %s... %s"
-msgstr "không thể áp dụng miếng vá %s… %s"
+msgstr "không thể áp dụng bản vá %s... %s"
 
 #, c-format
 msgid "dropping %s %s -- patch contents already upstream\n"
-msgstr "xóa %s %s -- vá nội dung thượng nguồn đã có\n"
+msgstr "xóa %s %s -- thượng nguồn đã có bản vá\n"
 
 #, c-format
 msgid "git %s: failed to read the index"
-msgstr "git %s: gặp lỗi đọc bảng mục lục"
+msgstr "git %s: gặp lỗi khi đọc chỉ mục"
 
 #, c-format
 msgid "git %s: failed to refresh the index"
-msgstr "git %s: gặp lỗi khi làm tươi mới bảng mục lục"
+msgstr "git %s: gặp lỗi khi làm mới chỉ mục"
 
 #, c-format
-msgid "%s does not accept arguments: '%s'"
-msgstr "%s không nhận các đối số: “%s”"
+msgid "'%s' is not a valid label"
+msgstr "'%s' không phải một nhãn hợp lệ"
+
+#, c-format
+msgid "'%s' is not a valid refname"
+msgstr "'%s' không phải tên tham chiếu hợp lệ"
+
+#, c-format
+msgid "update-ref requires a fully qualified refname e.g. refs/heads/%s"
+msgstr "update-ref yêu cầu tên tham chiếu đầy đủ v.d. refs/heads/%s"
+
+#, c-format
+msgid "invalid command '%.*s'"
+msgstr "lệnh không hợp lệ '%.*s'"
 
 #, c-format
 msgid "missing arguments for %s"
@@ -19250,7 +20406,7 @@
 
 #, c-format
 msgid "could not parse '%s'"
-msgstr "không thể phân tích cú pháp “%s”"
+msgstr "không thể đọc '%s'"
 
 #, c-format
 msgid "invalid line %d: %.*s"
@@ -19258,7 +20414,7 @@
 
 #, c-format
 msgid "cannot '%s' without a previous commit"
-msgstr "không thể “%s” thể mà không có lần chuyển giao kế trước"
+msgstr "không thể '%s' thể mà không có lần chuyển giao kế trước"
 
 msgid "cancelling a cherry picking in progress"
 msgstr "đang hủy bỏ thao tác cherry pick đang thực hiện"
@@ -19267,30 +20423,30 @@
 msgstr "đang hủy bỏ các thao tác hoàn nguyên đang thực hiện"
 
 msgid "please fix this using 'git rebase --edit-todo'."
-msgstr "vui lòng sửa lỗi này bằng cách dùng “git rebase --edit-todo”."
+msgstr "vui lòng sửa lỗi này bằng cách dùng 'git rebase --edit-todo'."
 
 #, c-format
 msgid "unusable instruction sheet: '%s'"
-msgstr "bảng chỉ thị không thể dùng được: %s"
+msgstr "bảng chỉ thị không dùng được: %s"
 
 msgid "no commits parsed."
-msgstr "không có lần chuyển giao nào được phân tích."
+msgstr "không đọc được lần chuyển giao nào."
 
 msgid "cannot cherry-pick during a revert."
-msgstr "không thể cherry-pick trong khi hoàn nguyên."
+msgstr "không thể cherry-pick trong khi đang hoàn nguyên."
 
 msgid "cannot revert during a cherry-pick."
-msgstr "không thể thực hiện việc hoàn nguyên trong khi đang cherry-pick."
+msgstr "không thể hoàn nguyên trong khi đang cherry-pick."
 
 msgid "unusable squash-onto"
-msgstr "squash-onto không dùng được"
+msgstr "không dùng được squash-onto"
 
 #, c-format
 msgid "malformed options sheet: '%s'"
-msgstr "bảng tùy chọn dị hình: “%s”"
+msgstr "bảng tùy chọn sai quy cách: '%s'"
 
 msgid "empty commit set passed"
-msgstr "lần chuyển giao trống rỗng đặt là hợp quy cách"
+msgstr "được chỉ định một lần chuyển giao trống rỗng"
 
 msgid "revert is already in progress"
 msgstr "có thao tác hoàn nguyên đang được thực hiện"
@@ -19300,7 +20456,7 @@
 msgstr "hãy thử \"git revert (--continue | %s--abort | --quit)\""
 
 msgid "cherry-pick is already in progress"
-msgstr "có thao tác “cherry-pick” đang được thực hiện"
+msgstr "có thao tác cherry-pick đang được thực hiện"
 
 #, c-format
 msgid "try \"git cherry-pick (--continue | %s--abort | --quit)\""
@@ -19308,62 +20464,57 @@
 
 #, c-format
 msgid "could not create sequencer directory '%s'"
-msgstr "không thể tạo thư mục xếp dãy “%s”"
-
-msgid "could not lock HEAD"
-msgstr "không thể khóa HEAD"
+msgstr "không thể tạo thư mục sequencer '%s'"
 
 msgid "no cherry-pick or revert in progress"
-msgstr "không cherry-pick hay hoàn nguyên trong tiến trình"
+msgstr "không có cherry-pick hay hoàn nguyên đang được thực hiện"
 
 msgid "cannot resolve HEAD"
 msgstr "không thể phân giải HEAD"
 
 msgid "cannot abort from a branch yet to be born"
-msgstr "không thể hủy bỏ từ một nhánh mà nó còn chưa được tạo ra"
+msgstr "không thể hủy bỏ từ một nhánh chưa được tạo ra"
 
 #, c-format
 msgid "cannot read '%s': %s"
-msgstr "không thể đọc “%s”: %s"
+msgstr "không thể đọc '%s': %s"
 
 msgid "unexpected end of file"
 msgstr "gặp kết thúc tập tin đột xuất"
 
 #, c-format
 msgid "stored pre-cherry-pick HEAD file '%s' is corrupt"
-msgstr "tập tin HEAD “pre-cherry-pick” đã lưu “%s” bị hỏng"
+msgstr "tập tin HEAD trước cherry-pick '%s' bị hỏng"
 
 msgid "You seem to have moved HEAD. Not rewinding, check your HEAD!"
-msgstr ""
-"Bạn có lẽ đã có HEAD đã bị di chuyển đi, Không thể tua, kiểm tra HEAD của "
-"bạn!"
+msgstr "Bạn có lẽ đã di chuyển HEAD, Không thể quay lại, hãy kiểm tra HEAD!"
 
 msgid "no revert in progress"
-msgstr "không có tiến trình hoàn nguyên nào"
+msgstr "không có hoàn nguyên nào đang được thực hiện"
 
 msgid "no cherry-pick in progress"
 msgstr "không có cherry-pick đang được thực hiện"
 
 msgid "failed to skip the commit"
-msgstr "gặp lỗi khi bỏ qua đối tượng chuyển giao"
+msgstr "gặp lỗi khi bỏ qua lần chuyển giao"
 
 msgid "there is nothing to skip"
-msgstr "ở đây không có gì để mà bỏ qua cả"
+msgstr "ở đây không có gì để bỏ qua"
 
 #, c-format
 msgid ""
 "have you committed already?\n"
 "try \"git %s --continue\""
 msgstr ""
-"bạn đã sẵn sàng chuyển giao chưa?\n"
-"thử \"git %s --continue\""
+"hình như bạn đã bắt đầu chuyển giao rồi?\n"
+"thử chạy \"git %s --continue\""
 
 msgid "cannot read HEAD"
 msgstr "không thể đọc HEAD"
 
 #, c-format
 msgid "unable to copy '%s' to '%s'"
-msgstr "không thể chép “%s” sang “%s”"
+msgstr "không thể sao chép '%s' sang '%s'"
 
 #, c-format
 msgid ""
@@ -19375,21 +20526,21 @@
 "\n"
 "  git rebase --continue\n"
 msgstr ""
-"Bạn có thể tu bổ lần chuyển giao ngay bây giờ bằng:\n"
+"Bạn có thể tu bổ lần chuyển giao bằng:\n"
 "\n"
 "  git commit --amend %s\n"
 "\n"
-"Một khi đã hài lòng với những thay đổi của mình, thì chạy:\n"
+"Sau khi hài lòng với những thay đổi của mình, hãy chạy:\n"
 "\n"
 "  git rebase --continue\n"
 
 #, c-format
 msgid "Could not apply %s... %.*s"
-msgstr "Không thể áp dụng %s… %.*s"
+msgstr "Không thể áp dụng %s... %.*s"
 
 #, c-format
 msgid "Could not merge %.*s"
-msgstr "Không hòa trộn %.*s"
+msgstr "Không thể hòa trộn %.*s"
 
 #, c-format
 msgid "Executing: %s\n"
@@ -19404,33 +20555,37 @@
 "\n"
 msgstr ""
 "thực thi gặp lỗi: %s\n"
-"%sBạn có thể sửa các trục trặc, và sau đó chạy lệnh\n"
+"%sBạn có thể sửa lại, và sau đó chạy lệnh\n"
 "\n"
 "  git rebase --continue\n"
 "\n"
 
-msgid "and made changes to the index and/or the working tree\n"
-msgstr "và tạo các thay đổi bảng mục lục và/hay cây làm việc\n"
+msgid "and made changes to the index and/or the working tree.\n"
+msgstr "và thay đổi chỉ mục hay cây làm việc\n"
 
 #, c-format
 msgid ""
 "execution succeeded: %s\n"
-"but left changes to the index and/or the working tree\n"
+"but left changes to the index and/or the working tree.\n"
 "Commit or stash your changes, and then run\n"
 "\n"
 "  git rebase --continue\n"
 "\n"
 msgstr ""
 "thực thi thành công: %s\n"
-"nhưng còn các thay đổi trong mục lục và/hoặc cây làm việc\n"
-"Chuyển giao hay tạm cất các thay đổi này đi, rồi chạy\n"
+"nhưng còn các thay đổi trong chỉ mục hay cây làm việc.\n"
+"Hãy chuyển giao hay tạm cất các thay đổi này, rồi chạy\n"
 "\n"
 "  git rebase --continue\n"
 "\n"
 
 #, c-format
 msgid "illegal label name: '%.*s'"
-msgstr "tên nhãn dị hình: “%.*s”"
+msgstr "tên nhãn không hợp lệ: '%.*s'"
+
+#, c-format
+msgid "could not resolve '%s'"
+msgstr "không thể phân giải '%s'"
 
 msgid "writing fake root commit"
 msgstr "ghi lần chuyển giao gốc giả"
@@ -19438,45 +20593,63 @@
 msgid "writing squash-onto"
 msgstr "đang ghi squash-onto"
 
-#, c-format
-msgid "could not resolve '%s'"
-msgstr "không thể phân giải “%s”"
-
 msgid "cannot merge without a current revision"
-msgstr "không thể hòa trộn mà không có một điểm xét duyệt hiện tại"
+msgstr "không thể hòa trộn mà không có điểm hiệu chỉnh hiện tại"
 
 #, c-format
 msgid "unable to parse '%.*s'"
-msgstr "không thể phân tích “%.*s”"
+msgstr "không thể đọc '%.*s'"
 
 #, c-format
 msgid "nothing to merge: '%.*s'"
-msgstr "chẳng có gì để hòa trộn: “%.*s”"
+msgstr "chẳng có gì để hòa trộn: '%.*s'"
 
 msgid "octopus merge cannot be executed on top of a [new root]"
-msgstr "hòa trộn octopus không thể được thực thi trên đỉnh của một [new root]"
+msgstr ""
+"hòa trộn kiểu bạch tuộc không thể được thực thi trên đỉnh của [new root]"
 
 #, c-format
 msgid "could not get commit message of '%s'"
-msgstr "không thể lấy chú thích của lần chuyển giao của “%s”"
+msgstr "không thể lấy chú thích của lần chuyển giao của '%s'"
 
 #, c-format
 msgid "could not even attempt to merge '%.*s'"
-msgstr "không thể ngay cả khi thử hòa trộn “%.*s”"
+msgstr "hoàn toàn không thể hòa trộn '%.*s'"
 
 msgid "merge: Unable to write new index file"
-msgstr "merge: Không thể ghi tập tin lưu bảng mục lục mới"
+msgstr "merge: Không thể ghi tập tin chỉ mục mới"
+
+#, c-format
+msgid ""
+"another 'rebase' process appears to be running; '%s.lock' already exists"
+msgstr "Một lần cải tổ khác đang diễn ra; %s.lock đã tồn tại"
+
+#, c-format
+msgid ""
+"Updated the following refs with %s:\n"
+"%s"
+msgstr ""
+"Đã cập nhật các tham chiếu sau thành %s:\n"
+"%s"
+
+#, c-format
+msgid ""
+"Failed to update the following refs with %s:\n"
+"%s"
+msgstr ""
+"Không thể cập nhật các tham chiếu sau thành %s:\n"
+"%s"
 
 msgid "Cannot autostash"
 msgstr "Không thể autostash"
 
 #, c-format
 msgid "Unexpected stash response: '%s'"
-msgstr "Gặp đáp ứng stash không cần: “%s”"
+msgstr "Gặp phản hồi stash bất thường '%s'"
 
 #, c-format
 msgid "Could not create directory for '%s'"
-msgstr "Không thể tạo thư mục cho “%s”"
+msgstr "Không thể tạo thư mục cho '%s'"
 
 #, c-format
 msgid "Created autostash: %s\n"
@@ -19491,7 +20664,7 @@
 
 #, c-format
 msgid "cannot store %s"
-msgstr "không thử lưu “%s”"
+msgstr "không thể lưu '%s'"
 
 #, c-format
 msgid ""
@@ -19500,16 +20673,19 @@
 "You can run \"git stash pop\" or \"git stash drop\" at any time.\n"
 msgstr ""
 "%s\n"
-"Các thay đổi của bạn an toàn trong stash (tạm cất đi).\n"
+"Các thay đổi của bạn an toàn trong tạm cất.\n"
 "Bạn có thể chạy lệnh \"git stash pop\" hay \"git stash drop\" bất kỳ lúc "
 "nào.\n"
 
 msgid "Applying autostash resulted in conflicts."
-msgstr "Áp dụng autostash có hiệu quả trong các xung đột."
+msgstr "Áp dụng autostash đã gây nên xung đột."
 
 msgid "Autostash exists; creating a new stash entry."
 msgstr "Autostash đã sẵn có; nên tạo một mục stash mới."
 
+msgid "autostash reference is a symref"
+msgstr "tham chiếu autostash là symref"
+
 msgid "could not detach HEAD"
 msgstr "không thể tách rời HEAD"
 
@@ -19535,19 +20711,19 @@
 "Không thể thực thi lệnh todo\n"
 "\n"
 "    %.*s\n"
-"Nó đã được lên lịch lại: Để sửa lệnh trước khi tiếp tục, vui lòng\n"
+"Lệnh đã được lên lịch lại. Để sửa lệnh trước khi tiếp tục, vui lòng\n"
 "sửa danh sách todo trước:\n"
 "\n"
 "    git rebase --edit-todo\n"
 "    git rebase --continue\n"
 
 #, c-format
-msgid "Rebasing (%d/%d)%s"
-msgstr "Đang cải tổ (%d/%d)%s"
+msgid "Stopped at %s...  %.*s\n"
+msgstr "Dừng lại ở %s...  %.*s\n"
 
 #, c-format
-msgid "Stopped at %s...  %.*s\n"
-msgstr "Dừng lại ở %s…  %.*s\n"
+msgid "Rebasing (%d/%d)%s"
+msgstr "Đang cải tổ (%d/%d)%s"
 
 #, c-format
 msgid "unknown command %d"
@@ -19557,7 +20733,7 @@
 msgstr "không thể đọc orig-head"
 
 msgid "could not read 'onto'"
-msgstr "không thể đọc “onto”."
+msgstr "không thể đọc 'onto'."
 
 #, c-format
 msgid "could not update HEAD to %s"
@@ -19571,15 +20747,15 @@
 msgstr "không thể cải tổ: Bạn có các thay đổi chưa được đưa lên bệ phóng."
 
 msgid "cannot amend non-existing commit"
-msgstr "không thể tu bỏ một lần chuyển giao không tồn tại"
+msgstr "không thể tu sửa lần chuyển giao không tồn tại"
 
 #, c-format
 msgid "invalid file: '%s'"
-msgstr "tập tin không hợp lệ: “%s”"
+msgstr "tập tin không hợp lệ: '%s'"
 
 #, c-format
 msgid "invalid contents: '%s'"
-msgstr "nội dung không hợp lệ: “%s”"
+msgstr "nội dung không hợp lệ: '%s'"
 
 msgid ""
 "\n"
@@ -19588,11 +20764,11 @@
 msgstr ""
 "\n"
 "Bạn có các thay đổi chưa chuyển giao trong thư mục làm việc. Vui lòng\n"
-"chuyển giao chúng trước và sau đó chạy lệnh “git rebase --continue” lần nữa."
+"chuyển giao chúng trước rồi sau đó chạy lệnh 'git rebase --continue'."
 
 #, c-format
 msgid "could not write file: '%s'"
-msgstr "không thể ghi tập tin: “%s”"
+msgstr "không thể ghi tập tin: '%s'"
 
 msgid "could not remove CHERRY_PICK_HEAD"
 msgstr "không thể xóa bỏ CHERRY_PICK_HEAD"
@@ -19602,14 +20778,14 @@
 
 #, c-format
 msgid "%s: can't cherry-pick a %s"
-msgstr "%s: không thể cherry-pick một %s"
+msgstr "%s: không thể cherry-pick %s"
 
 #, c-format
 msgid "%s: bad revision"
-msgstr "%s: điểm xét duyệt sai"
+msgstr "%s: điểm hiệu chỉnh không hợp lệ"
 
 msgid "can't revert as initial commit"
-msgstr "không thể hoàn nguyên một lần chuyển giao khởi tạo"
+msgstr "không thể hoàn nguyên lần chuyển giao khởi tạo"
 
 #, c-format
 msgid "skipped previously applied commit %s"
@@ -19629,14 +20805,18 @@
 msgstr "không có gì để làm"
 
 msgid "could not skip unnecessary pick commands"
-msgstr "không thể bỏ qua các lệnh cậy (pick) không cần thiết"
+msgstr "không thể bỏ qua các lệnh pick không cần thiết"
 
 msgid "the script was already rearranged."
-msgstr "văn lệnh đã sẵn được sắp đặt rồi."
+msgstr "script đã được sắp đặt rồi."
+
+#, c-format
+msgid "update-refs file at '%s' is invalid"
+msgstr "tập tin update-refs '%s' không hợp lệ"
 
 #, c-format
 msgid "'%s' is outside repository at '%s'"
-msgstr "“%s” ngoài một kho chứa tại “%s”"
+msgstr "'%s' nằm ngoài kho chứa tại '%s'"
 
 #, c-format
 msgid ""
@@ -19644,8 +20824,8 @@
 "Use 'git <command> -- <path>...' to specify paths that do not exist locally."
 msgstr ""
 "%s: không có đường dẫn nào như thế ở trong cây làm việc.\n"
-"Dùng “git <lệnh> -- <đường/dẫn>…” để chỉ định đường dẫn mà nó không tồn tại "
-"một cách nội bộ."
+"Dùng 'git <lệnh> -- <đường/dẫn>...' để chỉ định đường dẫn không tồn tại nội "
+"bộ."
 
 #, c-format
 msgid ""
@@ -19653,14 +20833,14 @@
 "Use '--' to separate paths from revisions, like this:\n"
 "'git <command> [<revision>...] -- [<file>...]'"
 msgstr ""
-"tham số chưa rõ ràng “%s”: chưa biết điểm xem xét hay đường dẫn không trong "
-"cây làm việc.\n"
-"Dùng “--” để ngăn cách các đường dẫn khỏi điểm xem xét, như thế này:\n"
-"“git <lệnh> [<điểm xem xét>…] -- [<tập tin>…]”"
+"tham số chưa rõ ràng '%s': chưa biết điểm xét duyệt hay đường dẫn không "
+"trong cây làm việc.\n"
+"Dùng '--' để ngăn cách các đường dẫn khỏi điểm xét duyệt, như thế này:\n"
+"'git <lệnh> [<điểm xét duyệt>...] -- [<tập tin>...]'"
 
 #, c-format
 msgid "option '%s' must come before non-option arguments"
-msgstr "tùy chọn “%s” phải trước các đối số đầu tiên không có tùy chọn"
+msgstr "tùy chọn '%s' phải trước các đối số đầu tiên không có tùy chọn"
 
 #, c-format
 msgid ""
@@ -19668,16 +20848,20 @@
 "Use '--' to separate paths from revisions, like this:\n"
 "'git <command> [<revision>...] -- [<file>...]'"
 msgstr ""
-"tham số chưa rõ ràng “%s”: cả điểm xem xét và tên tập tin.\n"
-"Dùng “--” để ngăn cách các đường dẫn khỏi điểm xem xét, như thế này:\n"
-"“git <lệnh> [<điểm xem xét>…] -- [<tập tin>…]”"
+"tham số chưa rõ ràng '%s': cả điểm xem xét và tên tập tin.\n"
+"Dùng '--' để ngăn cách các đường dẫn khỏi điểm xem xét, như thế này:\n"
+"'git <lệnh> [<điểm xem xét>...] -- [<tập tin>...]'"
 
 msgid "unable to set up work tree using invalid config"
-msgstr "không thể cài đặt thư mục làm việc sử dụng cấu hình không hợp lệ"
+msgstr "không thể thiết lập thư mục làm việc với cấu hình không hợp lệ"
+
+#, c-format
+msgid "'%s' already specified as '%s'"
+msgstr "'%s' đã được chỉ định là '%s' rồi"
 
 #, c-format
 msgid "Expected git repo version <= %d, found %d"
-msgstr "Cần phiên bản kho git <= %d, nhưng lại nhận được %d"
+msgstr "Cần phiên bản kho git <= %d, nhưng lại là %d"
 
 msgid "unknown repository extension found:"
 msgid_plural "unknown repository extensions found:"
@@ -19685,15 +20869,16 @@
 
 msgid "repo version is 0, but v1-only extension found:"
 msgid_plural "repo version is 0, but v1-only extensions found:"
-msgstr[0] "phiên bản kho là 0, nhưng lại tìm thấy phần mở rộng chỉ v1:"
+msgstr[0] ""
+"phiên bản kho là 0, nhưng lại tìm thấy phần mở rộng chỉ dành cho v1:"
 
 #, c-format
 msgid "error opening '%s'"
-msgstr "gặp lỗi khi mở “%s”"
+msgstr "gặp lỗi khi mở '%s'"
 
 #, c-format
 msgid "too large to be a .git file: '%s'"
-msgstr "tập tin .git là quá lớn: “%s”"
+msgstr "tập tin .git quá lớn: '%s'"
 
 #, c-format
 msgid "error reading %s"
@@ -19701,11 +20886,11 @@
 
 #, c-format
 msgid "invalid gitfile format: %s"
-msgstr "định dạng tập tin git không hợp lệ: %s"
+msgstr "định dạng gitfile không hợp lệ: %s"
 
 #, c-format
 msgid "no path in gitfile: %s"
-msgstr "không có đường dẫn trong tập tin git: %s"
+msgstr "không có đường dẫn trong gitfile: %s"
 
 #, c-format
 msgid "not a git repository: %s"
@@ -19713,56 +20898,61 @@
 
 #, c-format
 msgid "'$%s' too big"
-msgstr "“$%s” quá lớn"
+msgstr "'$%s' quá lớn"
 
 #, c-format
 msgid "not a git repository: '%s'"
-msgstr "không phải là kho git: “%s”"
+msgstr "không phải là kho git: '%s'"
 
 #, c-format
 msgid "cannot chdir to '%s'"
-msgstr "không thể chdir (chuyển đổi thư mục) sang “%s”"
+msgstr "không thể chdir (chuyển thư mục) sang '%s'"
 
 msgid "cannot come back to cwd"
-msgstr "không thể quay lại cwd"
+msgstr "không thể quay lại thư mục làm việc hiện hành"
 
 #, c-format
 msgid "failed to stat '%*s%s%s'"
-msgstr "gặp lỗi khi lấy thống kê về “%*s%s%s”"
+msgstr "gặp lỗi khi stat'%*s%s%s'"
 
 msgid "Unable to read current working directory"
 msgstr "Không thể đọc thư mục làm việc hiện hành"
 
 #, c-format
 msgid "cannot change to '%s'"
-msgstr "không thể chuyển sang “%s”"
+msgstr "không thể chuyển sang '%s'"
 
 #, c-format
 msgid "not a git repository (or any of the parent directories): %s"
-msgstr "không phải là kho git (hoặc bất kỳ thư mục cha mẹ nào): %s"
+msgstr "không phải là kho git (các thư mục cha cũng không phải): %s"
 
 #, c-format
 msgid ""
 "not a git repository (or any parent up to mount point %s)\n"
 "Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set)."
 msgstr ""
-"không phải là kho git (hay bất kỳ cha mẹ nào đến tận điểm gắn kết %s)\n"
+"không phải là kho git (các thư mục cha dưới điểm gắn kết %s cũng không "
+"phải)\n"
 "Dừng tại biên của hệ thống tập tin (GIT_DISCOVERY_ACROSS_FILESYSTEM chưa "
-"đặt)."
+"được đặt)."
 
 #, c-format
 msgid ""
-"unsafe repository ('%s' is owned by someone else)\n"
-"To add an exception for this directory, call:\n"
+"detected dubious ownership in repository at '%s'\n"
+"%sTo add an exception for this directory, call:\n"
 "\n"
 "\tgit config --global --add safe.directory %s"
 msgstr ""
-"kho lưu trữ không an toàn ('%s' thuộc sở hữu của người khác)\n"
-"Để thêm ngoại lệ cho thư mục này, hãy gọi:\n"
+"kho lưu trữ '%s' thuộc sở hữu của người khác\n"
+"%sĐể thêm ngoại lệ cho thư mục này, hãy gọi:\n"
 "\n"
 "\tgit config --global --add safe.directory %s"
 
 #, c-format
+msgid "cannot use bare repository '%s' (safe.bareRepository is '%s')"
+msgstr "không thể dùng kho chứa bare '%s' (safe.bareRepository là '%s')"
+
+#, c-format
 msgid ""
 "problem with core.sharedRepository filemode value (0%.3o).\n"
 "The owner of files must always have read and write permissions."
@@ -19771,17 +20961,107 @@
 "người sở hữu tập tin phải luôn có quyền đọc và ghi."
 
 msgid "fork failed"
-msgstr "gặp lỗi khi rẽ nhánh tiến trình"
+msgstr "gặp lỗi khi fork"
 
 msgid "setsid failed"
 msgstr "setsid gặp lỗi"
 
 #, c-format
+msgid "cannot stat template '%s'"
+msgstr "không thể lấy thông tin về mẫu '%s'"
+
+#, c-format
+msgid "cannot opendir '%s'"
+msgstr "không thể mở thư mục '%s'"
+
+#, c-format
+msgid "cannot readlink '%s'"
+msgstr "không thể đọc nội dung liên kết '%s'"
+
+#, c-format
+msgid "cannot symlink '%s' '%s'"
+msgstr "không thể tạo liên kết mềm '%s' '%s'"
+
+#, c-format
+msgid "cannot copy '%s' to '%s'"
+msgstr "không thể sao chép '%s' sang '%s'"
+
+#, c-format
+msgid "ignoring template %s"
+msgstr "đang bỏ qua mẫu '%s'"
+
+#, c-format
+msgid "templates not found in %s"
+msgstr "các mẫu không được tìm thấy trong %s"
+
+#, c-format
+msgid "not copying templates from '%s': %s"
+msgstr "không sao chép các mẫu từ '%s': %s"
+
+#, c-format
+msgid "invalid initial branch name: '%s'"
+msgstr "tên nhánh khởi tạo không hợp lệ: '%s'"
+
+#, c-format
+msgid "re-init: ignored --initial-branch=%s"
+msgstr "re-init: --initial-branch=%s bị bỏ qua"
+
+#, c-format
+msgid "unable to handle file type %d"
+msgstr "không thể xử lý (handle) tập tin kiểu %d"
+
+#, c-format
+msgid "unable to move %s to %s"
+msgstr "không di chuyển được %s vào %s"
+
+msgid "attempt to reinitialize repository with different hash"
+msgstr "cố để khởi tạo lại một kho với kiểu băm dữ liệu khác"
+
+msgid ""
+"attempt to reinitialize repository with different reference storage format"
+msgstr "cố khởi tạo lại một kho với kiểu lưu tham chiếu dữ liệu khác"
+
+#, c-format
+msgid "%s already exists"
+msgstr "%s đã có từ trước rồi"
+
+#, c-format
+msgid "Reinitialized existing shared Git repository in %s%s\n"
+msgstr "Đã khởi tạo lại kho Git chia sẻ sẵn có trong %s%s\n"
+
+#, c-format
+msgid "Reinitialized existing Git repository in %s%s\n"
+msgstr "Đã khởi tạo lại kho Git sẵn có trong %s%s\n"
+
+#, c-format
+msgid "Initialized empty shared Git repository in %s%s\n"
+msgstr "Đã khởi tạo lại kho Git chia sẻ trống rỗng sẵn có trong %s%s\n"
+
+#, c-format
+msgid "Initialized empty Git repository in %s%s\n"
+msgstr "Đã khởi tạo lại kho Git trống rỗng sẵn có trong %s%s\n"
+
+#, c-format
 msgid "index entry is a directory, but not sparse (%08x)"
-msgstr "mục tin mục lục là một thư mục, nhưng không \"sparse\" (%08x)"
+msgstr "mục tin chỉ mục là một thư mục, nhưng không \"sparse\" (%08x)"
 
 msgid "cannot use split index with a sparse index"
-msgstr "không thể sử dụng bảng mục lục chia tách với một \"sparse index\""
+msgstr "không thể sử dụng chỉ mục chia tách với một \"sparse index\""
+
+#. TRANSLATORS: The first %s is a command like "ls-tree".
+#, c-format
+msgid "bad %s format: element '%s' does not start with '('"
+msgstr "định dạng %s sai: phần tử '%s' không bắt đầu bằng '('"
+
+#. TRANSLATORS: The first %s is a command like "ls-tree".
+#, c-format
+msgid "bad %s format: element '%s' does not end in ')'"
+msgstr "định dạng %s sai: phần tử '%s' không bắt kết thúc bằng ')'"
+
+#. TRANSLATORS: %s is a command like "ls-tree".
+#, c-format
+msgid "bad %s format: %%%.*s"
+msgstr "định dạng %s sai: %%%.*s"
 
 #. TRANSLATORS: IEC 80000-13:2008 gibibyte
 #, c-format
@@ -19826,21 +21106,15 @@
 msgstr[0] "%u byte/giây"
 
 #, c-format
-msgid "could not edit '%s'"
-msgstr "không thể sửa “%s”"
-
-#, c-format
 msgid "ignoring suspicious submodule name: %s"
-msgstr "đang lờ đi tên mô-đun-con mập mờ: %s"
+msgstr "đang bỏ qua tên mô-đun-con mập mờ: %s"
 
 msgid "negative values not allowed for submodule.fetchJobs"
 msgstr "không cho phép giá trị âm ở submodule.fetchJobs"
 
 #, c-format
 msgid "ignoring '%s' which may be interpreted as a command-line option: %s"
-msgstr ""
-"đang bỏ qua “%s” cái mà có thể được phiên dịch như là một tùy chọn dòng "
-"lệnh: %s"
+msgstr "đang bỏ qua '%s' nhưng có thể được hiểu là tùy chọn trên dòng lệnh: %s"
 
 #, c-format
 msgid "Could not update .gitmodules entry %s"
@@ -19864,11 +21138,11 @@
 
 #, c-format
 msgid "in unpopulated submodule '%s'"
-msgstr "trong mô-đun-con không có gì “%s”"
+msgstr "trong mô-đun-con không có gì '%s'"
 
 #, c-format
 msgid "Pathspec '%s' is in submodule '%.*s'"
-msgstr "Đặc tả đường dẫn “%s” thì ở trong mô-đun-con “%.*s”"
+msgstr "Đặc tả đường dẫn '%s' ở trong mô-đun-con '%.*s'"
 
 #, c-format
 msgid "bad --ignore-submodules argument: %s"
@@ -19879,33 +21153,33 @@
 "Submodule in commit %s at path: '%s' collides with a submodule named the "
 "same. Skipping it."
 msgstr ""
-"Mô-đun-con trong lần chuyển giao %s tại đường dẫn: “%s” va chạm với mô-đun-"
-"con cùng tên. Nên bỏ qua nó."
+"Mô-đun-con trong lần chuyển giao %s tại đường dẫn: '%s' va chạm với mô-đun-"
+"con cùng tên. Nên sẽ bỏ qua."
 
 #, c-format
 msgid "submodule entry '%s' (%s) is a %s, not a commit"
 msgstr ""
-"mục tin mô-đun-con “%s” (%s) là một %s, không phải là một lần chuyển giao"
+"mục tin mô-đun-con '%s' (%s) là một %s, không phải là một lần chuyển giao"
 
 #, c-format
 msgid ""
 "Could not run 'git rev-list <commits> --not --remotes -n 1' command in "
 "submodule %s"
 msgstr ""
-"Không thể chạy lệnh “git rev-list <các lần chuyển giao> --not --remotes -n "
-"1” trong mô-đun-con “%s”"
+"Không thể chạy lệnh 'git rev-list <các lần chuyển giao> --not --remotes -n "
+"1' trong mô-đun-con '%s'"
 
 #, c-format
 msgid "process for submodule '%s' failed"
-msgstr "xử lý cho mô-đun-con “%s” gặp lỗi"
+msgstr "xử lý cho mô-đun-con '%s' gặp lỗi"
 
 #, c-format
 msgid "Pushing submodule '%s'\n"
-msgstr "Đẩy lên mô-đun-con “%s”\n"
+msgstr "Đẩy lên mô-đun-con '%s'\n"
 
 #, c-format
 msgid "Unable to push submodule '%s'\n"
-msgstr "Không thể đẩy lên mô-đun-con “%s”\n"
+msgstr "Không thể đẩy lên mô-đun-con '%s'\n"
 
 #, c-format
 msgid "Fetching submodule %s%s\n"
@@ -19913,11 +21187,11 @@
 
 #, c-format
 msgid "Could not access submodule '%s'\n"
-msgstr "Không thể truy cập mô-đun-con “%s”\n"
+msgstr "Không thể truy cập mô-đun-con '%s'\n"
 
 #, c-format
 msgid "Could not access submodule '%s' at commit %s\n"
-msgstr "Không thể truy cập mô-đun-con “%s” ở lần chuyển giao %s\n"
+msgstr "Không thể truy cập mô-đun-con '%s' ở lần chuyển giao %s\n"
 
 #, c-format
 msgid "Fetching submodule %s%s at commit %s\n"
@@ -19929,65 +21203,65 @@
 "%s"
 msgstr ""
 "Có lỗi khi lấy về mô-đun-con:\n"
-" “%s”"
+" '%s'"
 
 #, c-format
 msgid "'%s' not recognized as a git repository"
-msgstr "không nhận ra “%s” là một kho git"
+msgstr "không nhận ra '%s' là một kho git"
 
 #, c-format
 msgid "Could not run 'git status --porcelain=2' in submodule %s"
-msgstr "Không thể chạy “git status --porcelain=2” trong mô-đun-con “%s”"
+msgstr "Không thể chạy 'git status --porcelain=2' trong mô-đun-con '%s'"
 
 #, c-format
 msgid "'git status --porcelain=2' failed in submodule %s"
-msgstr "“git status --porcelain=2” gặp lỗi trong mô-đun-con “%s”"
+msgstr "'git status --porcelain=2' gặp lỗi trong mô-đun-con '%s'"
 
 #, c-format
 msgid "could not start 'git status' in submodule '%s'"
-msgstr "không thể lấy thống kê “git status” trong mô-đun-con “%s”"
+msgstr "không thể khởi chạy 'git status' trong mô-đun-con '%s'"
 
 #, c-format
 msgid "could not run 'git status' in submodule '%s'"
-msgstr "không thể chạy “git status” trong mô-đun-con “%s”"
+msgstr "không thể chạy 'git status' trong mô-đun-con '%s'"
 
 #, c-format
 msgid "Could not unset core.worktree setting in submodule '%s'"
-msgstr "Không thể đặt core.worktree trong mô-đun-con “%s”"
+msgstr "Không thể đặt core.worktree trong mô-đun-con '%s'"
 
 #, c-format
 msgid "could not recurse into submodule '%s'"
-msgstr "không thể đệ quy vào trong mô-đun-con “%s”"
+msgstr "không thể đệ quy vào trong mô-đun-con '%s'"
 
 msgid "could not reset submodule index"
-msgstr "không thể đặt lại mục lục của mô-đun-con"
+msgstr "không thể đặt lại chỉ mục của mô-đun-con"
 
 #, c-format
 msgid "submodule '%s' has dirty index"
-msgstr "mô-đun-con “%s” có mục lục còn bẩn"
+msgstr "mô-đun-con '%s' có chỉ mục không sạch"
 
 #, c-format
 msgid "Submodule '%s' could not be updated."
-msgstr "Mô-đun-con “%s” không thể được cập nhật."
+msgstr "Mô-đun-con '%s' không thể được cập nhật."
 
 #, c-format
 msgid "submodule git dir '%s' is inside git dir '%.*s'"
-msgstr "thư mục git mô đun con “%s” là bên trong git DIR “%.*s”"
+msgstr "thư mục git mô đun con '%s' là bên trong git DIR '%.*s'"
 
 #, c-format
 msgid ""
 "relocate_gitdir for submodule '%s' with more than one worktree not supported"
 msgstr ""
-"relocate_gitdir cho mô-đun-con “%s” với nhiều hơn một cây làm việc là chưa "
+"relocate_gitdir cho mô-đun-con '%s' với nhiều hơn một cây làm việc là chưa "
 "được hỗ trợ"
 
 #, c-format
 msgid "could not lookup name for submodule '%s'"
-msgstr "không thể tìm kiếm tên cho mô-đun-con “%s”"
+msgstr "không thể tìm kiếm tên cho mô-đun-con '%s'"
 
 #, c-format
 msgid "refusing to move '%s' into an existing git dir"
-msgstr "từ chối di chuyển “%s” vào trong một thư mục git sẵn có"
+msgstr "từ chối di chuyển '%s' vào trong một thư mục git sẵn có"
 
 #, c-format
 msgid ""
@@ -19995,12 +21269,12 @@
 "'%s' to\n"
 "'%s'\n"
 msgstr ""
-"Di cư thư mục git của “%s%s” từ\n"
-"“%s” sang\n"
-"“%s”\n"
+"Di cư thư mục git của '%s%s' từ\n"
+"'%s' sang\n"
+"'%s'\n"
 
 msgid "could not start ls-files in .."
-msgstr "không thể lấy thông tin thống kê về ls-files trong .."
+msgstr "không thể khởi chạy ls-files trong .."
 
 #, c-format
 msgid "ls-tree returned unexpected return code %d"
@@ -20008,13 +21282,26 @@
 
 #, c-format
 msgid "failed to lstat '%s'"
-msgstr "gặp lỗi khi lstat “%s”"
+msgstr "gặp lỗi khi lstat '%s'"
 
-msgid "unhandled options"
-msgstr "các tùy chọn được không xử lý"
+msgid "no remote configured to get bundle URIs from"
+msgstr "không có máy chủ để lấy URI bundle"
 
-msgid "error preparing revisions"
-msgstr "gặp lỗi khi chuẩn bị các điểm xét duyệt"
+#, c-format
+msgid "remote '%s' has no configured URL"
+msgstr "máy chủ '%s' không có cấu hình URL"
+
+msgid "could not get the bundle-uri list"
+msgstr "không thể lấy về danh sách bundle-uri"
+
+msgid "test-tool cache-tree <options> (control|prime|update)"
+msgstr "test-tool cache-tree <các tuỳ chọn> (control|prime|update)"
+
+msgid "clear the cache tree before each iteration"
+msgstr "dọn cây nhớ tạm trước mỗi chu kỳ"
+
+msgid "number of entries in the cache tree to invalidate (default 0)"
+msgstr "số mục cần huỷ trong câu nhớ tạm (mặc định 0)"
 
 #, c-format
 msgid "commit %s is not marked reachable"
@@ -20027,7 +21314,7 @@
 msgstr "test-tool serve-v2 [<các tùy chọn>]"
 
 msgid "exit immediately after advertising capabilities"
-msgstr "thoát ngay sau khi khởi tạo quảng cáo capabilities"
+msgstr "thoát ngay sau khi quảng bá capabilities"
 
 msgid "test-helper simple-ipc is-active    [<name>] [<options>]"
 msgstr "test-helper simple-ipc is-active    [<tên>] [<các tùy chọn>]"
@@ -20062,7 +21349,7 @@
 msgstr "tên named-pipe"
 
 msgid "number of threads in server thread pool"
-msgstr "số lượng tiến trình trong kho tiến trình máy phục vụ"
+msgstr "số lượng tiến trình trong kho tiến trình máy chủ"
 
 msgid "seconds to wait for daemon to start or stop"
 msgstr "số giây mà dịch vụ chạy nền chờ khi khởi động hoặc dừng"
@@ -20083,67 +21370,44 @@
 msgstr "thẻ bài"
 
 msgid "command token to send to the server"
-msgstr "thẻ bài lệnh để gửi lên cho máy phục vụ"
+msgstr "thẻ bài lệnh để gửi lên cho máy chủ"
 
 #, c-format
 msgid "running trailer command '%s' failed"
-msgstr "chạy lệnh kéo theo “%s” gặp lỗi"
+msgstr "chạy lệnh kéo theo '%s' gặp lỗi"
 
 #, c-format
 msgid "unknown value '%s' for key '%s'"
-msgstr "không hiểu giá trị “%s” cho khóa “%s”"
+msgstr "không hiểu giá trị '%s' cho khóa '%s'"
 
 #, c-format
 msgid "empty trailer token in trailer '%.*s'"
-msgstr "thẻ thừa trống rỗng trong phần thừa “%.*s”"
-
-#, c-format
-msgid "could not read input file '%s'"
-msgstr "không đọc được tập tin đầu vào “%s”"
-
-#, c-format
-msgid "could not stat %s"
-msgstr "không thể lấy thông tin thống kê về %s"
-
-#, c-format
-msgid "file %s is not a regular file"
-msgstr "\"%s\" không phải là tập tin bình thường"
-
-#, c-format
-msgid "file %s is not writable by user"
-msgstr "tập tin %s người dùng không thể ghi được"
-
-msgid "could not open temporary file"
-msgstr "không thể tạo tập tin tạm thời"
-
-#, c-format
-msgid "could not rename temporary file to %s"
-msgstr "không thể đổi tên tập tin tạm thời thành %s"
+msgstr "thẻ thừa trống rỗng trong phần thừa '%.*s'"
 
 msgid "full write to remote helper failed"
-msgstr "ghi đầy đủ lên bộ hỗ trợ máy chủ gặp lỗi"
+msgstr "ghi đầy đủ lên helper máy chủ gặp lỗi"
 
 #, c-format
 msgid "unable to find remote helper for '%s'"
-msgstr "không thể tìm thấy bộ hỗ trợ máy chủ cho “%s”"
+msgstr "không thể tìm thấy helper máy chủ cho '%s'"
 
 msgid "can't dup helper output fd"
-msgstr "không thể nhân đôi fd dầu ra bộ hỗ trợ"
+msgstr "không thể nhân đôi fd dầu ra helper"
 
 #, c-format
 msgid ""
 "unknown mandatory capability %s; this remote helper probably needs newer "
 "version of Git"
 msgstr ""
-"không hiểu capability bắt buộc %s; bộ hỗ trợ máy chủ này gần như chắc chắn "
-"là cần phiên bản Git mới hơn"
+"không hiểu capability bắt buộc %s; helper máy chủ này gần như chắc chắn là "
+"cần phiên bản Git mới hơn"
 
 msgid "this remote helper should implement refspec capability"
-msgstr "bộ hỗ trợ máy chủ này cần phải thực thi capability đặc tả tham chiếu"
+msgstr "remote helper này cần hỗ trợ capability đặc tả tham chiếu"
 
 #, c-format
 msgid "%s unexpectedly said: '%s'"
-msgstr "%s said bất ngờ: “%s”"
+msgstr "%s bất ngờ trả lời: '%s'"
 
 #, c-format
 msgid "%s also locked %s"
@@ -20169,9 +21433,6 @@
 msgid "invalid remote service path"
 msgstr "đường dẫn dịch vụ máy chủ không hợp lệ"
 
-msgid "operation not supported by protocol"
-msgstr "thao tác không được gia thức hỗ trợ"
-
 #, c-format
 msgid "can't connect to subservice %s"
 msgstr "không thể kết nối đến dịch vụ phụ %s"
@@ -20180,15 +21441,15 @@
 msgstr "--negotiate-only cần giao thức v2"
 
 msgid "'option' without a matching 'ok/error' directive"
-msgstr "“option” không có chỉ thị “ok/error” tương ứng"
+msgstr "'option' không có chỉ thị 'ok/error' tương ứng"
 
 #, c-format
 msgid "expected ok/error, helper said '%s'"
-msgstr "cần ok/error, nhưng bộ hỗ trợ lại nói “%s”"
+msgstr "cần ok/error, nhưng helper lại nói '%s'"
 
 #, c-format
 msgid "helper reported unexpected status of %s"
-msgstr "bộ hỗ trợ báo cáo rằng không cần tình trạng của %s"
+msgstr "helper báo cáo tình trạng bất thường của %s"
 
 #, c-format
 msgid "helper %s does not support dry-run"
@@ -20212,14 +21473,14 @@
 
 #, c-format
 msgid "helper %s does not support 'push-option'"
-msgstr "helper %s không hỗ trợ “push-option”"
+msgstr "helper %s không hỗ trợ 'push-option'"
 
 msgid "remote-helper doesn't support push; refspec needed"
 msgstr "remote-helper không hỗ trợ push; cần đặc tả tham chiếu"
 
 #, c-format
-msgid "helper %s does not support 'force'"
-msgstr "helper %s không hỗ trợ “force”"
+msgid "helper %s does not support '--force'"
+msgstr "helper %s không hỗ trợ '--force'"
 
 msgid "couldn't run fast-export"
 msgstr "không thể chạy fast-export"
@@ -20238,7 +21499,7 @@
 
 #, c-format
 msgid "unsupported object format '%s'"
-msgstr "không hỗ trợ định dạng đối tượng “%s”"
+msgstr "không hỗ trợ định dạng đối tượng '%s'"
 
 #, c-format
 msgid "malformed response in ref list: %s"
@@ -20277,18 +21538,18 @@
 
 #, c-format
 msgid "Would set upstream of '%s' to '%s' of '%s'\n"
-msgstr "Không thể đặt thượng nguồn của “%s” thành “%s” của “%s”\n"
+msgstr "Không thể đặt thượng nguồn của '%s' thành '%s' của '%s'\n"
 
 #, c-format
 msgid "could not read bundle '%s'"
-msgstr "không thể đọc bó “%s”"
+msgstr "không thể đọc bó '%s'"
 
 #, c-format
 msgid "transport: invalid depth option '%s'"
-msgstr "vận chuyển: tùy chọn độ sâu “%s” không hợp lệ"
+msgstr "vận chuyển: tùy chọn độ sâu '%s' không hợp lệ"
 
 msgid "see protocol.version in 'git help config' for more details"
-msgstr "xem protocol.version trong “git help config” để có thêm thông tin"
+msgstr "xem protocol.version trong 'git help config' để có thêm thông tin"
 
 msgid "server options require protocol version 2 or later"
 msgstr "các tùy chọn máy chủ yêu cầu giao thức phiên bản 2 hoặc mới hơn"
@@ -20297,18 +21558,14 @@
 msgstr "máy chủ không hỗ trợ wait-for-done"
 
 msgid "could not parse transport.color.* config"
-msgstr "không thể phân tích cú pháp cấu hình transport.color.*"
+msgstr "không hiểu cú pháp cấu hình transport.color.*"
 
 msgid "support for protocol v2 not implemented yet"
-msgstr "việc hỗ trợ giao thức v2 chưa được thực hiện"
-
-#, c-format
-msgid "unknown value for config '%s': %s"
-msgstr "không hiểu giá trị cho cho cấu hình “%s”: %s"
+msgstr "chưa hỗ trợ giao thức v2"
 
 #, c-format
 msgid "transport '%s' not allowed"
-msgstr "không cho phép phương thức vận chuyển “%s”"
+msgstr "không cho phép phương thức vận chuyển '%s'"
 
 msgid "git-over-rsync is no longer supported"
 msgstr "git-over-rsync không còn được hỗ trợ nữa"
@@ -20319,7 +21576,7 @@
 "not be found on any remote:\n"
 msgstr ""
 "Các đường dẫn mô-đun-con sau đây có chứa các thay đổi cái mà\n"
-"có thể được tìm thấy trên mọi máy phục vụ:\n"
+"có thể được tìm thấy trên mọi máy chủ:\n"
 
 #, c-format
 msgid ""
@@ -20344,20 +21601,29 @@
 "\n"
 "\tgit push\n"
 "\n"
-"để đẩy chúng lên máy phục vụ.\n"
+"để đẩy chúng lên máy chủ.\n"
 "\n"
 
 msgid "Aborting."
-msgstr "Bãi bỏ."
+msgstr "huỷ bỏ."
 
 msgid "failed to push all needed submodules"
 msgstr "gặp lỗi khi đẩy dữ liệu của tất cả các mô-đun-con cần thiết"
 
+msgid "bundle-uri operation not supported by protocol"
+msgstr "thao tác bundle-uri không được giao thức hỗ trợ"
+
+msgid "could not retrieve server-advertised bundle-uri list"
+msgstr "không thể lấy về danh sách bundle-uri do phía máy chủ quảng bá"
+
+msgid "operation not supported by protocol"
+msgstr "thao tác không được giao thức hỗ trợ"
+
 msgid "too-short tree object"
 msgstr "đối tượng cây quá ngắn"
 
 msgid "malformed mode in tree entry"
-msgstr "chế độ dị hình trong đề mục cây"
+msgstr "chế độ sai quy cách trong đề mục cây"
 
 msgid "empty filename in tree entry"
 msgstr "tên tập tin trống rỗng trong mục tin cây"
@@ -20452,7 +21718,7 @@
 "The following untracked working tree files would be removed by checkout:\n"
 "%%s"
 msgstr ""
-"Các tập tin cây làm việc chưa được theo dõi sau đây sẽ bị gỡ bỏ bởi lệnh "
+"Các tập tin trong cây làm việc chưa được theo dõi sau sẽ bị xoá bỏ bởi lệnh "
 "checkout:\n"
 "%%s"
 
@@ -20461,17 +21727,17 @@
 "The following untracked working tree files would be removed by merge:\n"
 "%%sPlease move or remove them before you merge."
 msgstr ""
-"Các tập tin cây làm việc chưa được theo dõi sau đây sẽ bị gỡ bỏ bởi lệnh hòa "
-"trộn:\n"
-"%%sVui lòng di chuyển hay gỡ bỏ chúng trước khi bạn hòa trộn."
+"Các tập tin trong cây làm việc chưa được theo dõi sau sẽ bị xoá bỏ bởi lệnh "
+"hòa trộn:\n"
+"%%sVui lòng di chuyển hay xoá bỏ chúng trước khi bạn hòa trộn."
 
 #, c-format
 msgid ""
 "The following untracked working tree files would be removed by merge:\n"
 "%%s"
 msgstr ""
-"Các tập tin cây làm việc chưa được theo dõi sau đây sẽ bị gỡ bỏ bởi lệnh hòa "
-"trộn:\n"
+"Các tập tin trong cây làm việc chưa được theo dõi sau sẽ bị xoá bỏ bởi lệnh "
+"hòa trộn:\n"
 "%%s"
 
 #, c-format
@@ -20479,15 +21745,15 @@
 "The following untracked working tree files would be removed by %s:\n"
 "%%sPlease move or remove them before you %s."
 msgstr ""
-"Các tập tin cây làm việc chưa được theo dõi sau đây sẽ bị gỡ bỏ bởi %s:\n"
-"%%sVui lòng di chuyển hay gỡ bỏ chúng trước khi bạn %s."
+"Các tập tin trong cây làm việc chưa được theo dõi sau sẽ bị xoá bỏ bởi %s:\n"
+"%%sVui lòng di chuyển hay xoá bỏ chúng trước khi bạn %s."
 
 #, c-format
 msgid ""
 "The following untracked working tree files would be removed by %s:\n"
 "%%s"
 msgstr ""
-"Các tập tin cây làm việc chưa được theo dõi sau đây sẽ bị gỡ bỏ bởi %s:\n"
+"Các tập tin trong cây làm việc chưa được theo dõi sau sẽ bị xoá bỏ bởi %s:\n"
 "%%s"
 
 #, c-format
@@ -20496,9 +21762,9 @@
 "checkout:\n"
 "%%sPlease move or remove them before you switch branches."
 msgstr ""
-"Các tập tin cây làm việc chưa được theo dõi sau đây sẽ bị ghi đè bởi lệnh "
+"Các tập tin trong cây làm việc chưa được theo dõi sau sẽ bị ghi đè bởi lệnh "
 "checkout:\n"
-"%%sVui lòng di chuyển hay gỡ bỏ chúng trước khi bạn chuyển nhánh."
+"%%sVui lòng di chuyển hay xoá bỏ chúng trước khi bạn chuyển nhánh."
 
 #, c-format
 msgid ""
@@ -20506,7 +21772,7 @@
 "checkout:\n"
 "%%s"
 msgstr ""
-"Các tập tin cây làm việc chưa được theo dõi sau đây sẽ bị ghi đè bởi lệnh "
+"Các tập tin trong cây làm việc chưa được theo dõi sau sẽ bị ghi đè bởi lệnh "
 "checkout:\n"
 "%%s"
 
@@ -20515,16 +21781,16 @@
 "The following untracked working tree files would be overwritten by merge:\n"
 "%%sPlease move or remove them before you merge."
 msgstr ""
-"Các tập tin cây làm việc chưa được theo dõi sau đây sẽ bị ghi đè bởi lệnh "
+"Các tập tin trong cây làm việc chưa được theo dõi sau sẽ bị ghi đè bởi lệnh "
 "hòa trộn:\n"
-"%%sVui lòng di chuyển hay gỡ bỏ chúng trước khi bạn hòa trộn."
+"%%sVui lòng di chuyển hay xoá bỏ chúng trước khi bạn hòa trộn."
 
 #, c-format
 msgid ""
 "The following untracked working tree files would be overwritten by merge:\n"
 "%%s"
 msgstr ""
-"Các tập tin cây làm việc chưa được theo dõi sau đây sẽ bị ghi đè bởi lệnh "
+"Các tập tin trong cây làm việc chưa được theo dõi sau sẽ bị ghi đè bởi lệnh "
 "hòa trộn:\n"
 "%%s"
 
@@ -20533,22 +21799,22 @@
 "The following untracked working tree files would be overwritten by %s:\n"
 "%%sPlease move or remove them before you %s."
 msgstr ""
-"Các tập tin cây làm việc chưa được theo dõi sau đây sẽ bị ghi đè bởi lệnh "
+"Các tập tin trong cây làm việc chưa được theo dõi sau sẽ bị ghi đè bởi lệnh "
 "%s:\n"
-"%%sVui lòng di chuyển hay gỡ bỏ chúng trước khi bạn %s."
+"%%sVui lòng di chuyển hay xoá chúng trước khi bạn %s."
 
 #, c-format
 msgid ""
 "The following untracked working tree files would be overwritten by %s:\n"
 "%%s"
 msgstr ""
-"Các tập tin cây làm việc chưa được theo dõi sau đây sẽ bị ghi đè bởi lệnh "
+"Các tập tin trong cây làm việc chưa được theo dõi sau sẽ bị ghi đè bởi lệnh "
 "%s:\n"
 "%%s"
 
 #, c-format
 msgid "Entry '%s' overlaps with '%s'.  Cannot bind."
-msgstr "Mục “%s” đè lên “%s”. Không thể buộc."
+msgstr "Mục '%s' đè lên '%s'. Không thể bind."
 
 #, c-format
 msgid ""
@@ -20564,7 +21830,7 @@
 "patterns:\n"
 "%s"
 msgstr ""
-"Các đường dẫn sau đây không được cập nhật và vẫn được để lại bất chấp các "
+"Các đường dẫn sau đây chưa được cập nhật và vẫn được để lại mặc dù khớp các "
 "mẫu sparse:\n"
 "%s"
 
@@ -20583,21 +21849,21 @@
 "patterns:\n"
 "%s"
 msgstr ""
-"Các đường dẫn sau đây đã sẵn hiện diện và như vậy không được cập nhật bất "
-"cấp các mẫu sparse:\n"
+"Các đường dẫn sau đây đã tồn tại và như vậy không được cập nhật mặc dù khớp "
+"các mẫu sparse:\n"
 "%s"
 
 #, c-format
 msgid "Aborting\n"
-msgstr "Bãi bỏ\n"
+msgstr "Huỷ bỏ\n"
 
 #, c-format
 msgid ""
 "After fixing the above paths, you may want to run `git sparse-checkout "
 "reapply`.\n"
 msgstr ""
-"Sau khi sửa các đường dẫn phía trên, bạn có thể chạy “git sparse-checkout "
-"reapply“.\n"
+"Sau khi sửa các đường dẫn phía trên, bạn có thể chạy 'git sparse-checkout "
+"reapply'.\n"
 
 msgid "Updating files"
 msgstr "Đang cập nhật các tập tin"
@@ -20607,12 +21873,12 @@
 "on a case-insensitive filesystem) and only one from the same\n"
 "colliding group is in the working tree:\n"
 msgstr ""
-"các đường dẫn sau đây có xung đột(vd: các đường dẫn phân biệt\n"
-"HOA/thường trên một hệ thống tập tin không phân biệt HOA/thường)\n"
-"và chỉ một từ cùng một nhóm xung đột là trong cây làm việc hiện tại:\n"
+"các đường dẫn sau đây có xung đột (vd: các đường dẫn phân biệt HOA/thường\n"
+"trên hệ thống tập tin không phân biệt HOA/thường) và chỉ một đường dẫn\n"
+"trong nhóm xung đột nằm trong cây làm việc hiện tại:\n"
 
 msgid "Updating index flags"
-msgstr "Đang cập nhật các cờ mục lục"
+msgstr "Đang cập nhật các cờ chỉ mục"
 
 #, c-format
 msgid "worktree and untracked commit have duplicate entries: %s"
@@ -20623,17 +21889,17 @@
 msgstr "cần đẩy dữ liệu lên đĩa sau các tham số của lệnh fetch"
 
 msgid "invalid URL scheme name or missing '://' suffix"
-msgstr "tên lược đồ URL không hợp lệ, hoặc thiếu hậu tố “://”"
+msgstr "tên lược đồ URL không hợp lệ, hoặc thiếu hậu tố '://'"
 
 #, c-format
 msgid "invalid %XX escape sequence"
 msgstr "thoát chuỗi %XX không hợp lệ"
 
 msgid "missing host and scheme is not 'file:'"
-msgstr "thiếu máy chủ và lược đồ thì không phải là giao thức “file:”"
+msgstr "thiếu máy chủ và lược đồ không phải là 'file:'"
 
 msgid "a 'file:' URL may not have a port number"
-msgstr "một URL kiểu “file:” không được chứa cổng"
+msgstr "URL kiểu 'file:' không được chứa cổng"
 
 msgid "invalid characters in host name"
 msgstr "có các ký tự không hợp lệ trong tên máy"
@@ -20642,27 +21908,43 @@
 msgstr "tên cổng không hợp lệ"
 
 msgid "invalid '..' path segment"
-msgstr "đoạn đường dẫn “..” không hợp lệ"
+msgstr "đoạn đường dẫn '..' không hợp lệ"
+
+#, c-format
+msgid "error: unable to format message: %s\n"
+msgstr "lỗi: không thể định dạng thông điệp: %s\n"
+
+msgid "usage: "
+msgstr "cách dùng: %s"
+
+msgid "fatal: "
+msgstr "lỗi nghiêm trọng: "
+
+msgid "error: "
+msgstr "lỗi: "
+
+msgid "warning: "
+msgstr "cảnh báo: "
 
 msgid "Fetching objects"
 msgstr "Đang lấy về các đối tượng"
 
 #, c-format
 msgid "'%s' at main working tree is not the repository directory"
-msgstr "“%s” tại cây làm việc chình không phải là thư mục kho"
+msgstr "'%s' tại cây làm việc chính không phải là thư mục kho"
 
 #, c-format
 msgid "'%s' file does not contain absolute path to the working tree location"
 msgstr ""
-"tập tin “%s” không chứa đường dẫn tuyệt đối đến vị trí cây làm việc hiện"
+"tập tin '%s' không chứa đường dẫn tuyệt đối đến vị trí cây làm việc hiện"
 
 #, c-format
 msgid "'%s' is not a .git file, error code %d"
-msgstr "“%s” không phải là tập tin .git, mã lỗi %d"
+msgstr "'%s' không phải là tập tin .git, mã lỗi %d"
 
 #, c-format
 msgid "'%s' does not point back to '%s'"
-msgstr "“%s” không chỉ ngược đến “%s”"
+msgstr "'%s' không chỉ ngược đến '%s'"
 
 msgid "not a directory"
 msgstr "không phải thư mục"
@@ -20671,7 +21953,7 @@
 msgstr ".git không phải là một tập tin"
 
 msgid ".git file broken"
-msgstr "tệp .git bị hỏng"
+msgstr "tập tin .git bị hỏng"
 
 msgid ".git file incorrect"
 msgstr "tập tin .git không chính xác"
@@ -20680,13 +21962,13 @@
 msgstr "không phải là một đường dẫn hợp lệ"
 
 msgid "unable to locate repository; .git is not a file"
-msgstr "không thể phân bổ kho chứa; .git không phải là một tập tin"
+msgstr "không thể định vị kho chứa; .git không phải là một tập tin"
 
 msgid "unable to locate repository; .git file does not reference a repository"
-msgstr "không thể phân bổ kho chứa; tập tin .git tham chiếu đến một kho"
+msgstr "không thể định vị kho chứa; tập tin .git không chỉ đến một kho"
 
 msgid "unable to locate repository; .git file broken"
-msgstr "không thể phân bổ kho chứa; tập tin .git bị hỏng"
+msgstr "không thể định vị kho chứa; tập tin .git bị hỏng"
 
 msgid "gitdir unreadable"
 msgstr "gitdir không thể đọc được"
@@ -20716,7 +21998,7 @@
 
 #, c-format
 msgid "unable to set %s in '%s'"
-msgstr "không thể đặt %s trong “%s”"
+msgstr "không thể đặt %s trong '%s'"
 
 #, c-format
 msgid "unable to unset %s in '%s'"
@@ -20727,48 +22009,49 @@
 
 #, c-format
 msgid "could not setenv '%s'"
-msgstr "không thể setenv “%s”"
+msgstr "không thể setenv '%s'"
 
 #, c-format
 msgid "unable to create '%s'"
-msgstr "không thể tạo “%s”"
+msgstr "không thể tạo '%s'"
 
 #, c-format
 msgid "could not open '%s' for reading and writing"
-msgstr "không thể mở “%s” để đọc và ghi"
+msgstr "không thể mở '%s' để đọc và ghi"
 
 #, c-format
 msgid "unable to access '%s'"
-msgstr "không thể truy cập “%s”"
+msgstr "không thể truy cập '%s'"
 
 msgid "unable to get current working directory"
 msgstr "không thể lấy thư mục làm việc hiện hành"
 
+msgid "unable to get random bytes"
+msgstr "không thể lấy byte ngẫu nhiên"
+
 msgid "Unmerged paths:"
 msgstr "Những đường dẫn chưa được hòa trộn:"
 
 msgid "  (use \"git restore --staged <file>...\" to unstage)"
-msgstr "  (dùng \"git restore --staged <tập-tin>…\" để bỏ ra khỏi bệ phóng)"
+msgstr "  (dùng \"git restore --staged <tập-tin>...\" để bỏ ra khỏi bệ phóng)"
 
 #, c-format
 msgid "  (use \"git restore --source=%s --staged <file>...\" to unstage)"
 msgstr ""
-"  (dùng \"git restore --source=%s --staged <tập-tin>…\" để bỏ ra khỏi bệ "
+"  (dùng \"git restore --source=%s --staged <tập-tin>...\" để bỏ ra khỏi bệ "
 "phóng)"
 
 msgid "  (use \"git rm --cached <file>...\" to unstage)"
-msgstr "  (dùng \"git rm --cached <tập-tin>…\" để bỏ ra khỏi bệ phóng)"
+msgstr "  (dùng \"git rm --cached <tập-tin>...\" để bỏ ra khỏi bệ phóng)"
 
 msgid "  (use \"git add <file>...\" to mark resolution)"
-msgstr "  (dùng \"git add <tập-tin>…\" để đánh dấu là cần giải quyết)"
+msgstr "  (dùng \"git add <tập-tin>...\" để đánh dấu là muốn thêm)"
 
 msgid "  (use \"git add/rm <file>...\" as appropriate to mark resolution)"
-msgstr ""
-"  (dùng \"git add/rm <tập-tin>…\" như là một cách thích hợp để đánh dấu là "
-"cần được giải quyết)"
+msgstr "  (dùng \"git add/rm <tập-tin>...\" để đánh dấu là muốn thêm/xoá)"
 
 msgid "  (use \"git rm <file>...\" to mark resolution)"
-msgstr "  (dùng \"git rm <tập-tin>…\" để đánh dấu là cần giải quyết)"
+msgstr "  (dùng \"git rm <tập-tin>...\" để đánh dấu là muốn xoá)"
 
 msgid "Changes to be committed:"
 msgstr "Những thay đổi sẽ được chuyển giao:"
@@ -20777,45 +22060,46 @@
 msgstr "Các thay đổi chưa được đặt lên bệ phóng để chuyển giao:"
 
 msgid "  (use \"git add <file>...\" to update what will be committed)"
-msgstr "  (dùng \"git add <tập-tin>…\" để cập nhật những gì sẽ chuyển giao)"
+msgstr ""
+"  (dùng \"git add <tập-tin>...\" để cập nhật những gì sẽ được chuyển giao)"
 
 msgid "  (use \"git add/rm <file>...\" to update what will be committed)"
 msgstr ""
-"  (dùng \"git add/rm <tập-tin>…\" để cập nhật những gì sẽ được chuyển giao)"
+"  (dùng \"git add/rm <tập-tin>...\" để cập nhật những gì sẽ được chuyển giao)"
 
 msgid ""
 "  (use \"git restore <file>...\" to discard changes in working directory)"
 msgstr ""
-"  (dùng \"git restore <tập-tin>…\" để loại bỏ các thay đổi trong thư mục làm "
-"việc)"
+"  (dùng \"git restore <tập-tin>...\" để loại bỏ các thay đổi trong thư mục "
+"làm việc)"
 
 msgid "  (commit or discard the untracked or modified content in submodules)"
 msgstr ""
 "  (chuyển giao hoặc là loại bỏ các nội dung chưa được theo dõi hay đã sửa "
-"chữa trong mô-đun-con)"
+"trong mô-đun-con)"
 
 #, c-format
 msgid "  (use \"git %s <file>...\" to include in what will be committed)"
 msgstr ""
-"  (dùng \"git %s <tập-tin>…\" để thêm vào những gì cần được chuyển giao)"
+"  (dùng \"git %s <tập-tin>...\" để thêm vào những gì cần được chuyển giao)"
 
 msgid "both deleted:"
-msgstr "bị xóa bởi cả hai:"
+msgstr "bị cả hai xóa đi:"
 
 msgid "added by us:"
-msgstr "được thêm vào bởi chúng ta:"
+msgstr "được ta thêm vào:"
 
 msgid "deleted by them:"
-msgstr "bị xóa đi bởi họ:"
+msgstr "bị họ xóa đi:"
 
 msgid "added by them:"
-msgstr "được thêm vào bởi họ:"
+msgstr "được họ thêm vào:"
 
 msgid "deleted by us:"
-msgstr "bị xóa bởi chúng ta:"
+msgstr "bị ta xóa đi:"
 
 msgid "both added:"
-msgstr "được thêm vào bởi cả hai:"
+msgstr "được cả hai thêm vào:"
 
 msgid "both modified:"
 msgstr "bị sửa bởi cả hai:"
@@ -20836,10 +22120,10 @@
 msgstr "đã đổi tên:"
 
 msgid "typechange:"
-msgstr "đổi-kiểu:"
+msgstr "đổi kiểu:"
 
 msgid "unknown:"
-msgstr "không hiểu:"
+msgstr "không rõ:"
 
 msgid "unmerged:"
 msgstr "chưa hòa trộn:"
@@ -20856,20 +22140,20 @@
 #, c-format
 msgid "Your stash currently has %d entry"
 msgid_plural "Your stash currently has %d entries"
-msgstr[0] "Bạn hiện nay ở trong phần cất đi đang có %d mục"
+msgstr[0] "Hiện trong phần cất đi đang có %d mục"
 
 msgid "Submodules changed but not updated:"
 msgstr "Những mô-đun-con đã bị thay đổi nhưng chưa được cập nhật:"
 
 msgid "Submodule changes to be committed:"
-msgstr "Những mô-đun-con thay đổi đã được chuyển giao:"
+msgstr "Những thay đổi mô-đun-con sẽ được chuyển giao:"
 
 msgid ""
 "Do not modify or remove the line above.\n"
 "Everything below it will be ignored."
 msgstr ""
 "Không sửa hay xóa bỏ đường ở trên.\n"
-"Mọi thứ phía dưới sẽ được xóa bỏ."
+"Mọi thứ phía dưới sẽ được bỏ qua."
 
 #, c-format
 msgid ""
@@ -20878,8 +22162,8 @@
 "You can use '--no-ahead-behind' to avoid this.\n"
 msgstr ""
 "\n"
-"Nó cần %.2f giây để tính toán giá trị của trước/sau của nhánh.\n"
-"Bạn có thể dùng “--no-ahead-behind” tránh phải điều này.\n"
+"Cần tới %.2f giây để tính toán giá trị đứng trước/sau của nhánh.\n"
+"Bạn có thể dùng '--no-ahead-behind' để bỏ qua.\n"
 
 msgid "You have unmerged paths."
 msgstr "Bạn có những đường dẫn chưa được hòa trộn."
@@ -20888,7 +22172,7 @@
 msgstr "  (sửa các xung đột rồi chạy \"git commit\")"
 
 msgid "  (use \"git merge --abort\" to abort the merge)"
-msgstr "  (dùng \"git merge --abort\" để bãi bỏ việc hòa trộn)"
+msgstr "  (dùng \"git merge --abort\" để huỷ bỏ việc hòa trộn)"
 
 msgid "All conflicts fixed but you are still merging."
 msgstr "Tất cả các xung đột đã được giải quyết nhưng bạn vẫn đang hòa trộn."
@@ -20897,112 +22181,107 @@
 msgstr "  (dùng \"git commit\" để hoàn tất việc hòa trộn)"
 
 msgid "You are in the middle of an am session."
-msgstr "Bạn đang ở giữa của một phiên “am”."
+msgstr "Bạn đang trong một phiên 'am' (áp dụng bản vá từ hòm thư)."
 
 msgid "The current patch is empty."
-msgstr "Miếng vá hiện tại bị trống rỗng."
+msgstr "bản vá hiện tại bị trống."
 
 msgid "  (fix conflicts and then run \"git am --continue\")"
 msgstr "  (sửa các xung đột và sau đó chạy lệnh \"git am --continue\")"
 
 msgid "  (use \"git am --skip\" to skip this patch)"
-msgstr "  (dùng \"git am --skip\" để bỏ qua miếng vá này)"
+msgstr "  (dùng \"git am --skip\" để bỏ qua bản vá này)"
 
 msgid ""
 "  (use \"git am --allow-empty\" to record this patch as an empty commit)"
 msgstr ""
-"  (dùng \"git am --allow-empty\" ghi miếng vá này như một lần chuyển giao "
+"  (dùng \"git am --allow-empty\" để ghi bản vá này thành một lần chuyển giao "
 "rỗng)"
 
 msgid "  (use \"git am --abort\" to restore the original branch)"
-msgstr "  (dùng \"git am --abort\" để phục hồi lại nhánh nguyên thủy)"
+msgstr "  (dùng \"git am --abort\" để phục hồi lại nhánh gốc)"
 
 msgid "git-rebase-todo is missing."
 msgstr "thiếu git-rebase-todo."
 
 msgid "No commands done."
-msgstr "Không thực hiện lệnh nào."
+msgstr "Chưa thực hiện lệnh nào."
 
 #, c-format
 msgid "Last command done (%<PRIuMAX> command done):"
 msgid_plural "Last commands done (%<PRIuMAX> commands done):"
-msgstr[0] "Lệnh thực hiện cuối (%<PRIuMAX> lệnh được thực thi):"
+msgstr[0] "Lệnh thực hiện cuối (đã thực thi %<PRIuMAX> lệnh):"
 
 #, c-format
 msgid "  (see more in file %s)"
 msgstr "  (xem thêm trong %s)"
 
 msgid "No commands remaining."
-msgstr "Không có lệnh nào còn lại."
+msgstr "Không còn lệnh nào."
 
 #, c-format
 msgid "Next command to do (%<PRIuMAX> remaining command):"
 msgid_plural "Next commands to do (%<PRIuMAX> remaining commands):"
-msgstr[0] "Lệnh cần làm kế tiếp (%<PRIuMAX> lệnh còn lại):"
+msgstr[0] "Lệnh cần làm kế tiếp (còn %<PRIuMAX> lệnh):"
 
 msgid "  (use \"git rebase --edit-todo\" to view and edit)"
 msgstr "  (dùng lệnh \"git rebase --edit-todo\" để xem và sửa)"
 
 #, c-format
 msgid "You are currently rebasing branch '%s' on '%s'."
-msgstr "Bạn hiện nay đang thực hiện việc “rebase” nhánh “%s” trên “%s”."
+msgstr "Bạn hiện đang thực hiện rebase (cải tổ) nhánh '%s' lên '%s'."
 
 msgid "You are currently rebasing."
-msgstr "Bạn hiện nay đang thực hiện việc “rebase” (cải tổ)."
+msgstr "Bạn hiện đang thực hiện rebase (cải tổ)."
 
 msgid "  (fix conflicts and then run \"git rebase --continue\")"
-msgstr ""
-"  (sửa các xung đột và sau đó chạy lệnh “cải tổ” \"git rebase --continue\")"
+msgstr "  (sửa các xung đột và sau đó chạy lệnh \"git rebase --continue\")"
 
 msgid "  (use \"git rebase --skip\" to skip this patch)"
-msgstr "  (dùng lệnh “cải tổ” \"git rebase --skip\" để bỏ qua lần vá này)"
+msgstr "  (dùng lệnh \"git rebase --skip\" để bỏ qua bản vá này)"
 
 msgid "  (use \"git rebase --abort\" to check out the original branch)"
-msgstr ""
-"  (dùng lệnh “cải tổ” \"git rebase --abort\" để check-out nhánh nguyên thủy)"
+msgstr "  (dùng lệnh \"git rebase --abort\" để check-out nhánh gốc)"
 
 msgid "  (all conflicts fixed: run \"git rebase --continue\")"
 msgstr ""
-"  (khi tất cả các xung đột đã sửa xong: chạy lệnh “cải tổ” \"git rebase --"
-"continue\")"
+"  (khi tất cả các xung đột đã sửa xong: chạy lệnh \"git rebase --continue\")"
 
 #, c-format
 msgid ""
 "You are currently splitting a commit while rebasing branch '%s' on '%s'."
 msgstr ""
-"Bạn hiện nay đang thực hiện việc chia tách một lần chuyển giao trong khi "
-"đang “rebase” nhánh “%s” trên “%s”."
+"Bạn hiện đang chia nhỏ một lần chuyển giao trong khi đang rebase nhánh '%s' "
+"lên '%s'."
 
 msgid "You are currently splitting a commit during a rebase."
 msgstr ""
-"Bạn hiện tại đang cắt đôi một lần chuyển giao trong khi đang thực hiện việc "
-"rebase."
+"Bạn hiện đang chia nhỏ một lần chuyển giao trong khi đang thực hiện rebase."
 
 msgid "  (Once your working directory is clean, run \"git rebase --continue\")"
 msgstr ""
-"  (Một khi thư mục làm việc của bạn đã gọn gàng, chạy lệnh “cải tổ” \"git "
-"rebase --continue\")"
+"  (Sau khi thư mục làm việc đã ổn, chạy lệnh \"git rebase --continue\")"
 
 #, c-format
 msgid "You are currently editing a commit while rebasing branch '%s' on '%s'."
 msgstr ""
-"Bạn hiện nay đang thực hiện việc sửa chữa một lần chuyển giao trong khi đang "
-"rebase nhánh “%s” trên “%s”."
+"Bạn hiện đang thực hiện sửa chữa một lần chuyển giao trong khi đang rebase "
+"nhánh '%s' lên '%s'."
 
 msgid "You are currently editing a commit during a rebase."
-msgstr "Bạn hiện đang sửa một lần chuyển giao trong khi bạn thực hiện rebase."
+msgstr "Bạn hiện đang sửa một lần chuyển giao trong khi đang thực hiện rebase."
 
 msgid "  (use \"git commit --amend\" to amend the current commit)"
-msgstr "  (dùng \"git commit --amend\" để “tu bổ” lần chuyển giao hiện tại)"
+msgstr "  (dùng \"git commit --amend\" để tu bổ lần chuyển giao hiện tại)"
 
 msgid ""
 "  (use \"git rebase --continue\" once you are satisfied with your changes)"
 msgstr ""
-"  (chạy lệnh “cải tổ” \"git rebase --continue\" một khi bạn cảm thấy hài "
-"lòng về những thay đổi của mình)"
+"  (chạy lệnh \"git rebase --continue\" khi bạn cảm thấy hài lòng về những "
+"thay đổi của mình)"
 
 msgid "Cherry-pick currently in progress."
-msgstr "Cherry-pick hiện tại đang được thực hiện."
+msgstr "Cherry-pick hiện đang được thực hiện."
 
 #, c-format
 msgid "You are currently cherry-picking commit %s."
@@ -21021,17 +22300,17 @@
 "continue\")"
 
 msgid "  (use \"git cherry-pick --skip\" to skip this patch)"
-msgstr "  (dùng \"git cherry-pick --skip\" để bỏ qua miếng vá này)"
+msgstr "  (dùng \"git cherry-pick --skip\" để bỏ qua bản vá này)"
 
 msgid "  (use \"git cherry-pick --abort\" to cancel the cherry-pick operation)"
 msgstr "  (dùng \"git cherry-pick --abort\" để hủy bỏ thao tác cherry-pick)"
 
 msgid "Revert currently in progress."
-msgstr "Hoàn nguyên hiện tại đang thực hiện."
+msgstr "Hoàn nguyên hiện đang được thực hiện."
 
 #, c-format
 msgid "You are currently reverting commit %s."
-msgstr "Bạn hiện nay đang thực hiện thao tác hoàn nguyên lần chuyển giao “%s”."
+msgstr "Bạn hiện nay đang thực hiện thao tác hoàn nguyên lần chuyển giao '%s'."
 
 msgid "  (fix conflicts and run \"git revert --continue\")"
 msgstr "  (sửa các xung đột và sau đó chạy lệnh \"git revert --continue\")"
@@ -21053,7 +22332,7 @@
 msgid "You are currently bisecting, started from branch '%s'."
 msgstr ""
 "Bạn hiện nay đang thực hiện thao tác di chuyển nửa bước (bisect), bắt đầu từ "
-"nhánh “%s”."
+"nhánh '%s'."
 
 msgid "You are currently bisecting."
 msgstr "Bạn hiện tại đang thực hiện việc bisect (di chuyển nửa bước)."
@@ -21062,19 +22341,18 @@
 msgstr "  (dùng \"git bisect reset\" để quay trở lại nhánh nguyên thủy)"
 
 msgid "You are in a sparse checkout."
-msgstr "Bạn đang trong lần lấy ra sparse."
+msgstr "Bạn đang ở trong lần checkout thưa."
 
 #, c-format
 msgid "You are in a sparse checkout with %d%% of tracked files present."
 msgstr ""
-"Bạn đang ở trong lần lấy ra sparser %d%% của các tập tin được theo dõi hiện "
-"tại."
+"Bạn đang ở trong lần checkout thưa với %d%% tập tin hiện được theo dõi."
 
 msgid "On branch "
 msgstr "Trên nhánh "
 
 msgid "interactive rebase in progress; onto "
-msgstr "rebase ở chế độ tương tác đang được thực hiện; lên trên "
+msgstr "rebase có tương tác đang được thực hiện; lên trên "
 
 msgid "rebase in progress; onto "
 msgstr "rebase đang được thực hiện: lên trên "
@@ -21098,33 +22376,37 @@
 msgstr "Những tập tin chưa được theo dõi"
 
 msgid "Ignored files"
-msgstr "Những tập tin bị lờ đi"
+msgstr "Những tập tin bị bỏ qua"
 
 #, 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')."
+"It took %.2f seconds to enumerate untracked files,\n"
+"but the results were cached, and subsequent runs may be faster."
 msgstr ""
-"Cần %.2f giây để liệt kê tất cả các tập tin chưa được theo dõi. “status -"
-"uno”\n"
-"có lẽ làm nó nhanh hơn, nhưng bạn phải cẩn thận đừng quên mình phải\n"
-"tự thêm các tập tin mới (xem “git help status”.."
+"Cần %.2f để duyệt các tập tin không được theo dõi,\n"
+"nhưng đã ghi nhớ kết quả, và các lần chạy sau sẽ nhanh hơn."
+
+#, c-format
+msgid "It took %.2f seconds to enumerate untracked files."
+msgstr "Cần %.2f để duyệt các tập tin không được theo dõi."
+
+msgid "See 'git help status' for information on how to improve this."
+msgstr "Xem 'git help status' để biết cách cải thiện việc này."
 
 #, c-format
 msgid "Untracked files not listed%s"
-msgstr "Những tập tin chưa được theo dõi không được liệt kê ra %s"
+msgstr "Không liệt kê những tập tin chưa được theo dõi%s"
 
 msgid " (use -u option to show untracked files)"
-msgstr " (dùng tùy chọn -u để hiển thị các tập tin chưa được theo dõi)"
+msgstr " (dùng tùy chọn -u để hiển thị những tập tin chưa được theo dõi)"
 
 msgid "No changes"
-msgstr "Không có thay đổi nào"
+msgstr "Không có thay đổi"
 
 #, c-format
 msgid "no changes added to commit (use \"git add\" and/or \"git commit -a\")\n"
 msgstr ""
-"không có thay đổi nào được thêm vào để chuyển giao (dùng \"git add\" và/hoặc "
+"không có thay đổi nào được thêm vào để chuyển giao (dùng \"git add\" hoặc "
 "\"git commit -a\")\n"
 
 #, c-format
@@ -21136,14 +22418,14 @@
 "nothing added to commit but untracked files present (use \"git add\" to "
 "track)\n"
 msgstr ""
-"không có gì được thêm vào lần chuyển giao nhưng có những tập tin chưa được "
-"theo dõi hiện diện (dùng \"git add\" để đưa vào theo dõi)\n"
+"không có gì được thêm vào để chuyển giao nhưng hiện có những tập tin chưa "
+"được theo dõi (dùng \"git add\" để đưa vào theo dõi)\n"
 
 #, c-format
 msgid "nothing added to commit but untracked files present\n"
 msgstr ""
-"không có gì được thêm vào lần chuyển giao nhưng có những tập tin chưa được "
-"theo dõi hiện diện\n"
+"không có gì được thêm vào lần chuyển giao nhưng có những tập tin hiện chưa "
+"được theo dõi\n"
 
 #, c-format
 msgid "nothing to commit (create/copy files and use \"git add\" to track)\n"
@@ -21158,26 +22440,27 @@
 #, c-format
 msgid "nothing to commit (use -u to show untracked files)\n"
 msgstr ""
-"không có gì để chuyển giao (dùng -u xem các tập tin chưa được theo dõi)\n"
+"không có gì để chuyển giao (dùng -u để xem những tập tin chưa được theo "
+"dõi)\n"
 
 #, c-format
 msgid "nothing to commit, working tree clean\n"
 msgstr "không có gì để chuyển giao, thư mục làm việc sạch sẽ\n"
 
 msgid "No commits yet on "
-msgstr "Vẫn không thực hiện lệnh chuyển giao nào "
+msgstr "Chưa thực hiện lệnh chuyển giao nào trên"
 
 msgid "HEAD (no branch)"
 msgstr "HEAD (không nhánh)"
 
 msgid "different"
-msgstr "khác"
+msgstr "khác nhau"
 
 msgid "behind "
-msgstr "đằng sau "
+msgstr "đứng sau "
 
 msgid "ahead "
-msgstr "phía trước "
+msgstr "đứng trước "
 
 #. TRANSLATORS: the action is e.g. "pull with rebase"
 #, c-format
@@ -21185,26 +22468,29 @@
 msgstr "không thể %s: Bạn có các thay đổi chưa được đưa lên bệ phóng."
 
 msgid "additionally, your index contains uncommitted changes."
-msgstr ""
-"thêm vào đó, bảng mục lục của bạn có chứa các thay đổi chưa được chuyển giao."
+msgstr "ngoài ra, chỉ mục của bạn có chứa các thay đổi chưa được chuyển giao."
 
 #, c-format
 msgid "cannot %s: Your index contains uncommitted changes."
 msgstr ""
-"không thể %s: Mục lục của bạn có chứa các thay đổi chưa được chuyển giao."
+"không thể %s: chỉ mục của bạn có chứa các thay đổi chưa được chuyển giao."
+
+#, c-format
+msgid "unknown style '%s' given for '%s'"
+msgstr "không hiểu style '%s' cho '%s'"
 
 msgid ""
 "Error: Your local changes to the following files would be overwritten by "
 "merge"
 msgstr ""
-"Lỗi: Các thay đổi nội bộ của bạn với các tập tin sau đây sẽ bị ghi đè bởi "
-"lệnh hòa trộn"
+"Lỗi: Các thay đổi nội bộ của bạn với các tập tin sau đây sẽ bị ghi đè khi "
+"hòa trộn"
 
 msgid "Automated merge did not work."
-msgstr "Hòa trộn một cách tự động không làm việc."
+msgstr "Hòa trộn tự động không thành công."
 
 msgid "Should not be doing an octopus."
-msgstr "Không thể thực hiện một octopus."
+msgstr "Không thể thực hiện hoà trộn kiểu bạch tuộc."
 
 #, sh-format
 msgid "Unable to find common commit with $pretty_name"
@@ -21223,7 +22509,7 @@
 msgstr "Đang thử hòa trộn đơn giản với $pretty_name"
 
 msgid "Simple merge did not work, trying automatic merge."
-msgstr "Hòa trộn đơn giản không làm việc, thử hòa trộn tự động."
+msgstr "Hòa trộn đơn giản không thành công, thử hòa trộn tự động."
 
 #, sh-format
 msgid "usage: $dashless $USAGE"
@@ -21231,14 +22517,12 @@
 
 #, sh-format
 msgid "Cannot chdir to $cdup, the toplevel of the working tree"
-msgstr ""
-"Không thể chuyển thư mục (chdir) sang $cdup, thư mục ở mức cao nhất của cây "
-"làm việc"
+msgstr "Không thể chuyển thư mục sang $cdup, ở mức cao nhất của cây làm việc"
 
 #, sh-format
 msgid "fatal: $program_name cannot be used without a working tree."
 msgstr ""
-"lỗi nghiêm trọng: $program_name không thể được dùng ngoaoif thư mục làm việc."
+"lỗi nghiêm trọng: $program_name không thể được dùng ngoài thư mục làm việc."
 
 msgid "Cannot rewrite branches: You have unstaged changes."
 msgstr ""
@@ -21251,12 +22535,11 @@
 #, sh-format
 msgid "Cannot $action: Your index contains uncommitted changes."
 msgstr ""
-"Không thể $action: Mục lục của bạn có chứa các thay đổi chưa được chuyển "
+"Không thể $action: chỉ mục của bạn có chứa các thay đổi chưa được chuyển "
 "giao."
 
 msgid "Additionally, your index contains uncommitted changes."
-msgstr ""
-"Thêm vào đó, bảng mục lục của bạn có chứa các thay đổi chưa được chuyển giao."
+msgstr "Ngoài ra, chỉ mục của bạn có chứa các thay đổi chưa được chuyển giao."
 
 msgid "You need to run this command from the toplevel of the working tree."
 msgstr "Bạn cần chạy lệnh này từ thư mục ở mức cao nhất của cây làm việc."
@@ -21264,360 +22547,73 @@
 msgid "Unable to determine absolute path of git directory"
 msgstr "Không thể dò tìm đường dẫn tuyệt đối của thư mục git"
 
-#. TRANSLATORS: you can adjust this to align "git add -i" status menu
-#, perl-format
-msgid "%12s %12s %s"
-msgstr "%12s %12s %s"
-
-#, perl-format
-msgid "touched %d path\n"
-msgid_plural "touched %d paths\n"
-msgstr[0] "%d đường dẫn đã touch (chạm)\n"
-
-msgid ""
-"If the patch applies cleanly, the edited hunk will immediately be\n"
-"marked for staging."
-msgstr ""
-"Nếu miếng vá được áp dụng sạch sẽ, khúc đã sửa sẽ ngay lập tức\n"
-"được đánh dấu để chuyển lên bệ phóng."
-
-msgid ""
-"If the patch applies cleanly, the edited hunk will immediately be\n"
-"marked for stashing."
-msgstr ""
-"Nếu miếng vá được áp dụng sạch sẽ, khúc đã sửa sẽ ngay lập tức\n"
-"được đánh dấu để tạm cất."
-
-msgid ""
-"If the patch applies cleanly, the edited hunk will immediately be\n"
-"marked for unstaging."
-msgstr ""
-"Nếu miếng vá được áp dụng sạch sẽ, khúc đã sửa sẽ ngay lập tức\n"
-"được đánh dấu để bỏ chuyển lên bệ phóng."
-
-msgid ""
-"If the patch applies cleanly, the edited hunk will immediately be\n"
-"marked for applying."
-msgstr ""
-"Nếu miếng vá được áp dụng sạch sẽ, khúc đã sửa sẽ ngay lập tức\n"
-"được đánh dấu để áp dụng."
-
-msgid ""
-"If the patch applies cleanly, the edited hunk will immediately be\n"
-"marked for discarding."
-msgstr ""
-"Nếu miếng vá được áp dụng sạch sẽ, khúc đã sửa sẽ ngay lập tức\n"
-"được đánh dấu để loại bỏ."
-
-#, perl-format
-msgid "failed to open hunk edit file for writing: %s"
-msgstr "gặp lỗi khi tập tin sửa khúc để ghi: %s"
-
-#, perl-format
-msgid ""
-"---\n"
-"To remove '%s' lines, make them ' ' lines (context).\n"
-"To remove '%s' lines, delete them.\n"
-"Lines starting with %s will be removed.\n"
-msgstr ""
-"---\n"
-"Để gỡ bỏ các dòng “%s”, làm chúng thành những dòng “ “ (nội dung).\n"
-"Để xóa bỏ dòng “%s”, xóa chúng đi.\n"
-"Những dòng bắt đầu bằng %s sẽ bị loại bỏ.\n"
-
-#, perl-format
-msgid "failed to open hunk edit file for reading: %s"
-msgstr "gặp lỗi khi mở tập tin khúc để đọc: %s"
-
-msgid ""
-"y - stage this hunk\n"
-"n - do not stage this hunk\n"
-"q - quit; do not stage this hunk or any of the remaining ones\n"
-"a - stage this hunk and all later hunks in the file\n"
-"d - do not stage this hunk or any of the later hunks in the file"
-msgstr ""
-"y - đưa lên bệ phóng khúc này\n"
-"n - đừng đưa lên bệ phóng khúc này\n"
-"q - thoát; đừng đưa lên bệ phóng khúc này cũng như bất kỳ cái nào còn lại\n"
-"a - đưa lên bệ phóng khúc này và tất cả các khúc sau này trong tập tin\n"
-"d - đừng đưa lên bệ phóng khúc này cũng như bất kỳ cái nào còn lại trong tập "
-"tin"
-
-msgid ""
-"y - stash this hunk\n"
-"n - do not stash this hunk\n"
-"q - quit; do not stash this hunk or any of the remaining ones\n"
-"a - stash this hunk and all later hunks in the file\n"
-"d - do not stash this hunk or any of the later hunks in the file"
-msgstr ""
-"y - tạm cất khúc này\n"
-"n - đừng tạm cất khúc này\n"
-"q - thoát; đừng tạm cất khúc này cũng như bất kỳ cái nào còn lại\n"
-"a - tạm cất khúc này và tất cả các khúc sau này trong tập tin\n"
-"d - đừng tạm cất khúc này cũng như bất kỳ cái nào còn lại trong tập tin"
-
-msgid ""
-"y - unstage this hunk\n"
-"n - do not unstage this hunk\n"
-"q - quit; do not unstage this hunk or any of the remaining ones\n"
-"a - unstage this hunk and all later hunks in the file\n"
-"d - do not unstage this hunk or any of the later hunks in the file"
-msgstr ""
-"y - đưa ra khỏi bệ phóng khúc này\n"
-"n - đừng đưa ra khỏi bệ phóng khúc này\n"
-"q - thoát; đừng đưa ra khỏi bệ phóng khúc này cũng như bất kỳ cái nào còn "
-"lại\n"
-"a - đưa ra khỏi bệ phóng khúc này và tất cả các khúc sau này trong tập tin\n"
-"d - đừng đưa ra khỏi bệ phóng khúc này cũng như bất kỳ cái nào còn lại trong "
-"tập tin"
-
-msgid ""
-"y - apply this hunk to index\n"
-"n - do not apply this hunk to index\n"
-"q - quit; do not apply this hunk or any of the remaining ones\n"
-"a - apply this hunk and all later hunks in the file\n"
-"d - do not apply this hunk or any of the later hunks in the file"
-msgstr ""
-"y - áp dụng khúc này vào mục lục\n"
-"n - đừng áp dụng khúc này vào mục lục\n"
-"q - thoát; đừng áp dụng khúc này cũng như bất kỳ cái nào còn lại\n"
-"a - áp dụng khúc này và tất cả các khúc sau này trong tập tin\n"
-"d - đừng áp dụng khúc này cũng như bất kỳ cái nào sau này trong tập tin"
-
-msgid ""
-"y - discard this hunk from worktree\n"
-"n - do not discard this hunk from worktree\n"
-"q - quit; do not discard this hunk or any of the remaining ones\n"
-"a - discard this hunk and all later hunks in the file\n"
-"d - do not discard this hunk or any of the later hunks in the file"
-msgstr ""
-"y - loại bỏ khúc này khỏi cây làm việc\n"
-"n - đừng loại bỏ khúc khỏi cây làm việc\n"
-"q - thoát; đừng loại bỏ khúc này cũng như bất kỳ cái nào còn lại\n"
-"a - loại bỏ khúc này và tất cả các khúc sau này trong tập tin\n"
-"d - đừng loại bỏ khúc này cũng như bất kỳ cái nào sau này trong tập tin"
-
-msgid ""
-"y - discard this hunk from index and worktree\n"
-"n - do not discard this hunk from index and worktree\n"
-"q - quit; do not discard this hunk or any of the remaining ones\n"
-"a - discard this hunk and all later hunks in the file\n"
-"d - do not discard this hunk or any of the later hunks in the file"
-msgstr ""
-"y - loại bỏ khúc này khỏi mục lục và cây làm việc\n"
-"n - đừng loại bỏ khúc khỏi mục lục và cây làm việc\n"
-"q - thoát; đừng loại bỏ khúc này cũng như bất kỳ cái nào còn lại\n"
-"a - loại bỏ khúc này và tất cả các khúc sau này trong tập tin\n"
-"d - đừng loại bỏ khúc này cũng như bất kỳ cái nào sau này trong tập tin"
-
-msgid ""
-"y - apply this hunk to index and worktree\n"
-"n - do not apply this hunk to index and worktree\n"
-"q - quit; do not apply this hunk or any of the remaining ones\n"
-"a - apply this hunk and all later hunks in the file\n"
-"d - do not apply this hunk or any of the later hunks in the file"
-msgstr ""
-"y - áp dụng khúc này vào mục lục và cây làm việc\n"
-"n - đừng áp dụng khúc vào mục lục và cây làm việc\n"
-"q - thoát; đừng áp dụng khúc này cũng như bất kỳ cái nào còn lại\n"
-"a - áp dụng khúc này và tất cả các khúc sau này trong tập tin\n"
-"d - đừng áp dụng khúc này cũng như bất kỳ cái nào sau này trong tập tin"
-
-msgid ""
-"y - apply this hunk to worktree\n"
-"n - do not apply this hunk to worktree\n"
-"q - quit; do not apply this hunk or any of the remaining ones\n"
-"a - apply this hunk and all later hunks in the file\n"
-"d - do not apply this hunk or any of the later hunks in the file"
-msgstr ""
-"y - áp dụng khúc này vào cây làm việc\n"
-"n - đừng áp dụng khúc vào cây làm việc\n"
-"q - thoát; đừng áp dụng khúc này cũng như bất kỳ cái nào còn lại\n"
-"a - áp dụng khúc này và tất cả các khúc sau này trong tập tin\n"
-"d - đừng áp dụng khúc này cũng như bất kỳ cái nào sau này trong tập tin"
-
-msgid ""
-"g - select a hunk to go to\n"
-"/ - search for a hunk matching the given regex\n"
-"j - leave this hunk undecided, see next undecided hunk\n"
-"J - leave this hunk undecided, see next hunk\n"
-"k - leave this hunk undecided, see previous undecided hunk\n"
-"K - leave this hunk undecided, see previous hunk\n"
-"s - split the current hunk into smaller hunks\n"
-"e - manually edit the current hunk\n"
-"? - print help\n"
-msgstr ""
-"g - chọn một khúc muốn tới\n"
-"/ - tìm một khúc khớp với biểu thức chính quy đưa ra\n"
-"j - để lại khúc này là chưa quyết định, xem khúc chưa quyết định kế\n"
-"J - để lại khúc này là chưa quyết định, xem khúc kế\n"
-"k - để lại khúc này là chưa quyết định, xem khúc chưa quyết định kế trước\n"
-"K - để lại khúc này là chưa quyết định, xem khúc kế trước\n"
-"s - chia khúc hiện tại thành các khúc nhỏ hơn\n"
-"e - sửa bằng tay khúc hiện hành\n"
-"? - in trợ giúp\n"
-
-msgid "The selected hunks do not apply to the index!\n"
-msgstr "Các khúc đã chọn không được áp dụng vào bảng mục lục!\n"
-
-#, perl-format
-msgid "ignoring unmerged: %s\n"
-msgstr "bỏ qua những thứ chưa hòa trộn: %s\n"
-
-#, perl-format
-msgid "Apply mode change to worktree [y,n,q,a,d%s,?]? "
-msgstr "Áp dụng thay đổi chế độ cho cây làm việc [y,n,q,a,d%s,?]? "
-
-#, perl-format
-msgid "Apply deletion to worktree [y,n,q,a,d%s,?]? "
-msgstr "Áp dụng việc xóa cho cây làm việc [y,n,q,a,d%s,?]? "
-
-#, perl-format
-msgid "Apply addition to worktree [y,n,q,a,d%s,?]? "
-msgstr "Áp dụng việc thêm cho cây làm việc [y,n,q,a,d%s,?]? "
-
-#, perl-format
-msgid "Apply this hunk to worktree [y,n,q,a,d%s,?]? "
-msgstr "Áp dụng khúc này vào cây làm việc [y,n,q,a,d%s,?]? "
-
-msgid "No other hunks to goto\n"
-msgstr "Không còn khúc nào để mà nhảy đến\n"
-
-#, perl-format
-msgid "Invalid number: '%s'\n"
-msgstr "Số không hợp lệ: “%s”\n"
-
-#, perl-format
-msgid "Sorry, only %d hunk available.\n"
-msgid_plural "Sorry, only %d hunks available.\n"
-msgstr[0] "Rất tiếc, chỉ có sẵn %d khúc.\n"
-
-msgid "No other hunks to search\n"
-msgstr "Không còn khúc nào để mà tìm kiếm\n"
-
-#, perl-format
-msgid "Malformed search regexp %s: %s\n"
-msgstr "Định dạng tìm kiếm của biểu thức chính quy không đúng %s: %s\n"
-
-msgid "No hunk matches the given pattern\n"
-msgstr "Không thấy khúc nào khớp mẫu đã cho\n"
-
-msgid "No previous hunk\n"
-msgstr "Không có khúc kế trước\n"
-
-msgid "No next hunk\n"
-msgstr "Không có khúc kế tiếp\n"
-
-msgid "Sorry, cannot split this hunk\n"
-msgstr "Rất tiếc, không thể chia nhỏ khúc này\n"
-
-#, perl-format
-msgid "Split into %d hunk.\n"
-msgid_plural "Split into %d hunks.\n"
-msgstr[0] "Chi nhỏ thành %d khúc.\n"
-
-msgid "Sorry, cannot edit this hunk\n"
-msgstr "Rất tiếc, không thể sửa khúc này\n"
-
-#. TRANSLATORS: please do not translate the command names
-#. 'status', 'update', 'revert', etc.
-msgid ""
-"status        - show paths with changes\n"
-"update        - add working tree state to the staged set of changes\n"
-"revert        - revert staged set of changes back to the HEAD version\n"
-"patch         - pick hunks and update selectively\n"
-"diff          - view diff between HEAD and index\n"
-"add untracked - add contents of untracked files to the staged set of "
-"changes\n"
-msgstr ""
-"status        - hiển thị các đường dẫn với các thay đổi\n"
-"update        - đặt trạng thái cây làm việc thành tập hợp các thay đổi đã "
-"đặt lên bệ phóng\n"
-"revert        - hoàn nguyên tập hợp các thay đổi đã đặt lên bệ phóng trở lại "
-"phiên bản HEAD\n"
-"patch         - cậy các khúc và cập nhật có lựa chọn\n"
-"diff\t      - xem khác biệt giữa HEAD và mục lục\n"
-"add untracked - thêm nội dung các các tập tin chưa theo dõi và tập hợp các "
-"thay đổi đã đặt lên bệ phóng\n"
-
-msgid "missing --"
-msgstr "thiếu --"
-
-#, perl-format
-msgid "unknown --patch mode: %s"
-msgstr "không hiểu chế độ --patch: %s"
-
-#, perl-format
-msgid "invalid argument %s, expecting --"
-msgstr "đối số không hợp lệ %s, cần --"
-
 msgid "local zone differs from GMT by a non-minute interval\n"
-msgstr "múi giờ nội bộ khác biệt với GMT bởi khoảng thời gian không-phút\n"
+msgstr "múi giờ nội bộ lệch với GMT một khoảng thời gian không-tròn-phút\n"
 
 msgid "local time offset greater than or equal to 24 hours\n"
-msgstr "khoảng bù thời gian nội bộ lớn hơn hoặc bằng 24 giờ\n"
+msgstr "độ lệch thời gian nội bộ lớn hơn hoặc bằng 24 giờ\n"
 
 #, perl-format
 msgid "fatal: command '%s' died with exit code %d"
-msgstr "lỗi nghiêm trọng: lệnh “%s” chết với mã thoát %d"
+msgstr "lỗi nghiêm trọng: lệnh '%s' đã thoát với mã %d"
 
 msgid "the editor exited uncleanly, aborting everything"
-msgstr "trình soạn thảo thoát không sạch sẽ, bãi bỏ mọi thứ"
+msgstr "trình soạn thảo thoát không thành công, huỷ bỏ các thay đổi"
 
 #, perl-format
 msgid ""
 "'%s' contains an intermediate version of the email you were composing.\n"
-msgstr "“%s” có chưa một phiên bản trung gian của thư bạn đã soạn.\n"
+msgstr "'%s' có chứa một phiên bản trung gian của email bạn đã soạn.\n"
 
 #, perl-format
 msgid "'%s.final' contains the composed email.\n"
-msgstr "“%s.final” chứa thư điện tử đã soạn thảo.\n"
+msgstr "'%s.final' chứa emal đã soạn thảo.\n"
 
 msgid "--dump-aliases incompatible with other options\n"
-msgstr "--dump-aliases xung khắc với các tùy chọn khác\n"
+msgstr "--dump-aliases không tương thích với các tùy chọn khác\n"
 
 msgid ""
 "fatal: found configuration options for 'sendmail'\n"
 "git-send-email is configured with the sendemail.* options - note the 'e'.\n"
 "Set sendemail.forbidSendmailVariables to false to disable this check.\n"
 msgstr ""
-"lỗi nghiêm trọng: tìm thấy các tùy chọn cấu hình cho “sendmail”\n"
-"git-send-email được cấu hình với các tùy chọn sendemail.* - chú ý “e”.\n"
+"lỗi nghiêm trọng: tìm thấy các tùy chọn cấu hình có tên 'sendmail'\n"
+"git-send-email được cấu hình với các tùy chọn sendemail.* - chú ý chữ 'e'.\n"
 "Đặt sendemail.forbidSendmailVariables thành false để tắt kiểm tra này.\n"
 
 msgid "Cannot run git format-patch from outside a repository\n"
-msgstr "Không thể chạy git format-patch ở ngoài một kho chứa\n"
+msgstr "Không thể chạy git format-patch ở ngoài kho chứa\n"
 
 msgid ""
 "`batch-size` and `relogin` must be specified together (via command-line or "
 "configuration option)\n"
 msgstr ""
-"“batch-size” và “relogin” phải được chỉ định cùng với nhau (thông qua dòng "
-"lệnh hoặc tùy chọn cấu hình)\n"
+"'batch-size' và 'relogin' phải được chỉ định cùng nhau (thông qua dòng lệnh "
+"hoặc tùy chọn cấu hình)\n"
 
 #, perl-format
 msgid "Unknown --suppress-cc field: '%s'\n"
-msgstr "Không hiểu trường --suppress-cc: “%s”\n"
+msgstr "Không hiểu trường --suppress-cc: '%s'\n"
 
 #, perl-format
 msgid "Unknown --confirm setting: '%s'\n"
-msgstr "Không hiểu cài đặt --confirm: “%s”\n"
+msgstr "Không hiểu cài đặt --confirm: '%s'\n"
 
 #, perl-format
 msgid "warning: sendmail alias with quotes is not supported: %s\n"
-msgstr "cảnh báo: bí danh sendmail với dấu trích dẫn không được hỗ trợ: %s\n"
+msgstr "cảnh báo: không hỗ trợ bí danh sendmail với dấu trích dẫn: %s\n"
 
 #, perl-format
 msgid "warning: `:include:` not supported: %s\n"
-msgstr "cảnh báo: “:include:“ không được hỗ trợ: %s\n"
+msgstr "cảnh báo: không hỗ trợ ':include:': %s\n"
 
 #, perl-format
 msgid "warning: `/file` or `|pipe` redirection not supported: %s\n"
-msgstr "cảnh báo: chuyển hướng “/file“ hay “|pipe“ không được hỗ trợ: %s\n"
+msgstr "cảnh báo: không hỗ trợ chuyển hướng '/file' hay '|pipe': %s\n"
 
 #, perl-format
 msgid "warning: sendmail line is not recognized: %s\n"
-msgstr "cảnh báo: dòng sendmail không nhận ra được: %s\n"
+msgstr "cảnh báo: không hiểu dòng cấu hình sendmail: %s\n"
 
 #, perl-format
 msgid ""
@@ -21627,15 +22623,15 @@
 "    * Saying \"./%s\" if you mean a file; or\n"
 "    * Giving --format-patch option if you mean a range.\n"
 msgstr ""
-"Tập tin “%s” đã có sẵn nhưng nó có lẽ cũng là chuẩn bị của\n"
-"các miếng vá tạo lần chuyển giao. Vui lòng làm rõ ý bằng…\n"
+"Tập tin '%s' có tồn tại nhưng cũng có thể hiểu là cần tạo bản vá cho\n"
+"một khoảng các lần chuyển giao. Vui lòng làm rõ ý của bạn bằng...\n"
 "\n"
-"    * Nói \"./%s\" nếu ý bạn là một tập tin; hoặc\n"
-"    * Đưa ra tùy chọn --format-patch nếu ý bạn là chuẩn bị.\n"
+"    * Ghi \"./%s\" nếu ý bạn là tập tin; hoặc\n"
+"    * Đưa ra tùy chọn --format-patch nếu ý bạn là tạo bản vá.\n"
 
 #, perl-format
 msgid "Failed to opendir %s: %s"
-msgstr "Gặp lỗi khi mở thư mục “%s”: %s"
+msgstr "Gặp lỗi khi opendir %s: %s"
 
 msgid ""
 "\n"
@@ -21643,7 +22639,7 @@
 "\n"
 msgstr ""
 "\n"
-"Chưa chỉ định các tập tin miếng vá!\n"
+"Chưa chỉ định các tập tin bản vá!\n"
 "\n"
 
 #, perl-format
@@ -21652,7 +22648,7 @@
 
 #, perl-format
 msgid "Failed to open for writing %s: %s"
-msgstr "Gặp lỗi khi mở “%s” để ghi: %s"
+msgstr "Gặp lỗi khi mở %s để ghi: %s"
 
 msgid ""
 "Lines beginning in \"GIT:\" will be removed.\n"
@@ -21662,21 +22658,21 @@
 "Clear the body content if you don't wish to send a summary.\n"
 msgstr ""
 "Các dòng bắt đầu bằng \"GIT:\" sẽ bị xóa bỏ.\n"
-"Cân nhắc bao gồm một thống kê diff toàn thể hay bảng nội dung\n"
-"cho miếng vá mà bạn đang viết.\n"
+"Hãy cân nhắc bao gồm một bản diffstat hay chỉ mục\n"
+"cho bản vá bạn đang viết.\n"
 "\n"
 "Xóa nội dung phần thân nếu bạn không muốn gửi tóm tắt.\n"
 
 #, perl-format
-msgid "Failed to open %s: %s"
-msgstr "Gặp lỗi khi mở “%s”: %s"
-
-#, perl-format
 msgid "Failed to open %s.final: %s"
 msgstr "Gặp lỗi khi mở %s.final: %s"
 
+#, perl-format
+msgid "Failed to open %s: %s"
+msgstr "Gặp lỗi khi mở %s: %s"
+
 msgid "Summary email is empty, skipping it\n"
-msgstr "Thư tổng thể là trống rỗng, nên bỏ qua nó\n"
+msgstr "Thư tóm tắt trống, nên sẽ bỏ qua\n"
 
 #. TRANSLATORS: please keep [y/N] as is.
 #, perl-format
@@ -21687,11 +22683,10 @@
 "The following files are 8bit, but do not declare a Content-Transfer-"
 "Encoding.\n"
 msgstr ""
-"Các trường sau đây là 8bit, nhưng không khai báo một Content-Transfer-"
-"Encoding.\n"
+"Các trường sau đây là 8bit, nhưng không khai báo Content-Transfer-Encoding.\n"
 
 msgid "Which 8bit encoding should I declare [UTF-8]? "
-msgstr "Bảng mã 8bit nào tôi nên khai báo [UTF-8]? "
+msgstr "Nên khai báo bảng mã 8bit nào [UTF-8]? "
 
 #, perl-format
 msgid ""
@@ -21700,24 +22695,24 @@
 "has the template subject '*** SUBJECT HERE ***'. Pass --force if you really "
 "want to send.\n"
 msgstr ""
-"Từ chối gửi bởi vì miếng vá\n"
+"Từ chối gửi vì bản vá\n"
 "\t%s\n"
-"có chủ đề ở dạng mẫu “*** SUBJECT HERE ***”. Dùng --force nếu bạn thực sự "
+"có chủ đề ở dạng mẫu '*** SUBJECT HERE ***'. Dùng --force nếu bạn thực sự "
 "muốn gửi.\n"
 
 msgid "To whom should the emails be sent (if anyone)?"
-msgstr "Tới người mà thư được gửi (nếu có)?"
+msgstr "Gửi email đến ai (nếu có)?"
 
 #, perl-format
 msgid "fatal: alias '%s' expands to itself\n"
-msgstr "nghiêm trọng: bí danh “%s” được khai triển thành chính nó\n"
+msgstr "lỗi nghiêm trọng: khai triển bí danh '%s' lại thành chính nó\n"
 
 msgid "Message-ID to be used as In-Reply-To for the first email (if any)? "
-msgstr "Message-ID được dùng như là In-Reply-To cho thư đầu tiên (nếu có)? "
+msgstr "Dùng Message-ID như In-Reply-To cho email đầu tiên (nếu có)? "
 
 #, perl-format
 msgid "error: unable to extract a valid address from: %s\n"
-msgstr "lỗi: không thể rút trích một địa chỉ hợp lệ từ: %s\n"
+msgstr "lỗi: không thể trích xuất địa chỉ hợp lệ từ: %s\n"
 
 #. TRANSLATORS: Make sure to include [q] [d] [e] in your
 #. translation. The program will only accept English input
@@ -21727,7 +22722,7 @@
 
 #, perl-format
 msgid "CA path \"%s\" does not exist"
-msgstr "Đường dẫn CA “%s” không tồn tại"
+msgstr "CA path '%s' không tồn tại"
 
 msgid ""
 "    The Cc list above has been expanded by additional\n"
@@ -21741,28 +22736,28 @@
 "    run 'git config --global sendemail.confirm auto'.\n"
 "\n"
 msgstr ""
-"    Danh sách Cc ở trên được diễn giải bằng các địa chỉ phụ\n"
-"    thêm tìm thấy trong lời ghi chú lần chuyển giao của miếng vá.\n"
-"    Theo mặc định send-email sẽ nhắc trước khi gửi bất cứ khi\n"
-"    nào điều này xảy ra. Cách hành xử này được điều khiển bởi cài\n"
+"    Danh sách Cc ở trên đã được thêm các địa chỉ có trong\n"
+"    nội dung lần chuyển giao của bản vá. Theo mặc định\n"
+"    send-email sẽ nhắc bạn trước khi gửi mỗi khi điều này \n"
+"    xảy ra. Bạn có thể điều chỉnh hành vi này qua cài\n"
 "    đặt cấu hình sendemail.confirm.\n"
 "\n"
-"    Để biết thêm chi tiết, hãy chạy lệnh “git send-email --help”.\n"
-"    Để giữ lại cách hành xử hiện nay, làm hết lời nhắn này,\n"
-"    chạy “git config --global sendemail.confirm auto”.\n"
+"    Để biết thêm chi tiết, hãy chạy lệnh 'git send-email --help'.\n"
+"    Để tiếp tục sử dụng hành vi này, nhưng bỏ hiển thị lời nhắc,\n"
+"    chạy 'git config --global sendemail.confirm auto'.\n"
 "\n"
 
 #. TRANSLATORS: Make sure to include [y] [n] [e] [q] [a] in your
 #. translation. The program will only accept English input
 #. at this point.
 msgid "Send this email? ([y]es|[n]o|[e]dit|[q]uit|[a]ll): "
-msgstr "Gửi thư này chứ? ([y]có|[n]không|[e]sửa|[q]thoát|[a]tất): "
+msgstr "Gửi email này chứ? ([y]có|[n]không|[e]sửa|[q]thoát|[a]tất): "
 
 msgid "Send this email reply required"
-msgstr "Gửi thư này trả lời yêu cầu"
+msgstr "Hãy trả lời yêu cầu gửi email"
 
 msgid "The required SMTP server is not properly defined."
-msgstr "Máy phục vụ SMTP chưa được định nghĩa một cách thích hợp."
+msgstr "Máy chủ SMTP chưa được định nghĩa đúng cách."
 
 #, perl-format
 msgid "Server does not support STARTTLS! %s"
@@ -21774,8 +22769,7 @@
 
 msgid "Unable to initialize SMTP properly. Check config and use --smtp-debug."
 msgstr ""
-"Không thể khởi tạo SMTP một cách đúng đắn. Kiểm tra cấu hình và dùng --smtp-"
-"debug."
+"Không thể khởi tạo SMTP đúng cách. Kiểm tra cấu hình và dùng --smtp-debug."
 
 #, perl-format
 msgid "Failed to send %s\n"
@@ -21790,51 +22784,55 @@
 msgstr "Gửi %s\n"
 
 msgid "Dry-OK. Log says:\n"
-msgstr "Dry-OK. Nhật ký nói rằng:\n"
+msgstr "Thử gửi OK. Nhật ký ghi lại:\n"
 
 msgid "OK. Log says:\n"
-msgstr "OK. Nhật ký nói rằng:\n"
+msgstr "OK. Nhật ký ghi lại:\n"
 
 msgid "Result: "
 msgstr "Kết quả: "
 
 msgid "Result: OK\n"
-msgstr "Kết quả: Tốt\n"
+msgstr "Kết quả: OK\n"
 
 #, perl-format
 msgid "can't open file %s"
-msgstr "không thể mở tập tin “%s”"
+msgstr "không thể mở tập tin '%s'"
 
 #, perl-format
 msgid "(mbox) Adding cc: %s from line '%s'\n"
-msgstr "(mbox) Thêm cc: %s từ dòng “%s”\n"
+msgstr "(mbox) Thêm cc: %s từ dòng '%s'\n"
 
 #, perl-format
 msgid "(mbox) Adding to: %s from line '%s'\n"
-msgstr "(mbox) Đang thêm to: %s từ dòng “%s”\n"
+msgstr "(mbox) Thêm to: %s từ dòng '%s'\n"
 
 #, perl-format
 msgid "(non-mbox) Adding cc: %s from line '%s'\n"
-msgstr "(non-mbox) Thêm cc: %s từ dòng “%s”\n"
+msgstr "(non-mbox) Thêm cc: %s từ dòng '%s'\n"
 
 #, perl-format
 msgid "(body) Adding cc: %s from line '%s'\n"
-msgstr "(body) Thêm cc: %s từ dòng “%s”\n"
+msgstr "(body) Thêm cc: %s từ dòng '%s'\n"
 
 #, perl-format
 msgid "(%s) Could not execute '%s'"
-msgstr "(%s) Không thể thực thi “%s”"
+msgstr "(%s) Không thể thực thi '%s'"
 
 #, perl-format
-msgid "(%s) Adding %s: %s from: '%s'\n"
-msgstr "(%s) Đang thêm %s: %s từ: “%s”\n"
+msgid "(%s) Malformed output from '%s'"
+msgstr "(%s) Dòng đầu ra sai quy cách từ '%s'"
 
 #, perl-format
 msgid "(%s) failed to close pipe to '%s'"
-msgstr "(%s) gặp lỗi khi đóng đường ống đến “%s”"
+msgstr "(%s) gặp lỗi khi đóng pipe đến '%s'"
+
+#, perl-format
+msgid "(%s) Adding %s: %s from: '%s'\n"
+msgstr "(%s) Thêm %s: %s từ: '%s'\n"
 
 msgid "cannot send message as 7bit"
-msgstr "không thể lấy gửi thư dạng 7 bít"
+msgstr "không thể gửi thư dạng 7bit"
 
 msgid "invalid transfer encoding"
 msgstr "bảng mã truyền không hợp lệ"
@@ -21845,9 +22843,9 @@
 "%s\n"
 "warning: no patches were sent\n"
 msgstr ""
-"nghiêm trọng: %s: bị từ chối bởi móc %s\n"
+"nghiêm trọng: %s: bị từ chối bởi hook %s\n"
 "%s\n"
-"cảnh báo: không có miếng vá nào được gửi đi\n"
+"cảnh báo: không gửi đi bản vá nào\n"
 
 #, perl-format
 msgid "unable to open %s: %s\n"
@@ -21858,307 +22856,14 @@
 "fatal: %s:%d is longer than 998 characters\n"
 "warning: no patches were sent\n"
 msgstr ""
-"nghiêm trọng: %s: %d là dài hơn 998 ký tự\n"
-"cảnh báo: không có miếng vá nào được gửi đi\n"
+"nghiêm trọng: %s: %d dài hơn 998 ký tự\n"
+"cảnh báo: không có bản vá nào được gửi đi\n"
 
 #, perl-format
 msgid "Skipping %s with backup suffix '%s'.\n"
-msgstr "Bỏ qua %s với hậu tố sao lưu dự phòng “%s”.\n"
+msgstr "Bỏ qua %s với hậu tố sao lưu '%s'.\n"
 
 #. TRANSLATORS: please keep "[y|N]" as is.
 #, perl-format
 msgid "Do you really want to send %s? [y|N]: "
 msgstr "Bạn có thực sự muốn gửi %s? [y|N](có/KHÔNG): "
-
-#~ msgid "--preserve-merges was replaced by --rebase-merges"
-#~ msgstr "--preserve-merges đã bị thay thế bằng --rebase-merges"
-
-#, c-format
-#~ msgid ""
-#~ "CRLF will be replaced by LF in %s.\n"
-#~ "The file will have its original line endings in your working directory"
-#~ msgstr ""
-#~ "CRLF sẽ bị thay thế bằng LF trong %s.\n"
-#~ "Tập tin sẽ có kiểu xuống dòng như bản gốc trong thư mục làm việc của bạn"
-
-#, c-format
-#~ msgid ""
-#~ "LF will be replaced by CRLF in %s.\n"
-#~ "The file will have its original line endings in your working directory"
-#~ msgstr ""
-#~ "LF sẽ bị thay thế bằng CRLF trong %s.\n"
-#~ "Tập tin sẽ có kiểu xuống dòng như bản gốc trong thư mục làm việc của bạn"
-
-#, c-format
-#~ msgid "error reading section header '%s'"
-#~ msgstr "gặp lỗi khi đọc phần đầu của đoạn %s"
-
-#~ msgid "load_reverse_index: could not open pack"
-#~ msgstr "load_reverse_index: không thể mở gói"
-
-#, perl-format
-#~ msgid "fatal: %s: rejected by %s hook\n"
-#~ msgstr "lỗi nghiêm trọng: %s: bị từ chối bởi móc %s\n"
-
-#~ msgid "git archive --list"
-#~ msgstr "git archive --list"
-
-#, c-format
-#~ msgid "unknown value for --diff-merges: %s"
-#~ msgstr "không hiểu giá trị cho --diff-merges: %s"
-
-#, c-format
-#~ msgid "invalid value '%s' for lsrefs.unborn"
-#~ msgstr "giá trị “%s” không hợp lệ cho lsrefs.unborn"
-
-#~ msgid "backend for `git stash -p`"
-#~ msgstr "ứng dụng chạy phía sau cho “git stash -p”"
-
-#, c-format
-#~ msgid "Invalid value for --empty: %s"
-#~ msgstr "Giá trị cho --empty không hợp lệ: %s"
-
-#, c-format
-#~ msgid "Invalid value for --patch-format: %s"
-#~ msgstr "Giá trị không hợp lệ cho --patch-format: %s"
-
-#, c-format
-#~ msgid "Invalid value for --show-current-patch: %s"
-#~ msgstr "Giá trị không hợp lệ cho --show-current-patch: %s"
-
-#~ msgid ""
-#~ "git bisect--helper --bisect-terms [--term-good | --term-old | --term-bad "
-#~ "| --term-new]"
-#~ msgstr ""
-#~ "git bisect--helper --bisect-terms [--term-good | --term-old | --term-bad "
-#~ "| --term-new]"
-
-#~ msgid "git bisect--helper --bisect-next"
-#~ msgstr "git bisect--helper --bisect-next"
-
-#~ msgid "git bisect--helper --bisect-visualize"
-#~ msgstr "git bisect--helper --bisect-visualize"
-
-#, c-format
-#~ msgid "invalid color '%s' in color.blame.repeatedLines"
-#~ msgstr "màu không hợp lệ “%s” trong color.blame.repeatedLines"
-
-#~ msgid "invalid value for blame.coloring"
-#~ msgstr "màu không hợp lệ cho blame.coloring"
-
-#~ msgid ""
-#~ "git cat-file (-t [--allow-unknown-type] | -s [--allow-unknown-type] | -e "
-#~ "| -p | <type> | --textconv | --filters) [--path=<path>] <object>"
-#~ msgstr ""
-#~ "git cat-file (-t [--allow-unknown-type] | -s [--allow-unknown-type] | -e "
-#~ "| -p | <kiểu> | --textconv) | --filters) [--path=<đường/dẫn>] <đối_tượng>"
-
-#~ msgid "show object type"
-#~ msgstr "hiển thị kiểu đối tượng"
-
-#~ msgid "exit with zero when there's no error"
-#~ msgstr "thoát với 0 khi không có lỗi"
-
-#~ msgid "show info and content of objects fed from the standard input"
-#~ msgstr ""
-#~ "hiển thị thông tin và nội dung của các đối tượng lấy từ đầu vào tiêu chuẩn"
-
-#~ msgid "show info about objects fed from the standard input"
-#~ msgstr "hiển thị các thông tin về đối tượng fed  từ đầu vào tiêu chuẩn"
-
-#~ msgid "follow in-tree symlinks (used with --batch or --batch-check)"
-#~ msgstr ""
-#~ "theo liên kết mềm trong-cây (được dùng với --batch hay --batch-check)"
-
-#~ msgid "show all objects with --batch or --batch-check"
-#~ msgstr "hiển thị mọi đối tượng với --batch hay --batch-check"
-
-#~ msgid "do not order --batch-all-objects output"
-#~ msgstr "đừng sắp xếp đầu ra --batch-all-objects"
-
-#~ msgid "set up tracking mode (see git-pull(1))"
-#~ msgstr "cài đặt chế độ theo dõi (xem git-pull(1))"
-
-#~ msgid "Using both --reset-author and --author does not make sense"
-#~ msgstr "Sử dụng cả hai tùy chọn --reset-author và --author không hợp lý"
-
-#~ msgid "Options --squash and --fixup cannot be used together"
-#~ msgstr "Các tùy chọn --squash và --fixup không thể sử dụng cùng với nhau"
-
-#~ msgid "Only one of -c/-C/-F/--fixup can be used."
-#~ msgstr "Chỉ được dùng một trong số tùy chọn trong số -c/-C/-F/--fixup."
-
-#~ msgid "Option -m cannot be combined with -c/-C/-F."
-#~ msgstr "Tùy chọn -m không thể được tổ hợp cùng với -c/-C/-F."
-
-#~ msgid ""
-#~ "Only one of --include/--only/--all/--interactive/--patch can be used."
-#~ msgstr ""
-#~ "Chỉ một trong các tùy chọn --include/--only/--all/--interactive/--patch "
-#~ "được sử dụng."
-
-#~ msgid "git count-objects [-v] [-H | --human-readable]"
-#~ msgstr "git count-objects [-v] [-H | --human-readable]"
-
-#, c-format
-#~ msgid "configuration fetch.output contains invalid value %s"
-#~ msgstr "phần cấu hình fetch.output có chứa giá-trị không hợp lệ %s"
-
-#~ msgid "--cached or --untracked cannot be used with --no-index"
-#~ msgstr "--cached hay --untracked không được sử dụng với --no-index"
-
-#~ msgid "--untracked cannot be used with --cached"
-#~ msgstr "--untracked không thể được sử dụng với tùy chọn --cached"
-
-#~ msgid "git hash-object  --stdin-paths"
-#~ msgstr "git hash-object  --stdin-paths"
-
-#~ msgid "git help [-g|--guides]"
-#~ msgstr "git help [-g|--guides]"
-
-#~ msgid "git help [-c|--config]"
-#~ msgstr "git help [-c|--config]"
-
-#~ msgid "git mktag"
-#~ msgstr "git mktag"
-
-#~ msgid "git mktree [-z] [--missing] [--batch]"
-#~ msgstr "git mktree [-z] [--missing] [--batch]"
-
-#~ msgid "read from stdin"
-#~ msgstr "đọc từ đầu vào tiêu chuẩn"
-
-#~ msgid "git notes merge --commit [-v | -q]"
-#~ msgstr "git notes merge --commit [-v | -q]"
-
-#~ msgid "git notes merge --abort [-v | -q]"
-#~ msgstr "git notes merge --abort [-v | -q]"
-
-#~ msgid "git notes get-ref"
-#~ msgstr "git notes get-ref"
-
-#~ msgid "invalid value for --missing"
-#~ msgstr "giá trị cho --missing không hợp lệ"
-
-#~ msgid "git prune-packed [-n | --dry-run] [-q | --quiet]"
-#~ msgstr "git prune-packed [-n | --dry-run] [-q | --quiet]"
-
-#, c-format
-#~ msgid "Invalid value for %s: %s"
-#~ msgstr "Giá trị không hợp lệ %s: %s"
-
-#, c-format
-#~ msgid "Invalid value for pull.ff: %s"
-#~ msgstr "Giá trị không hợp lệ cho pull.ff: %s"
-
-#~ msgid "git rebase --continue | --abort | --skip | --edit-todo"
-#~ msgstr "git rebase --continue | --abort | --skip | --edit-todo"
-
-#, c-format
-#~ msgid "'%s' is not a valid timestamp"
-#~ msgstr "“%s” không phải là dấu thời gian hợp lệ"
-
-#~ msgid "git reflog [ show | expire | delete | exists ]"
-#~ msgstr "git reflog [ show | expire | delete | exists ]"
-
-#~ msgid "git remote [-v | --verbose]"
-#~ msgstr "git remote [-v | --verbose]"
-
-#~ msgid "git replace [-f] --convert-graft-file"
-#~ msgstr "git replace [-f] --convert-graft-file"
-
-#, c-format
-#~ msgid ""
-#~ "\n"
-#~ "It took %.2f seconds to enumerate unstaged changes after reset.  You can\n"
-#~ "use '--quiet' to avoid this.  Set the config setting reset.quiet to true\n"
-#~ "to make this the default.\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Cần %.2f giây để kiểm đếm các thay đổi chưa đưa lên bệ phóng sau khi đặt "
-#~ "lại.\n"
-#~ "Bạn có thể sử dụng “--quiet” để tránh việc này. Đặt reset.quiet thành "
-#~ "true trong\n"
-#~ "cài đặt config nếu bạn muốn thực hiện nó như là mặc định.\n"
-
-#~ msgid "git sparse-checkout list"
-#~ msgstr "git sparse-checkout list"
-
-#~ msgid "unable to upgrade repository format to enable worktreeConfig"
-#~ msgstr ""
-#~ "không thể nâng cấp định dạng kho lưu trữ để kích hoạt worktreeConfig"
-
-#~ msgid "git sparse-checkout init [--cone] [--[no-]sparse-index]"
-#~ msgstr "git sparse-checkout init [--cone] [--[no-]sparse-index]"
-
-#~ msgid "git sparse-checkout reapply [--[no-]cone] [--[no-]sparse-index]"
-#~ msgstr "git sparse-checkout reapply [--[no-]cone] [--[no-]sparse-index]"
-
-#~ msgid "git sparse-checkout disable"
-#~ msgstr "git sparse-checkout disable"
-
-#~ msgid ""
-#~ "the stash.useBuiltin support has been removed!\n"
-#~ "See its entry in 'git help config' for details."
-#~ msgstr ""
-#~ "việc hỗ trợ stash.useBuiltin đã bị xóa!\n"
-#~ "Xem mục tin của nó trong “git help config” để biết chi tiết."
-
-#~ msgid "git stripspace [-s | --strip-comments]"
-#~ msgstr "git stripspace [-s | --strip-comments]"
-
-#~ msgid "git stripspace [-c | --comment-lines]"
-#~ msgstr "git stripspace [-c | --comment-lines]"
-
-#~ msgid "submodule--helper print-default-remote takes no arguments"
-#~ msgstr "submodule--helper print-default-remote takes không nhận tham số"
-
-#~ msgid "git submodule--helper update-clone [--prefix=<path>] [<path>...]"
-#~ msgstr ""
-#~ "git submodule--helper update-clone [--prefix=</đường/dẫn>] [</đường/dẫn>…]"
-
-#~ msgid "suppress output for update by rebase or merge"
-#~ msgstr "chặn kết xuất cho cập nhật bởi cải tổ hoặc hòa trộn"
-
-#~ msgid "overrides update mode in case the repository is a fresh clone"
-#~ msgstr "ghi đè chế độ cập nhật trong trường hợp kho lưu trữ là bản sao mới"
-
-#~ msgid "depth for shallow fetch"
-#~ msgstr "chiều sâu lịch sử muốn lấy về"
-
-#~ msgid "sha1"
-#~ msgstr "sha1"
-
-#~ msgid "SHA1 expected by superproject"
-#~ msgstr "SHA1 là cần thiết cho superproject"
-
-#~ msgid "subsha1"
-#~ msgstr "subsha1"
-
-#~ msgid "SHA1 of submodule's HEAD"
-#~ msgstr "SHA1 của HEAD của mô-đun-con"
-
-#~ msgid "git submodule--helper run-update-procedure [<options>] <path>"
-#~ msgstr ""
-#~ "git submodule--helper run-update-procedure [<các tùy chọn>] </đường/dẫn>"
-
-#~ msgid "git submodule--helper config --check-writeable"
-#~ msgstr "git submodule--helper config --check-writeable"
-
-#~ msgid "git update-server-info [--force]"
-#~ msgstr "git update-server-info [--force]"
-
-#~ msgid "Initialize and modify the sparse-checkout"
-#~ msgstr "Khởi tạo và sửa đổi sparse-checkout"
-
-#, sh-format
-#~ msgid ""
-#~ "Unable to find current ${remote_name}/${branch} revision in submodule "
-#~ "path '$sm_path'"
-#~ msgstr ""
-#~ "Không thể tìm thấy điểm xét duyệt hiện hành ${remote_name}/${branch} "
-#~ "trong đường dẫn mô-đun-con “$sm_path”"
-
-#, sh-format
-#~ msgid "Failed to recurse into submodule path '$displaypath'"
-#~ msgstr "Gặp lỗi khi đệ quy vào trong đường dẫn mô-đun-con “$displaypath”"
diff --git a/po/zh_CN.po b/po/zh_CN.po
index 8640272..4838c19 100644
--- a/po/zh_CN.po
+++ b/po/zh_CN.po
@@ -46,6 +46,7 @@
 #   commit                           |  提交
 #   commit message                   |  提交说明
 #   commit object                    |  提交对象
+#   commit-graph                     |  提交图
 #   commit-ish (also committish)     |  提交号
 #   cone                             |  锥形(稀疏检出模型);锥(稀疏检出)
 #   conflict                         |  冲突
@@ -99,8 +100,10 @@
 #   plumbing                         |  管件(Git 底层核心命令的别称)
 #   porcelain                        |  瓷件(Git 上层封装命令的别称)
 #   precious-objects repo            |  珍品仓库
+#   preferred pack                   |  首选包(多包索引中引入的首选包概念)
 #   promisor                         |  承诺者
 #   prune                            |  清除
+#   pseudorefs                       |  伪引用
 #   pull                             |  拉,拉取
 #   push                             |  推,推送
 #   reachable                        |  可达
@@ -151,8 +154,8 @@
 msgstr ""
 "Project-Id-Version: Git\n"
 "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2023-11-10 10:49+0800\n"
-"PO-Revision-Date: 2023-11-10 17:13+0800\n"
+"POT-Creation-Date: 2024-04-28 19:59+0800\n"
+"PO-Revision-Date: 2024-04-28 20:31+0800\n"
 "Last-Translator: Teng Long <dyroneteng@gmail.com>\n"
 "Language-Team: GitHub <https://github.com/dyrone/git/>\n"
 "Language: zh_CN\n"
@@ -724,12 +727,12 @@
 "---\n"
 "To remove '%c' lines, make them ' ' lines (context).\n"
 "To remove '%c' lines, delete them.\n"
-"Lines starting with %c will be removed.\n"
+"Lines starting with %s will be removed.\n"
 msgstr ""
 "---\n"
 "要删除 '%c' 开始的行,使其成为 ' ' 开始的行(上下文)。\n"
 "要删除 '%c' 开始的行,删除它们。\n"
-"以 %c 开始的行将被删除。\n"
+"以 %s 开始的行将被删除。\n"
 
 #: add-patch.c
 msgid ""
@@ -781,6 +784,7 @@
 "/ - search for a hunk matching the given regex\n"
 "s - split the current hunk into smaller hunks\n"
 "e - manually edit the current hunk\n"
+"p - print the current hunk\n"
 "? - print help\n"
 msgstr ""
 "j - 维持该块未决状态,查看下一个未决块\n"
@@ -791,6 +795,7 @@
 "/ - 查找和给定正则表达式匹配的块\n"
 "s - 拆分当前块为更小的块\n"
 "e - 手动编辑当前块\n"
+"p - 显示当前块\n"
 "? - 显示帮助\n"
 
 #: add-patch.c
@@ -870,8 +875,8 @@
 
 #: advice.c
 #, c-format
-msgid "%shint: %.*s%s\n"
-msgstr "%s提示:%.*s%s\n"
+msgid "%shint:%s%.*s%s\n"
+msgstr "%s提示:%s%.*s%s\n"
 
 #: advice.c
 msgid "Cherry-picking is not possible because you have unmerged files."
@@ -1031,7 +1036,7 @@
 msgstr "未关闭的引号"
 
 #: alias.c builtin/cat-file.c builtin/notes.c builtin/prune-packed.c
-#: builtin/receive-pack.c builtin/tag.c
+#: builtin/receive-pack.c builtin/tag.c t/helper/test-pkt-line.c
 msgid "too many arguments"
 msgstr "太多参数"
 
@@ -1046,12 +1051,13 @@
 msgstr "未能识别的空白字符忽略选项 '%s'"
 
 #: apply.c archive.c builtin/add.c builtin/branch.c builtin/checkout-index.c
-#: builtin/checkout.c builtin/clone.c builtin/commit.c builtin/describe.c
-#: builtin/diff-tree.c builtin/difftool.c builtin/fast-export.c builtin/fetch.c
-#: builtin/help.c builtin/index-pack.c builtin/init-db.c builtin/log.c
-#: builtin/ls-files.c builtin/merge-base.c builtin/merge.c
-#: builtin/pack-objects.c builtin/push.c builtin/rebase.c builtin/repack.c
-#: builtin/reset.c builtin/rev-list.c builtin/show-branch.c builtin/stash.c
+#: builtin/checkout.c builtin/clean.c builtin/clone.c builtin/commit.c
+#: builtin/describe.c builtin/diff-tree.c builtin/difftool.c
+#: builtin/fast-export.c builtin/fetch.c builtin/help.c builtin/index-pack.c
+#: builtin/init-db.c builtin/log.c builtin/ls-files.c builtin/merge-base.c
+#: builtin/merge-tree.c builtin/merge.c builtin/pack-objects.c builtin/rebase.c
+#: builtin/repack.c builtin/replay.c builtin/reset.c builtin/rev-list.c
+#: builtin/rev-parse.c builtin/show-branch.c builtin/stash.c
 #: builtin/submodule--helper.c builtin/tag.c builtin/worktree.c parse-options.c
 #: range-diff.c revision.c
 #, c-format
@@ -1468,11 +1474,6 @@
 
 #: apply.c
 #, c-format
-msgid "truncating .rej filename to %.*s.rej"
-msgstr "截短 .rej 文件名为 %.*s.rej"
-
-#: apply.c
-#, c-format
 msgid "cannot open %s"
 msgstr "不能打开 %s"
 
@@ -1861,6 +1862,11 @@
 
 #: archive.c
 #, c-format
+msgid "extra command line parameter '%s'"
+msgstr "额外的命令行参数:'%s'"
+
+#: archive.c
+#, c-format
 msgid "Unknown archive format '%s'"
 msgstr "未知归档格式 '%s'"
 
@@ -1915,6 +1921,17 @@
 msgid "bad --attr-source or GIT_ATTR_SOURCE"
 msgstr "错误的 --attr-source 或 GIT_ATTR_SOURCE"
 
+#: attr.c read-cache.c
+#, c-format
+msgid "unable to stat '%s'"
+msgstr "无法对 %s 执行 stat"
+
+#: bisect.c builtin/cat-file.c builtin/index-pack.c builtin/notes.c
+#: builtin/pack-objects.c combine-diff.c rerere.c
+#, c-format
+msgid "unable to read %s"
+msgstr "不能读 %s"
+
 #: bisect.c
 #, c-format
 msgid "Badly quoted content in file '%s': %s"
@@ -1994,6 +2011,11 @@
 msgid "could not create file '%s'"
 msgstr "不能创建文件 '%s'"
 
+#: bisect.c builtin/notes.c
+#, c-format
+msgid "unable to start 'show' for object '%s'"
+msgstr "不能为对象 '%s' 开始 'show'"
+
 #: bisect.c builtin/merge.c
 #, c-format
 msgid "could not read file '%s'"
@@ -2043,8 +2065,8 @@
 msgstr "--reverse 和 --first-parent 共用,需要指定最新的提交"
 
 #: blame.c builtin/commit.c builtin/log.c builtin/merge.c
-#: builtin/pack-objects.c builtin/shortlog.c midx.c pack-bitmap.c remote.c
-#: sequencer.c submodule.c
+#: builtin/pack-objects.c builtin/shortlog.c midx-write.c pack-bitmap.c
+#: remote.c sequencer.c submodule.c
 msgid "revision walk setup failed"
 msgstr "版本遍历初始化失败"
 
@@ -2161,6 +2183,10 @@
 msgid "'%s' is not a valid branch name"
 msgstr "'%s' 不是一个有效的分支名称"
 
+#: branch.c builtin/branch.c
+msgid "See `man git check-ref-format`"
+msgstr "查阅 `man git check-ref-format`"
+
 #: branch.c
 #, c-format
 msgid "a branch named '%s' already exists"
@@ -2391,14 +2417,8 @@
 msgstr "正在添加嵌入式 git 仓库:%s"
 
 #: builtin/add.c
-msgid ""
-"Use -f if you really want to add them.\n"
-"Turn this message off by running\n"
-"\"git config advice.addIgnoredFile false\""
-msgstr ""
-"如果您确实要添加它们,使用 -f 参数。\n"
-"运行下面的命令来关闭本消息\n"
-"\"git config advice.addIgnoredFile false\""
+msgid "Use -f if you really want to add them."
+msgstr "如果您确实想添加它们,请使用 -f 选项。"
 
 #: builtin/add.c
 msgid "adding files failed"
@@ -2421,14 +2441,8 @@
 msgstr "没有指定文件,也没有文件被添加。\n"
 
 #: builtin/add.c
-msgid ""
-"Maybe you wanted to say 'git add .'?\n"
-"Turn this message off by running\n"
-"\"git config advice.addEmptyPathspec false\""
-msgstr ""
-"也许您想要执行 'git add .'?\n"
-"运行下面的命令来关闭本消息\n"
-"\"git config advice.addEmptyPathspec false\""
+msgid "Maybe you wanted to say 'git add .'?"
+msgstr "也许您想要执行 'git add .'?"
 
 #: builtin/add.c builtin/check-ignore.c builtin/checkout.c builtin/clean.c
 #: builtin/commit.c builtin/diff-tree.c builtin/grep.c builtin/mv.c
@@ -2448,8 +2462,8 @@
 msgstr "'%2$s' 的错误动作 '%1$s'"
 
 #: builtin/am.c builtin/blame.c builtin/fetch.c builtin/pack-objects.c
-#: builtin/pull.c diff-merges.c gpg-interface.c ls-refs.c parallel-checkout.c
-#: sequencer.c setup.c
+#: builtin/pull.c builtin/revert.c config.c diff-merges.c gpg-interface.c
+#: ls-refs.c parallel-checkout.c sequencer.c setup.c
 #, c-format
 msgid "invalid value for '%s': '%s'"
 msgstr "'%s' 的值无效:'%s'"
@@ -2533,18 +2547,19 @@
 
 #: builtin/am.c
 #, c-format
-msgid "When you have resolved this problem, run \"%s --continue\"."
-msgstr "当您解决这一问题,执行 \"%s --continue\"。"
+msgid "When you have resolved this problem, run \"%s --continue\".\n"
+msgstr "当您解决这一问题之后,执行 \"%s --continue\"。\n"
 
 #: builtin/am.c
 #, c-format
-msgid "If you prefer to skip this patch, run \"%s --skip\" instead."
-msgstr "如果您想要跳过这一补丁,则执行 \"%s --skip\"。"
+msgid "If you prefer to skip this patch, run \"%s --skip\" instead.\n"
+msgstr "如果您想要跳过这一补丁,则执行 \"%s --skip\"。\n"
 
 #: builtin/am.c
 #, c-format
-msgid "To record the empty patch as an empty commit, run \"%s --allow-empty\"."
-msgstr "若要把空补丁记录为空提交,执行 \"%s --allow-empty\"。"
+msgid ""
+"To record the empty patch as an empty commit, run \"%s --allow-empty\".\n"
+msgstr "若要把空补丁记录为空提交,执行 \"%s --allow-empty\"。\n"
 
 #: builtin/am.c
 #, c-format
@@ -2602,8 +2617,7 @@
 msgid "applying to an empty history"
 msgstr "正应用到一个空历史上"
 
-#: builtin/am.c builtin/commit.c builtin/merge.c sequencer.c
-#: t/helper/test-fast-rebase.c
+#: builtin/am.c builtin/commit.c builtin/merge.c builtin/replay.c sequencer.c
 msgid "failed to write commit object"
 msgstr "无法写提交对象"
 
@@ -2783,8 +2797,9 @@
 msgstr "n"
 
 #: builtin/am.c builtin/branch.c builtin/bugreport.c builtin/cat-file.c
-#: builtin/diagnose.c builtin/for-each-ref.c builtin/ls-files.c
-#: builtin/ls-tree.c builtin/replace.c builtin/tag.c builtin/verify-tag.c
+#: builtin/clone.c builtin/diagnose.c builtin/for-each-ref.c builtin/init-db.c
+#: builtin/ls-files.c builtin/ls-tree.c builtin/replace.c builtin/tag.c
+#: builtin/verify-tag.c
 msgid "format"
 msgstr "格式"
 
@@ -2916,7 +2931,9 @@
 msgid ""
 "git bisect start [--term-(new|bad)=<term> --term-(old|good)=<term>]    [--no-"
 "checkout] [--first-parent] [<bad> [<good>...]] [--]    [<pathspec>...]"
-msgstr "git bisect start [--term-{new|bad}=<术语> --term-{old|good}=<术语>]    [--no-checkout] [--first-parent] [<坏> [<好>...]] [--]    [<路径规格>...]"
+msgstr ""
+"git bisect start [--term-{new|bad}=<术语> --term-{old|good}=<术语>]    [--no-"
+"checkout] [--first-parent] [<坏> [<好>...]] [--]    [<路径规格>...]"
 
 #: builtin/bisect.c
 msgid "git bisect (good|bad) [<rev>...]"
@@ -3473,12 +3490,13 @@
 
 #: builtin/branch.c
 #, c-format
-msgid ""
-"the branch '%s' is not fully merged.\n"
-"If you are sure you want to delete it, run 'git branch -D %s'"
-msgstr ""
-"分支 '%s' 没有完全合并。\n"
-"如果您确认要删除它,执行 'git branch -D %s'"
+msgid "the branch '%s' is not fully merged"
+msgstr "分支 '%s' 没有完全合并"
+
+#: builtin/branch.c
+#, c-format
+msgid "If you are sure you want to delete it, run 'git branch -D %s'"
+msgstr "如果您确认要删除它,执行 'git branch -D %s'"
 
 #: builtin/branch.c
 msgid "update of config-file failed"
@@ -3601,11 +3619,11 @@
 msgid ""
 "Please edit the description for the branch\n"
 "  %s\n"
-"Lines starting with '%c' will be stripped.\n"
+"Lines starting with '%s' will be stripped.\n"
 msgstr ""
 "请编辑分支的描述\n"
 "  %s\n"
-"以 '%c' 开头的行将被过滤。\n"
+"以 '%s' 开头的行将被过滤。\n"
 
 #: builtin/branch.c
 msgid "Generic options"
@@ -3861,10 +3879,12 @@
 
 #: builtin/bugreport.c
 msgid ""
-"git bugreport [(-o | --output-directory) <path>] [(-s | --suffix) <format>]\n"
+"git bugreport [(-o | --output-directory) <path>]\n"
+"              [(-s | --suffix) <format> | --no-suffix]\n"
 "              [--diagnose[=<mode>]]"
 msgstr ""
-"git bugreport [-o|--output-directory <文件>] [(-s|--suffix) <格式>]\n"
+"git bugreport [-o | --output-directory <文件>]\n"
+"              [(-s | --suffix) <格式> | --no-suffix]\n"
 "              [--diagnose[=<模式>]"
 
 #: builtin/bugreport.c
@@ -4466,6 +4486,12 @@
 msgid "path '%s' is unmerged"
 msgstr "路径 '%s' 未合并"
 
+#: builtin/checkout.c builtin/grep.c builtin/merge-tree.c builtin/reset.c
+#: merge-ort.c reset.c sequencer.c tree-walk.c
+#, c-format
+msgid "unable to read tree (%s)"
+msgstr "无法读取树(%s)"
+
 #: builtin/checkout.c
 msgid "you need to resolve your current index first"
 msgstr "您需要先解决当前索引的冲突"
@@ -4488,7 +4514,7 @@
 msgid "HEAD is now at"
 msgstr "HEAD 目前位于"
 
-#: builtin/checkout.c builtin/clone.c t/helper/test-fast-rebase.c
+#: builtin/checkout.c builtin/clone.c
 msgid "unable to update HEAD"
 msgstr "不能更新 HEAD"
 
@@ -4733,6 +4759,11 @@
 msgstr "缺少分支或提交参数"
 
 #: builtin/checkout.c
+#, c-format
+msgid "unknown conflict style '%s'"
+msgstr "未知的冲突风格 '%s'"
+
+#: builtin/checkout.c
 msgid "perform a 3-way merge with the new branch"
 msgstr "和新的分支执行三方合并"
 
@@ -4757,8 +4788,8 @@
 msgstr "新分支"
 
 #: builtin/checkout.c
-msgid "new unparented branch"
-msgstr "新的没有父提交的分支"
+msgid "new unborn branch"
+msgstr "新的未诞生的分支"
 
 #: builtin/checkout.c builtin/merge.c
 msgid "update ignored files (default)"
@@ -4824,7 +4855,7 @@
 msgid "you must specify path(s) to restore"
 msgstr "您必须指定要恢复的路径"
 
-#: builtin/checkout.c builtin/clone.c builtin/remote.c
+#: builtin/checkout.c builtin/clone.c builtin/remote.c builtin/replay.c
 #: builtin/submodule--helper.c builtin/worktree.c
 msgid "branch"
 msgstr "分支"
@@ -5052,22 +5083,8 @@
 msgstr "只删除忽略的文件"
 
 #: builtin/clean.c
-msgid ""
-"clean.requireForce set to true and neither -i, -n, nor -f given; refusing to "
-"clean"
-msgstr ""
-"clean.requireForce 设置为 true 且未提供 -i、-n 或 -f 选项,拒绝执行清理动作"
-
-#: builtin/clean.c
-msgid ""
-"clean.requireForce defaults to true and neither -i, -n, nor -f given; "
-"refusing to clean"
-msgstr ""
-"clean.requireForce 默认为 true 且未提供 -i、-n 或 -f 选项,拒绝执行清理动作"
-
-#: builtin/clean.c
-msgid "-x and -X cannot be used together"
-msgstr "-x 和 -X 不能同时使用"
+msgid "clean.requireForce is true and -f not given: refusing to clean"
+msgstr "clean.requireForce 设置为 true 且未提供 -f 选项:拒绝执行清理动作"
 
 #: builtin/clone.c
 msgid "git clone [<options>] [--] <repo> [<dir>]"
@@ -5086,8 +5103,8 @@
 msgstr "创建一个纯仓库"
 
 #: builtin/clone.c
-msgid "create a mirror repository (implies bare)"
-msgstr "创建一个镜像仓库(也是纯仓库)"
+msgid "create a mirror repository (implies --bare)"
+msgstr "创建一个镜像仓库(隐含 --bare)"
 
 #: builtin/clone.c
 msgid "to clone from a local repository"
@@ -5160,6 +5177,7 @@
 msgstr "从一个特定时间创建一个浅克隆"
 
 #: builtin/clone.c builtin/fetch.c builtin/pull.c builtin/rebase.c
+#: builtin/replay.c
 msgid "revision"
 msgstr "版本"
 
@@ -5187,6 +5205,10 @@
 msgid "separate git dir from working tree"
 msgstr "git目录和工作区分离"
 
+#: builtin/clone.c builtin/init-db.c
+msgid "specify the reference format to use"
+msgstr "指定要使用的引用格式"
+
 #: builtin/clone.c
 msgid "key=value"
 msgstr "key=value"
@@ -5336,11 +5358,10 @@
 msgid "You must specify a repository to clone."
 msgstr "您必须指定一个仓库来克隆。"
 
-#: builtin/clone.c
-msgid ""
-"--bundle-uri is incompatible with --depth, --shallow-since, and --shallow-"
-"exclude"
-msgstr "--bundle-uri 与 --depth、--shallow-since 和 --shallow-exclude 不兼容"
+#: builtin/clone.c builtin/init-db.c setup.c
+#, c-format
+msgid "unknown ref storage format '%s'"
+msgstr "未知的引用存储格式 '%s'"
 
 #: builtin/clone.c
 #, c-format
@@ -5485,6 +5506,11 @@
 msgstr "两列之间的填充空间"
 
 #: builtin/column.c
+#, c-format
+msgid "%s must be non-negative"
+msgstr "%s 必须为非负整数"
+
+#: builtin/column.c
 msgid "--command must be the first argument"
 msgstr "--command 必须是第一个参数"
 
@@ -5501,7 +5527,7 @@
 "--stdin-commits]\n"
 "                       [--changed-paths] [--[no-]max-new-filters <n>] [--"
 "[no-]progress]\n"
-"                       <split options>"
+"                       <split-options>"
 msgstr ""
 "git commit-graph write [--object-dir <目录>] [--append]\n"
 "                       [--split[=<策略>]] [--reachable | --stdin-packs | --"
@@ -5520,17 +5546,17 @@
 
 #: builtin/commit-graph.c
 msgid "if the commit-graph is split, only verify the tip file"
-msgstr "如果提交图形被拆分,只验证头一个文件"
+msgstr "如果提交图被拆分,只验证头一个文件"
 
 #: builtin/commit-graph.c
 #, c-format
 msgid "Could not open commit-graph '%s'"
-msgstr "无法打开提交图形 '%s'"
+msgstr "无法打开提交图 '%s'"
 
 #: builtin/commit-graph.c
 #, c-format
 msgid "could not open commit-graph chain '%s'"
-msgstr "无法打开提交图形链 '%s'"
+msgstr "无法打开提交图链 '%s'"
 
 #: builtin/commit-graph.c
 #, c-format
@@ -5574,15 +5600,15 @@
 
 #: builtin/commit-graph.c
 msgid "allow writing an incremental commit-graph file"
-msgstr "允许写一个增量提交图形文件"
+msgstr "允许写一个增量提交图文件"
 
 #: builtin/commit-graph.c
 msgid "maximum number of commits in a non-base split commit-graph"
-msgstr "在非基本拆分提交图形中的最大提交数"
+msgstr "在非基本拆分提交图中的最大提交数"
 
 #: builtin/commit-graph.c
 msgid "maximum ratio between two levels of a split commit-graph"
-msgstr "一个拆分提交图形的两个级别之间的最大比率"
+msgstr "一个拆分提交图的两个级别之间的最大比率"
 
 #: builtin/commit-graph.c
 msgid "only expire files older than a given date-time"
@@ -5817,7 +5843,7 @@
 "in the current commit message"
 msgstr "无法选择一个未被当前提交说明使用的注释字符"
 
-#: builtin/commit.c builtin/merge-tree.c
+#: builtin/commit.c
 #, c-format
 msgid "could not lookup commit '%s'"
 msgstr "不能查询提交 '%s'"
@@ -5862,35 +5888,35 @@
 #, c-format
 msgid ""
 "Please enter the commit message for your changes. Lines starting\n"
-"with '%c' will be ignored.\n"
-msgstr "请为您的变更输入提交说明。以 '%c' 开始的行将被忽略。\n"
+"with '%s' will be ignored.\n"
+msgstr "请为您的变更输入提交说明。以 '%s' 开始的行将被忽略。\n"
 
 #: builtin/commit.c
 #, 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"
+"with '%s' will be ignored, and an empty message aborts the commit.\n"
 msgstr ""
-"请为您的变更输入提交说明。以 '%c' 开始的行将被忽略,而一个空的提交\n"
+"请为您的变更输入提交说明。以 '%s' 开始的行将被忽略,而一个空的提交\n"
 "说明将会终止提交。\n"
 
 #: builtin/commit.c
 #, 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"
+"with '%s' will be kept; you may remove them yourself if you want to.\n"
 msgstr ""
-"请为您的变更输入提交说明。以 '%c' 开始的行将被保留,如果您愿意\n"
+"请为您的变更输入提交说明。以 '%s' 开始的行将被保留,如果您愿意\n"
 "也可以删除它们。\n"
 
 #: builtin/commit.c
 #, 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"
+"with '%s' will be kept; you may remove them yourself if you want to.\n"
 "An empty message aborts the commit.\n"
 msgstr ""
-"请为您的变更输入提交说明。以 '%c' 开始的行将被保留,如果您愿意\n"
+"请为您的变更输入提交说明。以 '%s' 开始的行将被保留,如果您愿意\n"
 "也可以删除它们。一个空的提交说明将会终止提交。\n"
 
 #: builtin/commit.c
@@ -6119,7 +6145,7 @@
 msgid "override date for commit"
 msgstr "提交时覆盖日期"
 
-#: builtin/commit.c builtin/merge-tree.c parse-options.h ref-filter.h
+#: builtin/commit.c parse-options.h ref-filter.h
 msgid "commit"
 msgstr "提交"
 
@@ -6444,6 +6470,10 @@
 msgstr "使用 --get 参数,当缺少设置时使用默认值"
 
 #: builtin/config.c
+msgid "human-readable comment string (# will be prepended as needed)"
+msgstr "人类可读的注释字符串(# 将根据需要添加到前面)"
+
+#: builtin/config.c
 #, c-format
 msgid "wrong number of arguments, should be %d"
 msgstr "错误的参数个数,应该为 %d 个"
@@ -6556,6 +6586,10 @@
 msgstr "--default 仅适用于 --get"
 
 #: builtin/config.c
+msgid "--comment is only applicable to add/set/replace operations"
+msgstr "--comment 仅适用于 add/set/replace 操作"
+
+#: builtin/config.c
 msgid "--fixed-value only applies with 'value-pattern'"
 msgstr "--fixed-value 仅适用于有 '值模式'"
 
@@ -6821,7 +6855,7 @@
 #: builtin/diff.c
 #, c-format
 msgid "'%s': not a regular file or symlink"
-msgstr "'%s':不是一个正规文件或符号链接"
+msgstr "'%s':不是一个普通文件或符号链接"
 
 #: builtin/diff.c
 msgid "no merge given, only parents."
@@ -7601,6 +7635,10 @@
 msgstr "从标准输入读取引用的模式"
 
 #: builtin/for-each-ref.c
+msgid "also include HEAD ref and pseudorefs"
+msgstr "还包括 HEAD 引用和伪引用"
+
+#: builtin/for-each-ref.c
 msgid "unknown arguments supplied with --stdin"
 msgstr "为 --stdin 提供了未知的命令参数"
 
@@ -8375,8 +8413,8 @@
 
 #: builtin/grep.c
 #, c-format
-msgid "unable to read tree (%s)"
-msgstr "无法读取树(%s)"
+msgid "unable to read tree %s"
+msgstr "无法读取树 %s"
 
 #: builtin/grep.c
 #, c-format
@@ -8901,11 +8939,6 @@
 msgid "SHA1 COLLISION FOUND WITH %s !"
 msgstr "发现 %s 出现 SHA1 冲突!"
 
-#: builtin/index-pack.c builtin/pack-objects.c
-#, c-format
-msgid "unable to read %s"
-msgstr "不能读 %s"
-
 #: builtin/index-pack.c
 #, c-format
 msgid "cannot read existing object info %s"
@@ -9083,11 +9116,13 @@
 msgid ""
 "git init [-q | --quiet] [--bare] [--template=<template-directory>]\n"
 "         [--separate-git-dir <git-dir>] [--object-format=<format>]\n"
+"         [--ref-format=<format>]\n"
 "         [-b <branch-name> | --initial-branch=<branch-name>]\n"
 "         [--shared[=<permissions>]] [<directory>]"
 msgstr ""
 "git init [-q | --quiet] [--bare] [--template=<模板目录>]\n"
 "         [--separate-git-dir <git 目录>] [--object-format=<格式>]\n"
+"         [--ref-format=<格式>]\n"
 "         [-b <分支名> | --initial-branch=<分支名>]\n"
 "         [--shared[=<权限>]] [<目录>]"
 
@@ -9140,13 +9175,46 @@
 #: builtin/interpret-trailers.c
 msgid ""
 "git interpret-trailers [--in-place] [--trim-empty]\n"
-"                       [(--trailer (<key>|<keyAlias>)[(=|:)<value>])...]\n"
+"                       [(--trailer (<key>|<key-alias>)[(=|:)<value>])...]\n"
 "                       [--parse] [<file>...]"
 msgstr ""
 "git interpret-trailers [--in-place] [--trim-empty]\n"
 "                       [(--trailer (<键|键别名>)[(=|:)<值>])...]\n"
 "                       [--parse] [<文件>...]"
 
+#: builtin/interpret-trailers.c wrapper.c
+#, c-format
+msgid "could not stat %s"
+msgstr "不能对 %s 调用 stat"
+
+#: builtin/interpret-trailers.c
+#, c-format
+msgid "file %s is not a regular file"
+msgstr "文件 %s 不是一个普通文件"
+
+#: builtin/interpret-trailers.c
+#, c-format
+msgid "file %s is not writable by user"
+msgstr "文件 %s 用户不可写"
+
+#: builtin/interpret-trailers.c
+msgid "could not open temporary file"
+msgstr "不能打开临时文件"
+
+#: builtin/interpret-trailers.c
+#, c-format
+msgid "could not read input file '%s'"
+msgstr "不能读取输入文件 '%s'"
+
+#: builtin/interpret-trailers.c builtin/mktag.c imap-send.c
+msgid "could not read from stdin"
+msgstr "不能自标准输入读取"
+
+#: builtin/interpret-trailers.c
+#, c-format
+msgid "could not rename temporary file to %s"
+msgstr "不能重命名临时文件为 %s"
+
 #: builtin/interpret-trailers.c
 msgid "edit files in place"
 msgstr "在原位编辑文件"
@@ -9246,7 +9314,7 @@
 "<file>"
 msgstr "跟踪 <文件> 中 <开始>,<结束> 范围内的行或函数 :<函数名> 的演变"
 
-#: builtin/log.c builtin/shortlog.c bundle.c
+#: builtin/log.c builtin/replay.c builtin/shortlog.c bundle.c
 #, c-format
 msgid "unrecognized argument: %s"
 msgstr "未能识别的参数:%s"
@@ -9645,21 +9713,6 @@
 msgstr "无法获得关于 '%s' 的对象信息"
 
 #: builtin/ls-files.c
-#, c-format
-msgid "bad ls-files format: element '%s' does not start with '('"
-msgstr "坏的 ls-files 格式:元素 '%s' 没有以 '(' 开头"
-
-#: builtin/ls-files.c
-#, c-format
-msgid "bad ls-files format: element '%s' does not end in ')'"
-msgstr "坏的 ls-files 格式:元素 '%s' 没有以 ')' 结尾"
-
-#: builtin/ls-files.c
-#, c-format
-msgid "bad ls-files format: %%%.*s"
-msgstr "坏的 ls-files 格式: %%%.*s"
-
-#: builtin/ls-files.c
 msgid "git ls-files [<options>] [<file>...]"
 msgstr "git ls-files [<选项>] [<文件>...]"
 
@@ -9751,7 +9804,7 @@
 msgid "if any <file> is not in the index, treat this as an error"
 msgstr "如果任何 <文件> 都不在索引区,视为错误"
 
-#: builtin/ls-files.c
+#: builtin/ls-files.c builtin/merge-tree.c
 msgid "tree-ish"
 msgstr "树对象"
 
@@ -9830,21 +9883,6 @@
 msgstr "git ls-tree [<选项>] <树对象> [<路径>...]"
 
 #: builtin/ls-tree.c
-#, c-format
-msgid "bad ls-tree format: element '%s' does not start with '('"
-msgstr "坏的 ls-tree 格式:元素 '%s' 没有以 '(' 开头"
-
-#: builtin/ls-tree.c
-#, c-format
-msgid "bad ls-tree format: element '%s' does not end in ')'"
-msgstr "坏的 ls-tree 格式:元素 '%s' 没有以 ')' 结尾"
-
-#: builtin/ls-tree.c
-#, c-format
-msgid "bad ls-tree format: %%%.*s"
-msgstr "坏的 ls-tree 格式: %%%.*s"
-
-#: builtin/ls-tree.c
 msgid "only show trees"
 msgstr "只显示树"
 
@@ -9990,6 +10028,14 @@
 "git merge-file [<选项>] [-L <名字1> [-L <初始名字> [-L <名字2>]]] <文件1> <初"
 "始文件> <文件2>"
 
+#: builtin/merge-file.c diff.c
+msgid ""
+"option diff-algorithm accepts \"myers\", \"minimal\", \"patience\" and "
+"\"histogram\""
+msgstr ""
+"选项 diff-algorithm 接受参数 \"myers\"、\"minimal\"、\"patience\" 和 "
+"\"histogram\""
+
 #: builtin/merge-file.c
 msgid "send results to standard output"
 msgstr "将结果发送到标准输出"
@@ -10018,6 +10064,14 @@
 msgid "for conflicts, use a union version"
 msgstr "如果冲突,使用联合版本"
 
+#: builtin/merge-file.c diff.c
+msgid "<algorithm>"
+msgstr "<算法>"
+
+#: builtin/merge-file.c diff.c
+msgid "choose a diff algorithm"
+msgstr "选择一个差异算法"
+
 #: builtin/merge-file.c
 msgid "for conflicts, use this marker size"
 msgstr "如果冲突,使用指定长度的标记"
@@ -10070,6 +10124,11 @@
 msgid "Merging %s with %s\n"
 msgstr "合并 %s 和 %s\n"
 
+#: builtin/merge-tree.c
+#, c-format
+msgid "could not parse as tree '%s'"
+msgstr "无法解析为树对象 '%s'"
+
 #: builtin/merge-tree.c builtin/merge.c
 msgid "not something we can merge"
 msgstr "不是可以合并的东西"
@@ -10135,10 +10194,6 @@
 msgid "unknown strategy option: -X%s"
 msgstr "未知的策略选项:-X%s"
 
-#: builtin/merge-tree.c
-msgid "--merge-base is incompatible with --stdin"
-msgstr "--merge-base 与 --stdin 不兼容"
-
 #: builtin/merge-tree.c builtin/notes.c
 #, c-format
 msgid "malformed input line: '%s'."
@@ -10296,7 +10351,7 @@
 msgid "Bad branch.%s.mergeoptions string: %s"
 msgstr "坏的 branch.%s.mergeoptions 字符串:%s"
 
-#: builtin/merge.c builtin/stash.c merge-recursive.c
+#: builtin/merge.c merge-recursive.c
 msgid "Unable to write index."
 msgstr "不能写入索引。"
 
@@ -10304,7 +10359,7 @@
 msgid "Not handling anything other than two heads merge."
 msgstr "未处理两个头合并之外的任何操作。"
 
-#: builtin/merge.c t/helper/test-fast-rebase.c
+#: builtin/merge.c
 #, c-format
 msgid "unable to write %s"
 msgstr "不能写 %s"
@@ -10336,9 +10391,9 @@
 #: builtin/merge.c
 #, c-format
 msgid ""
-"Lines starting with '%c' will be ignored, and an empty message aborts\n"
+"Lines starting with '%s' will be ignored, and an empty message aborts\n"
 "the commit.\n"
-msgstr "以 '%c' 开始的行将被忽略,而空的提交说明将终止提交。\n"
+msgstr "以 '%s' 开始的行将被忽略,而空的提交说明将终止提交。\n"
 
 #: builtin/merge.c
 msgid "Empty commit message."
@@ -10531,10 +10586,6 @@
 msgid "object '%s' tagged as '%s', but is a '%s' type"
 msgstr "对象 '%s' 被标记为 '%s',然而是一个 '%s' 类型"
 
-#: builtin/mktag.c imap-send.c trailer.c
-msgid "could not read from stdin"
-msgstr "不能自标准输入读取"
-
 #: builtin/mktag.c
 msgid "tag on stdin did not pass our strict fsck check"
 msgstr "标准输入上的标签未通过我们严格的 fsck 检查"
@@ -10867,11 +10918,6 @@
 msgstr "为下面的对象写/编辑说明:"
 
 #: builtin/notes.c
-#, c-format
-msgid "unable to start 'show' for object '%s'"
-msgstr "不能为对象 '%s' 开始 'show'"
-
-#: builtin/notes.c
 msgid "could not read 'show' output"
 msgstr "不能读取 'show' 的输出"
 
@@ -11292,6 +11338,11 @@
 
 #: builtin/pack-objects.c
 #, c-format
+msgid "invalid pack.allowPackReuse value: '%s'"
+msgstr "无效的 pack.allowPackReuse 值:'%s'"
+
+#: builtin/pack-objects.c
+#, c-format
 msgid ""
 "value of uploadpack.blobpackfileuri must be of the form '<object-hash> <pack-"
 "hash> <uri>' (got '%s')"
@@ -11614,10 +11665,10 @@
 #, c-format
 msgid ""
 "Total %<PRIu32> (delta %<PRIu32>), reused %<PRIu32> (delta %<PRIu32>), pack-"
-"reused %<PRIu32>"
+"reused %<PRIu32> (from %<PRIuMAX>)"
 msgstr ""
 "总共 %<PRIu32>(差异 %<PRIu32>),复用 %<PRIu32>(差异 %<PRIu32>),包复用 "
-"%<PRIu32>"
+"%<PRIu32>(来自  %<PRIuMAX> 个包)"
 
 #: builtin/pack-redundant.c
 msgid ""
@@ -11638,10 +11689,11 @@
 
 #: builtin/pack-refs.c
 msgid ""
-"git pack-refs [--all] [--no-prune] [--include <pattern>] [--exclude "
+"git pack-refs [--all] [--no-prune] [--auto] [--include <pattern>] [--exclude "
 "<pattern>]"
 msgstr ""
-"git pack-refs [--all] [--no-prune] [--include <模式>] [--exclude <模式>]"
+"git pack-refs [--all] [--no-prune] [--auto] [--include <模式>] [--exclude <模"
+"式>]"
 
 #: builtin/pack-refs.c
 msgid "pack everything"
@@ -11652,6 +11704,10 @@
 msgstr "清除松散的引用(默认)"
 
 #: builtin/pack-refs.c
+msgid "auto-pack refs as needed"
+msgstr "按需对引用自动打包"
+
+#: builtin/pack-refs.c
 msgid "references to include"
 msgstr "需包含的引用"
 
@@ -12412,19 +12468,6 @@
 msgstr "无法删除 '%s'"
 
 #: builtin/rebase.c
-msgid ""
-"Resolve all conflicts manually, mark them as resolved with\n"
-"\"git add/rm <conflicted_files>\", then run \"git rebase --continue\".\n"
-"You can instead skip this commit: run \"git rebase --skip\".\n"
-"To abort and get back to the state before \"git rebase\", run \"git rebase --"
-"abort\"."
-msgstr ""
-"手工解决所有冲突,执行 \"git add/rm <冲突的文件>\" 标记\n"
-"冲突已解决,然后执行 \"git rebase --continue\"。您也可以执行\n"
-"\"git rebase --skip\" 命令跳过这个提交。如果想要终止执行并回到\n"
-"\"git rebase\" 执行之前的状态,执行 \"git rebase --abort\"。"
-
-#: builtin/rebase.c
 #, c-format
 msgid ""
 "\n"
@@ -12457,11 +12500,15 @@
 msgstr "应用选项和合并选项不能同时使用"
 
 #: builtin/rebase.c
+msgid "--empty=ask is deprecated; use '--empty=stop' instead."
+msgstr "--empty=ask 已弃用;请使用 '--empty=stop'。"
+
+#: builtin/rebase.c
 #, c-format
 msgid ""
 "unrecognized empty type '%s'; valid values are \"drop\", \"keep\", and "
-"\"ask\"."
-msgstr "无法识别的空类型 '%s';有效值有 \"drop\"、\"keep\" 和 \"ask\"。"
+"\"stop\"."
+msgstr "无法识别的空类型 '%s';有效值有 \"drop\"、\"keep\" 和 \"stop\"。"
 
 #: builtin/rebase.c
 msgid ""
@@ -12603,7 +12650,7 @@
 msgid "(REMOVED) was: try to recreate merges instead of ignoring them"
 msgstr "(已删除)曾是:尝试重建合并提交而非忽略它们"
 
-#: builtin/rebase.c
+#: builtin/rebase.c builtin/revert.c
 msgid "how to handle commits that become empty"
 msgstr "如何处理成为空提交的提交"
 
@@ -12684,14 +12731,14 @@
 "取而代之请使用 'merges'"
 
 #: builtin/rebase.c
-msgid "No rebase in progress?"
-msgstr "没有正在进行的变基?"
+msgid "no rebase in progress"
+msgstr "没有正在进行的变基"
 
 #: builtin/rebase.c
 msgid "The --edit-todo action can only be used during interactive rebase."
 msgstr "动作 --edit-todo 只能用在交互式变基过程中。"
 
-#: builtin/rebase.c t/helper/test-fast-rebase.c
+#: builtin/rebase.c
 msgid "Cannot read HEAD"
 msgstr "不能读取 HEAD"
 
@@ -12737,12 +12784,6 @@
 
 #: builtin/rebase.c
 msgid ""
-"apply options are incompatible with rebase.autoSquash.  Consider adding --no-"
-"autosquash"
-msgstr "应用的选项与 rebase.autoSquash 不兼容。考虑加上 --no-autosquash"
-
-#: builtin/rebase.c
-msgid ""
 "apply options are incompatible with rebase.rebaseMerges.  Consider adding --"
 "no-rebase-merges"
 msgstr "应用的选项与 rebase.rebaseMerges 不兼容。考虑加上 --no-rebase-merges"
@@ -12908,6 +12949,10 @@
 msgstr "git reflog [show] [<log 选项>] [<引用>]"
 
 #: builtin/reflog.c
+msgid "git reflog list"
+msgstr "git reflog list"
+
+#: builtin/reflog.c
 msgid ""
 "git reflog expire [--expire=<time>] [--expire-unreachable=<time>]\n"
 "                  [--rewrite] [--updateref] [--stale-fix]\n"
@@ -12936,6 +12981,11 @@
 msgid "invalid timestamp '%s' given to '--%s'"
 msgstr "给 '--%2$s' 的时间戳 '%1$s' 无效"
 
+#: builtin/reflog.c sequencer.c
+#, c-format
+msgid "%s does not accept arguments: '%s'"
+msgstr "%s 不接受参数:'%s'"
+
 #: builtin/reflog.c
 msgid "do not actually prune any entries"
 msgstr "不要实际清除任何条目"
@@ -13095,8 +13145,8 @@
 
 #: builtin/remote.c
 #, c-format
-msgid "unknown mirror argument: %s"
-msgstr "未知的镜像参数:%s"
+msgid "unknown --mirror argument: %s"
+msgstr "未知的 --mirror 参数:%s"
 
 #: builtin/remote.c
 msgid "fetch the remote branches"
@@ -13224,8 +13274,8 @@
 msgid_plural ""
 "Note: Some branches outside the refs/remotes/ hierarchy were not removed;\n"
 "to delete them, use:"
-msgstr[0] "注意:ref/remotes 层级之外的一个分支未被移除。要删除它,使用:"
-msgstr[1] "注意:ref/remotes 层级之外的一些分支未被移除。要删除它们,使用:"
+msgstr[0] "注意:refs/remotes/ 层级之外的一个分支未被移除。要删除它,使用:"
+msgstr[1] "注意:refs/remotes/ 层级之外的一些分支未被移除。要删除它们,使用:"
 
 #: builtin/remote.c
 #, c-format
@@ -13547,6 +13597,10 @@
 msgstr "无法开始 pack-objects 来重新打包 promisor 对象"
 
 #: builtin/repack.c
+msgid "failed to feed promisor objects to pack-objects"
+msgstr "无法将承诺者对象提供给 pack-objects"
+
+#: builtin/repack.c
 msgid "repack: Expecting full hex object ID lines only from pack-objects."
 msgstr "repack:期望来自 pack-objects 的完整十六进制对象 ID。"
 
@@ -13956,6 +14010,87 @@
 msgid "only one pattern can be given with -l"
 msgstr "只能为 -l 提供一个模式"
 
+#: builtin/replay.c
+msgid "need some commits to replay"
+msgstr "需要一些提交来重放"
+
+#: builtin/replay.c
+msgid "--onto and --advance are incompatible"
+msgstr "--onto 和 --advance 不兼容"
+
+#: builtin/replay.c
+msgid "all positive revisions given must be references"
+msgstr "提供的所有正向版本必须为引用"
+
+#: builtin/replay.c
+msgid "argument to --advance must be a reference"
+msgstr "--advance 的参数必须是引用"
+
+#: builtin/replay.c
+msgid ""
+"cannot advance target with multiple sources because ordering would be ill-"
+"defined"
+msgstr "不能使用多个源推进目标,因为无法明确如何排序"
+
+#: builtin/replay.c
+msgid ""
+"cannot implicitly determine whether this is an --advance or --onto operation"
+msgstr "不能隐式地确定这是 --advance 还是 --onto 的操作"
+
+#: builtin/replay.c
+msgid ""
+"cannot advance target with multiple source branches because ordering would "
+"be ill-defined"
+msgstr "不能使用多个源分支推进目标,因为无法明确如何排序"
+
+#: builtin/replay.c
+msgid "cannot implicitly determine correct base for --onto"
+msgstr "不能隐式地确定 --onto 正确的基线"
+
+#: builtin/replay.c
+msgid ""
+"(EXPERIMENTAL!) git replay ([--contained] --onto <newbase> | --advance "
+"<branch>) <revision-range>..."
+msgstr ""
+"(试验中!)git replay ([--contained] --onto <新基线> | --advance <分支>) <版"
+"本范围>..."
+
+#: builtin/replay.c
+msgid "make replay advance given branch"
+msgstr "重放时演进给定的分支"
+
+#: builtin/replay.c
+msgid "replay onto given commit"
+msgstr "重放到给定提交"
+
+#: builtin/replay.c
+msgid "advance all branches contained in revision-range"
+msgstr "演进版本范围中包含的所有分支"
+
+#: builtin/replay.c
+msgid "option --onto or --advance is mandatory"
+msgstr "选项 --onto 或 --advance 必须指定其一"
+
+#: builtin/replay.c
+#, c-format
+msgid ""
+"some rev walking options will be overridden as '%s' bit in 'struct rev_info' "
+"will be forced"
+msgstr ""
+"一些版本遍历选项将被覆盖,如 'struct rev_info' 中的 '%s' 位将被强制设定"
+
+#: builtin/replay.c
+msgid "error preparing revisions"
+msgstr "准备版本时错误"
+
+#: builtin/replay.c
+msgid "replaying down to root commit is not supported yet!"
+msgstr "目前还不支持重放到根提交!"
+
+#: builtin/replay.c
+msgid "replaying merge commits is not supported yet!"
+msgstr "目前还不支持重放到合并提交!"
+
 #: builtin/rerere.c
 msgid ""
 "git rerere [clear | forget <pathspec>... | diff | status | remaining | gc]"
@@ -14211,22 +14346,19 @@
 msgstr "--prefix 需要一个参数"
 
 #: builtin/rev-parse.c
+msgid "no object format specified"
+msgstr "未指定对象格式"
+
+#: builtin/rev-parse.c
+#, c-format
+msgid "unsupported object format: %s"
+msgstr "不支持的对象格式:'%s'"
+
+#: builtin/rev-parse.c
 #, c-format
 msgid "unknown mode for --abbrev-ref: %s"
 msgstr "未知的 --abbrev-ref 模式:%s"
 
-#: builtin/rev-parse.c revision.c
-msgid "--exclude-hidden cannot be used together with --branches"
-msgstr "--exclude-hidden 不能与 --branches 一起使用"
-
-#: builtin/rev-parse.c revision.c
-msgid "--exclude-hidden cannot be used together with --tags"
-msgstr "--exclude-hidden 不能与 --tags 一起使用"
-
-#: builtin/rev-parse.c revision.c
-msgid "--exclude-hidden cannot be used together with --remotes"
-msgstr "--exclude-hidden 不能与 --remotes 一起使用"
-
 #: builtin/rev-parse.c setup.c
 msgid "this operation must be run in a work tree"
 msgstr "该操作必须在一个工作区中运行"
@@ -14326,8 +14458,8 @@
 msgstr "允许提交说明为空"
 
 #: builtin/revert.c
-msgid "keep redundant, empty commits"
-msgstr "保持多余的、空的提交"
+msgid "deprecated: use --empty=keep instead"
+msgstr "已弃用:取而代之使用 --empty=keep"
 
 #: builtin/revert.c
 msgid "use the 'reference' format to refer to commits"
@@ -14730,11 +14862,6 @@
 msgid "show refs from stdin that aren't in local repository"
 msgstr "显示从标准输入中读入的不在本地仓库中的引用"
 
-#: builtin/show-ref.c
-#, c-format
-msgid "only one of '%s', '%s' or '%s' can be given"
-msgstr "选项 '%s'、'%s' 或 '%s' 只能使用其一"
-
 #: builtin/sparse-checkout.c
 msgid ""
 "git sparse-checkout (init | list | set | add | reapply | disable | check-"
@@ -14783,7 +14910,7 @@
 msgid "toggle the use of a sparse index"
 msgstr "切换稀疏索引的使用"
 
-#: builtin/sparse-checkout.c commit-graph.c midx.c sequencer.c
+#: builtin/sparse-checkout.c commit-graph.c midx-write.c sequencer.c
 #, c-format
 msgid "unable to create leading directories of %s"
 msgstr "不能为 %s 创建先导目录"
@@ -15947,12 +16074,12 @@
 "\n"
 "Write a message for tag:\n"
 "  %s\n"
-"Lines starting with '%c' will be ignored.\n"
+"Lines starting with '%s' will be ignored.\n"
 msgstr ""
 "\n"
 "输入一个标签说明:\n"
 "  %s\n"
-"以 '%c' 开头的行将被忽略。\n"
+"以 '%s' 开头的行将被忽略。\n"
 
 #: builtin/tag.c
 #, c-format
@@ -15960,13 +16087,13 @@
 "\n"
 "Write a message for tag:\n"
 "  %s\n"
-"Lines starting with '%c' will be kept; you may remove them yourself if you "
+"Lines starting with '%s' will be kept; you may remove them yourself if you "
 "want to.\n"
 msgstr ""
 "\n"
 "输入一个标签说明:\n"
 "  %s\n"
-"以 '%c' 开头的行将被保留,如果您愿意也可以删除它们。\n"
+"以 '%s' 开头的行将被保留,如果您愿意也可以删除它们。\n"
 
 #: builtin/tag.c
 msgid "unable to sign the tag"
@@ -16075,6 +16202,10 @@
 msgstr "只打印指向该对象的标签"
 
 #: builtin/tag.c
+msgid "could not start 'git column'"
+msgstr "无法启动 'git column'"
+
+#: builtin/tag.c
 #, c-format
 msgid "the '%s' option is only allowed in list mode"
 msgstr "'%s' 选项只允许用在列表显示模式"
@@ -16379,12 +16510,12 @@
 msgstr "fsmonitor 被禁用"
 
 #: builtin/update-ref.c
-msgid "git update-ref [<options>] -d <refname> [<old-val>]"
-msgstr "git update-ref [<选项>] -d <引用名> [<旧值>]"
+msgid "git update-ref [<options>] -d <refname> [<old-oid>]"
+msgstr "git update-ref [<选项>] -d <引用名> [<旧对象>]"
 
 #: builtin/update-ref.c
-msgid "git update-ref [<options>]    <refname> <new-val> [<old-val>]"
-msgstr "git update-ref [<选项>]    <引用名> <新值> [<旧值>]"
+msgid "git update-ref [<options>]    <refname> <new-oid> [<old-oid>]"
+msgstr "git update-ref [<选项>]    <引用名> <新对象> [<旧对象>]"
 
 #: builtin/update-ref.c
 msgid "git update-ref [<options>] --stdin [-z]"
@@ -16509,30 +16640,30 @@
 #: builtin/worktree.c
 #, c-format
 msgid ""
-"If you meant to create a worktree containing a new orphan branch\n"
+"If you meant to create a worktree containing a new unborn branch\n"
 "(branch with no commits) for this repository, you can do so\n"
 "using the --orphan flag:\n"
 "\n"
 "    git worktree add --orphan -b %s %s\n"
 msgstr ""
-"如果你打算为此仓库创建一个包含新的孤立分支\n"
-"(没有提交的分支)的工作区,你可以使用选项\n"
-"--orphan 来执行此操作:\n"
+"如果你打算为此仓库创建一个包含新的未诞生的\n"
+"分支(没有提交的分支)的工作区,你可以使用\n"
+"选项 --orphan 来执行此操作:\n"
 "\n"
 "    git worktree add --orphan -b %s %s\n"
 
 #: builtin/worktree.c
 #, c-format
 msgid ""
-"If you meant to create a worktree containing a new orphan branch\n"
+"If you meant to create a worktree containing a new unborn branch\n"
 "(branch with no commits) for this repository, you can do so\n"
 "using the --orphan flag:\n"
 "\n"
 "    git worktree add --orphan %s\n"
 msgstr ""
-"如果你打算为此仓库创建一个包含新的孤立分支\n"
-"(没有提交的分支)的工作区,你可以使用选项\n"
-"--orphan 来执行此操作:\n"
+"如果你打算为此仓库创建一个包含新的未诞生的\n"
+"分支(没有提交的分支)的工作区,你可以使用\n"
+"选项 --orphan 来执行此操作:\n"
 "\n"
 "    git worktree add --orphan %s\n"
 
@@ -16603,6 +16734,11 @@
 
 #: builtin/worktree.c
 #, c-format
+msgid "could not find created worktree '%s'"
+msgstr "无法找到已创建的工作树 '%s'"
+
+#: builtin/worktree.c
+#, c-format
 msgid "Preparing worktree (new branch '%s')"
 msgstr "准备工作区(新分支 '%s')"
 
@@ -16646,11 +16782,6 @@
 "请先使用 'add -f' 来覆盖或拉取一个远程仓库"
 
 #: builtin/worktree.c
-#, c-format
-msgid "'%s' and '%s' cannot be used together"
-msgstr "'%s' 和 '%s' 不能同时使用"
-
-#: builtin/worktree.c
 msgid "checkout <branch> even if already checked out in other worktree"
 msgstr "检出 <分支>,即使已经被检出到其它工作区"
 
@@ -16663,8 +16794,8 @@
 msgstr "创建或重置一个分支"
 
 #: builtin/worktree.c
-msgid "create unborn/orphaned branch"
-msgstr "创建一个尚未诞生的/孤立的分支"
+msgid "create unborn branch"
+msgstr "创建一个尚未诞生的分支"
 
 #: builtin/worktree.c
 msgid "populate the new working tree"
@@ -16693,12 +16824,8 @@
 
 #: builtin/worktree.c
 #, c-format
-msgid "options '%s', and '%s' cannot be used together"
-msgstr "选项 '%s' 与 '%s' 不能同时使用"
-
-#: builtin/worktree.c
-msgid "<commit-ish>"
-msgstr "<提交号>"
+msgid "option '%s' and commit-ish cannot be used together"
+msgstr "选项 '%s' 和提交号不能同时使用"
 
 #: builtin/worktree.c
 msgid "added with --lock"
@@ -17489,6 +17616,10 @@
 msgstr "创建、列出、删除对象替换引用"
 
 #: command-list.h
+msgid "EXPERIMENTAL: Replay commits on a new base, works with bare repos too"
+msgstr "试验中:基于一个新基线重放提交,同样适用于纯仓库"
+
+#: command-list.h
 msgid "Generates a summary of pending changes"
 msgstr "生成待定更改的摘要"
 
@@ -17803,39 +17934,82 @@
 
 #: commit-graph.c
 msgid "commit-graph file is too small"
-msgstr "提交图形文件太小"
+msgstr "提交图文件太小"
+
+#: commit-graph.c
+msgid "commit-graph oid fanout chunk is wrong size"
+msgstr "提交图中对象 ID 的扇出块大小错误"
+
+#: commit-graph.c
+msgid "commit-graph fanout values out of order"
+msgstr "提交图的扇出值失序"
+
+#: commit-graph.c
+msgid "commit-graph OID lookup chunk is the wrong size"
+msgstr "提交图的对象 ID 查询块大小错误"
+
+#: commit-graph.c
+msgid "commit-graph commit data chunk is wrong size"
+msgstr "提交图的提交数据块大小错误"
+
+#: commit-graph.c
+msgid "commit-graph generations chunk is wrong size"
+msgstr "提交图的世代块大小错误"
+
+#: commit-graph.c
+msgid "commit-graph changed-path index chunk is too small"
+msgstr "提交图的变更路径的索引块太小"
+
+#: commit-graph.c
+#, c-format
+msgid ""
+"ignoring too-small changed-path chunk (%<PRIuMAX> < %<PRIuMAX>) in commit-"
+"graph file"
+msgstr "忽略提交图文件中过小的更改路径块(%<PRIuMAX> < %<PRIuMAX>)"
 
 #: commit-graph.c
 #, c-format
 msgid "commit-graph signature %X does not match signature %X"
-msgstr "提交图形签名 %X 和签名 %X 不匹配"
+msgstr "提交图签名 %X 和签名 %X 不匹配"
 
 #: commit-graph.c
 #, c-format
 msgid "commit-graph version %X does not match version %X"
-msgstr "提交图形版本 %X 和版本 %X 不匹配"
+msgstr "提交图版本 %X 和版本 %X 不匹配"
 
 #: commit-graph.c
 #, c-format
 msgid "commit-graph hash version %X does not match version %X"
-msgstr "提交图形哈希版本 %X 和版本 %X 不匹配"
+msgstr "提交图哈希版本 %X 和版本 %X 不匹配"
 
 #: commit-graph.c
 #, c-format
 msgid "commit-graph file is too small to hold %u chunks"
-msgstr "提交图形文件太小,容不下 %u 个块"
+msgstr "提交图文件太小,容不下 %u 个块"
+
+#: commit-graph.c
+msgid "commit-graph required OID fanout chunk missing or corrupted"
+msgstr "提交图所需的对象 ID 扇出块缺失或损坏"
+
+#: commit-graph.c
+msgid "commit-graph required OID lookup chunk missing or corrupted"
+msgstr "提交图所需的对象 ID 查询块缺失或损坏"
+
+#: commit-graph.c
+msgid "commit-graph required commit data chunk missing or corrupted"
+msgstr "提交图所需的提交数据块缺失或损坏"
 
 #: commit-graph.c
 msgid "commit-graph has no base graphs chunk"
-msgstr "提交图形没有基础图形块"
+msgstr "提交图没有基础图形块"
 
 #: commit-graph.c
 msgid "commit-graph base graphs chunk is too small"
-msgstr "提交图形的基础图形块过小"
+msgstr "提交图的基础图形块过小"
 
 #: commit-graph.c
 msgid "commit-graph chain does not match"
-msgstr "提交图形链不匹配"
+msgstr "提交图链不匹配"
 
 #: commit-graph.c
 #, c-format
@@ -17843,17 +18017,21 @@
 msgstr "基础图形中的提交数量过高:%<PRIuMAX>"
 
 #: commit-graph.c
+msgid "commit-graph chain file too small"
+msgstr "提交图链文件太小"
+
+#: commit-graph.c
 #, c-format
 msgid "invalid commit-graph chain: line '%s' not a hash"
-msgstr "无效的提交图形链:行 '%s' 不是一个哈希值"
+msgstr "无效的提交图链:行 '%s' 不是一个哈希值"
 
 #: commit-graph.c
 msgid "unable to find all commit-graph files"
-msgstr "无法找到所有提交图形文件"
+msgstr "无法找到所有提交图文件"
 
 #: commit-graph.c
 msgid "invalid commit position. commit-graph is likely corrupt"
-msgstr "无效的提交位置。提交图形可能已损坏"
+msgstr "无效的提交位置。提交图可能已损坏"
 
 #: commit-graph.c
 #, c-format
@@ -17869,6 +18047,10 @@
 msgstr "提交图溢出世代数据过小"
 
 #: commit-graph.c
+msgid "commit-graph extra-edges pointer out of bounds"
+msgstr "提交图额外边的指针越界"
+
+#: commit-graph.c
 msgid "Loading known commits in commit graph"
 msgstr "正在加载提交图中的已知提交"
 
@@ -17943,26 +18125,26 @@
 
 #: commit-graph.c
 msgid "unable to open commit-graph chain file"
-msgstr "无法打开提交图形链文件"
+msgstr "无法打开提交图链文件"
 
 #: commit-graph.c
 msgid "failed to rename base commit-graph file"
-msgstr "无法重命名基础提交图形文件"
+msgstr "无法重命名基础提交图文件"
 
 #: commit-graph.c
 msgid "failed to rename temporary commit-graph file"
-msgstr "无法重命名临时提交图形文件"
+msgstr "无法重命名临时提交图文件"
 
 #: commit-graph.c
 #, c-format
 msgid "cannot merge graphs with %<PRIuMAX>, %<PRIuMAX> commits"
 msgstr ""
-"无法合并提交图形,总共已累加提交数:%<PRIuMAX>,当前待累加提交数:%<PRIuMAX>"
+"无法合并提交图,总共已累加提交数:%<PRIuMAX>,当前待累加提交数:%<PRIuMAX>"
 
 #: commit-graph.c
 #, c-format
 msgid "cannot merge graph %s, too many commits: %<PRIuMAX>"
-msgstr "无法合并提交图形 %s, 提交过多:%<PRIuMAX>"
+msgstr "无法合并提交图 %s, 提交过多:%<PRIuMAX>"
 
 #: commit-graph.c
 msgid "Scanning merged commits"
@@ -17970,7 +18152,7 @@
 
 #: commit-graph.c
 msgid "Merging commit-graph"
-msgstr "正在合并提交图形"
+msgstr "正在合并提交图"
 
 #: commit-graph.c
 msgid "attempting to write a commit-graph, but 'core.commitGraph' is disabled"
@@ -17987,64 +18169,69 @@
 #: commit-graph.c
 #, c-format
 msgid "commit-graph has incorrect OID order: %s then %s"
-msgstr "提交图形的对象 ID 顺序不正确:%s 然后 %s"
+msgstr "提交图的对象 ID 顺序不正确:%s 然后 %s"
 
 #: commit-graph.c
 #, c-format
 msgid "commit-graph has incorrect fanout value: fanout[%d] = %u != %u"
-msgstr "提交图形有不正确的扇出值:fanout[%d] = %u != %u"
+msgstr "提交图有不正确的扇出值:fanout[%d] = %u != %u"
 
 #: commit-graph.c
 #, c-format
 msgid "failed to parse commit %s from commit-graph"
-msgstr "无法从提交图形中解析提交 %s"
+msgstr "无法从提交图中解析提交 %s"
 
 #: commit-graph.c
 #, c-format
 msgid "failed to parse commit %s from object database for commit-graph"
-msgstr "无法从提交图形的对象库中解析提交 %s"
+msgstr "无法从提交图的对象库中解析提交 %s"
 
 #: commit-graph.c
 #, c-format
 msgid "root tree OID for commit %s in commit-graph is %s != %s"
-msgstr "提交图形中的提交 %s 的根树对象 ID 是 %s != %s"
+msgstr "提交图中的提交 %s 的根树对象 ID 是 %s != %s"
 
 #: commit-graph.c
 #, c-format
 msgid "commit-graph parent list for commit %s is too long"
-msgstr "提交 %s 的提交图形父提交列表太长了"
+msgstr "提交 %s 的提交图父提交列表太长了"
 
 #: commit-graph.c
 #, c-format
 msgid "commit-graph parent for %s is %s != %s"
-msgstr "%s 的提交图形父提交是 %s != %s"
+msgstr "%s 的提交图父提交是 %s != %s"
 
 #: commit-graph.c
 #, c-format
 msgid "commit-graph parent list for commit %s terminates early"
-msgstr "提交 %s 的提交图形父提交列表过早终止"
+msgstr "提交 %s 的提交图父提交列表过早终止"
 
 #: commit-graph.c
 #, c-format
 msgid "commit-graph generation for commit %s is %<PRIuMAX> < %<PRIuMAX>"
-msgstr "提交图形中的提交 %s 的世代号是 %<PRIuMAX> < %<PRIuMAX>"
+msgstr "提交图中的提交 %s 的世代号是 %<PRIuMAX> < %<PRIuMAX>"
 
 #: commit-graph.c
 #, c-format
 msgid "commit date for commit %s in commit-graph is %<PRIuMAX> != %<PRIuMAX>"
-msgstr "提交图形中提交 %s 的提交日期是 %<PRIuMAX> != %<PRIuMAX>"
+msgstr "提交图中提交 %s 的提交日期是 %<PRIuMAX> != %<PRIuMAX>"
 
 #: commit-graph.c
 #, c-format
 msgid ""
 "commit-graph has both zero and non-zero generations (e.g., commits '%s' and "
 "'%s')"
-msgstr "提交图形具有零和非零的世代(例如:提交 '%s' 和 '%s')"
+msgstr "提交图具有零和非零的世代(例如:提交 '%s' 和 '%s')"
 
 #: commit-graph.c
 msgid "Verifying commits in commit graph"
 msgstr "正在校验提交图中的提交"
 
+#: commit-reach.c sequencer.c
+#, c-format
+msgid "could not parse commit %s"
+msgstr "不能解析提交 %s"
+
 #: commit.c
 #, c-format
 msgid "%s %s is not a commit!"
@@ -18073,7 +18260,7 @@
 #: commit.c
 #, c-format
 msgid "commit %s exists in commit-graph but not in the object database"
-msgstr "提交 %s 存在于提交图形中,但不存在于对象数据库中"
+msgstr "提交 %s 存在于提交图中,但不存在于对象数据库中"
 
 #: commit.c
 #, c-format
@@ -18572,8 +18759,14 @@
 msgstr "错误的 zlib 压缩级别 %d"
 
 #: config.c
-msgid "core.commentChar should only be one ASCII character"
-msgstr "core.commentChar 应该是一个 ASCII 编码的字符"
+#, c-format
+msgid "%s cannot contain newline"
+msgstr "%s 不能包含换行符"
+
+#: config.c
+#, c-format
+msgid "%s must have at least one character"
+msgstr "%s 必须至少有一个字符"
 
 #: config.c
 #, c-format
@@ -18663,6 +18856,11 @@
 
 #: config.c
 #, c-format
+msgid "no multi-line comment allowed: '%s'"
+msgstr "不允许多行注释:'%s'"
+
+#: config.c
+#, c-format
 msgid "could not lock config file %s"
 msgstr "不能锁定配置文件 %s"
 
@@ -19255,6 +19453,11 @@
 msgid "Unknown value for 'diff.submodule' config variable: '%s'"
 msgstr "配置变量 'diff.submodule' 未知的取值:'%s'"
 
+#: diff.c transport.c
+#, c-format
+msgid "unknown value for config '%s': %s"
+msgstr "配置 '%s' 未知的取值:%s"
+
 #: diff.c
 #, c-format
 msgid ""
@@ -19349,13 +19552,6 @@
 msgstr "--color-moved-ws 中的无效模式 '%s' "
 
 #: diff.c
-msgid ""
-"option diff-algorithm accepts \"myers\", \"minimal\", \"patience\" and "
-"\"histogram\""
-msgstr ""
-"diff-algorithm 选项有 \"myers\"、\"minimal\"、\"patience\" 和 \"histogram\""
-
-#: diff.c
 #, c-format
 msgid "invalid argument to %s"
 msgstr "%s 的参数无效"
@@ -19412,8 +19608,8 @@
 msgstr "只输出 --stat 的最后一行"
 
 #: diff.c
-msgid "<param1,param2>..."
-msgstr "<参数1,参数2>..."
+msgid "<param1>,<param2>..."
+msgstr "<参数1>,<参数2>..."
 
 #: diff.c
 msgid ""
@@ -19425,8 +19621,8 @@
 msgstr "和 --dirstat=cumulative 同义"
 
 #: diff.c
-msgid "synonym for --dirstat=files,param1,param2..."
-msgstr "是 --dirstat=files,param1,param2... 的同义词"
+msgid "synonym for --dirstat=files,<param1>,<param2>..."
+msgstr "是 --dirstat=files,<参数1>,<参数2>... 的同义词"
 
 #: diff.c
 msgid "warn if changes introduce conflict markers or whitespace errors"
@@ -19649,14 +19845,6 @@
 msgstr "使用 \"histogram diff\" 算法生成差异"
 
 #: diff.c
-msgid "<algorithm>"
-msgstr "<算法>"
-
-#: diff.c
-msgid "choose a diff algorithm"
-msgstr "选择一个差异算法"
-
-#: diff.c
 msgid "<text>"
 msgstr "<文本>"
 
@@ -20849,6 +21037,16 @@
 msgid "Unable to create '%s.lock': %s"
 msgstr "不能创建 '%s.lock':%s"
 
+#: loose.c
+#, c-format
+msgid "could not write loose object index %s"
+msgstr "不能写入松散对象索引 %s"
+
+#: loose.c
+#, c-format
+msgid "failed to write loose object index %s\n"
+msgstr "无法写入松散对象索引 %s\n"
+
 #: ls-refs.c
 #, c-format
 msgid "unexpected line: '%s'"
@@ -20862,6 +21060,11 @@
 msgid "quoted CRLF detected"
 msgstr "检测到被引用的 CRLF"
 
+#: mem-pool.c strbuf.c wrapper.c
+#, c-format
+msgid "unable to format message: %s"
+msgstr "无法格式化消息:%s"
+
 #: merge-ort.c merge-recursive.c
 #, c-format
 msgid "Failed to merge submodule %s (not checked out)"
@@ -20879,6 +21082,11 @@
 
 #: merge-ort.c merge-recursive.c
 #, c-format
+msgid "Failed to merge submodule %s (repository corrupt)"
+msgstr "无法合并子模组 %s(仓库损坏)"
+
+#: merge-ort.c merge-recursive.c
+#, c-format
 msgid "Failed to merge submodule %s (commits don't follow merge-base)"
 msgstr "无法合并子模组 %s (提交未跟随合并基线)"
 
@@ -21407,11 +21615,115 @@
 msgid "failed to read the cache"
 msgstr "无法读取缓存"
 
+#: midx-write.c
+#, c-format
+msgid "failed to add packfile '%s'"
+msgstr "无法添加包文件 '%s'"
+
+#: midx-write.c
+#, c-format
+msgid "failed to open pack-index '%s'"
+msgstr "无法打开包索引 '%s'"
+
+#: midx-write.c
+#, c-format
+msgid "failed to locate object %d in packfile"
+msgstr "无法在包文件中定位对象 %d"
+
+#: midx-write.c
+msgid "cannot store reverse index file"
+msgstr "无法存储反向索引文件"
+
+#: midx-write.c
+#, c-format
+msgid "could not parse line: %s"
+msgstr "不能解析行:%s"
+
+#: midx-write.c
+#, c-format
+msgid "malformed line: %s"
+msgstr "格式错误的行:%s"
+
+#: midx-write.c
+msgid "ignoring existing multi-pack-index; checksum mismatch"
+msgstr "忽略已存在的多包索引,校验码不匹配"
+
+#: midx-write.c
+msgid "could not load pack"
+msgstr "不能载入包"
+
+#: midx-write.c
+#, c-format
+msgid "could not open index for %s"
+msgstr "不能打开 %s 的索引"
+
+#: midx-write.c
+msgid "Adding packfiles to multi-pack-index"
+msgstr "添加包文件到多包索引"
+
+#: midx-write.c
+#, c-format
+msgid "unknown preferred pack: '%s'"
+msgstr "未知的首选包:'%s'"
+
+#: midx-write.c
+#, c-format
+msgid "cannot select preferred pack %s with no objects"
+msgstr "不能选择没有对象的首选包 %s"
+
+#: midx-write.c
+#, c-format
+msgid "did not see pack-file %s to drop"
+msgstr "没有看到要丢弃的包文件 %s"
+
+#: midx-write.c
+#, c-format
+msgid "preferred pack '%s' is expired"
+msgstr "首选包 '%s' 已过期"
+
+#: midx-write.c
+msgid "no pack files to index."
+msgstr "没有要索引的包文件。"
+
+#: midx-write.c
+msgid "refusing to write multi-pack .bitmap without any objects"
+msgstr "拒绝写入没有任何对象的多包位图"
+
+#: midx-write.c
+msgid "could not write multi-pack bitmap"
+msgstr "无法写入多包位图"
+
+#: midx-write.c
+msgid "could not write multi-pack-index"
+msgstr "无法写入多包索引"
+
+#: midx-write.c
+msgid "Counting referenced objects"
+msgstr "正在对引用对象计数"
+
+#: midx-write.c
+msgid "Finding and deleting unreferenced packfiles"
+msgstr "正在查找和删除未引用的包文件"
+
+#: midx-write.c
+msgid "could not start pack-objects"
+msgstr "不能开始 pack-objects"
+
+#: midx-write.c
+msgid "could not finish pack-objects"
+msgstr "不能结束 pack-objects"
+
 #: midx.c
 msgid "multi-pack-index OID fanout is of the wrong size"
 msgstr "多包索引的对象 ID 扇出表大小错误"
 
 #: midx.c
+#, c-format
+msgid ""
+"oid fanout out of order: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]"
+msgstr "对象 ID 扇出失序:fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]"
+
+#: midx.c
 msgid "multi-pack-index OID lookup chunk is the wrong size"
 msgstr "多包索引的对象 ID 查询块大小错误"
 
@@ -21470,6 +21782,15 @@
 msgstr "错的 pack-int-id:%u(共有 %u 个包)"
 
 #: midx.c
+msgid "MIDX does not contain the BTMP chunk"
+msgstr "多包索引中未包含 BTMP 块"
+
+#: midx.c
+#, c-format
+msgid "could not load bitmapped pack %<PRIu32>"
+msgstr "不能打开已被位图索引的包 %<PRIu32>"
+
+#: midx.c
 msgid "multi-pack-index stores a 64-bit offset, but off_t is too small"
 msgstr "多包索引存储一个64位偏移,但是 off_t 太小"
 
@@ -21479,88 +21800,6 @@
 
 #: midx.c
 #, c-format
-msgid "failed to add packfile '%s'"
-msgstr "无法添加包文件 '%s'"
-
-#: midx.c
-#, c-format
-msgid "failed to open pack-index '%s'"
-msgstr "无法打开包索引 '%s'"
-
-#: midx.c
-#, c-format
-msgid "failed to locate object %d in packfile"
-msgstr "无法在包文件中定位对象 %d"
-
-#: midx.c
-msgid "cannot store reverse index file"
-msgstr "无法存储反向索引文件"
-
-#: midx.c
-#, c-format
-msgid "could not parse line: %s"
-msgstr "不能解析行:%s"
-
-#: midx.c
-#, c-format
-msgid "malformed line: %s"
-msgstr "格式错误的行:%s"
-
-#: midx.c
-msgid "ignoring existing multi-pack-index; checksum mismatch"
-msgstr "忽略已存在的多包索引,校验码不匹配"
-
-#: midx.c
-msgid "could not load pack"
-msgstr "不能载入包"
-
-#: midx.c
-#, c-format
-msgid "could not open index for %s"
-msgstr "不能打开 %s 的索引"
-
-#: midx.c
-msgid "Adding packfiles to multi-pack-index"
-msgstr "添加包文件到多包索引"
-
-#: midx.c
-#, c-format
-msgid "unknown preferred pack: '%s'"
-msgstr "未知的首选包:'%s'"
-
-#: midx.c
-#, c-format
-msgid "cannot select preferred pack %s with no objects"
-msgstr "不能选择没有对象的首选包 %s"
-
-#: midx.c
-#, c-format
-msgid "did not see pack-file %s to drop"
-msgstr "没有看到要丢弃的包文件 %s"
-
-#: midx.c
-#, c-format
-msgid "preferred pack '%s' is expired"
-msgstr "首选包 '%s' 已过期"
-
-#: midx.c
-msgid "no pack files to index."
-msgstr "没有要索引的包文件。"
-
-#: midx.c
-msgid "refusing to write multi-pack .bitmap without any objects"
-msgstr "拒绝写入没有任何对象的多包位图 .bitmap"
-
-#: midx.c
-msgid "could not write multi-pack bitmap"
-msgstr "无法写入多包位图"
-
-#: midx.c
-msgid "could not write multi-pack-index"
-msgstr "无法写入多包索引"
-
-#: midx.c
-#, c-format
 msgid "failed to clear multi-pack-index at %s"
 msgstr "无法清理位于 %s 的多包索引"
 
@@ -21577,12 +21816,6 @@
 msgstr "正在查找引用的包文件"
 
 #: midx.c
-#, c-format
-msgid ""
-"oid fanout out of order: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]"
-msgstr "对象 ID 扇出无序:fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]"
-
-#: midx.c
 msgid "the midx contains no oid"
 msgstr "midx 不包含 oid"
 
@@ -21618,22 +21851,6 @@
 msgid "incorrect object offset for oid[%d] = %s: %<PRIx64> != %<PRIx64>"
 msgstr "oid[%d] = %s 错误的对象偏移:%<PRIx64> != %<PRIx64>"
 
-#: midx.c
-msgid "Counting referenced objects"
-msgstr "正在对引用对象计数"
-
-#: midx.c
-msgid "Finding and deleting unreferenced packfiles"
-msgstr "正在查找和删除未引用的包文件"
-
-#: midx.c
-msgid "could not start pack-objects"
-msgstr "不能开始 pack-objects"
-
-#: midx.c
-msgid "could not finish pack-objects"
-msgstr "不能结束 pack-objects"
-
 #: name-hash.c
 #, c-format
 msgid "unable to create lazy_dir thread: %s"
@@ -21688,6 +21905,30 @@
 msgid "Bad %s value: '%s'"
 msgstr "坏的 %s 值:'%s'"
 
+#: object-file-convert.c
+msgid "failed to decode tree entry"
+msgstr "无法解码树对象"
+
+#: object-file-convert.c
+#, c-format
+msgid "failed to map tree entry for %s"
+msgstr "无法为 %s 映射树对象"
+
+#: object-file-convert.c
+#, c-format
+msgid "bad %s in commit"
+msgstr "提交中有错误的 %s"
+
+#: object-file-convert.c
+#, c-format
+msgid "unable to map %s %s in commit object"
+msgstr "无法将 %s %s 映射到提交对象中"
+
+#: object-file-convert.c
+#, c-format
+msgid "Failed to convert object from %s to %s"
+msgstr "无法将对象从 %s 转换为 %s"
+
 #: object-file.c
 #, c-format
 msgid "object directory %s does not exist; check .git/objects/info/alternates"
@@ -21816,6 +22057,11 @@
 
 #: object-file.c
 #, c-format
+msgid "missing mapping of %s to %s"
+msgstr "缺少 %s 到 %s 的映射"
+
+#: object-file.c
+#, c-format
 msgid "unable to write file %s"
 msgstr "无法写文件 %s"
 
@@ -21883,6 +22129,11 @@
 
 #: object-file.c
 #, c-format
+msgid "cannot map object %s to %s"
+msgstr "无法将对象 %s 映射到 %s"
+
+#: object-file.c
+#, c-format
 msgid "object fails fsck: %s"
 msgstr "对象 fsck 失败:%s"
 
@@ -22211,6 +22462,10 @@
 msgid "could not open pack %s"
 msgstr "不能打开包 %s"
 
+#: pack-bitmap.c t/helper/test-read-midx.c
+msgid "could not determine MIDX preferred pack"
+msgstr "不能确定多包索引的首选包"
+
 #: pack-bitmap.c
 #, c-format
 msgid "preferred pack (%s) is invalid"
@@ -22236,6 +22491,15 @@
 
 #: pack-bitmap.c
 #, c-format
+msgid "unable to load pack: '%s', disabling pack-reuse"
+msgstr "无法打开包:'%s',禁用包重用"
+
+#: pack-bitmap.c
+msgid "unable to compute preferred pack, disabling pack-reuse"
+msgstr "无法计算首选包,禁用包重用"
+
+#: pack-bitmap.c
+#, c-format
 msgid "object '%s' not found in type bitmaps"
 msgstr "对象 %s 为在类型位图中找到"
 
@@ -22349,6 +22613,10 @@
 msgid "multi-pack-index reverse-index chunk is the wrong size"
 msgstr "多包索引的反向索引块大小错误"
 
+#: pack-revindex.c
+msgid "could not determine preferred pack"
+msgstr "无法确定首选包"
+
 #: pack-write.c
 msgid "cannot both write and verify reverse index"
 msgstr "无法同时写入和校验反向索引"
@@ -22429,11 +22697,6 @@
 
 #: parse-options.c
 #, c-format
-msgid "%s is incompatible with %s"
-msgstr "%s 与 %s 不兼容"
-
-#: parse-options.c
-#, c-format
 msgid "ambiguous option: %s (could be --%s%s or --%s%s)"
 msgstr "有歧义的选项:%s(可以是 --%s%s 或 --%s%s)"
 
@@ -22823,11 +23086,6 @@
 
 #: read-cache.c
 #, c-format
-msgid "unable to stat '%s'"
-msgstr "无法对 %s 执行 stat"
-
-#: read-cache.c
-#, c-format
 msgid "'%s' appears as both a file and as a directory"
 msgstr "'%s' 看起来既是文件又是目录"
 
@@ -23500,21 +23758,94 @@
 msgid "cannot process '%s' and '%s' at the same time"
 msgstr "无法同时处理 '%s' 和 '%s'"
 
-#: refs/files-backend.c
-#, c-format
-msgid "could not remove reference %s"
-msgstr "无法删除引用 %s"
-
-#: refs/files-backend.c refs/packed-backend.c
+#: refs.c
 #, c-format
 msgid "could not delete reference %s: %s"
 msgstr "无法删除引用 %s:%s"
 
-#: refs/files-backend.c refs/packed-backend.c
+#: refs.c
 #, c-format
 msgid "could not delete references: %s"
 msgstr "无法删除引用:%s"
 
+#: refs/reftable-backend.c
+#, c-format
+msgid "refname is dangerous: %s"
+msgstr "危险的引用名称:%s"
+
+#: refs/reftable-backend.c
+#, c-format
+msgid "trying to write ref '%s' with nonexistent object %s"
+msgstr "试图用不存在的对象 %2$s 写入引用 '%1$s'"
+
+#: refs/reftable-backend.c
+#, c-format
+msgid "trying to write non-commit object %s to branch '%s'"
+msgstr "尝试将非提交对象 %s 写入分支 '%s'"
+
+#: refs/reftable-backend.c
+#, c-format
+msgid ""
+"multiple updates for 'HEAD' (including one via its referent '%s') are not "
+"allowed"
+msgstr "不允许对 'HEAD' 进行多次更新(包括通过其引用 '%s' 进行的更新)"
+
+#: refs/reftable-backend.c
+#, c-format
+msgid "cannot lock ref '%s': unable to resolve reference '%s'"
+msgstr "无法锁定引用 '%s':无法解析引用 '%s'"
+
+#: refs/reftable-backend.c
+#, c-format
+msgid "cannot lock ref '%s': error reading reference"
+msgstr "无法锁定引用 '%s':读取引用时出错"
+
+#: refs/reftable-backend.c
+#, c-format
+msgid ""
+"multiple updates for '%s' (including one via symref '%s') are not allowed"
+msgstr "不允许对 '%s' 进行多次更新(包括通过符号引用 '%s' 更新)"
+
+#: refs/reftable-backend.c
+#, c-format
+msgid "cannot lock ref '%s': reference already exists"
+msgstr "无法锁定引用 '%s':引用已存在"
+
+#: refs/reftable-backend.c
+#, c-format
+msgid "cannot lock ref '%s': reference is missing but expected %s"
+msgstr "无法锁定 '%s' 引用:引用丢失,但预期为 %s"
+
+#: refs/reftable-backend.c
+#, c-format
+msgid "cannot lock ref '%s': is at %s but expected %s"
+msgstr "无法锁定 '%s' 引用:位于 %s,但预期为 %s"
+
+#: refs/reftable-backend.c
+#, c-format
+msgid "reftable: transaction prepare: %s"
+msgstr "reftable: 事务准备:%s"
+
+#: refs/reftable-backend.c
+#, c-format
+msgid "reftable: transaction failure: %s"
+msgstr "reftable: 事务失败:%s"
+
+#: refs/reftable-backend.c
+#, c-format
+msgid "unable to compact stack: %s"
+msgstr "无法压缩栈:%s"
+
+#: refs/reftable-backend.c
+#, c-format
+msgid "refname %s not found"
+msgstr "引用名称 %s 未找到"
+
+#: refs/reftable-backend.c
+#, c-format
+msgid "refname %s is a symbolic ref, copying it is not supported"
+msgstr "引用名 %s 是一个符号引用,不支持复制"
+
 #: refspec.c
 #, c-format
 msgid "invalid refspec '%s'"
@@ -23527,6 +23858,11 @@
 
 #: remote-curl.c
 #, c-format
+msgid "unknown value for object-format: %s"
+msgstr "对象格式的未知取值:%s"
+
+#: remote-curl.c
+#, c-format
 msgid "%sinfo/refs not valid: is this a git repository?"
 msgstr "%sinfo/refs 无效:这是 git 仓库么?"
 
@@ -24062,8 +24398,21 @@
 
 #: revision.c
 #, c-format
-msgid "could not get commit for ancestry-path argument %s"
-msgstr "无法获得 ancestry-path 参数 %s 的提交"
+msgid "%s exists but is a symbolic ref"
+msgstr "%s 存在但是一个符号引用"
+
+#: revision.c
+msgid ""
+"--merge requires one of the pseudorefs MERGE_HEAD, CHERRY_PICK_HEAD, "
+"REVERT_HEAD or REBASE_HEAD"
+msgstr ""
+"--merge 选项需要指定 MERGE_HEAD、CHERRY_PICK_HEAD、REVERT_HEAD 或 "
+"REBASE_HEAD 中的一个伪引用"
+
+#: revision.c
+#, c-format
+msgid "could not get commit for --ancestry-path argument %s"
+msgstr "无法获得 --ancestry-path 参数 %s 的提交"
 
 #: revision.c
 msgid "--unpacked=<packfile> no longer supported"
@@ -24424,6 +24773,19 @@
 
 #: sequencer.c
 msgid ""
+"Resolve all conflicts manually, mark them as resolved with\n"
+"\"git add/rm <conflicted_files>\", then run \"git rebase --continue\".\n"
+"You can instead skip this commit: run \"git rebase --skip\".\n"
+"To abort and get back to the state before \"git rebase\", run \"git rebase --"
+"abort\"."
+msgstr ""
+"手工解决所有冲突,执行 \"git add/rm <冲突的文件>\" 标记\n"
+"冲突已解决,然后执行 \"git rebase --continue\"。您也可以执行\n"
+"\"git rebase --skip\" 命令跳过这个提交。如果想要终止执行并回到\n"
+"\"git rebase\" 执行之前的状态,执行 \"git rebase --abort\"。"
+
+#: sequencer.c
+msgid ""
 "after resolving the conflicts, mark the corrected paths\n"
 "with 'git add <paths>' or 'git rm <paths>'"
 msgstr ""
@@ -24665,18 +25027,13 @@
 msgid "corrupt author: missing date information"
 msgstr "损坏的作者:缺失日期信息"
 
-#: sequencer.c t/helper/test-fast-rebase.c
+#: sequencer.c
 #, c-format
 msgid "could not update %s"
 msgstr "不能更新 %s"
 
 #: sequencer.c
 #, c-format
-msgid "could not parse commit %s"
-msgstr "不能解析提交 %s"
-
-#: sequencer.c
-#, c-format
 msgid "could not parse parent commit %s"
 msgstr "不能解析父提交 %s"
 
@@ -24807,11 +25164,6 @@
 
 #: sequencer.c
 #, c-format
-msgid "%s does not accept arguments: '%s'"
-msgstr "%s 不接受参数:'%s'"
-
-#: sequencer.c
-#, c-format
 msgid "missing arguments for %s"
 msgstr "缺少 %s 的参数"
 
@@ -25156,6 +25508,10 @@
 msgstr "自动贮藏已经存在;正在创建一个新的贮藏条目。"
 
 #: sequencer.c
+msgid "autostash reference is a symref"
+msgstr "自动贮藏的引用是一个符号引用"
+
+#: sequencer.c
 msgid "could not detach HEAD"
 msgstr "不能分离头指针"
 
@@ -25357,6 +25713,11 @@
 
 #: setup.c
 #, c-format
+msgid "'%s' already specified as '%s'"
+msgstr "'%s' 已指定为 '%s'"
+
+#: setup.c
+#, c-format
 msgid "Expected git repo version <= %d, found %d"
 msgstr "期望 git 仓库版本 <= %d,却得到 %d"
 
@@ -25531,6 +25892,11 @@
 
 #: setup.c
 #, c-format
+msgid "re-init: ignored --initial-branch=%s"
+msgstr "re-init:已忽略 --initial-branch=%s"
+
+#: setup.c
+#, c-format
 msgid "unable to handle file type %d"
 msgstr "不能处理 %d 类型的文件"
 
@@ -25544,14 +25910,14 @@
 msgstr "尝试用不同的哈希算法重新初始化仓库"
 
 #: setup.c
-#, c-format
-msgid "%s already exists"
-msgstr "%s 已经存在"
+msgid ""
+"attempt to reinitialize repository with different reference storage format"
+msgstr "尝试使用不同的引用存储格式重新初始化仓库"
 
 #: setup.c
 #, c-format
-msgid "re-init: ignored --initial-branch=%s"
-msgstr "re-init:已忽略 --initial-branch=%s"
+msgid "%s already exists"
+msgstr "%s 已经存在"
 
 #: setup.c
 #, c-format
@@ -25582,6 +25948,24 @@
 msgid "cannot use split index with a sparse index"
 msgstr "拆分索引无法与稀疏索引一起使用"
 
+#. TRANSLATORS: The first %s is a command like "ls-tree".
+#: strbuf.c
+#, c-format
+msgid "bad %s format: element '%s' does not start with '('"
+msgstr "坏的 %s 格式:元素 '%s' 没有以 '(' 开头"
+
+#. TRANSLATORS: The first %s is a command like "ls-tree".
+#: strbuf.c
+#, c-format
+msgid "bad %s format: element '%s' does not end in ')'"
+msgstr "坏的 %s 格式:元素 '%s' 没有以 ')' 结尾"
+
+#. TRANSLATORS: %s is a command like "ls-tree".
+#: strbuf.c
+#, c-format
+msgid "bad %s format: %%%.*s"
+msgstr "坏的 %s 格式: %%%.*s"
+
 #. TRANSLATORS: IEC 80000-13:2008 gibibyte
 #: strbuf.c
 #, c-format
@@ -25869,14 +26253,6 @@
 msgid "number of entries in the cache tree to invalidate (default 0)"
 msgstr "缓存树中无效化的条目数量(默认 0)"
 
-#: t/helper/test-fast-rebase.c
-msgid "unhandled options"
-msgstr "未处理的选项"
-
-#: t/helper/test-fast-rebase.c
-msgid "error preparing revisions"
-msgstr "准备版本时错误"
-
 #: t/helper/test-reach.c
 #, c-format
 msgid "commit %s is not marked reachable"
@@ -25981,35 +26357,6 @@
 msgid "empty trailer token in trailer '%.*s'"
 msgstr "尾注 '%.*s' 的键为空"
 
-#: trailer.c
-#, c-format
-msgid "could not read input file '%s'"
-msgstr "不能读取输入文件 '%s'"
-
-#: trailer.c wrapper.c
-#, c-format
-msgid "could not stat %s"
-msgstr "不能对 %s 调用 stat"
-
-#: trailer.c
-#, c-format
-msgid "file %s is not a regular file"
-msgstr "文件 %s 不是一个正规文件"
-
-#: trailer.c
-#, c-format
-msgid "file %s is not writable by user"
-msgstr "文件 %s 用户不可写"
-
-#: trailer.c
-msgid "could not open temporary file"
-msgstr "不能打开临时文件"
-
-#: trailer.c
-#, c-format
-msgid "could not rename temporary file to %s"
-msgstr "不能重命名临时文件为 %s"
-
 #: transport-helper.c
 msgid "full write to remote helper failed"
 msgstr "完整写入远程助手失败"
@@ -26070,10 +26417,6 @@
 msgid "invalid remote service path"
 msgstr "无效的远程服务路径"
 
-#: transport-helper.c transport.c
-msgid "operation not supported by protocol"
-msgstr "协议不支持该操作"
-
 #: transport-helper.c
 #, c-format
 msgid "can't connect to subservice %s"
@@ -26133,8 +26476,8 @@
 
 #: transport-helper.c
 #, c-format
-msgid "helper %s does not support 'force'"
-msgstr "助手 %s 不支持 'force'"
+msgid "helper %s does not support '--force'"
+msgstr "助手 %s 不支持 '--force'"
 
 #: transport-helper.c
 msgid "couldn't run fast-export"
@@ -26239,11 +26582,6 @@
 
 #: transport.c
 #, c-format
-msgid "unknown value for config '%s': %s"
-msgstr "配置 '%s' 的取值未知:%s"
-
-#: transport.c
-#, c-format
 msgid "transport '%s' not allowed"
 msgstr "传输 '%s' 不允许"
 
@@ -26301,6 +26639,10 @@
 msgid "could not retrieve server-advertised bundle-uri list"
 msgstr "无法获取服务器公布的 bundle-uri 列表"
 
+#: transport.c
+msgid "operation not supported by protocol"
+msgstr "协议不支持该操作"
+
 #: tree-walk.c
 msgid "too-short tree object"
 msgstr "太短的树对象"
@@ -26610,6 +26952,11 @@
 msgstr "无效的 '..' 路径片段"
 
 #: usage.c
+#, c-format
+msgid "error: unable to format message: %s\n"
+msgstr "错误:无法格式化消息:%s\n"
+
+#: usage.c
 msgid "usage: "
 msgstr "用法:"
 
@@ -27329,6 +27676,11 @@
 msgid "cannot %s: Your index contains uncommitted changes."
 msgstr "不能%s:您的索引中包含未提交的变更。"
 
+#: xdiff-interface.c
+#, c-format
+msgid "unknown style '%s' given for '%s'"
+msgstr "'%2$s' 的未知风格取值 '%1$s'"
+
 #: git-merge-octopus.sh git-merge-resolve.sh
 msgid ""
 "Error: Your local changes to the following files would be overwritten by "
diff --git a/po/zh_TW.po b/po/zh_TW.po
index f777a05..f554381 100644
--- a/po/zh_TW.po
+++ b/po/zh_TW.po
@@ -19,15 +19,16 @@
 # - Yichao Yu <yyc1992 AT gmail.com>
 # - Zhuang Ya <zhuangya AT me.com>
 #
-# Yi-Jyun Pan <pan93412@gmail.com>, 2021, 2022, 2023.
+# Yi-Jyun Pan <pan93412@gmail.com>, 2021, 2022, 2023, 2024.
 # Kaiyang Wu <self@origincode.me>, 2022.
-# lumynou5 <lumynou5.tw@gmail.com>, 2023.
+# lumynou5 <lumynou5.tw@gmail.com>, 2023, 2024.
+# Kisaragi Hiu <mail@kisaragi-hiu.com>, 2024.
 msgid ""
 msgstr ""
 "Project-Id-Version: Git\n"
 "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2023-11-19 22:29+0800\n"
-"PO-Revision-Date: 2023-11-19 23:34+0800\n"
+"POT-Creation-Date: 2024-04-28 18:52+0800\n"
+"PO-Revision-Date: 2024-04-28 18:44+0800\n"
 "Last-Translator: Yi-Jyun Pan <pan93412@gmail.com>\n"
 "Language-Team: Chinese (Traditional) <http://weblate.slat.org/projects/git-"
 "po/git-cli/zh_Hant/>\n"
@@ -36,7 +37,7 @@
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Poedit 3.4.1\n"
+"X-Generator: Poedit 3.4.2\n"
 "X-ZhConverter: 繁化姬 dict-f4bc617e-r910 @ 2019/11/16 20:23:12 | https://"
 "zhconvert.org\n"
 
@@ -601,12 +602,12 @@
 "---\n"
 "To remove '%c' lines, make them ' ' lines (context).\n"
 "To remove '%c' lines, delete them.\n"
-"Lines starting with %c will be removed.\n"
+"Lines starting with %s will be removed.\n"
 msgstr ""
 "---\n"
-"要刪除 “%c” 開頭的列,請將列首(上下文)改成空白。\n"
-"要刪除 “%c” 開頭的列,請直接刪除。\n"
-"開頭是 %c 的列將會被移除。\n"
+"要刪除「%c」開頭的列,請將列首(上下文)改成空白。\n"
+"要刪除「%c」開頭的列,請直接刪除。\n"
+"開頭是 %s 的列將會被移除。\n"
 
 #: add-patch.c
 msgid ""
@@ -659,16 +660,18 @@
 "/ - search for a hunk matching the given regex\n"
 "s - split the current hunk into smaller hunks\n"
 "e - manually edit the current hunk\n"
+"p - print the current hunk\n"
 "? - print help\n"
 msgstr ""
-"j - 維持此區塊未決狀態,檢視下一個未決定區塊\n"
-"J - 維持此區塊未決狀態,檢視下一個區塊\n"
-"k - 維持此區塊未決狀態,檢視上一個未決定區塊\n"
-"K - 維持此區塊未決狀態,檢視上一個區塊\n"
+"j - 維持此區塊未決定狀態,檢視下一個未決定區塊\n"
+"J - 維持此區塊未決定狀態,檢視下一個區塊\n"
+"k - 維持此區塊未決定狀態,檢視上一個未決定區塊\n"
+"K - 維持此區塊未決定狀態,檢視上一個區塊\n"
 "g - 選擇要跳轉至的區塊\n"
 "/ - 尋找符合提供之常規表示式的區塊\n"
 "s - 分割目前區塊為更小的區塊\n"
 "e - 手動編輯目前區塊\n"
+"p - 輸出目前區塊\n"
 "? - 顯示說明\n"
 
 #: add-patch.c
@@ -747,8 +750,8 @@
 
 #: advice.c
 #, c-format
-msgid "%shint: %.*s%s\n"
-msgstr "%s提示:%.*s%s\n"
+msgid "%shint:%s%.*s%s\n"
+msgstr "%s提示:%s%.*s%s\n"
 
 #: advice.c
 msgid "Cherry-picking is not possible because you have unmerged files."
@@ -910,7 +913,7 @@
 msgstr "未閉合的引號"
 
 #: alias.c builtin/cat-file.c builtin/notes.c builtin/prune-packed.c
-#: builtin/receive-pack.c builtin/tag.c
+#: builtin/receive-pack.c builtin/tag.c t/helper/test-pkt-line.c
 msgid "too many arguments"
 msgstr "引數過多"
 
@@ -925,12 +928,13 @@
 msgstr "空白字元忽略選項 “%s” 無法識別"
 
 #: apply.c archive.c builtin/add.c builtin/branch.c builtin/checkout-index.c
-#: builtin/checkout.c builtin/clone.c builtin/commit.c builtin/describe.c
-#: builtin/diff-tree.c builtin/difftool.c builtin/fast-export.c builtin/fetch.c
-#: builtin/help.c builtin/index-pack.c builtin/init-db.c builtin/log.c
-#: builtin/ls-files.c builtin/merge-base.c builtin/merge.c
-#: builtin/pack-objects.c builtin/push.c builtin/rebase.c builtin/repack.c
-#: builtin/reset.c builtin/rev-list.c builtin/show-branch.c builtin/stash.c
+#: builtin/checkout.c builtin/clean.c builtin/clone.c builtin/commit.c
+#: builtin/describe.c builtin/diff-tree.c builtin/difftool.c
+#: builtin/fast-export.c builtin/fetch.c builtin/help.c builtin/index-pack.c
+#: builtin/init-db.c builtin/log.c builtin/ls-files.c builtin/merge-base.c
+#: builtin/merge-tree.c builtin/merge.c builtin/pack-objects.c builtin/rebase.c
+#: builtin/repack.c builtin/replay.c builtin/reset.c builtin/rev-list.c
+#: builtin/rev-parse.c builtin/show-branch.c builtin/stash.c
 #: builtin/submodule--helper.c builtin/tag.c builtin/worktree.c parse-options.c
 #: range-diff.c revision.c
 #, c-format
@@ -1240,12 +1244,12 @@
 #: apply.c
 #, c-format
 msgid "new mode (%o) of %s does not match old mode (%o)"
-msgstr "%2$s 的新模式 (%1$o) 和舊模式 (%3$o) 不符"
+msgstr "%2$s 的新模式(%1$o)和舊模式(%3$o)不符"
 
 #: apply.c
 #, c-format
 msgid "new mode (%o) of %s does not match old mode (%o) of %s"
-msgstr "%2$s 的新模式 (%1$o) 和 %4$s 的舊模式 (%3$o) 不符"
+msgstr "%2$s 的新模式(%1$o)和 %4$s 的舊模式(%3$o)不符"
 
 #: apply.c
 #, c-format
@@ -1344,11 +1348,6 @@
 
 #: apply.c
 #, c-format
-msgid "truncating .rej filename to %.*s.rej"
-msgstr "正在將 .rej 檔案名稱截短為 %.*s.rej"
-
-#: apply.c
-#, c-format
 msgid "cannot open %s"
 msgstr "無法開啟 %s"
 
@@ -1734,6 +1733,11 @@
 
 #: archive.c
 #, c-format
+msgid "extra command line parameter '%s'"
+msgstr "多出命令列參數 “%s”"
+
+#: archive.c
+#, c-format
 msgid "Unknown archive format '%s'"
 msgstr "封存格式 “%s” 未知"
 
@@ -1788,6 +1792,17 @@
 msgid "bad --attr-source or GIT_ATTR_SOURCE"
 msgstr "無效的 --attr-source 或 GIT_ATTR_SOURCE"
 
+#: attr.c read-cache.c
+#, c-format
+msgid "unable to stat '%s'"
+msgstr "無法對 %s 執行 stat"
+
+#: bisect.c builtin/cat-file.c builtin/index-pack.c builtin/notes.c
+#: builtin/pack-objects.c combine-diff.c rerere.c
+#, c-format
+msgid "unable to read %s"
+msgstr "不能讀 %s"
+
 #: bisect.c
 #, c-format
 msgid "Badly quoted content in file '%s': %s"
@@ -1867,6 +1882,11 @@
 msgid "could not create file '%s'"
 msgstr "無法建立 “%s” 檔案"
 
+#: bisect.c builtin/notes.c
+#, c-format
+msgid "unable to start 'show' for object '%s'"
+msgstr "不能為物件 '%s' 開始 'show'"
+
 #: bisect.c builtin/merge.c
 #, c-format
 msgid "could not read file '%s'"
@@ -1914,8 +1934,8 @@
 msgstr "--reverse 和 --first-parent 共用,需要指定最新的提交"
 
 #: blame.c builtin/commit.c builtin/log.c builtin/merge.c
-#: builtin/pack-objects.c builtin/shortlog.c midx.c pack-bitmap.c remote.c
-#: sequencer.c submodule.c
+#: builtin/pack-objects.c builtin/shortlog.c midx-write.c pack-bitmap.c
+#: remote.c sequencer.c submodule.c
 msgid "revision walk setup failed"
 msgstr "修訂版遍歷設定失敗"
 
@@ -1990,10 +2010,12 @@
 msgstr "未追蹤:“%s” 引用有歧義"
 
 #  譯者:為保證在輸出中對齊,注意調整句中空格!
+#. #-#-#-#-#  branch.c.po  #-#-#-#-#
 #. TRANSLATORS: This is a line listing a remote with duplicate
 #. refspecs in the advice message below. For RTL languages you'll
 #. probably want to swap the "%s" and leading "  " space around.
 #.
+#. #-#-#-#-#  object-name.c.po  #-#-#-#-#
 #. TRANSLATORS: This is line item of ambiguous object output
 #. from describe_ambiguous_object() above. For RTL languages
 #. you'll probably want to swap the "%s" and leading " " space
@@ -2032,6 +2054,10 @@
 msgid "'%s' is not a valid branch name"
 msgstr "“%s” 不是有效的分支名稱"
 
+#: branch.c builtin/branch.c
+msgid "See `man git check-ref-format`"
+msgstr "請參閱「man git check-ref-format」"
+
 #: branch.c
 #, c-format
 msgid "a branch named '%s' already exists"
@@ -2266,14 +2292,8 @@
 msgstr "正在加入嵌入式 git 版本庫:%s"
 
 #: builtin/add.c
-msgid ""
-"Use -f if you really want to add them.\n"
-"Turn this message off by running\n"
-"\"git config advice.addIgnoredFile false\""
-msgstr ""
-"若您真的想加入,請傳入 -f。\n"
-"如要關閉此訊息,請執行\n"
-"“git config advice.addIgnoredFile false”"
+msgid "Use -f if you really want to add them."
+msgstr "如果您確定想要加入他們,請使用「-f」。"
 
 #: builtin/add.c
 msgid "adding files failed"
@@ -2296,14 +2316,8 @@
 msgstr "沒有指定,亦未加入檔案。\n"
 
 #: builtin/add.c
-msgid ""
-"Maybe you wanted to say 'git add .'?\n"
-"Turn this message off by running\n"
-"\"git config advice.addEmptyPathspec false\""
-msgstr ""
-"可能您想做 “git add .”?\n"
-"如要關閉此訊息,請執行\n"
-"“git config advice.addEmptyPathspec false”"
+msgid "Maybe you wanted to say 'git add .'?"
+msgstr "也許您想要執行的是「git add .」?"
 
 #: builtin/add.c builtin/check-ignore.c builtin/checkout.c builtin/clean.c
 #: builtin/commit.c builtin/diff-tree.c builtin/grep.c builtin/mv.c
@@ -2323,8 +2337,8 @@
 msgstr "“%s” 動作對 “%s” 無效"
 
 #: builtin/am.c builtin/blame.c builtin/fetch.c builtin/pack-objects.c
-#: builtin/pull.c diff-merges.c gpg-interface.c ls-refs.c parallel-checkout.c
-#: sequencer.c setup.c
+#: builtin/pull.c builtin/revert.c config.c diff-merges.c gpg-interface.c
+#: ls-refs.c parallel-checkout.c sequencer.c setup.c
 #, c-format
 msgid "invalid value for '%s': '%s'"
 msgstr "“%s” 的值無效:“%s”"
@@ -2408,18 +2422,19 @@
 
 #: builtin/am.c
 #, c-format
-msgid "When you have resolved this problem, run \"%s --continue\"."
-msgstr "解決此問題後,請執行 “%s --continue”。"
+msgid "When you have resolved this problem, run \"%s --continue\".\n"
+msgstr "解決此問題後,請執行「%s --continue」。\n"
 
 #: builtin/am.c
 #, c-format
-msgid "If you prefer to skip this patch, run \"%s --skip\" instead."
-msgstr "若要略過此修補,請改執行 “%s --skip”。"
+msgid "If you prefer to skip this patch, run \"%s --skip\" instead.\n"
+msgstr "若要略過此修補,請改執行「%s --skip」。\n"
 
 #: builtin/am.c
 #, c-format
-msgid "To record the empty patch as an empty commit, run \"%s --allow-empty\"."
-msgstr "若要將空白修補檔錄入為空白提交,請執行 “%s --allow-empty”。"
+msgid ""
+"To record the empty patch as an empty commit, run \"%s --allow-empty\".\n"
+msgstr "若要將空白修補檔錄入為空白提交,請執行「%s --allow-empty」。\n"
 
 #: builtin/am.c
 #, c-format
@@ -2477,8 +2492,7 @@
 msgid "applying to an empty history"
 msgstr "正在套用至空白歷史記錄上"
 
-#: builtin/am.c builtin/commit.c builtin/merge.c sequencer.c
-#: t/helper/test-fast-rebase.c
+#: builtin/am.c builtin/commit.c builtin/merge.c builtin/replay.c sequencer.c
 msgid "failed to write commit object"
 msgstr "無法寫入提交物件"
 
@@ -2661,8 +2675,9 @@
 msgstr "n"
 
 #: builtin/am.c builtin/branch.c builtin/bugreport.c builtin/cat-file.c
-#: builtin/diagnose.c builtin/for-each-ref.c builtin/ls-files.c
-#: builtin/ls-tree.c builtin/replace.c builtin/tag.c builtin/verify-tag.c
+#: builtin/clone.c builtin/diagnose.c builtin/for-each-ref.c builtin/init-db.c
+#: builtin/ls-files.c builtin/ls-tree.c builtin/replace.c builtin/tag.c
+#: builtin/verify-tag.c
 msgid "format"
 msgstr "format"
 
@@ -3357,12 +3372,13 @@
 
 #: builtin/branch.c
 #, c-format
-msgid ""
-"the branch '%s' is not fully merged.\n"
-"If you are sure you want to delete it, run 'git branch -D %s'"
-msgstr ""
-"分支 “%s” 沒有完全合併。\n"
-"如果確定要刪除它,請執行 “git branch -D %s”"
+msgid "the branch '%s' is not fully merged"
+msgstr "分支 “%s” 沒有完全合併"
+
+#: builtin/branch.c
+#, c-format
+msgid "If you are sure you want to delete it, run 'git branch -D %s'"
+msgstr "如果確定要刪除它,請執行 “git branch -D %s”"
 
 #: builtin/branch.c
 msgid "update of config-file failed"
@@ -3485,11 +3501,11 @@
 msgid ""
 "Please edit the description for the branch\n"
 "  %s\n"
-"Lines starting with '%c' will be stripped.\n"
+"Lines starting with '%s' will be stripped.\n"
 msgstr ""
 "請編輯下述分支的描述\n"
 "  %s\n"
-"開頭是 “%c” 的列將被刪除。\n"
+"開頭是「%s」的列將被刪除。\n"
 
 #: builtin/branch.c
 msgid "Generic options"
@@ -3745,10 +3761,12 @@
 
 #: builtin/bugreport.c
 msgid ""
-"git bugreport [(-o | --output-directory) <path>] [(-s | --suffix) <format>]\n"
+"git bugreport [(-o | --output-directory) <path>]\n"
+"              [(-s | --suffix) <format> | --no-suffix]\n"
 "              [--diagnose[=<mode>]]"
 msgstr ""
-"git bugreport [(-o | --output-directory) <path>] [(-s | --suffix) <format>]\n"
+"git bugreport [(-o | --output-directory) <path>]\n"
+"              [(-s | --suffix) <format> | --no-suffix]\n"
 "              [--diagnose[=<mode>]]"
 
 #: builtin/bugreport.c
@@ -4348,6 +4366,12 @@
 msgid "path '%s' is unmerged"
 msgstr "路徑 “%s” 未合併"
 
+#: builtin/checkout.c builtin/grep.c builtin/merge-tree.c builtin/reset.c
+#: merge-ort.c reset.c sequencer.c tree-walk.c
+#, c-format
+msgid "unable to read tree (%s)"
+msgstr "無法讀取樹(%s)"
+
 #: builtin/checkout.c
 msgid "you need to resolve your current index first"
 msgstr "您需要先解決目前索引區的衝突"
@@ -4370,7 +4394,7 @@
 msgid "HEAD is now at"
 msgstr "HEAD 目前位於"
 
-#: builtin/checkout.c builtin/clone.c t/helper/test-fast-rebase.c
+#: builtin/checkout.c builtin/clone.c
 msgid "unable to update HEAD"
 msgstr "無法更新 HEAD"
 
@@ -4607,6 +4631,11 @@
 msgstr "缺少分支或提交引數"
 
 #: builtin/checkout.c
+#, c-format
+msgid "unknown conflict style '%s'"
+msgstr "未知的衝突輸出風格「%s」"
+
+#: builtin/checkout.c
 msgid "perform a 3-way merge with the new branch"
 msgstr "和新分支進行三方合併"
 
@@ -4631,8 +4660,8 @@
 msgstr "new-branch"
 
 #: builtin/checkout.c
-msgid "new unparented branch"
-msgstr "新的,沒有父提交的分支"
+msgid "new unborn branch"
+msgstr "新的未誕生分支"
 
 #: builtin/checkout.c builtin/merge.c
 msgid "update ignored files (default)"
@@ -4699,7 +4728,7 @@
 msgid "you must specify path(s) to restore"
 msgstr "您必須指定要還原的路徑"
 
-#: builtin/checkout.c builtin/clone.c builtin/remote.c
+#: builtin/checkout.c builtin/clone.c builtin/remote.c builtin/replay.c
 #: builtin/submodule--helper.c builtin/worktree.c
 msgid "branch"
 msgstr "branch"
@@ -4927,22 +4956,8 @@
 msgstr "只移除忽略的檔案"
 
 #: builtin/clean.c
-msgid ""
-"clean.requireForce set to true and neither -i, -n, nor -f given; refusing to "
-"clean"
-msgstr ""
-"clean.requireForce 設定為 true 且未提供 -i、-n 或 -f 選項,拒絕執行清理動作"
-
-#: builtin/clean.c
-msgid ""
-"clean.requireForce defaults to true and neither -i, -n, nor -f given; "
-"refusing to clean"
-msgstr ""
-"clean.requireForce 預設為 true 且未提供 -i、-n 或 -f 選項,拒絕執行清理動作"
-
-#: builtin/clean.c
-msgid "-x and -X cannot be used together"
-msgstr "-x 和 -X 不能同時使用"
+msgid "clean.requireForce is true and -f not given: refusing to clean"
+msgstr "clean.requireForce 是 true 且未給定 -f 選項:拒絕清理"
 
 #: builtin/clone.c
 msgid "git clone [<options>] [--] <repo> [<dir>]"
@@ -4961,8 +4976,8 @@
 msgstr "建立裸版本庫"
 
 #: builtin/clone.c
-msgid "create a mirror repository (implies bare)"
-msgstr "建立鏡像版本庫(亦即裸版本庫)"
+msgid "create a mirror repository (implies --bare)"
+msgstr "建立鏡像版本庫(隱含 --bare)"
 
 #: builtin/clone.c
 msgid "to clone from a local repository"
@@ -5035,6 +5050,7 @@
 msgstr "建立從指定時間到現在的淺層複製"
 
 #: builtin/clone.c builtin/fetch.c builtin/pull.c builtin/rebase.c
+#: builtin/replay.c
 msgid "revision"
 msgstr "revision"
 
@@ -5062,6 +5078,10 @@
 msgid "separate git dir from working tree"
 msgstr "git 目錄和工作區分離"
 
+#: builtin/clone.c builtin/init-db.c
+msgid "specify the reference format to use"
+msgstr "指定要使用的引用格式"
+
 #: builtin/clone.c
 msgid "key=value"
 msgstr "key=value"
@@ -5211,11 +5231,10 @@
 msgid "You must specify a repository to clone."
 msgstr "您必須指定要複製的版本庫。"
 
-#: builtin/clone.c
-msgid ""
-"--bundle-uri is incompatible with --depth, --shallow-since, and --shallow-"
-"exclude"
-msgstr "--bundle-uri 與 --depth、--shallow-since 和 --shallow-exclude 不相容"
+#: builtin/clone.c builtin/init-db.c setup.c
+#, c-format
+msgid "unknown ref storage format '%s'"
+msgstr "未知的引用儲存格式 “%s”"
 
 #: builtin/clone.c
 #, c-format
@@ -5360,6 +5379,11 @@
 msgstr "兩直行之間的填充空間"
 
 #: builtin/column.c
+#, c-format
+msgid "%s must be non-negative"
+msgstr "%s 不得為負數"
+
+#: builtin/column.c
 msgid "--command must be the first argument"
 msgstr "--command 必須是第一個參數"
 
@@ -5376,14 +5400,14 @@
 "--stdin-commits]\n"
 "                       [--changed-paths] [--[no-]max-new-filters <n>] [--"
 "[no-]progress]\n"
-"                       <split options>"
+"                       <split-options>"
 msgstr ""
 "git commit-graph write [--object-dir <dir>] [--append]\n"
 "                       [--split[=<strategy>]] [--reachable | --stdin-packs | "
 "--stdin-commits]\n"
 "                       [--changed-paths] [--[no-]max-new-filters <n>] [--"
 "[no-]progress]\n"
-"                       <split options>"
+"                       <split-options>"
 
 #: builtin/commit-graph.c builtin/fetch.c builtin/log.c builtin/repack.c
 msgid "dir"
@@ -5692,7 +5716,7 @@
 "in the current commit message"
 msgstr "無法選擇一個未被目前提交說明使用的備註字元"
 
-#: builtin/commit.c builtin/merge-tree.c
+#: builtin/commit.c
 #, c-format
 msgid "could not lookup commit '%s'"
 msgstr "無法查詢提交 “%s”"
@@ -5727,7 +5751,7 @@
 #: builtin/commit.c bundle.c rerere.c sequencer.c
 #, c-format
 msgid "could not open '%s'"
-msgstr "不能開啟 '%s'"
+msgstr "無法開啟「%s」"
 
 #: builtin/commit.c
 msgid "could not write commit template"
@@ -5737,38 +5761,38 @@
 #, c-format
 msgid ""
 "Please enter the commit message for your changes. Lines starting\n"
-"with '%c' will be ignored.\n"
+"with '%s' will be ignored.\n"
 msgstr ""
 "請輸入描述您變更的提交訊息。\n"
-"開頭是「%c」的行皆會忽略。\n"
+"開頭是「%s」的列皆會忽略。\n"
 
 #: builtin/commit.c
 #, 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"
+"with '%s' will be ignored, and an empty message aborts the commit.\n"
 msgstr ""
-"請輸入描述您變更的提交訊息。開頭是「%c」\n"
-"的行皆會忽略。提交訊息空白則取消本次提交作業。\n"
+"請輸入描述您變更的提交訊息。開頭是「%s」的列\n"
+"皆會忽略。提交訊息空白則取消本次提交作業。\n"
 
 #: builtin/commit.c
 #, 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"
+"with '%s' will be kept; you may remove them yourself if you want to.\n"
 msgstr ""
-"請輸入描述您變更的提交訊息。會保留開頭是「%c」\n"
-"的行,但也可以自己移除掉這些行。\n"
+"請輸入描述您變更的提交訊息。會保留開頭是「%s」\n"
+"的列,但也可以自己移除掉這些列。\n"
 
 #: builtin/commit.c
 #, 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"
+"with '%s' will be kept; you may remove them yourself if you want to.\n"
 "An empty message aborts the commit.\n"
 msgstr ""
 "請輸入描述您變更的提交訊息。會保留開頭是\n"
-"「%c」的行,但也可以自己移除掉這些行。\n"
+"「%s」的列,但也可以自己移除掉這些列。\n"
 "提交訊息空白則取消本次提交作業。\n"
 
 #: builtin/commit.c
@@ -6000,7 +6024,7 @@
 msgid "override date for commit"
 msgstr "提交時覆蓋日期"
 
-#: builtin/commit.c builtin/merge-tree.c parse-options.h ref-filter.h
+#: builtin/commit.c parse-options.h ref-filter.h
 msgid "commit"
 msgstr "提交"
 
@@ -6327,6 +6351,10 @@
 msgstr "使用 --get 但未指定參數時所使用的預設值"
 
 #: builtin/config.c
+msgid "human-readable comment string (# will be prepended as needed)"
+msgstr "人類可讀的備註字串(將按需插入 # 至前方)"
+
+#: builtin/config.c
 #, c-format
 msgid "wrong number of arguments, should be %d"
 msgstr "錯誤的參數個數,應該為 %d 個"
@@ -6439,6 +6467,10 @@
 msgstr "--default 僅適用於 --get"
 
 #: builtin/config.c
+msgid "--comment is only applicable to add/set/replace operations"
+msgstr "--comment 只能用於加入、設定和取代動作"
+
+#: builtin/config.c
 msgid "--fixed-value only applies with 'value-pattern'"
 msgstr "--fixed-value 僅套用至 'value-pattern'"
 
@@ -7007,7 +7039,7 @@
 #: builtin/fetch.c
 #, c-format
 msgid "object %s not found"
-msgstr "物件 %s 未發現"
+msgstr "找不到物件 %s"
 
 #: builtin/fetch.c
 msgid "[up to date]"
@@ -7487,6 +7519,10 @@
 msgstr "從 stdin 讀取引用模式"
 
 #: builtin/for-each-ref.c
+msgid "also include HEAD ref and pseudorefs"
+msgstr "包含 HEAD 引用和偽引用"
+
+#: builtin/for-each-ref.c
 msgid "unknown arguments supplied with --stdin"
 msgstr "為 --stdin 提供的引數未知"
 
@@ -8248,6 +8284,7 @@
 msgid "invalid number of threads specified (%d) for %s"
 msgstr "為 %2$s 設定的執行緒數 (%1$d) 無效"
 
+#. #-#-#-#-#  grep.c.po  #-#-#-#-#
 #. TRANSLATORS: %s is the configuration
 #. variable for tweaking threads, currently
 #. grep.threads
@@ -8259,8 +8296,8 @@
 
 #: builtin/grep.c
 #, c-format
-msgid "unable to read tree (%s)"
-msgstr "無法讀取樹(%s)"
+msgid "unable to read tree %s"
+msgstr "無法讀取 %s 樹狀物件"
 
 #: builtin/grep.c
 #, c-format
@@ -8784,11 +8821,6 @@
 msgid "SHA1 COLLISION FOUND WITH %s !"
 msgstr "發現 %s 出現 SHA1 衝突!"
 
-#: builtin/index-pack.c builtin/pack-objects.c
-#, c-format
-msgid "unable to read %s"
-msgstr "不能讀 %s"
-
 #: builtin/index-pack.c
 #, c-format
 msgid "cannot read existing object info %s"
@@ -8962,11 +8994,13 @@
 msgid ""
 "git init [-q | --quiet] [--bare] [--template=<template-directory>]\n"
 "         [--separate-git-dir <git-dir>] [--object-format=<format>]\n"
+"         [--ref-format=<format>]\n"
 "         [-b <branch-name> | --initial-branch=<branch-name>]\n"
 "         [--shared[=<permissions>]] [<directory>]"
 msgstr ""
 "git init [-q | --quiet] [--bare] [--template=<template-directory>]\n"
 "         [--separate-git-dir <git-dir>] [--object-format=<format>]\n"
+"         [--ref-format=<format>]\n"
 "         [-b <branch-name> | --initial-branch=<branch-name>]\n"
 "         [--shared[=<permissions>]] [<directory>]"
 
@@ -9019,13 +9053,46 @@
 #: builtin/interpret-trailers.c
 msgid ""
 "git interpret-trailers [--in-place] [--trim-empty]\n"
-"                       [(--trailer (<key>|<keyAlias>)[(=|:)<value>])...]\n"
+"                       [(--trailer (<key>|<key-alias>)[(=|:)<value>])...]\n"
 "                       [--parse] [<file>...]"
 msgstr ""
 "git interpret-trailers [--in-place] [--trim-empty]\n"
-"                       [(--trailer (<key>|<keyAlias>)[(=|:)<value>])...]\n"
+"                       [(--trailer (<key>|<key-alias>)[(=|:)<value>])...]\n"
 "                       [--parse] [<file>...]"
 
+#: builtin/interpret-trailers.c wrapper.c
+#, c-format
+msgid "could not stat %s"
+msgstr "不能對 %s 呼叫 stat"
+
+#: builtin/interpret-trailers.c
+#, c-format
+msgid "file %s is not a regular file"
+msgstr "檔案 %s 不是一個正規檔案"
+
+#: builtin/interpret-trailers.c
+#, c-format
+msgid "file %s is not writable by user"
+msgstr "檔案 %s 使用者不可寫"
+
+#: builtin/interpret-trailers.c
+msgid "could not open temporary file"
+msgstr "不能開啟暫存檔"
+
+#: builtin/interpret-trailers.c
+#, c-format
+msgid "could not read input file '%s'"
+msgstr "不能讀取輸入檔案 '%s'"
+
+#: builtin/interpret-trailers.c builtin/mktag.c imap-send.c
+msgid "could not read from stdin"
+msgstr "不能自標準輸入讀取"
+
+#: builtin/interpret-trailers.c
+#, c-format
+msgid "could not rename temporary file to %s"
+msgstr "不能重新命名暫存檔為 %s"
+
 #: builtin/interpret-trailers.c
 msgid "edit files in place"
 msgstr "在原位編輯檔案"
@@ -9125,10 +9192,10 @@
 "<file>"
 msgstr "追蹤 <開始>,<結束> 範圍中橫列或 <檔案> 中> :<函數名稱> 的變化史"
 
-#: builtin/log.c builtin/shortlog.c bundle.c
+#: builtin/log.c builtin/replay.c builtin/shortlog.c bundle.c
 #, c-format
 msgid "unrecognized argument: %s"
-msgstr "無法識別的參數:%s"
+msgstr "無法識別的引數:%s"
 
 #: builtin/log.c
 msgid "-L<range>:<file> cannot be used with pathspec"
@@ -9524,21 +9591,6 @@
 msgstr "無法取得「%s」相關的物件資訊"
 
 #: builtin/ls-files.c
-#, c-format
-msgid "bad ls-files format: element '%s' does not start with '('"
-msgstr "ls-files 格式錯誤:“%s” 元素不以 “(” 開頭"
-
-#: builtin/ls-files.c
-#, c-format
-msgid "bad ls-files format: element '%s' does not end in ')'"
-msgstr "ls-files 格式錯誤:“%s” 元素不以 “)” 結尾"
-
-#: builtin/ls-files.c
-#, c-format
-msgid "bad ls-files format: %%%.*s"
-msgstr "ls-files 格式錯誤:%%%.*s"
-
-#: builtin/ls-files.c
 msgid "git ls-files [<options>] [<file>...]"
 msgstr "git ls-files [<選項>] [<檔案>...]"
 
@@ -9630,7 +9682,7 @@
 msgid "if any <file> is not in the index, treat this as an error"
 msgstr "如果任何 <檔案> 都不在索引區,視為錯誤"
 
-#: builtin/ls-files.c
+#: builtin/ls-files.c builtin/merge-tree.c
 msgid "tree-ish"
 msgstr "樹或提交"
 
@@ -9708,21 +9760,6 @@
 msgstr "git ls-tree [<選項>] <樹或提交> [<路徑>...]"
 
 #: builtin/ls-tree.c
-#, c-format
-msgid "bad ls-tree format: element '%s' does not start with '('"
-msgstr "無效的 ls-tree 格式:「%s」元素的開頭不是「(」"
-
-#: builtin/ls-tree.c
-#, c-format
-msgid "bad ls-tree format: element '%s' does not end in ')'"
-msgstr "無效的 ls-tree 格式:「%s」元素的結尾不是「)」"
-
-#: builtin/ls-tree.c
-#, c-format
-msgid "bad ls-tree format: %%%.*s"
-msgstr "無效的 ls-tree 格式:%%%.*s"
-
-#: builtin/ls-tree.c
 msgid "only show trees"
 msgstr "只顯示樹"
 
@@ -9868,6 +9905,13 @@
 "git merge-file [<選項>] [-L <檔案1> [-L <初始> [-L <名字2>]]] <檔案1> <初始文"
 "件> <檔案2>"
 
+#: builtin/merge-file.c diff.c
+msgid ""
+"option diff-algorithm accepts \"myers\", \"minimal\", \"patience\" and "
+"\"histogram\""
+msgstr ""
+"diff-algorithm 選項有 \"myers\"、\"minimal\"、\"patience\" 和 \"histogram\""
+
 #: builtin/merge-file.c
 msgid "send results to standard output"
 msgstr "將結果傳送到標準輸出"
@@ -9896,6 +9940,14 @@
 msgid "for conflicts, use a union version"
 msgstr "如果衝突,使用聯合版本"
 
+#: builtin/merge-file.c diff.c
+msgid "<algorithm>"
+msgstr "<演算法>"
+
+#: builtin/merge-file.c diff.c
+msgid "choose a diff algorithm"
+msgstr "選擇一個差異演算法"
+
 #: builtin/merge-file.c
 msgid "for conflicts, use this marker size"
 msgstr "如果衝突,使用指定長度的標記"
@@ -9947,6 +9999,11 @@
 msgid "Merging %s with %s\n"
 msgstr "合併 %s 和 %s\n"
 
+#: builtin/merge-tree.c
+#, c-format
+msgid "could not parse as tree '%s'"
+msgstr "無法解析為樹狀物件「%s」"
+
 #: builtin/merge-tree.c builtin/merge.c
 msgid "not something we can merge"
 msgstr "不能合併"
@@ -10012,10 +10069,6 @@
 msgid "unknown strategy option: -X%s"
 msgstr "未知的策略選項:-X%s"
 
-#: builtin/merge-tree.c
-msgid "--merge-base is incompatible with --stdin"
-msgstr "--merge-base 與 --stdin 不相容"
-
 #: builtin/merge-tree.c builtin/notes.c
 #, c-format
 msgid "malformed input line: '%s'."
@@ -10174,7 +10227,7 @@
 msgid "Bad branch.%s.mergeoptions string: %s"
 msgstr "壞的 branch.%s.mergeoptions 字串:%s"
 
-#: builtin/merge.c builtin/stash.c merge-recursive.c
+#: builtin/merge.c merge-recursive.c
 msgid "Unable to write index."
 msgstr "不能寫入索引。"
 
@@ -10182,7 +10235,7 @@
 msgid "Not handling anything other than two heads merge."
 msgstr "未處理兩個頭合併之外的任何動作。"
 
-#: builtin/merge.c t/helper/test-fast-rebase.c
+#: builtin/merge.c
 #, c-format
 msgid "unable to write %s"
 msgstr "不能寫 %s"
@@ -10214,9 +10267,9 @@
 #: builtin/merge.c
 #, c-format
 msgid ""
-"Lines starting with '%c' will be ignored, and an empty message aborts\n"
+"Lines starting with '%s' will be ignored, and an empty message aborts\n"
 "the commit.\n"
-msgstr "以 '%c' 開始的行將被忽略,而空的提交說明將終止提交。\n"
+msgstr "以「%s」開始的列將被忽略,提交說明留空則會終止提交。\n"
 
 #: builtin/merge.c
 msgid "Empty commit message."
@@ -10409,10 +10462,6 @@
 msgid "object '%s' tagged as '%s', but is a '%s' type"
 msgstr "「%s」已標為「%s」,但卻是「%s」類型"
 
-#: builtin/mktag.c imap-send.c trailer.c
-msgid "could not read from stdin"
-msgstr "不能自標準輸入讀取"
-
 #: builtin/mktag.c
 msgid "tag on stdin did not pass our strict fsck check"
 msgstr "stdin 上的標籤未通過我們的嚴格 fsck 檢查"
@@ -10625,7 +10674,7 @@
 
 #: builtin/name-rev.c
 msgid "deprecated: use --annotate-stdin instead"
-msgstr "已廢棄:請改用 --annotate-stdin"
+msgstr "已棄用:請改用 --annotate-stdin"
 
 #: builtin/name-rev.c
 msgid "annotate text from stdin"
@@ -10745,11 +10794,6 @@
 msgstr "為下面的物件寫/編輯說明:"
 
 #: builtin/notes.c
-#, c-format
-msgid "unable to start 'show' for object '%s'"
-msgstr "不能為物件 '%s' 開始 'show'"
-
-#: builtin/notes.c
 msgid "could not read 'show' output"
 msgstr "不能讀取 'show' 的輸出"
 
@@ -10892,8 +10936,8 @@
 "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 ""
-"子指令 'edit' 的選項 -m/-F/-c/-C 已棄用。\n"
-"請換用 'git notes add -f -m/-F/-c/-C'。\n"
+"子指令「edit」的選項 -m/-F/-c/-C 已棄用。\n"
+"請換用「git notes add -f -m/-F/-c/-C」。\n"
 
 #: builtin/notes.c
 msgid "failed to delete ref NOTES_MERGE_PARTIAL"
@@ -11170,12 +11214,17 @@
 
 #: builtin/pack-objects.c
 #, c-format
+msgid "invalid pack.allowPackReuse value: '%s'"
+msgstr "無效的 pack.allowPackReuse 值:“%s”"
+
+#: builtin/pack-objects.c
+#, c-format
 msgid ""
 "value of uploadpack.blobpackfileuri must be of the form '<object-hash> <pack-"
 "hash> <uri>' (got '%s')"
 msgstr ""
-"uploadpack.blobpackfileuri 的值格式必須為 '<object-hash> <pack-hash> "
-"<uri>' (收到 '%s')"
+"uploadpack.blobpackfileuri 的值格式必須為 '<object-hash> <pack-hash> <uri>' "
+"(收到 '%s')"
 
 #: builtin/pack-objects.c
 #, c-format
@@ -11492,10 +11541,10 @@
 #, c-format
 msgid ""
 "Total %<PRIu32> (delta %<PRIu32>), reused %<PRIu32> (delta %<PRIu32>), pack-"
-"reused %<PRIu32>"
+"reused %<PRIu32> (from %<PRIuMAX>)"
 msgstr ""
 "總共 %<PRIu32> (差異 %<PRIu32>),復用 %<PRIu32> (差異 %<PRIu32>),重用包 "
-"%<PRIu32>"
+"%<PRIu32> (總共 %<PRIuMAX>)"
 
 #: builtin/pack-redundant.c
 msgid ""
@@ -11517,10 +11566,10 @@
 
 #: builtin/pack-refs.c
 msgid ""
-"git pack-refs [--all] [--no-prune] [--include <pattern>] [--exclude "
+"git pack-refs [--all] [--no-prune] [--auto] [--include <pattern>] [--exclude "
 "<pattern>]"
 msgstr ""
-"git pack-refs [--all] [--no-prune] [--include <pattern>] [--exclude "
+"git pack-refs [--all] [--no-prune] [--auto] [--include <pattern>] [--exclude "
 "<pattern>]"
 
 #: builtin/pack-refs.c
@@ -11532,6 +11581,10 @@
 msgstr "剪除鬆散引用(預設值)"
 
 #: builtin/pack-refs.c
+msgid "auto-pack refs as needed"
+msgstr "按需自動封裝引用"
+
+#: builtin/pack-refs.c
 msgid "references to include"
 msgstr "要包含的引用"
 
@@ -12295,19 +12348,6 @@
 msgstr "無法刪除 '%s'"
 
 #: builtin/rebase.c
-msgid ""
-"Resolve all conflicts manually, mark them as resolved with\n"
-"\"git add/rm <conflicted_files>\", then run \"git rebase --continue\".\n"
-"You can instead skip this commit: run \"git rebase --skip\".\n"
-"To abort and get back to the state before \"git rebase\", run \"git rebase --"
-"abort\"."
-msgstr ""
-"手動解決所有衝突,執行 \"git add/rm <衝突的檔案>\" 標記\n"
-"衝突已解決,然後執行 \"git rebase --continue\"。您也可以執行\n"
-"\"git rebase --skip\" 指令略過這個提交。如果想要終止執行並回到\n"
-"\"git rebase\" 執行之前的狀態,執行 \"git rebase --abort\"。"
-
-#: builtin/rebase.c
 #, c-format
 msgid ""
 "\n"
@@ -12340,11 +12380,15 @@
 msgstr "套用選項與合併選項不得同時使用"
 
 #: builtin/rebase.c
+msgid "--empty=ask is deprecated; use '--empty=stop' instead."
+msgstr "--empty=ask 已棄用。請改用「--empty=stop」。"
+
+#: builtin/rebase.c
 #, c-format
 msgid ""
 "unrecognized empty type '%s'; valid values are \"drop\", \"keep\", and "
-"\"ask\"."
-msgstr "無法識別的 '%s' 空類型;有效的數值有 \"drop\"、\"keep\" 跟 \"ask\"。"
+"\"stop\"."
+msgstr "無法識別空類型「%s」;有效的數值有「drop」、「keep」跟「stop」。"
 
 #: builtin/rebase.c
 msgid ""
@@ -12486,7 +12530,7 @@
 msgid "(REMOVED) was: try to recreate merges instead of ignoring them"
 msgstr "(已移除)曾為:嘗試重新建立,而非忽略合併"
 
-#: builtin/rebase.c
+#: builtin/rebase.c builtin/revert.c
 msgid "how to handle commits that become empty"
 msgstr "處理空白提交的方式"
 
@@ -12567,14 +12611,14 @@
 "請改用 “merges”"
 
 #: builtin/rebase.c
-msgid "No rebase in progress?"
-msgstr "沒有正在進行的重定基底?"
+msgid "no rebase in progress"
+msgstr "沒有進行中的重定基底流程"
 
 #: builtin/rebase.c
 msgid "The --edit-todo action can only be used during interactive rebase."
 msgstr "動作 --edit-todo 只能用在互動式重定基底過程中。"
 
-#: builtin/rebase.c t/helper/test-fast-rebase.c
+#: builtin/rebase.c
 msgid "Cannot read HEAD"
 msgstr "不能讀取 HEAD"
 
@@ -12620,12 +12664,6 @@
 
 #: builtin/rebase.c
 msgid ""
-"apply options are incompatible with rebase.autoSquash.  Consider adding --no-"
-"autosquash"
-msgstr "apply 選項與 rebase.autoSquash 不相容。請考慮加上 --no-autosquash"
-
-#: builtin/rebase.c
-msgid ""
 "apply options are incompatible with rebase.rebaseMerges.  Consider adding --"
 "no-rebase-merges"
 msgstr "apply 選項與 rebase.rebaseMerges 不相容。請考慮加上 --no-rebase-merges"
@@ -12791,6 +12829,10 @@
 msgstr "git reflog [show] [<log-options>] [<ref>]"
 
 #: builtin/reflog.c
+msgid "git reflog list"
+msgstr "git reflog list"
+
+#: builtin/reflog.c
 msgid ""
 "git reflog expire [--expire=<time>] [--expire-unreachable=<time>]\n"
 "                  [--rewrite] [--updateref] [--stale-fix]\n"
@@ -12819,6 +12861,11 @@
 msgid "invalid timestamp '%s' given to '--%s'"
 msgstr "傳入「--%s」的時間戳「%s」無效"
 
+#: builtin/reflog.c sequencer.c
+#, c-format
+msgid "%s does not accept arguments: '%s'"
+msgstr "%s 不接受參數:'%s'"
+
 #: builtin/reflog.c
 msgid "do not actually prune any entries"
 msgstr "不實際剪除任何項目"
@@ -12973,13 +13020,13 @@
 "--mirror is dangerous and deprecated; please\n"
 "\t use --mirror=fetch or --mirror=push instead"
 msgstr ""
-"--mirror 選項危險且過時,請使用 --mirror=fetch\n"
+"--mirror 選項危險且已棄用,請使用 --mirror=fetch\n"
 "\t 或 --mirror=push"
 
 #: builtin/remote.c
 #, c-format
-msgid "unknown mirror argument: %s"
-msgstr "未知的鏡像參數:%s"
+msgid "unknown --mirror argument: %s"
+msgstr "未知的 --mirror 引數:%s"
 
 #: builtin/remote.c
 msgid "fetch the remote branches"
@@ -13109,7 +13156,7 @@
 msgid_plural ""
 "Note: Some branches outside the refs/remotes/ hierarchy were not removed;\n"
 "to delete them, use:"
-msgstr[0] "注意:ref/remotes 層級之外的一個分支未被移除。要刪除它,使用:"
+msgstr[0] "注意:refs/remotes/ 層級之外的一個分支未被移除。要刪除它,使用:"
 
 #: builtin/remote.c
 #, c-format
@@ -13429,6 +13476,10 @@
 msgstr "無法開始 pack-objects 來重新打包 promisor 物件"
 
 #: builtin/repack.c
+msgid "failed to feed promisor objects to pack-objects"
+msgstr "無法將承諾者物件喂給 pack-objects"
+
+#: builtin/repack.c
 msgid "repack: Expecting full hex object ID lines only from pack-objects."
 msgstr "repack:期望來自 pack-objects 的完整十六進位物件 ID。"
 
@@ -13838,6 +13889,86 @@
 msgid "only one pattern can be given with -l"
 msgstr "只能為 -l 提供一個模式"
 
+#: builtin/replay.c
+msgid "need some commits to replay"
+msgstr "需要一些提交才能重放"
+
+#: builtin/replay.c